Typescript
SPL Token with Web3.js

SPL Token with Web3.js

Approve and Revoke Instructions

Approve grants a delegate the authority to transfer a specific amount of tokens on behalf of the account owner. This enables programmatic token transfers without giving full account control.

We set an "approved" amount, and the delegate can transfer only up to that amount

Revoke removes the current delegate's authority over the account, returning full control to the account owner.

Immediately cancels any existing delegation and only the account owner can revoke delegation (not the delegate itself)

Before we can mint any token, we'll need to already have:

  • Initialized a Mint account which we hold the mintAuthority
  • Initialized a Token account or Associated Token account where we're going to take control of

The amount of tokens we mint are "normalized" for decimals. This means that if we want to mint 1 token that has 6 decimals, we'll need to actually put 1e6 as amount

Raw Instruction

By using just "raw" instruction without any abstraction, this is how approve a token would look like:

const tokenAccount = Keypair.generate();
 
const tokenAccount = await getAssociatedTokenAddress(
    mint.publicKey,
    tokenAccount.publicKey,
);
 
// Create ATA creation instruction
const createAtaInstruction = createAssociatedTokenAccountIdempotentInstruction(
    keypair.publicKey, // payer
    tokenAccount, // associated token account address
    destination.publicKey, // owner
    mint.publicKey, // mint
);
 
// Delegate an ATA 
const approveInstruction = createApproveInstruction(
    tokenAccount // account
    delegate.publicKey, // delegate
    keypair.publickey // owner
    1e6, // amount of tokens
);
 
const transaction = new Transaction().add(
    createAtaInstruction,
    approveInstruction,
);
 
const signature = await sendAndConfirmTransaction(connection, transaction, [keypair]);
 
console.log(`Token accounts created and delegated! Check out your TX here: https://explorer.solana.com/tx/${signature}?cluster=devnet`);

By using just "raw" instruction without any abstraction, this is how revoke a token would look like:

// Revoke the delegate of an ATA 
const revokeInstruction = createRevokeInstruction(
    tokenAccount // account
    keypair.publickey // owner
);
 
const transaction = new Transaction().add(revokeInstruction);
 
const signature = await sendAndConfirmTransaction(connection, transaction, [keypair]);
 
console.log(`Token account delegate revoked! Check out your TX here: https://explorer.solana.com/tx/${signature}?cluster=devnet`);

Abstracted Instruction

This is how the same instructions would look like abstracted away with the approve() instruction:

const tokenAccount = Keypair.generate();
 
const ata = await getOrCreateAssociatedTokenAccount(
    connection,
    keypair,
    mint,
    tokenAccount.publicKey
);
 
console.log(`This is your ATA: ${ata.address}!`)
  
let tx = await approve(
    connection,
    keypair,
    ata.address, // token Account
    delegate-publicKey, // delegate
    keypair.publicKey, // owner
    1e6, // amount
);
 
console.log(`Succesfully Delegated!. Transaction Here: https://explorer.solana.com/tx/${tx}?cluster=devnet`)

This is how the same instructions would look like abstracted away with the revoke() instruction:

let tx = await revoke(
    connection,
    keypair,
    ata.address, // token Account
    keypair.publicKey, // owner
);
 
console.log(`Succesfully Revoked Delegate!. Transaction Here: https://explorer.solana.com/tx/${tx}?cluster=devnet`)
Contents
View Source
Blueshift © 2025Commit: dd6c76d