gill

Burn Tokens

Learn how to burn tokens from a wallet using the gill JavaScript library.

Burning tokens permanently removes them from circulation by destroying them from a wallet's Associated Token Account (ATA). The token account authority (owner) must sign the transaction to authorize the burn.

This guide demonstrates how to burn tokens using the gill package with the getBurnCheckedInstruction from gill/programs.

Install gill

Install gill using the core gill library:

npm install gill

Create an RPC connection

In order to send transactions and/or fetch data from the Solana blockchain, you will need a client connection. You can easily create a Solana client connection using the createSolanaClient() function.

The urlOrMoniker can be either a Solana network moniker (e.g. devnet, mainnet, localnet) or a full URL of your RPC provider.

import {  } from "gill";

const { ,  } = ({
  : "devnet", // `mainnet`, `localnet`, etc
});

Public RPC endpoints are subject to rate limits

Using a Solana moniker will connect to the public RPC endpoints. These are subject to rate limits and should not be used in production applications. Applications should find their own RPC provider and the URL provided from them.

Prepare a Signer

Every Solana transaction requires at least one "signer" to be the fee payer for the transaction. When burning tokens, the authority (the token account owner) must also be a signer to authorize the burn.

Load a signer from a local keypair file

For backend scripts and some server environments, you can load a signer from your local filesystem:

import { type  } from "gill";
import {  } from "gill/node";

// This defaults to the file path used by the Solana CLI: `~/.config/solana/id.json`
const :  = await ();
.("signer:", .);

Understanding token amounts

When burning tokens, the amount you provide is in raw base units, not human-readable units. The conversion depends on the decimals value of your token mint.

For example, if your token has decimals = 9 (the most common for fungible tokens):

  • 1_000_000_000 (1e9) = 1 token
  • 5_000_000_000 (5e9) = 5 tokens
  • 1_000_000 (1e6) = 0.001 tokens

Decimals matter

With decimals = 9, to burn 100 tokens you would set amount to 100_000_000_000 (100e9). With decimals = 6, to burn 100 tokens you would set amount to 100_000_000 (100e6). Always check your token's decimals to calculate the correct raw amount.

Build the burn transaction

To burn tokens, use the getBurnCheckedInstruction() from gill/programs. This is the recommended burn instruction because it validates the token's decimals for safety.

First, derive the ATA for the wallet that holds the tokens to burn:

import { getAssociatedTokenAccountAddress } from "gill/programs";

const ata = await getAssociatedTokenAccountAddress(mint, signer.address);

Then create the burn instruction and build the transaction:

import { createTransaction } from "gill";
import { getBurnCheckedInstruction } from "gill/programs";

const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();

const burnIx = getBurnCheckedInstruction({
  account: ata,
  mint,
  authority: signer,
  amount: 1_000_000_000, // 1 token (with decimals=9)
  decimals: 9,
});

const transaction = createTransaction({
  feePayer: signer,
  version: "legacy",
  instructions: [burnIx],
  latestBlockhash,
});

Where mint is the address of the token mint and signer is the owner of the token account.

Sign and send the transaction

With your transaction fully created, you can now sign and send it:

import {
  signTransactionMessageWithSigners,
  getSignatureFromTransaction,
  getExplorerLink,
} from "gill";

const signedTransaction = await signTransactionMessageWithSigners(transaction);

console.log(
  "Explorer:",
  getExplorerLink({
    cluster: "devnet",
    transaction: getSignatureFromTransaction(signedTransaction),
  }),
);

If your transaction is already fully signed or has all signers available, you can send and confirm it on the blockchain:

await sendAndConfirmTransaction(signedTransaction);

Pro Tip

If you do not need to know the transaction signature prior to sending the transaction AND all signers are attached to the transaction, you can pass a fully signable transaction to the sendAndConfirmTransaction() function initialized from createSolanaClient(). It will then perform the signing operations prior to sending and confirming.

Using Token Extensions (Token22)

If your token was created with the Token Extensions program (Token22), pass the programAddress in the config to getBurnCheckedInstruction() and the tokenProgram to getAssociatedTokenAccountAddress():

import {
  TOKEN_2022_PROGRAM_ADDRESS,
  getAssociatedTokenAccountAddress,
  getBurnCheckedInstruction,
} from "gill/programs";

const ata = await getAssociatedTokenAccountAddress(
  mint,
  signer.address,
  TOKEN_2022_PROGRAM_ADDRESS,
);

const burnIx = getBurnCheckedInstruction(
  {
    account: ata,
    mint,
    authority: signer,
    amount: 1_000_000_000,
    decimals: 9,
  },
  { programAddress: TOKEN_2022_PROGRAM_ADDRESS },
);