Sending SPL tokens is a common transaction on the Solana blockchain. This recipe walks you through creating and sending SPL token transfer transactions using @solana/spl-token
and @solana/web3.js
with Privy wallets. In this example, we’ll use USDC as the SPL token, but you can adapt it for any SPL token by changing the mint address and decimals.
Overview
This recipe demonstrates how to:
- Create an SPL token transfer transaction using
@solana/spl-token
- Handle token accounts and decimals properly
- Sign and send the transaction using Privy wallets
Prerequisites
Install the required dependencies:
bash npm install @solana/web3.js @solana/spl-token
1. Create the SPL token transfer transaction
Create an SPL token transfer transaction using your preferred language:
import {Connection, PublicKey, Transaction} from '@solana/web3.js';
import {getAssociatedTokenAddress, createTransferInstruction} from '@solana/spl-token';
const createSPLTransferTransaction = async (
fromAddress: string,
toAddress: string,
tokenMintAddress: string,
amount: number,
decimals: number = 6 // Default for USDC, adjust for your token
) => {
// Set up connection to Solana network
const connection = new Connection('https://api.mainnet-beta.solana.com', 'confirmed');
// Create public key objects
const fromPubkey = new PublicKey(fromAddress);
const toPubkey = new PublicKey(toAddress);
const mintPubkey = new PublicKey(tokenMintAddress);
// Get associated token accounts
const fromTokenAccount = await getAssociatedTokenAddress(mintPubkey, fromPubkey);
const toTokenAccount = await getAssociatedTokenAddress(mintPubkey, toPubkey);
// Convert amount to token units (considering decimals)
const tokenAmount = amount * Math.pow(10, decimals);
// Create transfer instruction
const transferInstruction = createTransferInstruction(
fromTokenAccount,
toTokenAccount,
fromPubkey,
tokenAmount
);
// Create transaction and add instruction
const transaction = new Transaction().add(transferInstruction);
// Get recent blockhash
const {blockhash} = await connection.getLatestBlockhash();
transaction.recentBlockhash = blockhash;
transaction.feePayer = fromPubkey;
return {transaction, connection};
};
2. Send the transaction
You can send the transaction using Privy’s different SDKs. Below are examples for React, React Native, NodeJS, and Python:
React
React Native
NodeJS
NodeJS (server-auth)
Python
import {useSignAndSendTransaction, useWallets} from '@privy-io/react-auth/solana';
const {wallets} = useWallets();
const {signAndSendTransaction} = useSignAndSendTransaction();
const {transaction, connection} = await createSPLTransferTransaction(
wallets[0].address,
'recipient-wallet-address', // Replace with recipient's token account address
'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC mint address
10 // Amount to send
);
// Assuming you have a transaction created from the previous step
const signature = await sendTransaction({
transaction.serialize(), // from createSPLTransferTransaction
wallet: wallets[0],
});
You’ve successfully sent SPL tokens!
Token account considerations
Before sending SPL tokens, ensure that the recipient has a token account for the specific token
mint.
You can check if token accounts exist and get their addresses:
import {Connection, PublicKey} from '@solana/web3.js';
import {getAssociatedTokenAddress} from '@solana/spl-token';
const connection = new Connection('https://api.mainnet-beta.solana.com', 'confirmed');
// Check if token account exists
const tokenAccountAddress = await getAssociatedTokenAddress(
new PublicKey('tokenMintAddress'),
new PublicKey('walletAddress')
);
const accountInfo = await connection.getAccountInfo(tokenAccountAddress);
const accountExists = accountInfo !== null;
Token mint addresses are different on each network, so make sure you’re using the correct addresses for your target environment.
Next steps
Now that you can send SPL tokens, you might want to explore: