Розширення групи та учасника
Розширення Group
та Member
є розширеннями облікового запису Mint
, які впроваджують можливість створювати групи, подібні до колекцій для NFT, що пов'язані з кількома активами.
Initializing the Mint Account
Розширення Member
та Group
дещо відрізняються від того, до чого ми звикли, оскільки вони складаються з 2 різних розширень, які обидва застосовуються до облікового запису Mint
:
Extension
, що містить усю інформацію про групу або учасника.Pointer Extension
, що посилається на обліковий записMint
, де знаходиться розширенняGroup
абоMember
.
Зазвичай, при використанні, Extension
та Pointer Extension
знаходяться на одному обліковому записі Mint
; і ми зробимо так само для цього прикладу.
Давайте почнемо з основ, перш ніж заглиблюватися в код:
Хоча розширення 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
виглядає так:
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`);
І після цього ми можемо використовувати групу, яку щойно створили, щоб додати учасника до неї таким чином:
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`);