Tokengroepen en leden

Wat Zijn Groeps- en Groepslidextensies?

Een groep is een mint die een collectie vertegenwoordigt. Een groepslid is een mint die tot die collectie behoort.

Gebruik deze extensies wanneer één mint de collectie moet vertegenwoordigen en andere mints items moeten vertegenwoordigen die erbij horen.

Het Token Extensions Program kan tokengroepsgegevens direct op een mint opslaan met vier gerelateerde extensies:

  • GroupPointer verwijst een mint naar het account dat de gegevens van de groep opslaat.
  • TokenGroup slaat de groepsgegevens zelf op, inclusief de update-autoriteit, huidige grootte en maximale grootte.
  • GroupMemberPointer verwijst een mint naar het account dat de gegevens van het lid opslaat.
  • TokenGroupMember slaat het groepsadres en het lidnummer van het lid op.

GroupPointer en GroupMemberPointer kunnen verwijzen naar elk account dat eigendom is van een programma dat de Token group interface implementeert.

Het Token Extensions Program implementeert die interface ook rechtstreeks via de TokenGroup- en TokenGroupMember-mintextensies.

Hoe Maak Je Groepen en Leden die Op Het Mint Account Zijn Opgeslagen

Om groepen en leden te maken die op het mint account zijn opgeslagen:

  1. Maak een groepsmint account aan en initialiseer GroupPointer.
  2. Initialiseer de groepsmint met InitializeMint.
  3. Initialiseer TokenGroup op datzelfde mint.
  4. Maak een lidmint account aan en initialiseer GroupMemberPointer.
  5. Initialiseer de lidmint met InitializeMint.
  6. Initialiseer TokenGroupMember op datzelfde mint zodat het naar de groepsmint verwijst.

Bereken grootte en rent van groep mint

Bereken de grootte en benodigde rent voor de groep mint.

Groep Mint aanmaken en initialiseren

Maak het groep mint account aan, initialiseer GroupPointer, initialiseer de mint en initialiseer TokenGroup in één transactie.

Bereken grootte en rent van lid mint

Bereken de grootte en benodigde rent voor de lid mint.

Lid Mint aanmaken en initialiseren

Maak het lid mint account aan, initialiseer GroupMemberPointer, initialiseer de mint en initialiseer TokenGroupMember in één transactie.

Bereken grootte en rent van groep mint

Bereken de grootte en benodigde rent voor de groep mint.

Groep Mint aanmaken en initialiseren

Maak het groep mint account aan, initialiseer GroupPointer, initialiseer de mint en initialiseer TokenGroup in één transactie.

Bereken grootte en rent van lid mint

Bereken de grootte en benodigde rent voor de lid mint.

Lid Mint aanmaken en initialiseren

Maak het lid mint account aan, initialiseer GroupMemberPointer, initialiseer de mint en initialiseer TokenGroupMember in één transactie.

Example
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();

Pointers en instructievolgorde

GroupPointer en GroupMemberPointer slaan het accountadres op waar de groeps- of lidgegevens zich bevinden. TokenGroup en TokenGroupMember slaan de daadwerkelijke groeps- of lidgegevens op.

GroupPointerInstruction::Initialize en GroupMemberPointerInstruction::Initialize moeten vóór InitializeMint komen. TokenGroupInstruction::InitializeGroup en TokenGroupInstruction::InitializeMember moeten na InitializeMint komen. Voor elke mint moeten CreateAccount, de pointer-initialisatie-instructie en InitializeMint in dezelfde transactie worden opgenomen.

Bronverwijzing

GroupPointer en GroupMemberPointer zijn pointer-instructies in het Token Extensions Program. TokenGroup en TokenGroupMember volgen de Token group interface, die door het Token Extensions Program wordt geïmplementeerd.

Group Pointer en Group Member Pointer

ItemBeschrijvingBron
GroupPointerMint-extensie die de authority en het adres opslaat voor het account dat de gegevens van een groep opslaat.Bron
GroupMemberPointerMint-extensie die de authority en het adres opslaat voor het account dat de gegevens van een lid opslaat.Bron
GroupPointerInstruction::InitializeInitialiseert de group pointer-extensie vóór InitializeMint.Bron
GroupPointerInstruction::UpdateWerkt het groepsadres bij dat opgeslagen is in de GroupPointer-extensie van de mint.Bron
GroupMemberPointerInstruction::InitializeInitialiseert de group member pointer-extensie vóór InitializeMint.Bron
GroupMemberPointerInstruction::UpdateWerkt het lidadres bij dat opgeslagen is in de GroupMemberPointer-extensie van de mint.Bron
process_initialize (GroupPointer)Schrijft de initiële GroupPointer authority en het groepsadres naar de mint.Bron
process_update (GroupPointer)Valideert de group pointer authority en herschrijft vervolgens het opgeslagen groepsadres van de mint.Bron
process_initialize (GroupMemberPointer)Schrijft de initiële GroupMemberPointer authority en het lidadres naar de mint.Bron
process_update (GroupMemberPointer)Valideert de group member pointer authority en herschrijft vervolgens het opgeslagen lidadres van de mint.Bron

Token Group en Token Group Member

ItemBeschrijvingBron
TokenGroupToken group interface state opgeslagen op de mint, inclusief de update authority, huidige grootte en maximale grootte.Bron
TokenGroupMemberToken group member interface state opgeslagen op de mint, inclusief de member mint, groepsadres en lidnummer.Bron
TokenGroupInstruction::InitializeGroupToken group interface instructie ondersteund door het Token Extensions Program om een nieuwe groep te initialiseren voor een reeds geïnitialiseerde mint.Bron
TokenGroupInstruction::UpdateGroupMaxSizeToken group interface instructie ondersteund door het Token Extensions Program om het maximale aantal toegestane leden in een groep bij te werken.Bron
TokenGroupInstruction::UpdateGroupAuthorityToken group interface instructie ondersteund door het Token Extensions Program om de update authority van de groep te roteren of te wissen.Bron
TokenGroupInstruction::InitializeMemberToken group interface instructie ondersteund door het Token Extensions Program om een nieuw lid te initialiseren voor een reeds geïnitialiseerde groep.Bron
process_initialize_groupValideert de mint, controleert of GroupPointer aanwezig is en wijst de TokenGroup state toe op de groep mint.Bron
process_update_group_max_sizeValideert de huidige update authority en werkt vervolgens de maximale grootte van de groep bij.Bron
process_update_group_authorityValideert de huidige update authority en roteert of wist vervolgens de update authority van de groep.Bron
process_initialize_memberValideert de member mint en groepsauthority, verhoogt de groepsgrootte en wijst de TokenGroupMember state toe op de mint.Bron

Typescript

Het onderstaande Kit-voorbeeld maakt direct gebruik van de gegenereerde instructies. Oude voorbeelden met @solana/web3.js, @solana/spl-token en de token group helpers zijn ter referentie opgenomen.

Kit

Instructions
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
)
);
Console
Click to execute the code.

Web3.js

Instructions
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
)
);
Console
Click to execute the code.

Rust

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(())
}
Console
Click to execute the code.

Is this page helpful?

Inhoudsopgave

Pagina Bewerken

Beheerd door

© 2026 Solana Foundation.
Alle rechten voorbehouden.
Blijf Verbonden