solana-tx-building
Solana transaction construction including instruction building, account resolution, compute budget, priority fees, and versioned transactions
What this skill does
# Solana Transaction Building
This skill covers how to construct, simulate, and inspect Solana transactions programmatically. It addresses the full anatomy of a Solana transaction — from raw instruction encoding to versioned transaction formats, compute budget management, priority fees, and address lookup tables.
**Safety**: This skill is for transaction *construction* and *analysis* only. Scripts in this skill NEVER sign or submit real transactions. Always simulate before sending. Never auto-sign.
## Transaction Anatomy
A Solana transaction consists of:
1. **Signatures**: One or more Ed25519 signatures (64 bytes each)
2. **Message**: The serializable payload containing:
- **Header**: Counts of required signers, read-only signers, read-only non-signers
- **Account keys**: Array of all pubkeys referenced by instructions
- **Recent blockhash**: 32-byte hash for replay protection (expires ~60-90 seconds)
- **Instructions**: Array of program calls
### Transaction Size Limit
The hard limit is **1232 bytes** for the entire serialized transaction. This constrains how many instructions and accounts you can include. Strategies to stay within the limit:
- Use versioned transactions with Address Lookup Tables (ALTs)
- Minimize the number of accounts per instruction
- Combine related operations into single instructions where supported
- Split complex operations across multiple transactions
### Instruction Format
Each instruction contains three fields:
```
Instruction {
program_id_index: u8, // Index into the account keys array
accounts: [u8], // Indices into account keys array
data: [u8], // Opaque byte array interpreted by the program
}
```
### Account Meta
Every account referenced in an instruction has metadata:
```
AccountMeta {
pubkey: Pubkey, // 32-byte public key
is_signer: bool, // Must sign the transaction
is_writable: bool, // Will be written to by this instruction
}
```
The four combinations determine the account's role:
| is_signer | is_writable | Role |
|-----------|-------------|------|
| true | true | Fee payer, token owner performing transfer |
| true | false | Multisig co-signer, read-only authority |
| false | true | Destination account, PDA being written |
| false | false | Program ID, sysvar, clock |
## Legacy vs Versioned Transactions
### Legacy Transactions
The original format. All accounts must be listed in the account keys array. With the 1232-byte limit, you can fit roughly 20-35 accounts depending on instruction data size.
### Versioned Transactions (v0)
Introduced to support **Address Lookup Tables (ALTs)**. A v0 transaction includes:
- A version prefix byte (`0x80` for v0)
- The same message structure as legacy
- An additional `address_table_lookups` array
ALTs let you reference accounts by a compact index into an on-chain table rather than including the full 32-byte pubkey. This dramatically increases the number of accounts a transaction can reference.
```
AddressTableLookup {
account_key: Pubkey, // The ALT account address
writable_indexes: [u8], // Indices for writable accounts
readonly_indexes: [u8], // Indices for read-only accounts
}
```
**When to use v0**: Any transaction referencing more than ~20 accounts, Jupiter swaps with multi-hop routes, complex DeFi interactions.
## Compute Budget
Every transaction has a compute budget that determines how many compute units (CUs) it can consume and what priority fee to pay.
### Compute Budget Instructions
Two key instructions from the Compute Budget Program (`ComputeBudget111111111111111111111111111111`):
**1. Set Compute Unit Limit**
```
Instruction data: [0x02, <units as u32 LE>]
```
Sets the maximum CUs this transaction can consume. Default is 200,000 per instruction (max 1,400,000 per transaction). Setting this lower than needed causes the transaction to fail. Setting it higher wastes budget but does not cost more (you only pay for requested, not consumed).
**2. Set Compute Unit Price**
```
Instruction data: [0x03, <micro_lamports as u64 LE>]
```
Sets the price per CU in micro-lamports. This is the priority fee mechanism. The total priority fee is:
```
priority_fee = compute_unit_limit * compute_unit_price / 1_000_000
```
### Priority Fee Estimation
To estimate an appropriate priority fee:
1. Call `getRecentPrioritizationFees` RPC method with the accounts your transaction touches
2. Look at the median or 75th percentile fee from recent slots
3. During congestion, fees spike — monitor and adjust dynamically
```python
import httpx
def get_priority_fees(rpc_url: str, accounts: list[str]) -> list[dict]:
"""Fetch recent prioritization fees for given accounts."""
resp = httpx.post(rpc_url, json={
"jsonrpc": "2.0",
"id": 1,
"method": "getRecentPrioritizationFees",
"params": [accounts]
})
return resp.json()["result"]
```
## Common Transaction Patterns
### 1. SOL Transfer
The simplest transaction: a System Program transfer.
```python
# System Program transfer instruction data layout:
# [2, 0, 0, 0] (u32 LE = instruction index 2 = Transfer)
# + amount as u64 LE (lamports)
import struct
def build_sol_transfer_data(lamports: int) -> bytes:
"""Build instruction data for a SOL transfer."""
return struct.pack("<I", 2) + struct.pack("<Q", lamports)
```
Accounts required:
1. Sender (signer, writable)
2. Recipient (writable)
### 2. SPL Token Transfer
Transferring SPL tokens requires the Token Program.
```python
# Token Program transfer instruction:
# [3] (instruction index 3 = Transfer)
# + amount as u64 LE
def build_token_transfer_data(amount: int) -> bytes:
"""Build instruction data for an SPL token transfer."""
return bytes([3]) + struct.pack("<Q", amount)
```
Accounts required:
1. Source token account (writable)
2. Destination token account (writable)
3. Owner/delegate (signer)
### 3. Create Associated Token Account (ATA)
Before transferring tokens, the recipient must have an Associated Token Account.
```python
# ATA Program: instruction index 0 = Create
# No instruction data needed (empty bytes)
ATA_PROGRAM_ID = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"
```
Accounts required (in order):
1. Payer (signer, writable) — pays rent
2. Associated token account (writable) — the ATA to create
3. Wallet address — owner of the new ATA
4. Token mint
5. System Program
6. Token Program
### 4. Jupiter Swap
Jupiter provides a `/swap-instructions` endpoint that returns pre-built instructions. See the `jupiter-api` skill for full details.
General flow:
1. Get a quote from `/quote`
2. Get swap instructions from `/swap-instructions`
3. Build transaction with setup instructions + swap instruction + cleanup instructions
4. Add compute budget instructions
5. Simulate, then sign and send
## Simulation
Always simulate before sending. Use the `simulateTransaction` RPC method:
```python
def simulate_transaction(rpc_url: str, tx_base64: str) -> dict:
"""Simulate a transaction without submitting it.
Args:
rpc_url: Solana RPC endpoint URL.
tx_base64: Base64-encoded serialized transaction.
Returns:
Simulation result with logs and compute units consumed.
"""
resp = httpx.post(rpc_url, json={
"jsonrpc": "2.0",
"id": 1,
"method": "simulateTransaction",
"params": [
tx_base64,
{"encoding": "base64", "replaceRecentBlockhash": True}
]
})
result = resp.json()["result"]
if result["value"]["err"]:
print(f"Simulation failed: {result['value']['err']}")
for log in result["value"].get("logs", []):
print(f" {log}")
else:
cu = result["value"].get("unitsConsumed", 0)
print(f"Simulation OK — {cu} compute units consumed")
return result
```
The `replaceRecentBlockhash: True` flag lets you simulate even if your blockhRelated in Web3
xaut-trade
IncludedBuy or sell XAUT (Tether Gold) on Ethereum. Supports market orders (Uniswap V3) and limit orders (UniswapX). Wallet modes: Foundry keystore or WDK. Delegates non-XAUT intents to registered skills (e.g. Polymarket prediction markets, Hyperliquid trading). Triggers: buy XAUT, XAUT trade, swap USDT for XAUT, sell XAUT, swap XAUT for USDT, limit order, limit buy XAUT, limit sell XAUT, check limit order, cancel limit order, XAUT when, create wallet, setup wallet, polymarket, prediction market, bet on, odds on, hyperliquid, perp, perpetual, long, short, open long, open short, close position, leverage.
qfc-openclaw-skill
IncludedQFC blockchain interaction — wallet, faucet, chain queries, staking, epoch & finality, AI inference
gate-dex-trade
IncludedExecutes on-chain token swaps via Gate DEX. Use when user wants to swap, buy, sell, exchange, or convert tokens, or bridge cross-chain. Covers full swap flow: price quotes, transaction build, signing, and submission. Do NOT use for read-only data lookups or wallet account management.
hunch
IncludedDiscover, bet on, track, and settle Hunch prediction markets in natural language. Trigger when a user wants to bet, take a position, or get odds on a crypto outcome — token market-cap milestones and flips, launchpad races (Bankr vs pump.fun volume / #1-days / launches over a cap), token head-to-head outperformance, mcap strike-ladders, and up/down price rounds. Also trigger on "what can I bet on about $TOKEN", "odds on …", "take YES/NO on …", "show my Hunch bets", "did my market resolve". Settles in USDC on Base via x402 (≤ $10 / bet); every bet returns an on-chain proof.
opensea
IncludedQuery NFT data, trade on the Seaport marketplace, and swap ERC20 tokens across Ethereum, Base, Arbitrum, Optimism, Polygon, and more.
polymarket
IncludedTrade on Polymarket prediction markets (CLOB V2) from a Privy EOA wallet. Search markets, place/cancel orders, manage positions. No private key handling. Use when the user wants to bet on event outcomes (e.g. "buy YES at 0.65 on the ceasefire market", "what are my open positions", "close my Trump bet").