Revoke tokens from account
Outline
In the previous chapter, we looked at approving tokens to an authority account. In this chapter we will revoke those approved tokens.
The final outcome of this chapter could be found here
Prerequisites
We will continue to use the previously built program.
You can get it here
How to Revoke approved tokens from an account ?
In the previous tutorial, we had approved 5 tokens of payer_mint_ata
to another_authority
account. We will revoke those 5 approved tokens from another_authority
.
It can be achieved by 2-step process.
- Create a
RevokeTokens
context - Create a
revoke_tokens
instruction.
Step-1 : Create a RevokeTokens
context
Let us create a RevokeTokens
context.
// Revoke approved token account
#[derive(Accounts)]
pub struct RevokeTokens<'info> {
#[account(
seeds = [
b"spl-token-mint".as_ref(),
],
bump = vault.spl_token_mint_bump,
)]
pub spl_token_mint: Account<'info, Mint>, // ---> 1
#[account(
seeds = [
b"vault"
],
bump = vault.bump, // --> 2
)]
pub vault: Account<'info, Vault>,
#[account(
mut,
associated_token::mint = spl_token_mint,
associated_token::authority = payer
)]
pub payer_mint_ata: Box<Account<'info, TokenAccount>>, // --> 3
#[account(mut)]
pub payer: Signer<'info>, // ---> 4
pub system_program: Program<'info, System>, // ---> 5
pub token_program: Program<'info, Token>, // ---> 6
}
payer_mint_ata
account usesspl_token_mint
as mintvault
account contains the bumps- Revoke approved tokens of
payer_mint_ata
account - Authority
payer
account is revoking tokens - Solana program uses
system_program
for executing program - We invoke cpi call to
token_program
to callrevoke
instruction.
Step-2 : Create a revoke_tokens
instruction
Now let us create a revoke_tokens
instruction. Add the following code
pub fn revoke_tokens(ctx: Context<RevokeTokens>) -> Result<()> {
let cpi_context = CpiContext::new(
ctx.accounts.token_program.to_account_info(),
token::Revoke {
authority: ctx.accounts.payer.to_account_info(),
source: ctx.accounts.payer_mint_ata.to_account_info(),
},
);
token::revoke(cpi_context)?;
Ok(())
}
Run the test case
With this, we should be ready to run test case on this. Add following test case in your spl-tokens.ts
file.
it("should revoke approved tokens", async () => {
try {
const [splTokenMint, _1] = await findSplTokenMintAddress();
const [vaultMint, _2] = await findVaultAddress();
const [payerMintAta, _3] = await findAssociatedTokenAccount(
payer.publicKey,
splTokenMint
);
const tx = await program.methods
.revokeTokens()
.accounts({
splTokenMint: splTokenMint,
vault: vaultMint,
tokenProgram: TOKEN_PROGRAM_ID,
systemProgram: SystemProgram.programId,
payerMintAta: payerMintAta,
payer: payer.publicKey,
})
.signers([payer])
.rpc();
console.log("Your transaction signature", tx);
} catch (err) {
console.log(err);
}
});
Run the following command
anchor test
You should be able to see the following output.
With this we have understood how to revoke any approved (delegated) tokens.