import {
Connection,
Keypair,
SystemProgram,
Transaction,
} from "@solana/web3.js";
import {
TOKEN_2022_PROGRAM_ID,
ExtensionType,
getMintLen,
createInitializeMint2Instruction,
createInitializeTransferFeeConfigInstruction,
} from "@solana/spl-token";
async function createMintWithTransferFee(
connection: Connection,
payer: Keypair,
mintAuthority: PublicKey,
decimals: number,
feeBasisPoints: number,
maxFee: bigint
): Promise<PublicKey> {
const mint = Keypair.generate();
// Calculate size dynamically based on extensions
const extensions = [ExtensionType.TransferFeeConfig];
const mintLen = getMintLen(extensions);
// Query rent for the dynamic size
const lamports = await connection.getMinimumBalanceForRentExemption(mintLen);
const transaction = new Transaction().add(
SystemProgram.createAccount({
fromPubkey: payer.publicKey,
newAccountPubkey: mint.publicKey,
space: mintLen, // Dynamic size
lamports, // Correct rent from chain
programId: TOKEN_2022_PROGRAM_ID,
}),
// Initialize extension BEFORE mint
createInitializeTransferFeeConfigInstruction(
mint.publicKey,
mintAuthority,
mintAuthority,
feeBasisPoints,
maxFee,
TOKEN_2022_PROGRAM_ID
),
// Use InitializeMint2
createInitializeMint2Instruction(
mint.publicKey,
decimals,
mintAuthority,
null,
TOKEN_2022_PROGRAM_ID
)
);
await sendAndConfirmTransaction(connection, transaction, [payer, mint]);
return mint.publicKey;
}