ما هي ملحقات المجموعة وعضو المجموعة؟
المجموعة هي عملية سك تمثل مجموعة. عضو المجموعة هو عملية سك تنتمي إلى تلك المجموعة.
استخدم هذه الملحقات عندما يجب أن تمثل إحدى عمليات السك المجموعة وأن تمثل عمليات السك الأخرى العناصر التي تنتمي إليها.
يمكن لبرنامج Token Extensions تخزين بيانات مجموعة الرموز مباشرة على عملية السك باستخدام أربعة ملحقات ذات صلة:
GroupPointerيوجه عملية السك إلى الحساب الذي يخزن بيانات المجموعة.TokenGroupيخزن بيانات المجموعة نفسها، بما في ذلك سلطة التحديث والحجم الحالي والحجم الأقصى.GroupMemberPointerيوجه عملية السك إلى الحساب الذي يخزن بيانات العضو.TokenGroupMemberيخزن عنوان مجموعة العضو ورقم العضو.
يمكن لـ GroupPointer و GroupMemberPointer الإشارة إلى أي حساب مملوك
لبرنامج يطبق
واجهة مجموعة الرموز.
يطبق برنامج Token Extensions أيضًا تلك الواجهة مباشرة من خلال ملحقات السك
TokenGroup و TokenGroupMember.
كيفية إنشاء مجموعات وأعضاء مخزنة على حساب السك
لإنشاء مجموعات وأعضاء مخزنة على حساب السك:
- أنشئ حساب سك المجموعة وابدأ تشغيل
GroupPointer. - ابدأ تشغيل سك المجموعة باستخدام
InitializeMint. - ابدأ تشغيل
TokenGroupعلى نفس عملية السك. - أنشئ حساب سك العضو وابدأ تشغيل
GroupMemberPointer. - ابدأ تشغيل سك العضو باستخدام
InitializeMint. - ابدأ تشغيل
TokenGroupMemberعلى نفس عملية السك بحيث يشير إلى سك المجموعة.
احسب حجم الصك الجماعي والإيجار
احسب الحجم والإيجار المطلوبين للصك الجماعي.
إنشاء وتهيئة الصك الجماعي
أنشئ حساب الصك الجماعي، وهيئ GroupPointer، وهيئ الصك، وهيئ
TokenGroup في معاملة واحدة.
احسب حجم صك العضو والإيجار
احسب الحجم والإيجار المطلوبين لصك العضو.
إنشاء وتهيئة صك العضو
أنشئ حساب صك العضو، وهيئ GroupMemberPointer، وهيئ الصك، وهيئ
TokenGroupMember في معاملة واحدة.
المؤشرات وترتيب التعليمات
يخزن GroupPointer و GroupMemberPointer عنوان الحساب
حيث تتواجد بيانات المجموعة أو العضو. يخزن TokenGroup و
TokenGroupMember بيانات المجموعة أو العضو الفعلية.
يجب أن يأتي GroupPointerInstruction::Initialize و
GroupMemberPointerInstruction::Initialize قبل InitializeMint. يجب أن
يأتي TokenGroupInstruction::InitializeGroup و
TokenGroupInstruction::InitializeMember بعد InitializeMint. لكل صك،
يجب تضمين CreateAccount وتعليمة تهيئة المؤشر و InitializeMint في نفس
المعاملة.
مرجع المصدر
GroupPointer و GroupMemberPointer هما تعليمات مؤشر في برنامج Token
Extensions. يتبع TokenGroup و TokenGroupMember واجهة مجموعة الرموز،
والتي ينفذها برنامج Token Extensions.
مؤشر المجموعة ومؤشر عضو المجموعة
| العنصر | الوصف | المصدر |
|---|---|---|
GroupPointer | امتداد صك يخزن الصلاحية والعنوان للحساب الذي يخزن بيانات المجموعة. | المصدر |
GroupMemberPointer | امتداد صك يخزن الصلاحية والعنوان للحساب الذي يخزن بيانات العضو. | المصدر |
GroupPointerInstruction::Initialize | يهيئ امتداد مؤشر المجموعة قبل InitializeMint. | المصدر |
GroupPointerInstruction::Update | يحدّث عنوان المجموعة المخزن بواسطة امتداد GroupPointer للصك. | المصدر |
GroupMemberPointerInstruction::Initialize | يهيئ امتداد مؤشر عضو المجموعة قبل InitializeMint. | المصدر |
GroupMemberPointerInstruction::Update | يحدّث عنوان العضو المخزن بواسطة امتداد GroupMemberPointer للصك. | المصدر |
process_initialize (GroupPointer) | يكتب صلاحية GroupPointer الأولية وعنوان المجموعة على الصك. | المصدر |
process_update (GroupPointer) | يتحقق من صلاحية مؤشر المجموعة، ثم يعيد كتابة عنوان المجموعة المخزن في الصك. | المصدر |
process_initialize (GroupMemberPointer) | يكتب صلاحية GroupMemberPointer الأولية وعنوان العضو على الصك. | المصدر |
process_update (GroupMemberPointer) | يتحقق من صلاحية مؤشر عضو المجموعة، ثم يعيد كتابة عنوان العضو المخزن في الصك. | المصدر |
مجموعة الرموز وعضو مجموعة الرموز
| العنصر | الوصف | المصدر |
|---|---|---|
TokenGroup | حالة واجهة مجموعة الرموز المخزنة على عملية السك، بما في ذلك سلطة التحديث والحجم الحالي والحجم الأقصى. | المصدر |
TokenGroupMember | حالة واجهة عضو مجموعة الرموز المخزنة على عملية السك، بما في ذلك عملية سك العضو وعنوان المجموعة ورقم العضو. | المصدر |
TokenGroupInstruction::InitializeGroup | تعليمات واجهة مجموعة الرموز المدعومة من قبل Token Extensions Program لتهيئة مجموعة جديدة لعملية سك تم تهيئتها بالفعل. | المصدر |
TokenGroupInstruction::UpdateGroupMaxSize | تعليمات واجهة مجموعة الرموز المدعومة من قبل Token Extensions Program لتحديث الحد الأقصى لعدد الأعضاء المسموح بهم في المجموعة. | المصدر |
TokenGroupInstruction::UpdateGroupAuthority | تعليمات واجهة مجموعة الرموز المدعومة من قبل Token Extensions Program لتدوير أو إلغاء سلطة التحديث الخاصة بالمجموعة. | المصدر |
TokenGroupInstruction::InitializeMember | تعليمات واجهة مجموعة الرموز المدعومة من قبل Token Extensions Program لتهيئة عضو جديد لمجموعة تم تهيئتها بالفعل. | المصدر |
process_initialize_group | يتحقق من صحة عملية السك، ويتأكد من وجود GroupPointer، ويخصص حالة TokenGroup على عملية سك المجموعة. | المصدر |
process_update_group_max_size | يتحقق من صحة سلطة التحديث الحالية، ثم يحدث الحجم الأقصى للمجموعة. | المصدر |
process_update_group_authority | يتحقق من صحة سلطة التحديث الحالية، ثم يدور أو يلغي سلطة التحديث الخاصة بالمجموعة. | المصدر |
process_initialize_member | يتحقق من صحة عملية سك العضو وسلطة المجموعة، ويزيد حجم المجموعة، ويخصص حالة TokenGroupMember على عملية السك. | المصدر |
تايب سكريبت
يستخدم المثال أدناه باستخدام Kit التعليمات المُنشأة مباشرة. تم تضمين الأمثلة
القديمة التي تستخدم @solana/web3.js و @solana/spl-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?