Transaction Interface
software.sava.core.tx.Transaction
Provides methods to create, sign, and serialize Solana transactions.
Constants
int MAX_SERIALIZED_LENGTH = 1232;
int MAX_BASE_64_ENCODED_LENGTH = 1683;
int SIGNATURE_LENGTH = 64;
int BLOCK_HASH_LENGTH = 32;
int MAX_ACCOUNTS = 64;
int BLOCK_QUEUE_SIZE = 151;
int BLOCKS_UNTIL_FINALIZED = 32;
Factory Methods
Basic Transaction Creation
static Transaction createTx(
PublicKey feePayer,
List<Instruction> instructions
)
Account that will pay transaction fees
instructions
List<Instruction>
required
List of instructions to execute
Legacy transaction ready to sign
static Transaction createTx(List<Instruction> instructions)
Transaction without explicit fee payer (uses first signer)
static Transaction createTx(
PublicKey feePayer,
Instruction instruction
)
With Address Lookup Tables
static Transaction createTx(
PublicKey feePayer,
List<Instruction> instructions,
AddressLookupTable lookupTable
)
instructions
List<Instruction>
required
Instructions to execute
lookupTable
AddressLookupTable
required
Address lookup table for versioned transaction (v0)
Versioned transaction with lookup table support
static Transaction createTx(
AccountMeta feePayer,
List<Instruction> instructions,
LookupTableAccountMeta[] tableAccountMetas
)
tableAccountMetas
LookupTableAccountMeta[]
required
Multiple lookup tables for complex transactions
Signing Methods
Sign with Single Signer
Signer to sign the transaction
void sign(byte[] recentBlockHash, Signer signer)
Recent block hash (32 bytes)
void sign(String recentBlockHash, Signer signer)
Base58-encoded recent block hash
Sign with Multiple Signers
void sign(SequencedCollection<Signer> signers)
signers
SequencedCollection<Signer>
required
Ordered collection of signers
void sign(
String recentBlockHash,
SequencedCollection<Signer> signers
)
Sign and Encode
String signAndBase64Encode(Signer signer)
Base64-encoded signed transaction ready for RPC submission
String signAndBase64Encode(
byte[] recentBlockHash,
Signer signer
)
String signAndBase64Encode(
String recentBlockHash,
SequencedCollection<Signer> signers
)
Static Signing Utilities
static void sign(
Signer signer,
byte[] out
)
Serialized transaction to sign in place
static String signAndBase64Encode(
Signer signer,
byte[] out
)
Transaction Manipulation
Block Hash Management
void setRecentBlockHash(byte[] recentBlockHash)
void setRecentBlockHash(String recentBlockHash)
Current block hash (32 bytes)
Instruction Modification
Transaction prependIx(Instruction ix)
New transaction with prepended instruction
Transaction appendIx(Instruction ix)
Transaction replaceInstruction(int index, Instruction instruction)
Index of instruction to replace
Transaction prependInstructions(
SequencedCollection<Instruction> instructions
)
Transaction appendInstructions(
SequencedCollection<Instruction> instructions
)
Transaction Properties
Base58-encoded transaction signature (transaction ID)
Transaction signature bytes (64 bytes)
Size of serialized transaction in bytes
boolean exceedsSizeLimit()
True if transaction exceeds 1232 byte limit
Transaction version (0 for versioned, -1 for legacy)
Number of required signers
List<Instruction> instructions()
List of instructions in the transaction
Fee payer account metadata
Serialization
Serialized transaction bytes
String base64EncodeToString()
Base64-encoded transaction for RPC submission
Example Usage
Simple Transfer
import software.sava.core.accounts.PublicKey;
import software.sava.core.accounts.Signer;
import software.sava.core.tx.Transaction;
import software.sava.core.tx.Instruction;
// Create signer
var signer = Signer.createFromKeyPair(keyPairBytes);
var fromPubKey = signer.publicKey();
var toPubKey = PublicKey.fromBase58Encoded(recipientAddress);
// Create transfer instruction
var transferIx = SystemProgram.transfer(
fromPubKey,
toPubKey,
1_000_000_000L // 1 SOL in lamports
);
// Create and sign transaction
var tx = Transaction.createTx(fromPubKey, transferIx);
String blockHash = getRecentBlockhash();
tx.sign(blockHash, signer);
// Get base64-encoded transaction
String encodedTx = tx.base64EncodeToString();
// Or sign and encode in one step
String encoded = tx.signAndBase64Encode(blockHash, signer);
Multiple Instructions
import java.util.List;
// Create multiple instructions
var computeBudgetIx = ComputeBudgetProgram.setComputeUnitLimit(200_000);
var transferIx1 = SystemProgram.transfer(from, to1, amount1);
var transferIx2 = SystemProgram.transfer(from, to2, amount2);
// Create transaction with multiple instructions
var instructions = List.of(
computeBudgetIx,
transferIx1,
transferIx2
);
var tx = Transaction.createTx(feePayer, instructions);
tx.sign(blockHash, signer);
Versioned Transaction with Lookup Table
// Load lookup table
var lookupTable = AddressLookupTable.read(
lookupTableAddress,
lookupTableData
);
// Create versioned transaction
var tx = Transaction.createTx(
feePayer,
instructions,
lookupTable
);
tx.sign(blockHash, signer);
// Transaction version will be 0
assert tx.version() == 0;
Multiple Signers
import java.util.List;
// Create signers
var signer1 = Signer.createFromKeyPair(keyPair1);
var signer2 = Signer.createFromKeyPair(keyPair2);
var signer3 = Signer.createFromKeyPair(keyPair3);
// Create transaction requiring multiple signatures
var tx = Transaction.createTx(feePayer, instructions);
// Sign with all required signers
var signers = List.of(signer1, signer2, signer3);
tx.sign(blockHash, signers);
// Or sign and encode
String encoded = tx.signAndBase64Encode(blockHash, signers);
Prepend Compute Budget
// Create transaction
var tx = Transaction.createTx(feePayer, instructions);
// Prepend compute budget instruction
var budgetIx = ComputeBudgetProgram.setComputeUnitLimit(300_000);
var newTx = tx.prependIx(budgetIx);
// Sign new transaction
newTx.sign(blockHash, signer);
Best Practices
- Always check
exceedsSizeLimit() before signing
- Use lookup tables for transactions with many accounts
- Set compute budget for complex programs
- Cache block hash for batch transaction creation
- Use versioned transactions (v0) for better efficiency