Solanaでトークンロジックをテストするには、実際にテストしたい転送ロジックの前に、ミント、token
account、およびオーソリティを設定する必要があります。@solana-program/tokenのtokenProgram()プラグインを使用すると、そのセットアップをわずかなメソッド呼び出しに集約でき、ATAの作成も自動的に処理されます。
インストール
pnpm add @solana/kit @solana/kit-plugin-litesvm @solana/kit-plugin-signer @solana-program/token
ミントの作成
import { createClient, generateKeyPairSigner, lamports } from "@solana/kit";import { litesvm } from "@solana/kit-plugin-litesvm";import { signer } from "@solana/kit-plugin-signer";import { tokenProgram } from "@solana-program/token";const mySigner = await generateKeyPairSigner();const client = createClient().use(signer(mySigner)).use(litesvm()).use(tokenProgram());client.svm.airdrop(client.payer.address, lamports(10_000_000_000n));const mintAuthority = await generateKeyPairSigner();const newMint = await generateKeyPairSigner();await client.token.instructions.createMint({newMint,decimals: 9,mintAuthority: mintAuthority.address}).sendTransaction();// Verifyconst mintAccount = await client.token.accounts.mint.fetch(newMint.address);console.log(mintAccount.data.supply); // 0nconsole.log(mintAccount.data.decimals); // 9
トークンのミント
mintToATAは、オーナーのassociated token
accountにトークンを発行します。ATAが存在しない場合は、同じトランザクション内で作成されます。
await client.token.instructions.mintToATA({mint: newMint.address,owner: client.payer.address,mintAuthority,amount: 1_000_000_000_000n, // 1000 tokens (9 decimals)decimals: 9}).sendTransaction();
decimalsパラメータは安全確認のためのもので、ミントの小数点以下桁数と完全に一致している必要があります。一致しない場合、Token
Programはエラーコード 0x24
でトランザクションを拒否します。これにより、誤って1000倍のトークンをミントしてしまうことを防ぎます。
トークンの転送
transferToATAはユーザー間でトークンを移動します。必要に応じて、受取人のATAは自動的に作成されます。
const alice = await generateKeyPairSigner();const bob = await generateKeyPairSigner();// Mint to Aliceawait client.token.instructions.mintToATA({mint: newMint.address,owner: alice.address,mintAuthority,amount: 1_000_000_000_000n,decimals: 9}).sendTransaction();// Transfer 400 tokens from Alice to Bobawait client.token.instructions.transferToATA({mint: newMint.address,authority: alice,recipient: bob.address,amount: 400_000_000_000n,decimals: 9}).sendTransaction();
authorityは、送金元トークンを所有する署名者です。プラグインは送金元と送金先のATAをそれぞれのアドレスとミントから導出します。
残高の確認
トークン残高を読み取るには、findAssociatedTokenPdaでATAアドレスを導出し、デコードされたアカウントを取得します:
import {findAssociatedTokenPda,TOKEN_PROGRAM_ADDRESS} from "@solana-program/token";const [aliceAta] = await findAssociatedTokenPda({owner: alice.address,mint: newMint.address,tokenProgram: TOKEN_PROGRAM_ADDRESS});const aliceAccount = await client.token.accounts.token.fetch(aliceAta);console.log(aliceAccount.data.amount); // 600_000_000_000nconsole.log(aliceAccount.data.mint); // newMint.addressconsole.log(aliceAccount.data.owner); // alice.address
小数点以下の桁数
トークン量は常にraw単位で表されます。小数点以下9桁のトークン1000個は1_000_000_000_000nであり、1000nではありません。
// USDC has 6 decimalsconst oneUSDC = 10n ** 6n; // 1_000_000n// SOL has 9 decimalsconst oneSOL = 10n ** 9n; // 1_000_000_000n
トークン量には必ずBigIntを使用してください。JavaScriptのNumberは2^53を超えると精度が失われます。
プラグインリファレンス
| メソッド | 説明 |
|---|---|
client.token.instructions.createMint() | 新しいSPLトークンのmint accountを作成する |
client.token.instructions.mintToATA() | オーナーのATAにトークンをミントする(必要に応じてATAを作成) |
client.token.instructions.transferToATA() | 受取人のATAにトークンを転送する(必要に応じてATAを作成) |
client.token.accounts.mint.fetch() | mint accountをフェッチしてデコードする |
client.token.accounts.token.fetch() | token accountをフェッチしてデコードする |
よくあるエラー
| エラー | 原因 | 対処法 |
|---|---|---|
custom program error: 0x24 | decimalsがmintと一致しない | createMintに渡したのと同じdecimalsの値を使用してください |
AccountNotFound | アカウントがまだ存在しない | ミントの前にmint accountが作成されていることを確認してください |
InsufficientFunds | rentに必要なlamportが不足している | 支払者にSOLをエアドロップしてください |
OwnerMismatch | 誤ったプログラムがアカウントを所有している | プログラムIDを確認してください |
Is this page helpful?