Skip to content

Error: The signer is not the owner #150

@ltfschoen

Description

@ltfschoen

As discussed with @andreevmaks in Unique Telegram support I was getting this error when trying to transfer an NFT token from one address to a different address.

I eventually established that the cause was because const { owner } = await sdk.token.owner(nft); was returning the Quartz network SS58 address (e.g. yGDNPKqns41j19kwFHRdmBRsuGgUzUm3PueF6Jh5NhxKeS4PB), whereas const { address } = await KeyringProvider.fromMnemonic(mnemonic) was returning the equivalent SS58 Substrate address with prefix 42 (not the Quartz parachain address with prefix 255) (e.g. 5Chai5UGBHXFrXXcHtDypVWdvHnjrny2rDtfa9RHbM3JGpCw), where Quartz network uses address prefix 255 instead of 42 https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fus-ws-quartz.unique.network#/settings/metadata.

So to get it to transfer I had to provide keyringOptions when loading the keyring account as shown below to ensure the ownerAccount matched the owner variable.

...
import { KeyringOptions } from '@polkadot/keyring/types';
...

async function main() {
  const mnemonic = process.env.WALLET_SEED ?? ""
  const keyringOptions: KeyringOptions = {
    /** The ss58Format to use for address encoding (defaults to 42) */
    ss58Format: 255, // Quartz network https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fus-ws-quartz.unique.network#/settings/metadata
    /** The type of keyring to create (defaults to ed25519) */
    type: 'sr25519',
  }
  const ownerAccount = await KeyringProvider.fromMnemonic(mnemonic, keyringOptions)
  const ownerAddress = ownerAccount.address

  const sdk = new Sdk({
    baseUrl: CHAIN_CONFIG.quartz.restUrl, 
    signer: ownerAccount,
  })
  ...

  const nft = {
    collectionId: 827,
    tokenId: 3
  };

  const { owner } = await sdk.token.owner(nft);
  console.log(`signer: ${ownerAddress}, actual owner: ${owner}`)
  if (ownerAddress !== owner) throw Error("The signer is not the owner");

It is understood that this is incorrect behaviour and will be fixed, as "ss58Format should only visually change the account's address representation and should not affect signing"

An alternative approach to initialize the SDK without the @PolkaDot dependency was shared by @andreevmaks as follows that uses "@unique-nft/sr25519", which is a pure js implementation of sr25519:

import Sdk, { CHAIN_CONFIG } from "@unique-nft/sdk";
import { Sr25519Account } from "@unique-nft/sr25519";

const mnemonic = process.env.WALLET_SEED ?? ""
const account = Sr25519Account.fromUri(mnemonicOwner);

const sdk = new Sdk({
  baseUrl: CHAIN_CONFIG.quartz.restUrl,
  account
});

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions