sof-tx
sof-tx is the transaction SDK for SOF.
It provides:
- ergonomic transaction/message building
- signed and pre-signed submission APIs
- runtime mode selection:
RpcOnlyDirectOnly(leader-targeted UDP send)Hybrid(direct first, RPC fallback)
- routing policy and signature-level dedupe
At a Glance
- Build
V0or legacy Solana transactions - Submit through RPC, direct leader routing, or hybrid fallback
- Attach live
sofruntime adapters when you want local leader/blockhash signals - Use replayable derived-state adapters when your service must survive restart or replay
- Evaluate typed flow-safety policies before acting on local control-plane state
- Use optional kernel-bypass direct transports for custom low-latency networking
Install
Enable SOF runtime adapters when you want provider values from live sof plugin events:
= { = "0.7.0", = ["sof-adapters"] }
Enable kernel-bypass transport hooks for kernel-bypass direct submit integrations:
= { = "0.7.0", = ["kernel-bypass"] }
Quick Start
Basic client setup:
use Arc;
use ;
use Keypair;
use Signer;
use instruction as system_instruction;
async
Core Types
TxBuilder: compose transaction instructions and signing inputs.TxSubmitClient: submit through RPC/direct/hybrid.SubmitMode: runtime mode switch.SignedTx: submit externally signed transaction bytes.RoutingPolicy: leader/backup fanout controls.LeaderProviderandRecentBlockhashProvider: provider boundaries.TxMessageVersion: selectV0(default) orLegacymessage output.MAX_TRANSACTION_WIRE_BYTES: current max over-the-wire transaction bytes.MAX_TRANSACTION_ACCOUNT_LOCKS: current max account locks per transaction.
Message Version and Limits
TxBuilder emits V0 messages by default without requiring address lookup tables.
Legacy output remains available through with_legacy_message().
Current protocol-aligned limits exposed by sof-tx:
MAX_TRANSACTION_WIRE_BYTES = 1232MAX_TRANSACTION_ACCOUNT_LOCKS = 128
SOF Adapter Layer
With sof-adapters enabled, PluginHostTxProviderAdapter can be:
- registered as a SOF plugin to ingest blockhash/leader/topology events, and
- passed directly into
TxSubmitClientas both providers. - evaluated with
evaluate_flow_safety(...)before using its control-plane state for direct send decisions.
use Arc;
use ;
use ;
use Keypair;
use Signer;
async
For restart-safe services built on SOF derived-state, use DerivedStateTxProviderAdapter instead.
It consumes the replayable derived-state feed, supports checkpoint persistence, and exposes the
same evaluate_flow_safety(...) helper for control-plane freshness checks.
The observer-side feed now also emits canonical control-plane quality snapshots, so services can
source freshness and confidence metadata from sof first and keep sof-tx focused on send-time
guard decisions.
For services that do not want to maintain a parallel checkpoint file format, use the adapter
persistence helper backed by SOF's generic DerivedStateCheckpointStore.
Direct submit needs TPU endpoints for scheduled leaders. The adapter gets these from
on_cluster_topology events, or you can inject them manually with:
set_leader_tpu_addr(pubkey, tpu_addr)remove_leader_tpu_addr(pubkey)
The flow-safety report is intended to keep stale or degraded control-plane state from silently driving direct or hybrid sends. Typical checks include:
- missing recent blockhash
- stale tip slot
- missing leader schedule
- missing TPU addresses for targeted leaders
- degraded topology freshness
Expanded Quickstart
use Arc;
use ;
use Keypair;
use Signer;
use instruction as system_instruction;
async
Simplifying OpenBook + CPMM Flows
The recommended pattern is to keep strategy-specific instruction creation separate, and route both through one shared SDK pipeline.
use ;
use Instruction;
use Keypair;
use Signer;
async
This gives one consistent path for signing, dedupe, routing, and fallback behavior.
Submitting Pre-Signed Transactions
If your signer is external (wallet/HSM/offline), submit bytes directly:
use ;
async
Developer Tip
TxBuilder::tip_developer() adds a developer-support transfer instruction using a default tip of 5000 lamports.
- default amount:
5000lamports (DEFAULT_DEVELOPER_TIP_LAMPORTS) - default recipient:
G3WHMVjx7Cb3MFhBAHe52zw8yhbHodWnas5gYLceaqze - custom amount:
tip_developer_lamports(...) - custom recipient + amount:
tip_to(...)
Thanks in advance for supporting continued SDK development.
Mode Guidance
RpcOnly: maximum compatibility.DirectOnly: lowest path latency when leader targets are reliable.Hybrid: practical default for latency + fallback resilience.
Reliability Profiles
Direct and hybrid modes include built-in reliability defaults through SubmitReliability.
LowLatency: minimal retries for fastest failover (direct_target_rounds=1,hybrid_direct_attempts=1)Balanced(default): extra direct retries before fallback (direct_target_rounds=2,hybrid_direct_attempts=2)HighReliability: most direct retrying (direct_target_rounds=3,hybrid_direct_attempts=3)
Use TxSubmitClient::with_reliability(...) for presets, or with_direct_config(...) for full control.
Reliability profiles are transport-side only. If you are sourcing blockhash, leader, and topology
state from SOF, pair them with evaluate_flow_safety(...) or TxSubmitGuardPolicy before sending.
KernelBypass Direct Transport
With kernel-bypass enabled, implement KernelBypassDatagramSocket for your socket type and wrap it with
KernelBypassDirectTransport.
use ;
use async_trait;
use ;
;
AF_XDP Demo and E2E
Linux-only AF_XDP demo (runs in an isolated user+network namespace via unshare -Urn):
Ignored integration test for AF_XDP kernel-bypass direct submit:
Requirements:
unsharefrom util-linuxipfrom iproute2- Linux kernel with AF_XDP support
Feature Model
Current implementation supports RPC/direct/hybrid runtime modes through one API. Compile-time capability flags from ADR-0006 can be introduced incrementally as the SDK stabilizes.
Docs
- ADR for SDK scope:
../../docs/architecture/adr/0006-transaction-sdk-and-dual-submit-routing.md - Workspace docs index:
../../docs/README.md - Architecture docs:
../../docs/architecture/README.md - Contribution guide:
../../CONTRIBUTING.md