user_claim
This is the pseudo-code for holder claim using @solana /web3.js in pure JavaScript.
import { PublicKey, SystemProgram, TransactionInstruction } from '@solana/web3.js';
import { Buffer } from 'buffer';
import { FEE_RECEIVER, PROGRAM_ID } from '../utils/constants';
import {
ASSOCIATED_TOKEN_PROGRAM_ID,
createAssociatedTokenAccountInstruction,
createCloseAccountInstruction,
createInitializeAccountInstruction,
getAssociatedTokenAddressSync,
NATIVE_MINT,
TOKEN_PROGRAM_ID
} from '@solana/spl-token';
import { sendAndConfirmTx } from '../utils/conn';
import { getClaimAuthAddress, getConfigAddress, getUserStateAddress } from '../utils/pda';
import { generateRandomSeed } from '../utils/tools';
const discriminator = Buffer.from([178, 17, 203, 100, 110, 186, 223, 38]);
const closeDiscriminator = Buffer.from([127, 206, 172, 187, 146, 179, 215, 194]);
export const userClaim = async (connection, wallet, mintAddress, claimMint, userMintAccount, claimTokenProgram) => {
const instructionData = discriminator;
const mint = new PublicKey(mintAddress);
const instructions = [];
// Instruction: Create userClaimAccount
let userClaimAccount;
if (claimMint.equals(NATIVE_MINT)) {
const seed = generateRandomSeed(24);
userClaimAccount = await PublicKey.createWithSeed(wallet.publicKey, seed, TOKEN_PROGRAM_ID);
const createAccountIx = SystemProgram.createAccountWithSeed({
fromPubkey: wallet.publicKey,
basePubkey: wallet.publicKey,
seed: seed,
newAccountPubkey: userClaimAccount,
lamports: 2039280,
space: 165,
programId: TOKEN_PROGRAM_ID,
});
instructions.push(createAccountIx);
const initAccountIx = createInitializeAccountInstruction(userClaimAccount, NATIVE_MINT, wallet.publicKey);
instructions.push(initAccountIx);
} else {
userClaimAccount = getAssociatedTokenAddressSync(claimMint, wallet.publicKey, false, claimTokenProgram);
const accountInfo = await connection.getAccountInfo(userClaimAccount);
if (!accountInfo) {
const createAccountIx = createAssociatedTokenAccountInstruction(
wallet.publicKey,
userClaimAccount,
wallet.publicKey,
claimMint,
claimTokenProgram,
);
instructions.push(createAccountIx);
}
}
// accounts
const claimAuthority = getClaimAuthAddress(mint);
const userState = getUserStateAddress(wallet.publicKey, mint);
const claimVault = getAssociatedTokenAddressSync(claimMint, claimAuthority, true, claimTokenProgram);
const feeAccount = getAssociatedTokenAddressSync(claimMint, FEE_RECEIVER, false, claimTokenProgram);
const accounts = [
{ pubkey: wallet.publicKey, isSigner: true, isWritable: true },
{ pubkey: getConfigAddress(), isSigner: false, isWritable: false },
{ pubkey: claimAuthority, isSigner: false, isWritable: false },
{ pubkey: mint, isSigner: false, isWritable: false },
{ pubkey: claimMint, isSigner: false, isWritable: false },
{ pubkey: claimVault, isSigner: false, isWritable: true },
{ pubkey: userState, isSigner: false, isWritable: true },
{ pubkey: userMintAccount, isSigner: false, isWritable: false },
{ pubkey: userClaimAccount, isSigner: false, isWritable: true },
{ pubkey: FEE_RECEIVER, isSigner: false, isWritable: false },
{ pubkey: feeAccount, isSigner: false, isWritable: true },
{ pubkey: claimTokenProgram, isSigner: false, isWritable: false },
{ pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
];
// user_claim instruction
const instruction = new TransactionInstruction({
keys: accounts,
programId: PROGRAM_ID,
data: instructionData,
});
instructions.push(instruction);
// Instruction: Close userClaimAccount
if (claimMint.equals(NATIVE_MINT)) {
const closeAccountIx = createCloseAccountInstruction(userClaimAccount, wallet.publicKey, wallet.publicKey);
instructions.push(closeAccountIx);
}
// send and confirm transaction
return sendAndConfirmTx(connection, wallet, instructions, []);
};
export const closeUserStates = async (connection, wallet, mints) => {
const instructions = [];
for (const mint of mints) {
const instructionData = closeDiscriminator;
// accounts
const claimAuthority = getClaimAuthAddress(mint);
const userState = getUserStateAddress(wallet.publicKey, mint);
const accounts = [
{ pubkey: wallet.publicKey, isSigner: true, isWritable: true },
{ pubkey: claimAuthority, isSigner: false, isWritable: false },
{ pubkey: mint, isSigner: false, isWritable: false },
{ pubkey: userState, isSigner: false, isWritable: true },
];
// create instruction
const instruction = new TransactionInstruction({
keys: accounts,
programId: PROGRAM_ID,
data: instructionData,
});
instructions.push(instruction);
}
// send and confirm transaction
return sendAndConfirmTx(connection, wallet, instructions, []);
};Last updated