0

I'm trying to create a token and its metadata using CPI (anchor lang). Everything works except verifying creators.

Transaction is first created in backend, on client side it is signed and backend signs right before sending the transaction. Both creators (backend, client) successfully sign the transaction. But when MPL token metadata is invoked, it asks You cannot unilaterally verify another creator, they must sign error.

How to properly provide signers using CPI?

Rust program:

    pub fn create_some_tokens(
        ctx: Context<CreateToken>,
        name: String,
        uri: String,
        symbol: String,
        creators: Vec<CreateTokenCreator>,
    ) -> Result<()> {
        let signer_seeds: &[&[&[u8]]] = &[&[
            b"metadata-update-authority",
            &[ctx.bumps.metadata_update_authority],
        ]];

        let data = DataV2 {
            name,
            uri,
            symbol,
            seller_fee_basis_points: 30_00,
            creators: Some(
                creators
                    .iter()
                    .map(|x| Creator {
                        address: x.address,
                        share: x.share,
                        verified: x.verified,
                    })
                    .collect(),
            ),
            collection: None,
            uses: None,
        };

        initialize_mint2(
            CpiContext::new(
                ctx.accounts.token_mint_program.to_account_info(),
                InitializeMint2 {
                    mint: ctx.accounts.token_mint.to_account_info(),
                },
            ),
            0,
            &ctx.accounts.token_mint_authority.key(),
            Some(&ctx.accounts.freeze_authority.key()),
        )?;

        CreateMetadataAccountV3CpiBuilder::new(&ctx.accounts.mpl_token_metadata_program)
            .update_authority(&ctx.accounts.metadata_update_authority, true)
            .system_program(&ctx.accounts.system_program)
            .payer(&ctx.accounts.payer)
            .mint_authority(&ctx.accounts.token_mint_authority)
            .mint(&ctx.accounts.token_mint)
            .metadata(&ctx.accounts.token_metadata_account)
            .is_mutable(true)
            .data(data)
            .add_remaining_accounts(&[
                (&ctx.accounts.payer, true, true),
                (&ctx.accounts.service_fee_recipient, false, true),
            ])
            .invoke_signed(signer_seeds)?;

        Ok(())
    }

Transaction details from backend right before sending:

_json: {
      recentBlockhash: 'EF2ekPhp9WiXghtAnHL88suydHKiMXMB7KKNJhyFTxXT',
      feePayer: '6tNwRrMUC6xsmwzig9NNqoSVRDZ1N7nBusCDNGtAnbm3',
      nonceInfo: null,
      instructions: [
        {
          keys: [
            {
              pubkey: '6tNwRrMUC6xsmwzig9NNqoSVRDZ1N7nBusCDNGtAnbm3',
              isSigner: true,
              isWritable: true
            },
            {
              pubkey: 'DYsFEpDiT52AXZASecVRkd9dyN6icmKfpVqncKAzRJNY',
              isSigner: true,
              isWritable: true
            }
          ],
          programId: '11111111111111111111111111111111',
          data: [
              0,   0,   0,   0,  96,  77,  22,   0,   0,  0,   0,
              0,  82,   0,   0,   0,   0,   0,   0,   0,  6, 221,
            246, 225, 215, 101, 161, 147, 217, 203, 225, 70, 206,
            235, 121, 172,  28, 180, 133, 237,  95,  91, 55, 145,
             58, 140, 245, 133, 126, 255,   0, 169
          ]
        },
        {
          keys: [
            {
              pubkey: '8UEWSHNkix5fL3hPzmC1p7jScqR7uLFwWv4CKDkMUnnh',
              isSigner: false,
              isWritable: true
            },
            {
              pubkey: 'DYsFEpDiT52AXZASecVRkd9dyN6icmKfpVqncKAzRJNY',
              isSigner: true,
              isWritable: true
            },
            {
              pubkey: 'GwqxCtj42vv12gRTs3rAV1A2a5dBnAJZ8zmNcE19ELxY',
              isSigner: false,
              isWritable: true
            },
            {
              pubkey: '6tNwRrMUC6xsmwzig9NNqoSVRDZ1N7nBusCDNGtAnbm3',
              isSigner: true,
              isWritable: true
            },
            {
              pubkey: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
              isSigner: false,
              isWritable: false
            },
            {
              pubkey: 'EmEbYbmAJKJZ15bb8zfXdszZdJ2a1MV6gWEw8Rr3nVFr',
              isSigner: false,
              isWritable: true
            },
            {
              pubkey: 'FiLhF9CatW4HvwcY9Ly25fCwPQho4MAYSzqZLwMFPiEH',
              isSigner: false,
              isWritable: false
            },
            {
              pubkey: '6tNwRrMUC6xsmwzig9NNqoSVRDZ1N7nBusCDNGtAnbm3',
              isSigner: true,
              isWritable: true
            },
            {
              pubkey: '8baMHRmtq5fbXeYcpUdoHqSEFQe4GEa8mfvc9qWxXntb',
              isSigner: true,
              isWritable: true
            },
            {
              pubkey: '11111111111111111111111111111111',
              isSigner: false,
              isWritable: false
            },
            {
              pubkey: 'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s',
              isSigner: false,
              isWritable: false
            }
          ],
          programId: 'BN542RvJA1bg8nZ5qmDVp3MuDJgovXQiH1fbtqUT8YkR',
          data: [
             65,  40, 218,  29,  41,  58, 145, 108,   7,   0,   0,   0,
             87,  82,  73,  84,  84,  69,  78,  51,   0,   0,   0, 104,
            116, 116, 112,  58,  47,  47, 108, 111,  99,  97, 108, 104,
            111, 115, 116,  58,  51,  48,  48,  49,  47,  97, 112, 105,
             47, 118,  49,  47, 116, 111, 107, 101, 110, 115,  47, 105,
            110, 102, 111,  47,  78,  84,  71, 110,  81,  90, 118, 104,
            118, 110,   4,   0,   0,   0,  87,  82,  84,  78,   2,   0,
              0,   0,  87, 115, 220, 155, 118, 202, 201, 224,  66,  38,
             84,  92, 193, 208,
            ... 54 more items
          ]
        },
        {
          keys: [
            {
              pubkey: '6tNwRrMUC6xsmwzig9NNqoSVRDZ1N7nBusCDNGtAnbm3',
              isSigner: true,
              isWritable: true
            },
            {
              pubkey: 'GwqxCtj42vv12gRTs3rAV1A2a5dBnAJZ8zmNcE19ELxY',
              isSigner: false,
              isWritable: true
            },
            {
              pubkey: '6tNwRrMUC6xsmwzig9NNqoSVRDZ1N7nBusCDNGtAnbm3',
              isSigner: true,
              isWritable: true
            },
            {
              pubkey: 'DYsFEpDiT52AXZASecVRkd9dyN6icmKfpVqncKAzRJNY',
              isSigner: true,
              isWritable: true
            },
            {
              pubkey: '11111111111111111111111111111111',
              isSigner: false,
              isWritable: false
            },
            {
              pubkey: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
              isSigner: false,
              isWritable: false
            }
          ],
          programId: 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL',
          data: [ 1 ]
        },
        {
          keys: [
            {
              pubkey: '6tNwRrMUC6xsmwzig9NNqoSVRDZ1N7nBusCDNGtAnbm3',
              isSigner: true,
              isWritable: true
            },
            {
              pubkey: 'B3jM5ycV6USQQjBe89s49tbrM4gBhY9vmVt89TjgdGBb',
              isSigner: false,
              isWritable: true
            },
            {
              pubkey: '6tNwRrMUC6xsmwzig9NNqoSVRDZ1N7nBusCDNGtAnbm3',
              isSigner: true,
              isWritable: true
            },
            {
              pubkey: 'So11111111111111111111111111111111111111112',
              isSigner: false,
              isWritable: false
            },
            {
              pubkey: '11111111111111111111111111111111',
              isSigner: false,
              isWritable: false
            },
            {
              pubkey: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
              isSigner: false,
              isWritable: false
            }
          ],
          programId: 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL',
          data: [ 1 ]
        },
        {
          keys: [
            {
              pubkey: '6tNwRrMUC6xsmwzig9NNqoSVRDZ1N7nBusCDNGtAnbm3',
              isSigner: true,
              isWritable: true
            },
            {
              pubkey: '2wa3wiYPwtoGhceSPQWsMGDkHDcCyip7ejc2T1qWisLn',
              isSigner: false,
              isWritable: true
            },
            {
              pubkey: '8baMHRmtq5fbXeYcpUdoHqSEFQe4GEa8mfvc9qWxXntb',
              isSigner: true,
              isWritable: true
            },
            {
              pubkey: 'So11111111111111111111111111111111111111112',
              isSigner: false,
              isWritable: false
            },
            {
              pubkey: '11111111111111111111111111111111',
              isSigner: false,
              isWritable: false
            },
            {
              pubkey: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
              isSigner: false,
              isWritable: false
            }
          ],
          programId: 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL',
          data: [ 1 ]
        },
        {
          keys: [
            {
              pubkey: '8baMHRmtq5fbXeYcpUdoHqSEFQe4GEa8mfvc9qWxXntb',
              isSigner: true,
              isWritable: true
            },
            {
              pubkey: '8UEWSHNkix5fL3hPzmC1p7jScqR7uLFwWv4CKDkMUnnh',
              isSigner: false,
              isWritable: true
            },
            {
              pubkey: 'DYsFEpDiT52AXZASecVRkd9dyN6icmKfpVqncKAzRJNY',
              isSigner: true,
              isWritable: true
            },
            {
              pubkey: 'GwqxCtj42vv12gRTs3rAV1A2a5dBnAJZ8zmNcE19ELxY',
              isSigner: false,
              isWritable: true
            },
            {
              pubkey: '6tNwRrMUC6xsmwzig9NNqoSVRDZ1N7nBusCDNGtAnbm3',
              isSigner: true,
              isWritable: true
            },
            {
              pubkey: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
              isSigner: false,
              isWritable: false
            },
            {
              pubkey: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
              isSigner: false,
              isWritable: false
            },
            {
              pubkey: 'So11111111111111111111111111111111111111112',
              isSigner: false,
              isWritable: false
            },
            {
              pubkey: '6tNwRrMUC6xsmwzig9NNqoSVRDZ1N7nBusCDNGtAnbm3',
              isSigner: true,
              isWritable: true
            },
            {
              pubkey: 'B3jM5ycV6USQQjBe89s49tbrM4gBhY9vmVt89TjgdGBb',
              isSigner: false,
              isWritable: true
            },
            {
              pubkey: '8baMHRmtq5fbXeYcpUdoHqSEFQe4GEa8mfvc9qWxXntb',
              isSigner: true,
              isWritable: true
            },
            {
              pubkey: '2wa3wiYPwtoGhceSPQWsMGDkHDcCyip7ejc2T1qWisLn',
              isSigner: false,
              isWritable: true
            },
            {
              pubkey: 'Bv73VNJdvzJvVcvw3Rpf5hof2FgwCa8GxEE99UWRqrBD',
              isSigner: false,
              isWritable: true
            },
            {
              pubkey: '11111111111111111111111111111111',
              isSigner: false,
              isWritable: false
            },
            {
              pubkey: '8baMHRmtq5fbXeYcpUdoHqSEFQe4GEa8mfvc9qWxXntb',
              isSigner: true,
              isWritable: true
            }
          ],
          programId: 'BN542RvJA1bg8nZ5qmDVp3MuDJgovXQiH1fbtqUT8YkR',
          data: [
            167, 6, 157, 184, 126, 21, 170,
            171, 1,   0,   0,   0,  0,   0,
              0, 0,   9
          ]
        }
      ],
      signers: [
        '6tNwRrMUC6xsmwzig9NNqoSVRDZ1N7nBusCDNGtAnbm3',
        '8baMHRmtq5fbXeYcpUdoHqSEFQe4GEa8mfvc9qWxXntb',
        'DYsFEpDiT52AXZASecVRkd9dyN6icmKfpVqncKAzRJNY'
      ]
    }
  }

6tNwRrMUC6xsmwzig9NNqoSVRDZ1N7nBusCDNGtAnbm3 is client side wallet, 8baMHRmtq5fbXeYcpUdoHqSEFQe4GEa8mfvc9qWxXntb is backend side wallet, DYsFEpDiT52AXZASecVRkd9dyN6icmKfpVqncKAzRJNY is token is being minted.

2 Answers 2

1

I haven't used the metadata creation with creator so my guess based on the code I checked is that there is a mismatch within the data provided in ctx.accounts.token_metadata_account and in how the creators: Vec<CreateTokenCreator> is constructed.

When you check the code of the metadata those parts seems need to match

https://github.com/metaplex-foundation/mpl-token-metadata/blob/mpl-token-metadata%40v3.3.0/programs/token-metadata/program/src/assertions/metadata.rs#L109

In checking some other code doing the CPI the metadata creators field is only transferred directly to DataV2 (not generating any new struct).

https://github.com/metaplex-foundation/mpl-bubblegum/blob/45f9f54ffd5296c45b1b560a2c5a55b885b21589/programs/bubblegum/program/src/processor/decompress.rs#L201


When asking on CPI call and the signing the signatures taken from the client call is extended to the inner CPI calls.

Signer privileges from a caller program are extended to the callee program.

https://solana.com/docs/core/cpi#key-points

0

During creation of CreateMetadataAccountV3CpiBuilder, creates shouldn't be verified: true.

You can call SignMetadataCpiBuilder for each creator and provide correct [signer] accounts

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.