Send Legacy Transaction

Learn how to create and send legacy transactions using the Gorbag wallet.

Basic Legacy Transaction

Send a simple SOL transfer using a legacy transaction:

JAVASCRIPT
1import { useConnection, useWallet } from '@solana/wallet-adapter-react';
2import { LAMPORTS_PER_SOL, PublicKey, Transaction, SystemProgram } from '@solana/web3.js';
3
4export function SendLegacyTransaction() {
5 const { connection } = useConnection();
6 const { publicKey, sendTransaction } = useWallet();
7
8 const sendSol = async () => {
9 if (!publicKey) {
10 throw new Error('Wallet not connected!');
11 }
12
13 // Create a legacy transaction
14 const transaction = new Transaction().add(
15 SystemProgram.transfer({
16 fromPubkey: publicKey,
17 toPubkey: new PublicKey('RecipientPublicKeyHere'),
18 lamports: 0.1 * LAMPORTS_PER_SOL, // 0.1 SOL
19 })
20 );
21
22 // Set recent blockhash
23 const { blockhash } = await connection.getLatestBlockhash();
24 transaction.recentBlockhash = blockhash;
25 transaction.feePayer = publicKey;
26
27 try {
28 // Send the transaction via the wallet
29 const signature = await sendTransaction(transaction, connection);
30 console.log('Transaction signature:', signature);
31
32 // Confirm the transaction
33 const confirmation = await connection.confirmTransaction(signature);
34 console.log('Transaction confirmed:', confirmation);
35 } catch (error) {
36 console.error('Transaction failed:', error);
37 }
38 };
39
40 return (
41 <button onClick={sendSol} disabled={!publicKey}>
42 Send 0.1 SOL
43 </button>
44 );
45}

How Transactions are Handled in Gorbag Adapter

The Gorbag wallet adapter handles transaction signing and sending:

TYPESCRIPT
1async signTransaction<T extends Transaction | VersionedTransaction>(transaction: T): Promise<T> {
2 try {
3 const wallet = this._wallet;
4 if (!wallet) throw new WalletNotConnectedError();
5
6 try {
7 return (await wallet.signTransaction(transaction)) || transaction;
8 } catch (error: any) {
9 throw new WalletSignTransactionError(error?.message, error);
10 }
11 } catch (error: any) {
12 this.emit('error', error);
13 throw error;
14 }
15}
16
17// The sendTransaction is typically handled by the base adapter and wallet UI
18// The wallet handles the actual signing and sending process

Multiple Instructions

Include multiple instructions in a single legacy transaction:

JAVASCRIPT
1import { useConnection, useWallet } from '@solana/wallet-adapter-react';
2import {
3 LAMPORTS_PER_SOL,
4 PublicKey,
5 Transaction,
6 SystemProgram
7} from '@solana/web3.js';
8
9export async function sendMultiInstructionTransaction() {
10 const { connection } = useConnection();
11 const { publicKey, sendTransaction } = useWallet();
12
13 if (!publicKey) {
14 throw new Error('Wallet not connected!');
15 }
16
17 // Create a transaction with multiple instructions
18 const transaction = new Transaction();
19
20 // Add transfer instruction
21 transaction.add(
22 SystemProgram.transfer({
23 fromPubkey: publicKey,
24 toPubkey: new PublicKey('RecipientPublicKeyHere'),
25 lamports: 0.05 * LAMPORTS_PER_SOL,
26 })
27 );
28
29 // Add another transfer instruction
30 transaction.add(
31 SystemProgram.transfer({
32 fromPubkey: publicKey,
33 toPubkey: new PublicKey('AnotherRecipientPublicKey'),
34 lamports: 0.02 * LAMPORTS_PER_SOL,
35 })
36 );
37
38 // Set recent blockhash
39 const { blockhash } = await connection.getLatestBlockhash();
40 transaction.recentBlockhash = blockhash;
41 transaction.feePayer = publicKey;
42
43 try {
44 const signature = await sendTransaction(transaction, connection);
45 console.log('Multi-instruction transaction signature:', signature);
46 return signature;
47 } catch (error) {
48 console.error('Multi-instruction transaction failed:', error);
49 throw error;
50 }
51}

Legacy Transaction with Memo

Add a memo to your legacy transaction:

JAVASCRIPT
1import { useConnection, useWallet } from '@solana/wallet-adapter-react';
2import {
3 PublicKey,
4 Transaction,
5 SystemProgram,
6 TransactionInstruction
7} from '@solana/web3.js';
8
9// Memo program ID for Solana/Gorbagana
10const MEMO_PROGRAM_ID = new PublicKey(
11 'MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr'
12);
13
14export async function sendTransactionWithMemo() {
15 const { connection } = useConnection();
16 const { publicKey, sendTransaction } = useWallet();
17
18 if (!publicKey) {
19 throw new Error('Wallet not connected!');
20 }
21
22 // Create transaction with transfer and memo
23 const transaction = new Transaction();
24
25 // Add transfer instruction
26 transaction.add(
27 SystemProgram.transfer({
28 fromPubkey: publicKey,
29 toPubkey: new PublicKey('RecipientPublicKeyHere'),
30 lamports: 0.1 * LAMPORTS_PER_SOL,
31 })
32 );
33
34 // Add memo instruction
35 transaction.add(
36 new TransactionInstruction({
37 keys: [],
38 programId: MEMO_PROGRAM_ID,
39 data: Buffer.from('This is a memo for the transaction', 'utf8'),
40 })
41 );
42
43 // Set recent blockhash
44 const { blockhash } = await connection.getLatestBlockhash();
45 transaction.recentBlockhash = blockhash;
46 transaction.feePayer = publicKey;
47
48 try {
49 const signature = await sendTransaction(transaction, connection);
50 console.log('Transaction with memo signature:', signature);
51 return signature;
52 } catch (error) {
53 console.error('Transaction with memo failed:', error);
54 throw error;
55 }
56}

Error Handling for Legacy Transactions

Properly handle errors that may occur during legacy transaction processing:

JAVASCRIPT
1import { useConnection, useWallet } from '@solana/wallet-adapter-react';
2import {
3 LAMPORTS_PER_SOL,
4 PublicKey,
5 Transaction,
6 SystemProgram
7} from '@solana/web3.js';
8
9export async function sendTransactionWithErrorHandling() {
10 const { connection } = useConnection();
11 const { publicKey, sendTransaction } = useWallet();
12
13 if (!publicKey) {
14 throw new Error('Wallet not connected!');
15 }
16
17 try {
18 // Create transaction
19 const transaction = new Transaction().add(
20 SystemProgram.transfer({
21 fromPubkey: publicKey,
22 toPubkey: new PublicKey('RecipientPublicKeyHere'),
23 lamports: 0.1 * LAMPORTS_PER_SOL,
24 })
25 );
26
27 // Set recent blockhash
28 const { blockhash } = await connection.getLatestBlockhash();
29 transaction.recentBlockhash = blockhash;
30 transaction.feePayer = publicKey;
31
32 // Send transaction
33 const signature = await sendTransaction(transaction, connection);
34 console.log('Transaction sent:', signature);
35
36 // Confirm transaction and handle potential errors
37 const confirmation = await connection.confirmTransaction(
38 signature,
39 'confirmed' // You can also use 'finalized' for more security
40 );
41
42 if (confirmation.value.err) {
43 console.error('Transaction failed during confirmation:', confirmation.value.err);
44 throw new Error(`Transaction failed: ${JSON.stringify(confirmation.value.err)}`);
45 }
46
47 console.log('Transaction confirmed successfully:', signature);
48 return signature;
49 } catch (error) {
50 console.error('Transaction error:', error);
51
52 // Handle different types of errors
53 if (error.name === 'WalletNotConnectedError') {
54 console.error('Wallet is not connected');
55 } else if (error.name === 'WalletSignTransactionError') {
56 console.error('Transaction signing failed:', error.message);
57 } else if (error.message.includes('blockhash not found')) {
58 console.error('Transaction expired - blockhash too old');
59 } else if (error.message.includes('insufficient funds')) {
60 console.error('Insufficient funds for transaction');
61 } else {
62 console.error('Unexpected error:', error.message);
63 }
64
65 throw error;
66 }
67}