Τι Είναι οι Επεκτάσεις Group και Group Member;
Μια ομάδα είναι ένα mint που αντιπροσωπεύει μια συλλογή. Ένα μέλος ομάδας είναι ένα mint που ανήκει σε αυτή τη συλλογή.
Χρησιμοποιήστε αυτές τις επεκτάσεις όταν ένα mint πρέπει να αντιπροσωπεύει τη συλλογή και άλλα mints πρέπει να αντιπροσωπεύουν στοιχεία που ανήκουν σε αυτή.
Το Token Extensions Program μπορεί να αποθηκεύσει δεδομένα ομάδας token απευθείας σε ένα mint με τέσσερις σχετικές επεκτάσεις:
GroupPointerδείχνει ένα mint στον λογαριασμό που αποθηκεύει τα δεδομένα της ομάδας.TokenGroupαποθηκεύει τα ίδια τα δεδομένα της ομάδας, συμπεριλαμβανομένης της αρχής ενημέρωσης, του τρέχοντος μεγέθους και του μέγιστου μεγέθους.GroupMemberPointerδείχνει ένα mint στον λογαριασμό που αποθηκεύει τα δεδομένα του μέλους.TokenGroupMemberαποθηκεύει τη διεύθυνση της ομάδας του μέλους και τον αριθμό μέλους.
Τα GroupPointer και GroupMemberPointer μπορούν να αναφέρονται σε
οποιονδήποτε λογαριασμό που ανήκει σε ένα πρόγραμμα που υλοποιεί το
Token group interface.
Το Token Extensions Program υλοποιεί επίσης αυτή τη διεπαφή απευθείας μέσω των
επεκτάσεων mint TokenGroup και TokenGroupMember.
Πώς να Δημιουργήσετε Ομάδες και Μέλη που Αποθηκεύονται στο Mint Account
Για να δημιουργήσετε ομάδες και μέλη που αποθηκεύονται στο mint account:
- Δημιουργήστε ένα group mint account και αρχικοποιήστε το
GroupPointer. - Αρχικοποιήστε το group mint με
InitializeMint. - Αρχικοποιήστε το
TokenGroupστο ίδιο αυτό mint. - Δημιουργήστε ένα member mint account και αρχικοποιήστε το
GroupMemberPointer. - Αρχικοποιήστε το member mint με
InitializeMint. - Αρχικοποιήστε το
TokenGroupMemberστο ίδιο αυτό mint ώστε να αναφέρεται στο group mint.
Υπολογισμός μεγέθους και ενοικίου για το group mint
Υπολογίστε το μέγεθος και το ενοίκιο που απαιτούνται για το group mint.
Δημιουργία και Αρχικοποίηση Group Mint
Δημιουργήστε το λογαριασμό group mint, αρχικοποιήστε το GroupPointer,
αρχικοποιήστε το mint και αρχικοποιήστε το TokenGroup σε μία συναλλαγή.
Υπολογισμός μεγέθους και ενοικίου για το member mint
Υπολογίστε το μέγεθος και το ενοίκιο που απαιτούνται για το member mint.
Δημιουργία και Αρχικοποίηση Member Mint
Δημιουργήστε το λογαριασμό member mint, αρχικοποιήστε το
GroupMemberPointer, αρχικοποιήστε το mint και αρχικοποιήστε το
TokenGroupMember σε μία συναλλαγή.
Δείκτες και Σειρά Εντολών
Το GroupPointer και το GroupMemberPointer αποθηκεύουν τη διεύθυνση του λογαριασμού
όπου βρίσκονται τα δεδομένα της ομάδας ή του μέλους. Το TokenGroup και
το TokenGroupMember αποθηκεύουν τα πραγματικά δεδομένα της ομάδας ή του μέλους.
Το GroupPointerInstruction::Initialize και το
GroupMemberPointerInstruction::Initialize πρέπει να προηγούνται του
InitializeMint. Το TokenGroupInstruction::InitializeGroup και το
TokenGroupInstruction::InitializeMember πρέπει να έπονται του
InitializeMint. Για κάθε mint, το CreateAccount, η εντολή
αρχικοποίησης του δείκτη και το InitializeMint πρέπει να
συμπεριλαμβάνονται στην ίδια συναλλαγή.
Αναφορά Πηγής
Το GroupPointer και το GroupMemberPointer είναι εντολές δείκτη στο
Token Extensions Program. Το TokenGroup και το TokenGroupMember
ακολουθούν τη διεπαφή Token group, την οποία υλοποιεί το Token Extensions
Program.
Group Pointer και Group Member Pointer
| Στοιχείο | Περιγραφή | Πηγή |
|---|---|---|
GroupPointer | Επέκταση mint που αποθηκεύει την εξουσιοδότηση και τη διεύθυνση για τον λογαριασμό που αποθηκεύει τα δεδομένα μιας ομάδας. | Πηγή |
GroupMemberPointer | Επέκταση mint που αποθηκεύει την εξουσιοδότηση και τη διεύθυνση για τον λογαριασμό που αποθηκεύει τα δεδομένα ενός μέλους. | Πηγή |
GroupPointerInstruction::Initialize | Αρχικοποιεί την επέκταση group pointer πριν από το InitializeMint. | Πηγή |
GroupPointerInstruction::Update | Ενημερώνει τη διεύθυνση ομάδας που αποθηκεύεται από την επέκταση GroupPointer του mint. | Πηγή |
GroupMemberPointerInstruction::Initialize | Αρχικοποιεί την επέκταση group member pointer πριν από το InitializeMint. | Πηγή |
GroupMemberPointerInstruction::Update | Ενημερώνει τη διεύθυνση μέλους που αποθηκεύεται από την επέκταση GroupMemberPointer του mint. | Πηγή |
process_initialize (GroupPointer) | Γράφει την αρχική εξουσιοδότηση GroupPointer και τη διεύθυνση ομάδας στο mint. | Πηγή |
process_update (GroupPointer) | Επικυρώνει την εξουσιοδότηση του group pointer και στη συνέχεια επανεγγράφει την αποθηκευμένη διεύθυνση ομάδας του mint. | Πηγή |
process_initialize (GroupMemberPointer) | Γράφει την αρχική εξουσιοδότηση GroupMemberPointer και τη διεύθυνση μέλους στο mint. | Πηγή |
process_update (GroupMemberPointer) | Επικυρώνει την εξουσιοδότηση του group member pointer και στη συνέχεια επανεγγράφει την αποθηκευμένη διεύθυνση μέλους του mint. | Πηγή |
Ομάδα Tokens και Μέλος Ομάδας Tokens
| Στοιχείο | Περιγραφή | Πηγή |
|---|---|---|
TokenGroup | Κατάσταση διεπαφής ομάδας tokens που αποθηκεύεται στο mint, συμπεριλαμβανομένης της αρχής ενημέρωσης, του τρέχοντος μεγέθους και του μέγιστου μεγέθους. | Πηγή |
TokenGroupMember | Κατάσταση διεπαφής μέλους ομάδας tokens που αποθηκεύεται στο mint, συμπεριλαμβανομένου του mint μέλους, της διεύθυνσης ομάδας και του αριθμού μέλους. | Πηγή |
TokenGroupInstruction::InitializeGroup | Εντολή διεπαφής ομάδας tokens που υποστηρίζεται από το Token Extensions Program για την προετοιμασία μιας νέας ομάδας για ένα ήδη προετοιμασμένο mint. | Πηγή |
TokenGroupInstruction::UpdateGroupMaxSize | Εντολή διεπαφής ομάδας tokens που υποστηρίζεται από το Token Extensions Program για την ενημέρωση του μέγιστου αριθμού μελών που επιτρέπονται σε μια ομάδα. | Πηγή |
TokenGroupInstruction::UpdateGroupAuthority | Εντολή διεπαφής ομάδας tokens που υποστηρίζεται από το Token Extensions Program για την εναλλαγή ή την εκκαθάριση της αρχής ενημέρωσης της ομάδας. | Πηγή |
TokenGroupInstruction::InitializeMember | Εντολή διεπαφής ομάδας tokens που υποστηρίζεται από το Token Extensions Program για την προετοιμασία ενός νέου μέλους για μια ήδη προετοιμασμένη ομάδα. | Πηγή |
process_initialize_group | Επικυρώνει το mint, ελέγχει ότι το GroupPointer είναι παρόν και εκχωρεί την κατάσταση TokenGroup στο mint της ομάδας. | Πηγή |
process_update_group_max_size | Επικυρώνει την τρέχουσα αρχή ενημέρωσης και στη συνέχεια ενημερώνει το μέγιστο μέγεθος της ομάδας. | Πηγή |
process_update_group_authority | Επικυρώνει την τρέχουσα αρχή ενημέρωσης και στη συνέχεια εναλλάσσει ή εκκαθαρίζει την αρχή ενημέρωσης της ομάδας. | Πηγή |
process_initialize_member | Επικυρώνει το mint μέλους και την αρχή της ομάδας, αυξάνει το μέγεθος της ομάδας και εκχωρεί την κατάσταση TokenGroupMember στο mint. | Πηγή |
Typescript
Το παρακάτω παράδειγμα με Kit χρησιμοποιεί απευθείας τις παραγόμενες οδηγίες.
Παλαιότερα παραδείγματα που χρησιμοποιούν @solana/web3.js, @solana/spl-token
και τους βοηθούς ομάδας token περιλαμβάνονται για αναφορά.
Kit
import {lamports,createClient,generateKeyPairSigner,unwrapOption} from "@solana/kit";import { solanaRpc, rpcAirdrop } from "@solana/kit-plugin-rpc";import { generatedPayer, airdropPayer } from "@solana/kit-plugin-signer";import { getCreateAccountInstruction } from "@solana-program/system";import {extension,fetchMint,getInitializeGroupMemberPointerInstruction,getInitializeGroupPointerInstruction,getInitializeMintInstruction,getInitializeTokenGroupInstruction,getInitializeTokenGroupMemberInstruction,getMintSize,isExtension,TOKEN_2022_PROGRAM_ADDRESS} from "@solana-program/token-2022";const client = await createClient().use(generatedPayer()).use(solanaRpc({rpcUrl: "http://localhost:8899",rpcSubscriptionsUrl: "ws://localhost:8900"})).use(rpcAirdrop()).use(airdropPayer(lamports(1_000_000_000n)));const groupMint = await generateKeyPairSigner();const memberMint = await generateKeyPairSigner();const groupPointerExtension = extension("GroupPointer", {authority: client.payer.address,groupAddress: groupMint.address});const groupExtension = extension("TokenGroup", {updateAuthority: client.payer.address,mint: groupMint.address,size: 0n,maxSize: 10n});const groupMintSpace = BigInt(getMintSize([groupPointerExtension, groupExtension]));const groupMintCreateSpace = BigInt(getMintSize([groupPointerExtension]));const groupMintRent = await client.rpc.getMinimumBalanceForRentExemption(groupMintSpace).send();await client.sendTransaction([getCreateAccountInstruction({payer: client.payer, // Account funding the new mint account.newAccount: groupMint, // New group mint account to create.lamports: groupMintRent, // Lamports funding the mint account rent.space: groupMintCreateSpace, // Account size in bytes for the mint plus GroupPointer.programAddress: TOKEN_2022_PROGRAM_ADDRESS // Program that owns the mint account.}),getInitializeGroupPointerInstruction({mint: groupMint.address, // Mint account that stores the GroupPointer extension.authority: client.payer.address, // Authority allowed to update the group pointer later.groupAddress: groupMint.address // Account address that stores the group data.}),getInitializeMintInstruction({mint: groupMint.address, // Mint account to initialize.decimals: 0, // Number of decimals for the token.mintAuthority: client.payer.address, // Authority allowed to mint new tokens.freezeAuthority: client.payer.address // Authority allowed to freeze token accounts.}),getInitializeTokenGroupInstruction({group: groupMint.address, // Mint account that stores the group data.mint: groupMint.address, // Mint that the group data describes.mintAuthority: client.payer, // Signer authorizing group initialization for the mint.updateAuthority: client.payer.address, // Authority allowed to update the group later.maxSize: 10n // Maximum number of members allowed in the group.})]);const memberPointerExtension = extension("GroupMemberPointer", {authority: client.payer.address,memberAddress: memberMint.address});const memberExtension = extension("TokenGroupMember", {mint: memberMint.address,group: groupMint.address,memberNumber: 1n});const memberMintSpace = BigInt(getMintSize([memberPointerExtension, memberExtension]));const memberMintCreateSpace = BigInt(getMintSize([memberPointerExtension]));const memberMintRent = await client.rpc.getMinimumBalanceForRentExemption(memberMintSpace).send();await client.sendTransaction([getCreateAccountInstruction({payer: client.payer, // Account funding the new mint account.newAccount: memberMint, // New member mint account to create.lamports: memberMintRent, // Lamports funding the mint account rent.space: memberMintCreateSpace, // Account size in bytes for the mint plus GroupMemberPointer.programAddress: TOKEN_2022_PROGRAM_ADDRESS // Program that owns the mint account.}),getInitializeGroupMemberPointerInstruction({mint: memberMint.address, // Mint account that stores the GroupMemberPointer extension.authority: client.payer.address, // Authority allowed to update the member pointer later.memberAddress: memberMint.address // Account address that stores the member data.}),getInitializeMintInstruction({mint: memberMint.address, // Mint account to initialize.decimals: 0, // Number of decimals for the token.mintAuthority: client.payer.address, // Authority allowed to mint new tokens.freezeAuthority: client.payer.address // Authority allowed to freeze token accounts.}),getInitializeTokenGroupMemberInstruction({member: memberMint.address, // Mint account that stores the member data.memberMint: memberMint.address, // Mint that the member data describes.memberMintAuthority: client.payer, // Signer authorizing member initialization for the mint.group: groupMint.address, // Group mint that this member belongs to.groupUpdateAuthority: client.payer // Signer matching the group's update authority.})]);const groupMintAccount = await fetchMint(client.rpc, groupMint.address);const memberMintAccount = await fetchMint(client.rpc, memberMint.address);const groupExtensions = unwrapOption(groupMintAccount.data.extensions) ?? [];const memberExtensions = unwrapOption(memberMintAccount.data.extensions) ?? [];console.log(JSON.stringify({groupMint: groupMint.address,groupPointer: groupExtensions.find((item) =>isExtension("GroupPointer", item)),group: groupExtensions.find((item) => isExtension("TokenGroup", item)),memberMint: memberMint.address,memberPointer: memberExtensions.find((item) =>isExtension("GroupMemberPointer", item)),member: memberExtensions.find((item) =>isExtension("TokenGroupMember", item))},(_, value) => (typeof value === "bigint" ? value.toString() : value),2));
Web3.js
import {Connection,Keypair,Transaction,SystemProgram,LAMPORTS_PER_SOL,sendAndConfirmTransaction} from "@solana/web3.js";import {TOKEN_2022_PROGRAM_ID,ExtensionType,getMintLen,getMint,createInitializeMintInstruction,createInitializeGroupPointerInstruction,createInitializeGroupInstruction,createInitializeGroupMemberPointerInstruction,createInitializeMemberInstruction,getGroupPointerState,getGroupMemberPointerState,getTokenGroupState,getTokenGroupMemberState} from "@solana/spl-token";const connection = new Connection("http://localhost:8899", "confirmed");const authority = Keypair.generate();const airdropSignature = await connection.requestAirdrop(authority.publicKey,5 * LAMPORTS_PER_SOL);await connection.confirmTransaction(airdropSignature, "confirmed");const groupMint = Keypair.generate();const groupPointerExtensions = [ExtensionType.GroupPointer];const spaceWithGroupPointerExtensions = getMintLen(groupPointerExtensions);const groupAndGroupPointerExtensions = [ExtensionType.GroupPointer,ExtensionType.TokenGroup];const spaceWithGroupAndGroupPointerExtensions = getMintLen(groupAndGroupPointerExtensions);const groupMintRent = await connection.getMinimumBalanceForRentExemption(spaceWithGroupAndGroupPointerExtensions);const { blockhash: latestBlockhash } = await connection.getLatestBlockhash();const createGroupMintAccountInstruction = SystemProgram.createAccount({fromPubkey: authority.publicKey, // Account funding the new mint account.newAccountPubkey: groupMint.publicKey, // New group mint account to create.lamports: groupMintRent, // Lamports funding the mint account rent.space: spaceWithGroupPointerExtensions, // Account size in bytes for the mint plus GroupPointer.programId: TOKEN_2022_PROGRAM_ID // Program that owns the mint account.});const initializeGroupPointerInstruction =createInitializeGroupPointerInstruction(groupMint.publicKey, // Mint account that stores the GroupPointer extension.authority.publicKey, // Authority allowed to update the group pointer later.groupMint.publicKey, // Account address that stores the group data.TOKEN_2022_PROGRAM_ID // Program that owns the mint account.);const initializeGroupMintInstruction = createInitializeMintInstruction(groupMint.publicKey, // Mint account to initialize.0, // Number of decimals for the token.authority.publicKey, // Authority allowed to mint new tokens.authority.publicKey, // Authority allowed to freeze token accounts.TOKEN_2022_PROGRAM_ID // Program that owns the mint account.);const initializeGroupInstruction = createInitializeGroupInstruction({programId: TOKEN_2022_PROGRAM_ID, // Token program that owns the mint.group: groupMint.publicKey, // Mint account that stores the group data.mint: groupMint.publicKey, // Mint that the group data describes.mintAuthority: authority.publicKey, // Signer authorizing group initialization for the mint.updateAuthority: authority.publicKey, // Authority allowed to update the group later.maxSize: 10n // Maximum number of members allowed in the group.});const groupTransaction = new Transaction({feePayer: authority.publicKey,recentBlockhash: latestBlockhash}).add(createGroupMintAccountInstruction,initializeGroupPointerInstruction,initializeGroupMintInstruction,initializeGroupInstruction);await sendAndConfirmTransaction(connection,groupTransaction,[authority, groupMint],{commitment: "confirmed",skipPreflight: true});const memberMint = Keypair.generate();const memberPointerExtensions = [ExtensionType.GroupMemberPointer];const spaceWithMemberPointerExtension = getMintLen(memberPointerExtensions);const memberAndMemberPointerExtensions = [ExtensionType.GroupMemberPointer,ExtensionType.TokenGroupMember];const spaceWithMemberAndMemberPointerExtensions = getMintLen(memberAndMemberPointerExtensions);const memberMintRent = await connection.getMinimumBalanceForRentExemption(spaceWithMemberAndMemberPointerExtensions);const { blockhash: memberLatestBlockhash } =await connection.getLatestBlockhash();const createMemberMintAccountInstruction = SystemProgram.createAccount({fromPubkey: authority.publicKey, // Account funding the new mint account.newAccountPubkey: memberMint.publicKey, // New member mint account to create.lamports: memberMintRent, // Lamports funding the mint account rent.space: spaceWithMemberPointerExtension, // Account size in bytes for the mint plus GroupMemberPointer.programId: TOKEN_2022_PROGRAM_ID // Program that owns the mint account.});const initializeMemberPointerInstruction =createInitializeGroupMemberPointerInstruction(memberMint.publicKey, // Mint account that stores the GroupMemberPointer extension.authority.publicKey, // Authority allowed to update the member pointer later.memberMint.publicKey, // Account address that stores the member data.TOKEN_2022_PROGRAM_ID // Program that owns the mint account.);const initializeMemberMintInstruction = createInitializeMintInstruction(memberMint.publicKey, // Mint account to initialize.0, // Number of decimals for the token.authority.publicKey, // Authority allowed to mint new tokens.authority.publicKey, // Authority allowed to freeze token accounts.TOKEN_2022_PROGRAM_ID // Program that owns the mint account.);const initializeMemberInstruction = createInitializeMemberInstruction({programId: TOKEN_2022_PROGRAM_ID, // Token program that owns the mint.member: memberMint.publicKey, // Mint account that stores the member data.memberMint: memberMint.publicKey, // Mint that the member data describes.memberMintAuthority: authority.publicKey, // Signer authorizing member initialization for the mint.group: groupMint.publicKey, // Group mint that this member belongs to.groupUpdateAuthority: authority.publicKey // Signer matching the group's update authority.});const memberTransaction = new Transaction({feePayer: authority.publicKey,recentBlockhash: memberLatestBlockhash}).add(createMemberMintAccountInstruction,initializeMemberPointerInstruction,initializeMemberMintInstruction,initializeMemberInstruction);await sendAndConfirmTransaction(connection,memberTransaction,[authority, memberMint],{commitment: "confirmed",skipPreflight: true});const groupMintAccount = await getMint(connection,groupMint.publicKey,"confirmed",TOKEN_2022_PROGRAM_ID);const memberMintAccount = await getMint(connection,memberMint.publicKey,"confirmed",TOKEN_2022_PROGRAM_ID);console.log(JSON.stringify({groupMint: groupMint.publicKey,groupPointer: getGroupPointerState(groupMintAccount),group: getTokenGroupState(groupMintAccount),memberMint: memberMint.publicKey,memberPointer: getGroupMemberPointerState(memberMintAccount),member: getTokenGroupMemberState(memberMintAccount)},(_, value) => (typeof value === "bigint" ? value.toString() : value),2));
Rust
use anyhow::Result;use solana_client::nonblocking::rpc_client::RpcClient;use solana_commitment_config::CommitmentConfig;use solana_sdk::{signature::{Keypair, Signer},transaction::Transaction,};use solana_system_interface::instruction::create_account;use spl_token_2022_interface::{extension::{group_member_pointer::{instruction::initialize as initialize_group_member_pointer, GroupMemberPointer,},group_pointer::{instruction::initialize as initialize_group_pointer, GroupPointer},BaseStateWithExtensions, ExtensionType, StateWithExtensions,},instruction::initialize_mint,state::Mint,ID as TOKEN_2022_PROGRAM_ID,};use spl_token_group_interface::{instruction::{initialize_group, initialize_member},state::{TokenGroup, TokenGroupMember},};#[tokio::main]async fn main() -> Result<()> {let client = RpcClient::new_with_commitment(String::from("http://localhost:8899"),CommitmentConfig::confirmed(),);let authority = Keypair::new();let airdrop_signature = client.request_airdrop(&authority.pubkey(), 5_000_000_000).await?;loop {let confirmed = client.confirm_transaction(&airdrop_signature).await?;if confirmed {break;}}let group_mint = Keypair::new();let group_mint_space =ExtensionType::try_calculate_account_len::<Mint>(&[ExtensionType::GroupPointer])?;let group_mint_space_with_data = ExtensionType::try_calculate_account_len::<Mint>(&[ExtensionType::GroupPointer,ExtensionType::TokenGroup,])?;let group_mint_rent = client.get_minimum_balance_for_rent_exemption(group_mint_space_with_data).await?;let create_group_mint_account_instruction = create_account(&authority.pubkey(), // Account funding the new mint account.&group_mint.pubkey(), // New group mint account to create.group_mint_rent, // Lamports funding the mint account rent.group_mint_space as u64, // Account size in bytes for the mint plus GroupPointer.&TOKEN_2022_PROGRAM_ID, // Program that owns the mint account.);let initialize_group_pointer_instruction = initialize_group_pointer(&TOKEN_2022_PROGRAM_ID,&group_mint.pubkey(), // Mint account that stores the GroupPointer extension.Some(authority.pubkey()), // Authority allowed to update the group pointer later.Some(group_mint.pubkey()), // Account address that stores the group data.)?;let initialize_group_mint_instruction = initialize_mint(&TOKEN_2022_PROGRAM_ID, // Program that owns the mint account.&group_mint.pubkey(), // Mint account to initialize.&authority.pubkey(), // Authority allowed to mint new tokens.Some(&authority.pubkey()), // Authority allowed to freeze token accounts.0, // Number of decimals for the token.)?;let initialize_group_instruction = initialize_group(&TOKEN_2022_PROGRAM_ID, // Program that owns the mint account.&group_mint.pubkey(), // Mint account that stores the group data.&group_mint.pubkey(), // Mint that the group data describes.&authority.pubkey(), // Signer authorizing group initialization for the mint.Some(authority.pubkey()), // Authority allowed to update the group later.10, // Maximum number of members allowed in the group.);let group_transaction = Transaction::new_signed_with_payer(&[create_group_mint_account_instruction,initialize_group_pointer_instruction,initialize_group_mint_instruction,initialize_group_instruction,],Some(&authority.pubkey()),&[&authority, &group_mint],client.get_latest_blockhash().await?,);client.send_and_confirm_transaction(&group_transaction).await?;let member_mint = Keypair::new();let member_mint_space =ExtensionType::try_calculate_account_len::<Mint>(&[ExtensionType::GroupMemberPointer])?;let member_mint_space_with_data = ExtensionType::try_calculate_account_len::<Mint>(&[ExtensionType::GroupMemberPointer,ExtensionType::TokenGroupMember,])?;let member_mint_rent = client.get_minimum_balance_for_rent_exemption(member_mint_space_with_data).await?;let create_member_mint_account_instruction = create_account(&authority.pubkey(), // Account funding the new mint account.&member_mint.pubkey(), // New member mint account to create.member_mint_rent, // Lamports funding the mint account rent.member_mint_space as u64, // Account size in bytes for the mint plus GroupMemberPointer.&TOKEN_2022_PROGRAM_ID, // Program that owns the mint account.);let initialize_member_pointer_instruction = initialize_group_member_pointer(&TOKEN_2022_PROGRAM_ID,&member_mint.pubkey(), // Mint account that stores the GroupMemberPointer extension.Some(authority.pubkey()), // Authority allowed to update the member pointer later.Some(member_mint.pubkey()), // Account address that stores the member data.)?;let initialize_member_mint_instruction = initialize_mint(&TOKEN_2022_PROGRAM_ID, // Program that owns the mint account.&member_mint.pubkey(), // Mint account to initialize.&authority.pubkey(), // Authority allowed to mint new tokens.Some(&authority.pubkey()), // Authority allowed to freeze token accounts.0, // Number of decimals for the token.)?;let initialize_member_instruction = initialize_member(&TOKEN_2022_PROGRAM_ID, // Program that owns the mint account.&member_mint.pubkey(), // Mint account that stores the member data.&member_mint.pubkey(), // Mint that the member data describes.&authority.pubkey(), // Signer authorizing member initialization for the mint.&group_mint.pubkey(), // Group mint that this member belongs to.&authority.pubkey(), // Signer matching the group's update authority.);let member_transaction = Transaction::new_signed_with_payer(&[create_member_mint_account_instruction,initialize_member_pointer_instruction,initialize_member_mint_instruction,initialize_member_instruction,],Some(&authority.pubkey()),&[&authority, &member_mint],client.get_latest_blockhash().await?,);client.send_and_confirm_transaction(&member_transaction).await?;let group_mint_account = client.get_account(&group_mint.pubkey()).await?;let group_mint_state = StateWithExtensions::<Mint>::unpack(&group_mint_account.data)?;let group_pointer = group_mint_state.get_extension::<GroupPointer>()?;let token_group = group_mint_state.get_extension::<TokenGroup>()?;let member_mint_account = client.get_account(&member_mint.pubkey()).await?;let member_mint_state = StateWithExtensions::<Mint>::unpack(&member_mint_account.data)?;let member_pointer = member_mint_state.get_extension::<GroupMemberPointer>()?;let token_group_member = member_mint_state.get_extension::<TokenGroupMember>()?;println!("\nGroup Mint: {}", group_mint.pubkey());println!("\nGroup Pointer: {:#?}", group_pointer);println!("\nToken Group: {:#?}", token_group);println!("\nMember Mint: {}", member_mint.pubkey());println!("\nGroup Member Pointer: {:#?}", member_pointer);println!("\nToken Group Member: {:#?}", token_group_member);Ok(())}
Is this page helpful?