В этом примере создаётся минт Token-2022 с метаданными в блокчейне, приостанавливаемыми переводами, постоянным делегатом и token accounts, которые изначально заморожены. Выберите Kit, legacy TypeScript или Rust, затем запустите на изолированной тестовой сети:
import { createClient, generateKeyPairSigner, lamports } from "@solana/kit";import { rpcAirdrop, solanaRpc } from "@solana/kit-plugin-rpc";import { airdropPayer, payer as kitPayer } from "@solana/kit-plugin-signer";import { getCreateAccountInstruction } from "@solana-program/system";import {AccountState,TOKEN_2022_PROGRAM_ADDRESS,extension,fetchMint,getInitializeMintInstruction,getMintSize,getPostInitializeInstructionsForMintExtensions,getPreInitializeInstructionsForMintExtensions,} from "@solana-program/token-2022";const payer = await generateKeyPairSigner();const mint = await generateKeyPairSigner();const client = await createClient().use(kitPayer(payer)).use(solanaRpc({rpcUrl: "http://localhost:8899",rpcSubscriptionsUrl: "ws://localhost:8900",}),).use(rpcAirdrop()).use(airdropPayer(lamports(1_000_000_000n)));// A compliance-ready Token-2022 mint: onchain metadata, pausable transfers,// a permanent delegate that can move or burn any balance, and token accounts// that start frozen until the issuer thaws them.const extensions = [extension("MetadataPointer", {authority: payer.address,metadataAddress: mint.address,}),extension("TokenMetadata", {updateAuthority: payer.address,mint: mint.address,name: "Example Stablecoin",symbol: "EXUSD",uri: "https://example.com/exusd.json",additionalMetadata: new Map<string, string>(),}),extension("PausableConfig", { authority: payer.address, paused: false }),extension("PermanentDelegate", { delegate: payer.address }),extension("DefaultAccountState", { state: AccountState.Frozen }),];// Token metadata is written after the mint is initialized, so allocate the// account without it but fund rent for the full size.const spaceWithoutMetadata = BigInt(getMintSize(extensions.filter(({ __kind }) => __kind !== "TokenMetadata")),);const spaceWithMetadata = BigInt(getMintSize(extensions));const rent = await client.rpc.getMinimumBalanceForRentExemption(spaceWithMetadata).send();const instructions = [getCreateAccountInstruction({payer,newAccount: mint,lamports: rent,space: spaceWithoutMetadata,programAddress: TOKEN_2022_PROGRAM_ADDRESS,}),...getPreInitializeInstructionsForMintExtensions(mint.address, extensions),getInitializeMintInstruction({mint: mint.address,decimals: 6,mintAuthority: payer.address,freezeAuthority: payer.address,}),...getPostInitializeInstructionsForMintExtensions(mint.address,payer,extensions,),];const { context } = await client.sendTransaction(instructions);console.log("Transaction Signature:", context.signature);// Verify the mint and its extensionsconst mintAccount = await fetchMint(client.rpc, mint.address);const enabledExtensions =mintAccount.data.extensions.__option === "Some"? mintAccount.data.extensions.value.map(({ __kind }) => __kind): [];console.log("Mint Address:", mintAccount.address);console.log("Decimals:", mintAccount.data.decimals);console.log("Extensions:", enabledExtensions.join(", "));
Console
Click to execute the code.
Вы должны увидеть подпись транзакции, адрес mint account и список включённых Token Extensions.
Подключение к devnet
Замените URL-адреса RPC на devnet и пополните счёт плательщика через фосет:
solanaRpc({rpcUrl: "https://api.devnet.solana.com",rpcSubscriptionsUrl: "wss://api.devnet.solana.com"});
Всё остальное остаётся без изменений. Перед использованием той же конфигурации в mainnet спланируйте управление полномочиями, операции по соблюдению требований и мониторинг актива.
Что дальше
- Активы в Solana — mint accounts, token accounts и полномочия
- Token extensions — выбирайте только те элементы управления, которые нужны вашему активу
- Token ACL — применение списков разрешений и блокировок
- Поставка против платежа — атомарное проведение расчётов по активу и его оплате
Is this page helpful?