Metaplex Bubblegum(cNFT)でdelegateすると「PublicKeyMismatch」エラー

Bubblegum - Revoking a Delegate Authority を試していたときに発生したエラー。

現象

実行すると以下のエラーが発生。

PublicKeyMismatch: PublicKeyMismatch

Source: Program > mplBubblegum [BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY]

Caused By: Error: failed to send transaction: Transaction simulation failed: Error processing Instruction 0: custom program error: 0x1771

Program Logs:
| Program BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY invoke [1]
| Program log: Instruction: Delegate
| Program noopb9bkMVfRPU8AsbpTUg8AQkHtKwMYZiFUjNRtMmV invoke [2]
| Program noopb9bkMVfRPU8AsbpTUg8AQkHtKwMYZiFUjNRtMmV consumed 97 of 183791 compute units
| Program noopb9bkMVfRPU8AsbpTUg8AQkHtKwMYZiFUjNRtMmV success
| Program cmtDvXumGCrqC1Age74AVPhSRVXJMd8PJS91L8KbNCK invoke [2]
| Program log: Instruction: ReplaceLeaf
| Program log: Attempting to fill in proof
| Program consumption: 145462 units remaining
| Program log: Active Index: 4
| Program log: Rightmost Index: 3
| Program log: Buffer Size: 5
| Program log: Leaf Index: 0
| Program log: Fast-forwarding proof, starting index 4
| Program consumption: 142569 units remaining
| Program consumption: 142465 units remaining
| Program log: Error using concurrent merkle tree: Invalid root recomputed from proof
| Program log: AnchorError thrown in programs/account-compression/src/lib.rs:273. Error Code: ConcurrentMerkleTreeError. Error Number: 6001. Error Message: Concurrent merkle tree error.
| Program cmtDvXumGCrqC1Age74AVPhSRVXJMd8PJS91L8KbNCK consumed 33162 of 169095 compute units
| Program cmtDvXumGCrqC1Age74AVPhSRVXJMd8PJS91L8KbNCK failed: custom program error: 0x1771
| Program BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY consumed 64067 of 200000 compute units
| Program BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY failed: custom program error: 0x1771

    at getMplBubblegumErrorFromCode (/Users/metaplex/bubblegum_CompressedNFT/node_modules/@metaplex-foundation/mpl-bubblegum/src/generated/errors/mplBubblegum.ts:591:24)
    at Object.getErrorFromCode (/Users/metaplex/bubblegum_CompressedNFT/node_modules/@metaplex-foundation/mpl-bubblegum/src/generated/programs/mplBubblegum.ts:28:42)
    at Object.resolveError (/Users/metaplex/bubblegum_CompressedNFT/node_modules/@metaplex-foundation/umi-program-repository/src/createDefaultProgramRepository.ts:135:35)
    at Object.sendTransaction (/Users/metaplex/bubblegum_CompressedNFT/node_modules/@metaplex-foundation/umi-rpc-web3js/src/createWeb3JsRpc.ts:335:42)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async TransactionBuilder.sendAndConfirm (/Users/metaplex/bubblegum_CompressedNFT/node_modules/@metaplex-foundation/umi/src/TransactionBuilder.ts:359:23)
    at async approvingDelegateAuthority (/Users/metaplex/bubblegum_CompressedNFT/src/revokingDelegateAuthority.ts:49:18) {
  source: 'program',
  sourceDetails: 'mplBubblegum [BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY]',
  cause: SendTransactionError: failed to send transaction: Transaction simulation failed: Error processing Instruction 0: custom program error: 0x1771
      at Connection.sendEncodedTransaction (/Users/metaplex/bubblegum_CompressedNFT/node_modules/@solana/web3.js/src/connection.ts:5920:13)
      at processTicksAndRejections (node:internal/process/task_queues:95:5)
      at async Connection.sendRawTransaction (/Users/metaplex/bubblegum_CompressedNFT/node_modules/@solana/web3.js/src/connection.ts:5879:20)
      at async Object.sendTransaction (/Users/metaplex/bubblegum_CompressedNFT/node_modules/@metaplex-foundation/umi-rpc-web3js/src/createWeb3JsRpc.ts:327:25)
      at async TransactionBuilder.sendAndConfirm (/Users/metaplex/bubblegum_CompressedNFT/node_modules/@metaplex-foundation/umi/src/TransactionBuilder.ts:359:23)
      at async approvingDelegateAuthority (/Users/metaplex/bubblegum_CompressedNFT/src/revokingDelegateAuthority.ts:49:18) {
    logs: [
      'Program BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY invoke [1]',
      'Program log: Instruction: Delegate',
      'Program noopb9bkMVfRPU8AsbpTUg8AQkHtKwMYZiFUjNRtMmV invoke [2]',
      'Program noopb9bkMVfRPU8AsbpTUg8AQkHtKwMYZiFUjNRtMmV consumed 97 of 183791 compute units',
      'Program noopb9bkMVfRPU8AsbpTUg8AQkHtKwMYZiFUjNRtMmV success',
      'Program cmtDvXumGCrqC1Age74AVPhSRVXJMd8PJS91L8KbNCK invoke [2]',
      'Program log: Instruction: ReplaceLeaf',
      'Program log: Attempting to fill in proof',
      'Program consumption: 145462 units remaining',
      'Program log: Active Index: 4',
      'Program log: Rightmost Index: 3',
      'Program log: Buffer Size: 5',
      'Program log: Leaf Index: 0',
      'Program log: Fast-forwarding proof, starting index 4',
      'Program consumption: 142569 units remaining',
      'Program consumption: 142465 units remaining',
      'Program log: Error using concurrent merkle tree: Invalid root recomputed from proof',
      'Program log: AnchorError thrown in programs/account-compression/src/lib.rs:273. Error Code: ConcurrentMerkleTreeError. Error Number: 6001. Error Message: Concurrent merkle tree error.',
      'Program cmtDvXumGCrqC1Age74AVPhSRVXJMd8PJS91L8KbNCK consumed 33162 of 169095 compute units',
      'Program cmtDvXumGCrqC1Age74AVPhSRVXJMd8PJS91L8KbNCK failed: custom program error: 0x1771',
      'Program BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY consumed 64067 of 200000 compute units',
      'Program BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY failed: custom program error: 0x1771'
    ]
  },
  program: {
    name: 'mplBubblegum',
    publicKey: 'BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY',
    getErrorFromCode: [Function: getErrorFromCode],
    getErrorFromName: [Function: getErrorFromName],
    isOnCluster: [Function: isOnCluster]
  },
  logs: [
    'Program BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY invoke [1]',
    'Program log: Instruction: Delegate',
    'Program noopb9bkMVfRPU8AsbpTUg8AQkHtKwMYZiFUjNRtMmV invoke [2]',
    'Program noopb9bkMVfRPU8AsbpTUg8AQkHtKwMYZiFUjNRtMmV consumed 97 of 183791 compute units',
    'Program noopb9bkMVfRPU8AsbpTUg8AQkHtKwMYZiFUjNRtMmV success',
    'Program cmtDvXumGCrqC1Age74AVPhSRVXJMd8PJS91L8KbNCK invoke [2]',
    'Program log: Instruction: ReplaceLeaf',
    'Program log: Attempting to fill in proof',
    'Program consumption: 145462 units remaining',
    'Program log: Active Index: 4',
    'Program log: Rightmost Index: 3',
    'Program log: Buffer Size: 5',
    'Program log: Leaf Index: 0',
    'Program log: Fast-forwarding proof, starting index 4',
    'Program consumption: 142569 units remaining',
    'Program consumption: 142465 units remaining',
    'Program log: Error using concurrent merkle tree: Invalid root recomputed from proof',
    'Program log: AnchorError thrown in programs/account-compression/src/lib.rs:273. Error Code: ConcurrentMerkleTreeError. Error Number: 6001. Error Message: Concurrent merkle tree error.',
    'Program cmtDvXumGCrqC1Age74AVPhSRVXJMd8PJS91L8KbNCK consumed 33162 of 169095 compute units',
    'Program cmtDvXumGCrqC1Age74AVPhSRVXJMd8PJS91L8KbNCK failed: custom program error: 0x1771',
    'Program BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY consumed 64067 of 200000 compute units',
    'Program BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY failed: custom program error: 0x1771'
  ],
  code: 6001
}

ソース


// Lib import * as bs58 from 'bs58'; import * as dotenv from 'dotenv'; // Metaplex import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'; import { keypairIdentity, publicKey, createSignerFromKeypair, } from '@metaplex-foundation/umi'; import { mplBubblegum, getAssetWithProof, delegate, } from '@metaplex-foundation/mpl-bubblegum'; const revokingDelegateAuthority = async () => { // ---------------------------------------------------- // Setup // ---------------------------------------------------- dotenv.config(); const endpoint = process.env.ENDPOINT; if (!endpoint) throw new Error('endpoint not found.'); const umi = createUmi(endpoint); // Set Payer const payerSecretKey = process.env.PAYER_SECRET_KEY; if (!payerSecretKey) throw new Error('payerSecretKey not found.'); const secretKeyUInt8Array = new Uint8Array(JSON.parse(payerSecretKey)); const payerKeypair = umi.eddsa.createKeypairFromSecretKey(secretKeyUInt8Array); umi.use(keypairIdentity(payerKeypair)); // Register Library umi.use(mplBubblegum()); // ---------------------------------------------------- // Approving a Delegate Authority // ---------------------------------------------------- const assetId = publicKey('HUotfePKvFWoCo7tYYv5YUkJZfif8sTbFNB2pn47Pt2u'); let assetWithProof = await getAssetWithProof(umi, assetId); const leafOwner = createSignerFromKeypair(umi, payerKeypair); const newDelegate = publicKey('HXtBm8XZbxaTt41uqaKhwUAa6Z1aPyvJdsZVENiWsetg'); const result = await delegate(umi, { ...assetWithProof, leafOwner, previousLeafDelegate: leafOwner.publicKey, newLeafDelegate: newDelegate, }).sendAndConfirm(umi); console.log('assetId =>', assetId); console.log('assetWithProof =>', assetWithProof); console.log('leafOwner =>', leafOwner.publicKey); console.log('newDelegate =>', newDelegate); console.log('signature =>', bs58.encode(result.signature)); console.log('\n--- After delegate ---------------------------------------------------'); assetWithProof = await getAssetWithProof(umi, assetId); console.log('assetWithProof =>', assetWithProof); }; revokingDelegateAuthority();

原因

delegateで指定したアドレスが誤っているため。

今回のケースでは、 現在のdelegate previousLeafDelegate: leafOwner.publicKey, が誤っていた。

対応

現在のdelegateに正しいアドレスをセットする。

以下、修正箇所の抜粋。

ソース

...
  // 現在のdelegateを指定
  const currentDelegate = publicKey('55AfqEL3TC9mpkDZ63UCgDrzPcMQd5aZtDegfQCWQ5tK');

  const result = await delegate(umi, {
    ...assetWithProof,
    leafOwner,
    previousLeafDelegate: currentDelegate, // 現在のdelegateを指定
    newLeafDelegate: newDelegate,
  }).sendAndConfirm(umi);
...

補足1(最初からやり直す)

どうしても解決できない場合は、Merkle Tree作成からやり直して、cNFT送信できるかテスト的に試すのがおすすめ。

  1. Merkle Tree作成
  2. Mint to Collection(コレクションに紐付けてcNFT発行)
  3. cNFTを他者に送信

ここまで成功していれば、delegateもできるはず。

補足2(バグかもしれない)

急に動かなくなることがあるため、Discordでエラーコードやメッセージを検索したり、質問してみる。
今回のケースだとMetaplexとHeliusのDiscordで情報が見つかったが、だいたい以下の順に調べるのがおすすめ。

  • Metaplex Discord
  • Helius Discord (使っているRPCにあわせて調べる。ShyftだったらShyftのDiscord)
  • Solana Tech Discord

即時性の高いバグだと、X、Google、Solana StackExchangeでは、おそらく情報見つからず、Discord頼みになる。