Metaplex Candy Machine v6.0.0.-alphaで、GuardsのsolPaymentを試していたときに発生したエラー。
長文になってしまうが、全文があったほうが理解しやすいため、一旦全部貼る。
Agenda
現象
実行すると以下のエラー。
% ts-node mint.ts
PublicKeyMismatch: Public key mismatch
Source: Program > mplCandyGuard [Guard1JwRhJkVH6XZhzoYxeBVQe872VH6QggF4BWmS9g]
Caused By: Error: failed to send transaction: Transaction simulation failed: Error processing Instruction 1: custom program error: 0x1772
Program Logs:
| Program ComputeBudget111111111111111111111111111111 invoke [1]
| Program ComputeBudget111111111111111111111111111111 success
| Program Guard1JwRhJkVH6XZhzoYxeBVQe872VH6QggF4BWmS9g invoke [1]
| Program log: Instruction: MintV2
| Program log: AnchorError thrown in program/src/utils.rs:95. Error Code: PublicKeyMismatch. Error Number: 6002. Error Message: Public key mismatch.
| Program Guard1JwRhJkVH6XZhzoYxeBVQe872VH6QggF4BWmS9g consumed 27348 of 800000 compute units
| Program Guard1JwRhJkVH6XZhzoYxeBVQe872VH6QggF4BWmS9g failed: custom program error: 0x1772
at getMplCandyGuardErrorFromCode (/mint-site/node_modules/@metaplex-foundation/mpl-candy-machine/src/generated/errors/mplCandyGuard.ts:744:24)
at Object.getErrorFromCode (/mint-site/node_modules/@metaplex-foundation/mpl-candy-machine/src/generated/programs/mplCandyGuard.ts:30:43)
at Object.resolveError (/mint-site/node_modules/@metaplex-foundation/umi-program-repository/src/createDefaultProgramRepository.ts:122:35)
at Object.sendTransaction (/mint-site/node_modules/@metaplex-foundation/umi-rpc-web3js/src/createWeb3JsRpc.ts:310:42)
at processTicksAndRejections (node:internal/process/task_queues:95:5)
at async TransactionBuilder.sendAndConfirm (/mint-site/node_modules/@metaplex-foundation/umi/src/TransactionBuilder.ts:303:23)
at async main (/mint-site/mint.ts:117:3) {
source: 'program',
sourceDetails: 'mplCandyGuard [Guard1JwRhJkVH6XZhzoYxeBVQe872VH6QggF4BWmS9g]',
cause: SendTransactionError: failed to send transaction: Transaction simulation failed: Error processing Instruction 1: custom program error: 0x1772
at Connection.sendEncodedTransaction (/mint-site/node_modules/@solana/web3.js/src/connection.ts:5860:13)
at processTicksAndRejections (node:internal/process/task_queues:95:5)
at async Connection.sendRawTransaction (/mint-site/node_modules/@solana/web3.js/src/connection.ts:5819:20)
at async Object.sendTransaction (/mint-site/node_modules/@metaplex-foundation/umi-rpc-web3js/src/createWeb3JsRpc.ts:302:25)
at async TransactionBuilder.sendAndConfirm (/mint-site/node_modules/@metaplex-foundation/umi/src/TransactionBuilder.ts:303:23)
at async main (/mint-site/mint.ts:117:3) {
logs: [
'Program ComputeBudget111111111111111111111111111111 invoke [1]',
'Program ComputeBudget111111111111111111111111111111 success',
'Program Guard1JwRhJkVH6XZhzoYxeBVQe872VH6QggF4BWmS9g invoke [1]',
'Program log: Instruction: MintV2',
'Program log: AnchorError thrown in program/src/utils.rs:95. Error Code: PublicKeyMismatch. Error Number: 6002. Error Message: Public key mismatch.',
'Program Guard1JwRhJkVH6XZhzoYxeBVQe872VH6QggF4BWmS9g consumed 27348 of 800000 compute units',
'Program Guard1JwRhJkVH6XZhzoYxeBVQe872VH6QggF4BWmS9g failed: custom program error: 0x1772'
]
},
program: {
name: 'mplCandyGuard',
publicKey: { bytes: [Uint8Array] },
getErrorFromCode: [Function: getErrorFromCode],
getErrorFromName: [Function: getErrorFromName],
isOnCluster: [Function: isOnCluster],
availableGuards: [
'botTax', 'solPayment',
'tokenPayment', 'startDate',
'thirdPartySigner', 'tokenGate',
'gatekeeper', 'endDate',
'allowList', 'mintLimit',
'nftPayment', 'redeemedAmount',
'addressGate', 'nftGate',
'nftBurn', 'tokenBurn',
'freezeSolPayment', 'freezeTokenPayment',
'programGate'
]
},
logs: [
'Program ComputeBudget111111111111111111111111111111 invoke [1]',
'Program ComputeBudget111111111111111111111111111111 success',
'Program Guard1JwRhJkVH6XZhzoYxeBVQe872VH6QggF4BWmS9g invoke [1]',
'Program log: Instruction: MintV2',
'Program log: AnchorError thrown in program/src/utils.rs:95. Error Code: PublicKeyMismatch. Error Number: 6002. Error Message: Public key mismatch.',
'Program Guard1JwRhJkVH6XZhzoYxeBVQe872VH6QggF4BWmS9g consumed 27348 of 800000 compute units',
'Program Guard1JwRhJkVH6XZhzoYxeBVQe872VH6QggF4BWmS9g failed: custom program error: 0x1772'
],
code: 6002
}
mint.ts
// Docs: https://docs.metaplex.com/programs/candy-machine/candy-guards
// Test Code: https://github.com/metaplex-foundation/mpl-candy-machine/blob/main/clients/js/test/mintV2.test.ts
// Lib
import * as fs from 'fs';
// Candy Machine
import {
mplCandyMachine,
addConfigLines,
create,
mintV2,
fetchCandyMachine,
} from "@metaplex-foundation/mpl-candy-machine";
import {
setComputeUnitLimit,
} from "@metaplex-foundation/mpl-essentials";
// Token
import {
createNft,
TokenStandard,
} from "@metaplex-foundation/mpl-token-metadata";
// Umi
import {
generateSigner,
keypairIdentity,
base58PublicKey,
transactionBuilder,
percentAmount,
some,
sol,
dateTime,
} from "@metaplex-foundation/umi";
import { createUmi } from "@metaplex-foundation/umi-bundle-defaults";
const main = async () => {
const endopoint = 'https://api.devnet.solana.com';
const umi = createUmi(endopoint, 'confirmed')
.use(mplCandyMachine());
// CAUTION: Use Env file instead of below file for Production.
const secretKey = new Uint8Array(JSON.parse(fs.readFileSync('./assets/id.json', 'utf8')));
// Ref: https://github.com/metaplex-foundation/umi/blob/main/docs/publickeys-signers.md#keypairs
const myKeypair = umi.eddsa.createKeypairFromSecretKey(secretKey);
umi.use(keypairIdentity(myKeypair));
// -------------------------------------
// Create Collection NFT
// -------------------------------------
const collectionUpdateAuthority = generateSigner(umi);
const collectionMint = generateSigner(umi);
// Ref: https://mpl-token-metadata-js-docs.vercel.app/functions/createNft.html
await createNft(umi, {
mint: collectionMint,
authority: collectionUpdateAuthority,
name: "My Collection NFT",
uri: "https://arweave.net/yfVoS8kmFiM_XjfZOETgdCfrByKDyheSJ20nyam8_ag",
sellerFeeBasisPoints: percentAmount(9.99, 2), // 9.99%
isCollection: true,
}).sendAndConfirm(umi);
// -------------------------------------
// Candy Machine
// -------------------------------------
// Create a Candy Machine with guards.
// Ref: https://docs.metaplex.com/programs/candy-machine/candy-machine-settings
const candyMachine = generateSigner(umi);
const createInstructions = await create(umi, {
candyMachine,
collectionMint: collectionMint.publicKey,
collectionUpdateAuthority,
tokenStandard: TokenStandard.NonFungible,
sellerFeeBasisPoints: percentAmount(9.99, 2), // 9.99%
itemsAvailable: 3, // Increase SOL cost per items. Check the cost on Devnet before launch.
creators: [
{
address: umi.identity.publicKey,
verified: true,
percentageShare: 100,
},
],
configLineSettings: some({
prefixName: "",
nameLength: 32,
prefixUri: "",
uriLength: 200,
// isSequential: indicates to whether a sequential index generation should be used during mint or not (recommended to set this value to false).
isSequential: false,
}),
guards: {
botTax: some({ lamports: sol(0.00321), lastInstruction: true }),
startDate: some({ date: dateTime("2023-04-04T16:00:00Z") }),
mintLimit: some({ id: 1, limit: 1 }),
solPayment: some({ lamports: sol(0.00123), destination: umi.identity.publicKey }),
// All other guards are disabled...
},
});
await transactionBuilder().add(createInstructions).sendAndConfirm(umi);
// -------------------------------------
// Insert Items
// -------------------------------------
// Ref: https://docs.metaplex.com/programs/candy-machine/inserting-items
await addConfigLines(umi, {
candyMachine: candyMachine.publicKey,
index: 0,
configLines: [
{ name: "My NFT #1", uri: "https://arweave.net/2V5Mx2dwnyrwlpHYPVshiyj_WtU7qIlPZzKs6nIwqw4" },
{ name: "My NFT #2", uri: "https://arweave.net/2dyAzm_p5kz8GYYLAzKj41KQL3vYT_kWyomJ3mTpBcA" },
{ name: "My NFT #3", uri: "https://arweave.net/tD5TVplWyzqYvM9feLbIKGqkuTzf0AIO0nLc4NDiiPk" },
],
}).sendAndConfirm(umi);
// -------------------------------------
// Mint NFT
// -------------------------------------
// This example temporarily uses minter as Umi's payer.
// const minter = generateSigner(umi);
const nftMint = generateSigner(umi);
await transactionBuilder()
.add(setComputeUnitLimit(umi, { units: 800_000 }))
.add(
mintV2(umi, {
candyMachine: candyMachine.publicKey,
// minter, // default to Umi's identity and payer
nftMint,
collectionMint: collectionMint.publicKey,
collectionUpdateAuthority: collectionUpdateAuthority.publicKey,
mintArgs: {
mintLimit: some({ id: 1 }),
},
}),
)
.sendAndConfirm(umi);
// -------------------------------------
// Fetch Candy Machine
// -------------------------------------
const candyMachineAccount = await fetchCandyMachine(
umi,
candyMachine.publicKey
);
原因
Guardsで設定したsolPaymentをMint時に指定していないため。
「Public key mismatch」という内容だったため、Mintアドレスが間違ったのかと思ったが、今回のケースではMint時の引数が足りなかっただけだった。
Guardsで設定したら、mintArgsでも指定が必要(ということであってそう)。
Guardsはオンチェーンで管理しているので、トランザクション送信時にMinter側(Mintするユーザー)で一緒に設定(厳密にはInstruction)を投げないといけないっぽい。
対応
以下のようにmintArgsにsolPaymentを追加して解決。
await transactionBuilder()
.add(setComputeUnitLimit(umi, { units: 800_000 }))
.add(
mintV2(umi, {
candyMachine: candyMachine.publicKey,
// minter, // default to Umi's identity and payer
nftMint,
collectionMint: collectionMint.publicKey,
collectionUpdateAuthority: collectionUpdateAuthority.publicKey,
mintArgs: {
mintLimit: some({ id: 1 }),
// 以下を追加!
solPayment: some({ destination: umi.identity.publicKey }),
},
}),
)
.sendAndConfirm(umi);
参考
利用したソース 256hax GitHub