How to send a Solana transaction from the connected wallet in React

In this tutorial, we are going to learn how to send a Solana transaction from the wallet connected to your React app using the Solana Web3 JS library.

In this tutorial, we are going to learn how to send a Solana transaction from the wallet connected to your React app using the Solana Web3 JS library.

Here is an example in which I send 0.1 SOL from the wallet connected to the app to another wallet :

import { useState } from 'react';
import { WalletMultiButton } from '@solana/wallet-adapter-react-ui';
import { useConnection, useWallet } from '@solana/wallet-adapter-react';
import { PublicKey, LAMPORTS_PER_SOL, Transaction, SystemProgram } from '@solana/web3.js';

export function Home() {
  const [txId, setTxId] = useState();
  // get a connection
  const { connection } = useConnection();
  // use the hook in your component
  const { sendTransaction, publicKey } = useWallet();

  const sendSolana = async () => {
    const toPublicKey = new PublicKey('A8t59GvWSN6W3W4LKcqKNDhm9YYDEL8PSt235fyECA8J');

    const transaction = new Transaction();
    transaction.add(
      SystemProgram.transfer({
        fromPubkey: publicKey,
        toPubkey: toPublicKey,
        lamports: LAMPORTS_PER_SOL * 0.1,
      })
    );

    // and then send the transaction:
    const hash = await sendTransaction(transaction, connection);
    setTxId(hash);
  };

  return (
    <div>
      <WalletMultiButton />
      <button disabled={!publicKey} onClick={sendSolana}>
        Send transaction
      </button>
      {txId && <p>The transaction hash is {txId}</p>}
    </div>
  );
}

Let's dive into the code

Setting up the app

The first thing to do is install all the libraries we need and allow users to connect their wallet.

We are going to use the following libraries: @solana/wallet-adapter-react-ui,  @solana/wallet-adapter-react and @solana/web3.js.

Now, you need to connect a wallet to your website which you will send the transaction from. To learn how to do that, you can read our article about how to connect a Solana wallet to your website.

How to send Solana from the wallet connected to your app

Getting a connection to the Solana blockchain

To start interacting with the Solana blockchain, we need to create a connection to the network of our choice, either Mainnet , Testnet or Devnet. Mainnet will be for real transaction on the main network and Testnet or Devnet will be used for testing.

Here, we are going to use the Devnet.

If you want to see how to configure your app to connect to the network of your choice, check out our tutorial on how to connect a Solana wallet.

Once we have that configuration in place and we have the right providers wrapping our app, we can use the useConnection hook that returns an object containing a connection property which is what we're going to need:

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

// IN YOUR COMPONENT:
const { connection } = useConnection();

Getting some SOL tokens for testing

For testing on the Testnet or Devnet, you will need to get some SOL tokens to your account on the Devnet.

For that, you can use this faucet https://solfaucet.com/. Faucets will give you free SOL tokens on the Devnet or Testnet. All you need to do is paste the address to which you want the faucet to send the tokens.

You can also use the requestAirdrop method:

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

const fromPubKey = new PublicKey(fromAddress);
const signature = await connection.requestAirdrop(fromPubKey, LAMPORTS_PER_SOL); // 1 SOL

Get the PublicKey objects

The next step is to get PublicKey objects with the address that the transaction is sent from and the address that receives the transaction.

To get the PublicKey of the connected wallet, you can use the useWallet hook. It returns an object that contains a publicKey property. That property is a PublicKey instance of the connected wallet:

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

// ... rest of the app

const { publicKey } = useWallet();

// ... rest of the app

Next, if you have the destination address of the transaction as a string, you can create a PublicKey instance from it:

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

// ... rest of the app

const toPubKey = new PublicKey("A8t59GvWSN6W3W4LKcqKNDhm9YYDEL8PSt235fyECA8J")

// ... rest of the app

Create the transaction

Now that we have that, we can create a Transaction object in which we configure the transaction:

import { useWallet } from '@solana/wallet-adapter-react';
import { PublicKey, LAMPORTS_PER_SOL, Transaction, SystemProgram } from '@solana/web3.js';

// ... REST OF THE APP ...

const { publicKey } = useWallet();


// ... IN THE FUNCTION IN WHICH YOU SEND THE TRANSACTION

const toPubKey = new PublicKey("A8t59GvWSN6W3W4LKcqKNDhm9YYDEL8PSt235fyECA8J")

const transaction = new Transaction();
transaction.add(
  SystemProgram.transfer({
    fromPubkey: publicKey,
    toPubkey: toPubKey,
    lamports: LAMPORTS_PER_SOL * 1,
  })
);


// ... REST OF THE APP ...

In this example, we create a transaction that sends 1 SOL to the address you passed in the parameters.

Now, the thing that might confuse you is the lamports. That's the property in which you pass the amount of SOL tokens you want to transfer.

Lamports are sub-units of Solana. 1 Solana is 10^9 Lamports. That unit is used in the Solana blockchain for better precision to avoid using floaters and other decimal types.

So in order to send SOL tokens, you need to multiply the amount of SOL tokens you want to send by the LAMPORTS_PER_SOL constant which is equal to 10^9.

In our case we send 1 SOL so we do LAMPORTS_PER_SOL * 1.

Now that the transaction object is created, we can send the transaction.

Sending the transaction

To send the transaction from the connected wallet, we can use the useWallet hook which returns an object containing a sendTransaction function.

Calling that function will open a pop-up in the connected wallet for the user to either confirm the transaction and send it or reject it.

That function is asynchronous and returns a Promise that returns the hash of the transaction when it resolves.

If sending the transaction failed, that Promise will throw an error. For example, if the user rejects the transaction on their wallet, it will throw an error.

That function takes in parameter the transaction to send which is a Transaction object like the one we created above and the connection to the blockchain. You can get that connection from the useConnection hook like we've done above.

Here is an example of how to use that function:

// import the sendTransaction function from the useWallet hook:
import { useWallet } from '@solana/wallet-adapter-react';

// use the hook in your component
const { sendTransaction } = useWallet();

// ...create the transaction with the code above...

// and then send the transaction:
const txId = await sendTransaction(transaction, connection);

Bonus: Sending a transaction from a wallet of which you have the private key as a string

For that, we need to install the bs58 library to be able to encode and decode base58 encoded strings. This is the encoding that is used for signatures on the Solana blockchain.

To install it, run: npm install bs58

Here is how to do it:

import { Keypair, sendAndConfirmTransaction } from "@solana/web3.js";
import * as bs58 from "bs58";

const fromAccount = Keypair.fromSecretKey(
    bs58.decode("YOUR PRIVATE KEY HERE")
);


// ....create your transaction here, with the code above....


const signature = await sendAndConfirmTransaction(connection, transaction, [fromAccount]);

And that's it 🎉

Thank you for reading this article