How to compute the fee for a Solana transaction in JavaScript or React

In this tutorial, we are going to learn how to compute the network fee that a transaction will cost on Solana in JavaScript or React with the Solana Web3 JS library.

In this tutorial, we are going to learn how to compute the network fee that a transaction will cost on Solana in JavaScript or React with the Solana Web3 JS library.

Here is an example in which I estimate the network fee for a transaction that transfers Solana tokens to another address but you can use the same logic to estimate the cost of any transaction:

const getFee = async (connection, fromPublicKey, toPublicKey) => {
  
  // Create the transaction as if you were going to send it
  const transaction = new Transaction();
  transaction.add(
    SystemProgram.transfer({
      fromPubkey: fromPublicKey,
      toPubkey: toPublicKey,
      lamports: LAMPORTS_PER_SOL * 1,
    })
  );
  
  // Add a recentBlockhash to the transaction
  const { blockhash } = await connection.getLatestBlockhash('finalized');
  transaction.recentBlockhash = blockhash;
  
  // Set the fee payer of the transaction
  transaction.feePayer = fromPublicKey;

  // Get the fee for your transaction
  const feeForMessage = await connection.getFeeForMessage(
    transaction.compileMessage(),
    'confirmed'
  );
  const feeInLamports = feeForMessage.value;

  // Convert the fee from Lamports to Solana
  const fee = feeInLamports / LAMPORTS_PER_SOL;
  return fee;
};

Preparing the estimation

First, we need a connection to the blockchain to start interacting with it. If you're using React, you can simply use the useConnection hook:

import { useConnection } from '@solana/wallet-adapter-react'

// In your component:

const { connection } = useConnection()

Otherwise, you can create a Connection object like this:

import { Connection, clusterApiUrl } from '@solana/web3.js'

// Create a connection:

// This one is a connection to the Mainnet but you can also pass "devnet" or "testnet"
const connection = new Connection(clusterApiUrl('mainnet-beta'))

Next, you need to get PublicKey objects from the address you send the transaction from and from the address you send the transaction to. That will be useful to create the Transaction that you want to estimate.

In React, you can just use the useWallet hook to get the PublicKey of the wallet connected to your app:

import { useWallet } from '@solana/wallet-adapter-react'

// In your component:

const { publicKey } = useWallet()

Otherwise, you can create PublicKey objects from an address as a string:

import { PublicKey } from '@solana/web3.js'

const publicKey = new PublicKey('A8t59GvWSN6W3W4LKcqKNDhm9YYDEL8PSt235fyECA8J');

Estimating your transaction

Next, you need to create your transaction just like you do before sending it. You need to create the exact same Transaction object that you would use to send the transaction.

Here is an example in which I create a Transaction that sends 0.1 SOL from an address to another:

// Create the transaction as if you were going to send it
  const transaction = new Transaction();
  transaction.add(
    SystemProgram.transfer({
      fromPubkey: fromPublicKey,
      toPubkey: toPublicKey,
      lamports: LAMPORTS_PER_SOL * 0.1,
    })
  );
  
  // Add a recentBlockhash to the transaction
  const { blockhash } = await connection.getLatestBlockhash('finalized');
  transaction.recentBlockhash = blockhash;
  
  // Set the fee payer of the transaction
  transaction.feePayer = fromPublicKey;

Check out this tutorial to learn how to send transactions that send Solana tokens and this one to learn how to send SPL tokens on Solana.

Once you have that Transaction object, you can use getFeeForMessage method which takes in parameter the transaction message to estimate.

There is also a second optional parameter which is the desired commitment that you want the transaction to have. It can be one of these values. Usually we don't pass anything as the default value is "confirmed" which corresponds to a transaction that is completed on the blockchain.

Here is an example in which I estimate the transaction we created above:

// Get the fee for your transaction
const feeForMessage = await connection.getFeeForMessage(
  transaction.compileMessage(),
  'confirmed'
);

const feeInLamports = feeForMessage.value;

// Convert the fee from Lamports to Solana
const fee = feeInLamports / LAMPORTS_PER_SOL;
return fee;

In the first parameter of the getFeeForMessage method, you have to pass the compiled message of the transaction you want to estimate.

To do that, we call the compileMessage() method of the Transaction we created and we pass the result of that function in the first parameter of the getFeeForMessage function.

The getFeeForMessage method returns a RpcResponseAndContext object and the fee will be in the value property of that object (it will be a number).

The fee returned will be in Lamports which is a sub-unit of Solana which has 9 decimals of precision. It is use to represent Solana amounts on the blockchain. We use that to avoid using floaters which could result in losses of precision.

To convert that value into Solana which is the unit we're used to, you have to divide that amount by LAMPORTS_PER_SOL or by 10 to the power of 9:

import { LAMPORTS_PER_SOL } from '@solana/web3.js';

const feeInLamports = feeForMessage.value;

const feeInSol = feeInLamports / LAMPORTS_PER_SOL

If you want to learn more about the Solana blockchain and how you can interact with it, check out all our tutorials on Solana here:

Solana - 0xDev
Learn web3 development and blockchain development for free with our tutorials and courses. You will find all you need to learn to become a web3 developer

And that's it 🎉

Thank you for reading this article