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