Closed johnbailon closed 3 years ago
Hi
I'm looking into this, and one thing I found is the point 10.
might not be matching this: https://github.com/metaplex-foundation/metaplex/blob/f3366f3ab09e9900407f10856659edab6c631fc0/js/packages/common/src/actions/metadata.ts#L1202
(i.e. the editionNumber, which is the last item in the seeds slice, which should be a string converted to a byte slice).
But that's probably no the issue that causes the error. Will update you.
For reference, the MintTo
instruction processing source code is here: https://github.com/solana-labs/solana-program-library/blob/e8b7009cc4d8cdd87232ccfc9ce93ab203ada496/token/program/src/processor.rs#L488-L542
And the error happens here: https://github.com/solana-labs/solana-program-library/blob/e8b7009cc4d8cdd87232ccfc9ce93ab203ada496/token/program/src/processor.rs#L519-L524
Which is a function that validates owners: https://github.com/solana-labs/solana-program-library/blob/e8b7009cc4d8cdd87232ccfc9ce93ab203ada496/token/program/src/processor.rs#L832-L867
Nope, scratch that.
MintNewEditionFromMasterEditionViaToken
instruction processing: https://github.com/metaplex-foundation/metaplex/blob/397f488935f2075b0798946c30cf5f7b0ddcd3f0/rust/token-metadata/program/src/utils.rs#L912-L1030
Example instruction usage:
When you see a incorrect account owner
, it might also mean that the account doesn't exist (yeah, that's very cryptic).
The Incorrect account owner
is a MetadataError::IncorrectOwner
error.
And it happens because one of these accounts have the wrong owner:
How to debug:
Check that all of the accounts marked with a // THIS
comment 1) exist and 2) are owned by the specified account.
printEditionInstruction := token_metadata.NewMintNewEditionFromMasterEditionViaTokenInstructionBuilder().
SetArgs(token_metadata.MintNewEditionFromMasterEditionViaTokenArgs{Edition: edition}).
SetNewMetadataKeyAccount(newMetadataKey). // pda from token_metadata.PREFIX, solana.TokenMetadataProgramID, newMintAccount.PublicKey()
SetNewEditionPDAAccount(newEditionPDA).
SetMasterRecordEditionV2Account(masterRecordEditionV2PDA). // THIS: assert_owned_by(master_edition_account_info, program_id)?;
SetMintOfNewTokenAccount(newMintAccount.PublicKey()). // THIS: assert_owned_by(mint_info, &spl_token::id())?;
SetEditionPDAAccount(editionPDA).
SetMintAuthorityAccount(payer.PublicKey()).
SetPayerAccount(payer.PublicKey()).
SetOwnerOfTokenAccount(payer.PublicKey()).
SetTokenAccount(tokenAccountOfMasterMint). // THIS: assert_owned_by(token_account_info, &spl_token::id())?;
SetUpdateAuthorityInfoAccount(payer.PublicKey()).
SetMasterRecordMetadataAccount(masterRecordMetadata). // THIS: assert_owned_by(master_metadata_account_info, program_id)?;
SetTokenProgramAccount(solana.TokenProgramID).
SetSystemProgramAccount(solana.SystemProgramID).
SetRentInfoAccount(solana.SysVarRentPubkey)
NOTES:
spl_token::id()
= token.ProgramID
program_id
= token_metadata.ProgramID
mainnet-beta
)You can print the IDs (use https://github.com/gagliardetto/solana-go#pretty-print-transactionsinstructions) and then use the solana CLI to check for their existence and ownership:
$ solana -u mainnet-beta account BpbtsWaS7Uo2XAxaRXKtXkUbEiAJUBZ8HeTSJmaZGgys
Public Key: BpbtsWaS7Uo2XAxaRXKtXkUbEiAJUBZ8HeTSJmaZGgys
Balance: 0.00157296 SOL
Owner: vau1zxA2LbssAUEF7Gpw91zMM1LvXrvpzJtmZ58rPsn
Executable: false
Rent Epoch: 234
Length: 98 (0x62) bytes
0000: 01 83 b8 05 ea a6 55 7b 0f 08 76 7c bd 77 70 f7 ......U{..v|.wp.
0010: 96 13 fc cc 63 a4 0b cf 87 ac 8d d2 82 d6 2c 2f ....c.........,/
0020: cc e6 dd 3d 4b 7c f8 b8 6f fd 11 7f 0b 01 18 c2 ...=K|..o.......
0030: 20 15 3c 2e 44 84 70 c5 a3 ba 97 a2 51 84 83 9b .<.D.p.....Q...
0040: 8d f8 51 10 f2 8d dc 96 2c 20 f0 54 7b 42 86 cd ..Q....., .T{B..
0050: 90 33 6c db 44 d4 65 e1 67 05 e8 3b aa 0c 69 bf .3l.D.e.g..;..i.
0060: 7d 00
Brilliant! Thank you for your effort, @gagliardetto. Much appreciated. The links to the lines of code on how metaplex's metadata program checks ownership did it, and also using the CLI to check ownership of said addresses.
(Although I have a new issue now I am trying to resolve first on my own. The phantom wallets receiving the new print editions are also receiving an "unknown" token in it. It doesn't seem to be that way when using the Metaplex Store to mint master and print editions.)
So just to close it all up, there were 3 issues related to this that are now resolved:
masterRecordEditionV2PDA
(9. on first post) was wrong, it should be:
masterRecordEditionV2PDA, _, err := solana.FindProgramAddress(
[][]byte{
[]byte(token_metadata.PREFIX),
solana.TokenMetadataProgramID.Bytes(),
masterMint.Bytes(), // this was masterRecordMetadata.Bytes()
[]byte(token_metadata.EDITION),
},
solana.TokenMetadataProgramID,
)
editionPDA
(10. on first post) was also wrong, it should be:
editionPDA, _, err := solana.FindProgramAddress(
[][]byte{
[]byte(token_metadata.PREFIX),
solana.TokenMetadataProgramID.Bytes(),
masterMint.Bytes(), // this was masterRecordMetadata.Bytes()
[]byte(token_metadata.EDITION),
[]byte(strEdition),
},
solana.TokenMetadataProgramID,
)
And the last error, which was a huge oversight on my part, the master edition I was using as an example was actually minted to another address, different from the payer
wallet, hence the incorrect owner error. 🤦 🤦
Awesome! Thanks for the summary of how you solved the issue!
Hello, first of all, thanks for working on this. Very helpful in learning Solana/Metaplex as a Go dev. Kudos. Hoping to get some help on this, I'm trying to mint a new edition from an existing master edition to a new address and I'm hitting this error:
This is how I am doing it:
payer
issolana.privateKey
of account that created and has the master editionwithdrawalAddress
is account to send the new edition tomasterMint
is the public key of the NFTgenerated new keypair called
newMintAccount
created token account: mint auth and freeze auth are
payer.PublicKey()
, mint account isnewMintAccount.PublicKey()
created associated token account: wallet is
withdrawalAddress
, mint isnewMintAccount
associatedTokenAddress
is found viasolana.FindAssociatedTokenAddress()
usingwithdrawalAddress
andnewMintAccount.PublicKey()
MintTo instruction: amount
1
, mint account isnewMintAccount.PublicKey()
, destination account isassociatedTokenAddress
and auth account ispayer.PublicKey()
newMetadataKey
is found via:newEditionPDA
is found via:masterRecordMetadata
is found via:masterRecordEditionV2PDA
is found via:editionPDA
is found via:tokenAccountOfMasterMint
is found via:Finally, this is the instruction for minting a new edition: