L'Extension Group and Member
Les extensions Group
(groupe) et Member
(membre) sont des extension de compte de Mint
qui introduisent la possibilité de créer des groupes, comme des collections pour les NFT, qui sont liés à plusieurs actifs.
Initialisation du Compte de Mint
Les extensions Member
et Group
sont un peu différents de ce que nous sommes habitués car ils sont composés de deux extensions différentes qui s'appliquent toutes deux à un compte de Mint
:
- L'
Extension
qui contient toutes les informations sur le groupe ou le membre. - Le
Pointer Extension
(extension pointeur) qui fait référence au compte deMint
où se trouvent lesGroup
ouMember
.
En général, lorsqu'elles sont utilisées, l'Extension
et le Pointer Extension
se trouvent dans le même compte de Mint
. C'est ce que nous allons faire dans cet exemple.
Commençons par quelques notions de base avant de nous plonger dans le code :
Bien que les extensions GroupPointer
et MemberPointer
se trouvent dans le package @solana/spl-token
, pour initialiser Group
et Member
nous devons utiliser le package @solana/spl-token-group
.
Installons donc le package nécessaire :
npm i @solana/spl-token-group
De plus, l'extension Group
et Member
est l'une des "seules" extensions qui nécessite d'initialiser l'extension après avoir initialisé le compte de Mint
.
Cela s'explique par le fait que l'instruction d'initialisation des métadonnées alloue de manière dynamique l'espace nécessaire pour la taille du groupe et le contenu des membres.
Dans le même temps, cela signifie que nous allons devoir initialiser le compte de Mint
avec suffisamment de lamports pour être exempt de rente avec l'extension Group
ou Member
incluse mais en allouant suffisamment d'espace uniquement pour l'extension GroupPointer
ou MemberPointer
car les instructions token_group_initialize()
et token_group_member_initialize()
augmentent automatiquement l'espace de manière correcte.
L'initialisation de Group
ressemble à ceci :
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`);
Et après cela, nous pouvons utiliser le groupe que nous venons de créer pour y ajouter un membre comme ceci :
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`);