QuickNode Raises $60M Series B!
Read the Letter from our CEO.

How to Burn SPL Tokens on Solana

January 13, 2023

Overview

🔥🔥🔥

Building a deflationary token protocol? Want to destroy a rugged NFT? Just want to have some fun with your community? The Solana SPL Token Program's Burn feature is what you need to take your Solana community to the next level.

In this guide, you will use TypeScript and the Solana SPL Token Program to burn SPL tokens in your wallet.

What You Will Need

Set Up Your Project

Create a new project directory in your terminal with the following:

set up your project

Copy
mkdir burn-spl
cd burn-spl

Create a file for your app, app.ts:

set up your project

Copy
echo > app.ts

Initialize your project with the "yes" flag to use default values for your new package:

set up your project

Copy
yarn init --yes
#or
npm init --yes

Create a tsconfig.json with .json importing enabled:

set up your project

Copy
tsc -init --resolveJsonModule true

Save your paper wallet with devnet SOL and one or more SPL tokens as guideSecret.json (format should be an array of 8-bit integers, e.g. [27,218,103, ...]).

Install Solana Web3 Dependency

We will need to add the Solana Web3 and SPL Token libraries for this exercise. In your terminal, enter:

set up your project

Copy
yarn add @solana/web3.js @solana/spl-token
#or
npm install @solana/web3.js @solana/spl-token

We will need a few components from these libraries and our secret key. Import them in app.ts at line 1 by adding:

set up your project

Copy
import { Connection, PublicKey, Keypair, TransactionMessage, VersionedTransaction } from "@solana/web3.js";
import { createBurnCheckedInstruction, TOKEN_PROGRAM_ID, getAssociatedTokenAddress } from "@solana/spl-token";
import secret from './guideSecret.json';

const WALLET = Keypair.fromSecretKey(new Uint8Array(secret));

Set Up Your QuickNode Endpoint

To build on Solana, you'll need an API endpoint to connect with the network. You're welcome to use public nodes or deploy and manage your own infrastructure; however, if you'd like 8x faster response times, you can leave the heavy lifting to us. See why over 50% of projects on Solana choose QuickNode and sign up for a free account here. We're going to use a Solana Devnet node.

Copy the HTTP Provider link:



Inside app.ts under your import statements, declare your RPC and establish your Connection to Solana:

set up your project

Copy
const QUICKNODE_RPC = 'https://example.solana-devnet.quiknode.pro/0123456/';
const SOLANA_CONNECTION = new Connection(QUICKNODE_RPC);

Your environment should look like this.



Ready? Let's build!

Set Up a Burn App

Declare the Mint Address

To burn an SPL token, you must have some in your wallet on the correct cluster (in this case, Devnet). We will need our token's mint address. To find this if you do not already have it, head over to Solana Explorer. You should be able to see a list of all of your token holdings.



Copy the mint address for the token you would like to use. Click on the mint address and also note the number of decimals. This is important for performing any interaction with the SPL Token program. If you do not have any SPL tokens on your devnet wallet (skip this step if you already have one), you can mint one for this demo at the SPL Token Faucet. You will need to connect your wallet to do this, so you may need to import your paper wallet into Phantom to do this:

  • In Phantom, click on the circle in the top left corner to go to "Settings"
  • Click your wallet to see a list of all of your wallets, and then click "Add/Connect Wallet":



  • Name your new wallet and paste the secret key (contents of guideSecret.json): 
     


Follow the site's instructions to Mint 1,000 USDC-DEV. The mint address for this token is Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr (it has 6 decimals).

Once you have the token you plan to burn and its mint address, open app.ts and add this line:

set up a burn app

Copy
const MINT_ADDRESS = 'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr'; // USDC-Dev from spl-token-faucet.com | replace with the mint you would like to burn
const MINT_DECIMALS = 6; // Value for USDC-Dev from spl-token-faucet.com | replace with the no. decimals of mint you would like to burn
const BURN_QUANTITY = 1; // Number of tokens to burn (feel free to replace with any number - just make sure you have enough)

Create an Async Code Block


Add the following async code block to app.ts. This will frame out our app and create a few steps that we will walk through together:

set up a burn app

Copy
(async () => {
    console.log(`Attempting to burn ${BURN_QUANTITY} [${MINT_ADDRESS}] tokens from Owner Wallet: ${WALLET.publicKey.toString()}`);
    // Step 1 - Fetch Associated Token Account Address

    // Step 2 - Create Burn Instructions

    // Step 3 - Fetch Blockhash

    // Step 4 - Assemble Transaction

    // Step 5 - Execute & Confirm Transaction 

})()

Step 1 - Fetch Associated Token Address

In Step 1 of your code block, we will need to find the account address that holds the tokens we want to burn. As a reminder, the user's wallet does not hold the SPL tokens. The user's wallet owns a separate SPL Token account that holds those tokens. We must find that address (the Associated Token Address, ATA). SPL Token accounts are Program Derived Addresses seeded with the public key of the user's wallet and the token mint address. We can pass both into getAssociatedTokenAddress to find our address:

step 1 fetch associated token address

Copy
    // Step 1 - Fetch Associated Token Account Address
    console.log(`Step 1 - Fetch Token Account`);
    const account = await getAssociatedTokenAddress(new PublicKey(MINT_ADDRESS), WALLET.publicKey);
    console.log(`    ✅ - Associated Token Account Address: ${account.toString()}`);

Note: you can also find the ATA of an account using Solana Explorer. If you look at your token account details, you will see the "Mint Address" and the "Account Address." The account address is the ATA. You can click on it for more information, or copy/paste it into your account variable instead of using getAssociatedTokenAddress. Our token address is the account starting with F9Se...:

You can test your code by running ts-node app in your terminal. You should see a log with your ATA.

Step 2 - Create Burn Instructions

The Solana SPL token program comes with a handy method, createBurnCheckedInstruction, that takes the inputs we have gathered and generates a TransactionInstruction. In Step 2 of your app, add this code:

step 2 create burn instructions

Copy
    // Step 2 - Create Burn Instructions
    console.log(`Step 2 - Create Burn Instructions`);
    const burnIx = createBurnCheckedInstruction(
      account, // PublicKey of Owner's Associated Token Account
      new PublicKey(MINT_ADDRESS), // Public Key of the Token Mint Address
      WALLET.publicKey, // Public Key of Owner's Wallet
      BURN_QUANTITY * (10**MINT_DECIMALS), // Number of tokens to burn
      MINT_DECIMALS // Number of Decimals of the Token Mint
    );
    console.log(`    ✅ - Burn Instruction Created`);

The biggest trick here is getting your types and parameter order correct. Addresses in this instruction are Public Keys, so we need to convert our Mint Address and Wallet. You can mouse over createBurnCheckInstructions to view the parameter inputs or ctrl/cmd + click it for more information about the method.

TypeScript should check that you have all the correct types, but you will need to ensure your parameters are entered in the right order.

Important, notice that we are multiplying BURN_QUANTITY by 10 to the power of the number of decimals. This is necessary for interacting with the SPL token program because they are used to represent the level of precision for the token's value. Without the decimal value, these operations may not produce accurate results and could lead to errors in the token's value.

Step 3 - Fetch the Latest Blockhash

To ensure your transaction efficiently propagates through the network, you will need the latest blockhash. Fetch the latest blockhash information from the cluster using the getLatestBlockhash method. This is necessary to confirm that our transaction has succeeded (and not timed out). Add this code to Step 3 of your app:

step 3 fetch the latest blockhash

Copy
    // Step 3 - Fetch Blockhash
    console.log(`Step 3 - Fetch Blockhash`);
    const { blockhash, lastValidBlockHeight } = await SOLANA_CONNECTION.getLatestBlockhash('finalized');
    console.log(`    ✅ - Latest Blockhash: ${blockhash}`);

You can run your code to make sure everything is working. In your terminal, type ts-node app. You should see the latest blockhash!

Step 4 - Assemble Transaction

We will use versioned transactions to burn our token (though legacy should also work). Check our Guide on How to Use Versioned Transactions if they are new to you. In Step 4 of app.ts add:

step 4 assemble transaction

Copy
    // Step 4 - Assemble Transaction
    console.log(`Step 4 - Assemble Transaction`);
    const messageV0 = new TransactionMessage({
      payerKey: WALLET.publicKey,
      recentBlockhash: blockhash,
      instructions: [burnIx]
    }).compileToV0Message();
    const transaction = new VersionedTransaction(messageV0);
    transaction.sign([WALLET]);
    console.log(`    ✅ - Transaction Created and Signed`);

Using our burnIx parameter and the latestBlockhash, we can create a new MessageV0 by constructing a new Message and executing the .compileToV0Message() method. We then pass our message into a new instance of VersionedTransaction. Finally, we sign the transaction by passing our WALLET into transaction.sign as an array (this allows for multiple signers on more complex transactions).

TypeScript should alert you if there are any errors in your code here, but if you are having trouble, hop on our Discord, and we will be happy to help.

Step 5 - Execute & Confirm Transaction

Alright. Everything is ready. We just need to send our transaction to the cluster and confirm that it has been successfully added to the chain. We can do this with the sendTransaction and confirmTransaction methods. In Step 5 of app.ts, add:

step 5 execute confirm transaction

Copy
    // Step 5 - Execute & Confirm Transaction 
    console.log(`Step 5 - Execute & Confirm Transaction`);
    const txid = await SOLANA_CONNECTION.sendTransaction(transaction);
    console.log("    ✅ - Transaction sent to network");
    const confirmation = await SOLANA_CONNECTION.confirmTransaction({
        signature: txid,
        blockhash: blockhash,
        lastValidBlockHeight: lastValidBlockHeight
    });
    if (confirmation.value.err) { throw new Error("    ❌ - Transaction not confirmed.") }
    console.log('🔥 SUCCESSFUL BURN!🔥', '\n', `https://explorer.solana.com/tx/${txid}?cluster=devnet`);

Here is a quick summary of what is happening:

  • sendTransaction sends our transaction to the network and will return a promise for a transaction ID, txid.
  • We pass that txid along with blockhash and lastValidBlockHeight into confirmTransaction to check that our transaction has been confirmed.
  • Finally, if our confirmation returns an error, we throw an error.

Run Your Code

You should be all set--let's make some fire! In your terminal, type:

run your code

Copy
ts-node app.ts



You should see the transaction progress in your terminal:



You should be able to open your Solana Explorer link and scroll to the instructions to verify that the burn was a success!



Great work!

Wrap Up

Let it burn. You now have the tools to build burn tools on Solana! This will work for any SPL token, even NFTs (NFTs will have decimals = 0). Here are a couple of starter ideas to keep building off of this example:


We love building and want to hear what you are cooking. Drop us a line on Discord or Twitter to tell us what you are up to!

We <3 Feedback!

If you have any feedback on this guide, let us know. We’d love to hear from you.

Related articles 41

Solana NFT Metadata Deep Dive
Published: Dec 16, 2022
Updated: Dec 16, 2022

Even in the 2022 bear market, Solana NFTs are showing no signs of slowing down. If you are building with Solana NFTs, understanding your NFTs' metadata will make it easier for you to deploy...

Continue reading
How to Transfer SPL Tokens on Solana
Published: Sep 23, 2022
Updated: Sep 23, 2022

Sending Solana Program Library (SPL) Tokens is a critical mechanism for Solana development. Whether you are airdropping whitelist tokens to your community, bulk sending NFTs to another wallet,...

Continue reading
Como crear un NFT en SOLANA
Published: Dec 27, 2021
Updated: Sep 23, 2022

¡Hola querido lector! Bienvenidos a una nueva guía de Solana.Solana es una blockchain que promete mucho a la hora de intentar resolver los problemas de escalabilidad que...

Continue reading
How to Mint an NFT on Solana
Published: Aug 27, 2021
Updated: Sep 23, 2022

Updated at: April 10, 2022Welcome to another QuickNode guide on Solana - the up-and-coming blockchain that seeks to solve the scalability issues of Ethereum. We will be walking through...

Continue reading
How to Send Bulk Transactions on Solana
Published: Aug 31, 2022
Updated: Oct 3, 2022

Are you running a batch process that has many transactions? Perhaps an airdrop to your community's NFT holders or a token distribution to early users of your dApp. Solana transaction...

Continue reading
How to Get Transaction Logs on Solana
Published: Jun 24, 2022
Updated: Oct 27, 2022

Ever need to pull all the transactions associated with a Wallet? Want to see all of the mint transactions associated with a Candy Machine? Or maybe see transaction history of an NFT? Solana's...

Continue reading
How to Use Priority Fees on Solana
Published: Jan 13, 2023
Updated: Jan 17, 2023

Are you looking to get your transactions confirmed as quickly as possible on Solana? This guide will show you how to use priority fees to bid for priority in the leader's queue and confirm...

Continue reading
Solana Fundamentals Reference Guide
Published: Oct 27, 2022
Updated: Oct 27, 2022

The Solana blockchain is a powerful tool, delivering thousands of transactions per second with almost no-cost transaction fees. If you are new to Web3 or have developed on EVM-based...

Continue reading