The Cpi Guard Extension
The CpiGuard
extension is a Token
account extension that prohibits certain actions inside cross-program invocations, protecting users from malicious programs that might attempt to manipulate their token accounts without explicit consent.
Initializing the Token Account
To initialie the CpiGuard
extension on a Token
account we're going to need the enableCpiGuard()
function.
Here's how to create a mint with the Cpi Guard extension:
import {
Keypair,
SystemProgram,
Transaction,
sendAndConfirmTransaction,
} from '@solana/web3.js';
import {
createInitializeAccountInstruction,
createInitializeImmutableOwnerInstruction,
getAccountLen,
ExtensionType,
TOKEN_2022_PROGRAM_ID,
} from '@solana/spl-token';
const tokenAccount = Keypair.generate();
// Calculate the size needed for a Token account with Transfer Fee extension
const accountLen = getAccountLen([ExtensionType.ImmutableOwner]);
// Calculate minimum lamports required for rent exemption
const lamports = await connection.getMinimumBalanceForRentExemption(accountLen);
// Create the account with the correct size and owner
const createAccountInstruction = SystemProgram.createAccount({
fromPubkey: keypair.publicKey,
newAccountPubkey: tokenAccount.publicKey,
space: accountLen,
lamports,
programId: TOKEN_2022_PROGRAM_ID,
});
// Initialize the Cpi Guard extension
const enableCpiGuardInstruction = createEnableCpiGuardInstruction(
tokenAccount.publicKey,
keypair.publicKey,
undefined,
TOKEN_2022_PROGRAM_ID,
);
// Initialize the Token account itself
const initializeAccountInstruction = createInitializeAccountInstruction(
tokenAccount.publicKey,
mint.publicKey,
keypair.publicKey,
TOKEN_2022_PROGRAM_ID,
);
const transaction = new Transaction().add(
createAccountInstruction,
initializeAccountInstruction,
enableCpiGuardInstruction
);
const signature = await sendAndConfirmTransaction(connection, transaction, [keypair, tokenAccount], {skipPreflight: false});
console.log(`Token accounts created! Check out your TX here: https://explorer.solana.com/tx/${signature}?cluster=devnet`);
Disabling the CPI Guard
When we want to enable some of the behaviours that are blocked by the Cpi guard we can easily disable the guard using the disableCpiGuard
instruction like so:
const disableCpiGuardInstruction = createDisableCpiGuardInstruction(
tokenAccount,
keypair.publicKey,
undefined,
TOKEN_2022_PROGRAM_ID,
);
And when we're done and we want to re-add the layer of security we can re-enable using the enableCpiGuard
instruction like so:
const enableCpiGuardInstruction = createEnableCpiGuardInstruction(
tokenAccount,
keypair.publicKey,
undefined,
TOKEN_2022_PROGRAM_ID,
);