Typescript
Token2022 з Web3.js

Token2022 з Web3.js

Розширення групи та учасника

Розширення Group та Member є розширеннями облікового запису Mint, які впроваджують можливість створювати групи, подібні до колекцій для NFT, що пов'язані з кількома активами.

Initializing the Mint Account

Розширення Member та Group дещо відрізняються від того, до чого ми звикли, оскільки вони складаються з 2 різних розширень, які обидва застосовуються до облікового запису Mint:

  • Extension, що містить усю інформацію про групу або учасника.
  • Pointer Extension, що посилається на обліковий запис Mint, де знаходиться розширення Group або Member.

Зазвичай, при використанні, Extension та Pointer Extension знаходяться на одному обліковому записі Mint; і ми зробимо так само для цього прикладу.

Розширення Group та Member не можуть бути на одному обліковому записі

Давайте почнемо з основ, перш ніж заглиблюватися в код:

Хоча розширення GroupPointer та MemberPointer знаходяться в пакеті @solana/spl-token, для ініціалізації Group та Member нам потрібно використовувати пакет @solana/spl-token-group.

Отже, встановимо необхідний пакет:

 
npm i @solana/spl-token-group

Крім того, розширення Group та Member є одним з "єдиних" розширень, які вимагають ініціалізації розширення після ініціалізації облікового запису Mint.

Це тому, що інструкція ініціалізації метаданих динамічно виділяє необхідний простір для довжини вмісту групи та учасника.

Водночас, це означає, що нам потрібно буде ініціалізувати обліковий запис Mint з достатньою кількістю лампортів, щоб бути звільненим від оренди з включеним розширенням Group або Member, але виділяючи достатньо місця лише для розширення GroupPointer або MemberPointer, оскільки інструкція token_group_initialize() та token_group_member_initialize() фактично збільшує простір правильно.

У коді ініціалізація Group виглядає так:

ts
const mint = Keypair.generate();
 
// Size of Mint Account with extensions
const mintLen = getMintLen([ExtensionType.GroupPointer]);
 
// Minimum lamports required for Mint Account
const lamports = await connection.getMinimumBalanceForRentExemption(mintLen + TYPE_SIZE + LENGTH_SIZE + TOKEN_GROUP_SIZE);
 
const createAccountInstruction = SystemProgram.createAccount({
    fromPubkey: keypair.publicKey,
    newAccountPubkey: mint.publicKey,
    space: mintLen,
    lamports,
    programId: TOKEN_2022_PROGRAM_ID,
});
 
const initializeGroupPointer = createInitializeGroupPointerInstruction(
    mint.publicKey,
    keypair.publicKey,
    mint.publicKey,
    TOKEN_2022_PROGRAM_ID,
);
 
const initializeMintInstruction = createInitializeMintInstruction(
    mint.publicKey,
    6,
    keypair.publicKey,
    null,
    TOKEN_2022_PROGRAM_ID,
);
 
const initializeGroupInstruction = createInitializeGroupInstruction(
    {
        programId: TOKEN_2022_PROGRAM_ID,
        group: mint.publicKey,
        mint: mint.publicKey,
        mintAuthority: keypair.publicKey,
        updateAuthority: keypair.publicKey,
        maxSize: BigInt(100),
    }
);
 
const transaction = new Transaction().add(
    createAccountInstruction,
    initializeGroupPointer,
    initializeMintInstruction,
    initializeGroupInstruction,
);
 
const signature = await sendAndConfirmTransaction(connection, transaction, [keypair, mint], {commitment: "finalized"});
 
console.log(`Mint created! Check out your TX here: https://explorer.solana.com/tx/${signature}?cluster=devnet`);

І після цього ми можемо використовувати групу, яку щойно створили, щоб додати учасника до неї таким чином:

ts
const member = Keypair.generate();
 
// Size of Member Account with extensions
const memberLen = getMintLen([ExtensionType.GroupMemberPointer]);
 
// Minimum lamports required for Member Account
const lamports = await connection.getMinimumBalanceForRentExemption(memberLen + TYPE_SIZE + LENGTH_SIZE + TOKEN_GROUP_MEMBER_SIZE);
 
const createAccountInstruction = SystemProgram.createAccount({
    fromPubkey: keypair.publicKey,
    newAccountPubkey: member.publicKey,
    space: memberLen,
    lamports,
    programId: TOKEN_2022_PROGRAM_ID,
});
 
const initializeGroupMemberPointer = createInitializeGroupMemberPointerInstruction(
    member.publicKey,
    keypair.publicKey,
    member.publicKey,
    TOKEN_2022_PROGRAM_ID,
);
 
const initializeMintInstruction = createInitializeMintInstruction(
    member.publicKey,
    6,
    keypair.publicKey,
    null,
    TOKEN_2022_PROGRAM_ID,
);
 
const initializeGroupMemberInstruction = createInitializeMemberInstruction(
    {
        programId: TOKEN_2022_PROGRAM_ID,
        group: mint.publicKey,
        member: member.publicKey,
        memberMint: member.publicKey,
        memberMintAuthority: keypair.publicKey,
        groupUpdateAuthority: keypair.publicKey,
    }
);
 
const transaction = new Transaction().add(
    createAccountInstruction,
    initializeGroupMemberPointer,
    initializeMintInstruction,
    initializeGroupMemberInstruction,
);
 
const signature = await sendAndConfirmTransaction(connection, transaction, [keypair, member], {commitment: "finalized"});
 
console.log(`Member created! Check out your TX here: https://explorer.solana.com/tx/${signature}?cluster=devnet`);
Blueshift © 2025Commit: 6d01265