orbitflare-apex is the reference client for Apex. It keeps one persistent QUIC connection per Apex endpoint, authenticates with a client certificate derived from your API key, sends one serialized transaction per stream, and reconnects with 0-RTT when the connection drops.
Install
The crate is published on crates.io asorbitflare-apex; the source is on GitHub:
rpc feature adds the HTTP helpers: getTipAccounts, JSON-RPC sendTransaction, the binary routes, and a blockhash and confirmation helper for any Solana RPC. The QUIC path alone has no HTTP dependency, so leave the feature off if you only need QUIC.
That is the only dependency you need to build and send a transaction. The crate re-exports the Solana types through orbitflare_apex::prelude, pinned to the versions the endpoint sends with, so you do not add or version-match any solana-* crate yourself.
The crate requires Rust 1.92 or newer.
Quick Start
Cargo.toml, see the Rust tab of the Quickstart.
Regions
Region names every Apex endpoint. Region::parse("fra") and Region::code() map to and from the short codes, and Region::ALL lists them.
region.quic_endpoint() returns <code>.apex.orbitflare.com:7001 and region.rpc_url() returns http://<code>.apex.orbitflare.com. See Endpoints and regions.
Transports
The transport does not change priority or routing. The tip does.
API
The client is cheap to
Clone, and clones share one connection. Create it once and hand clones to your tasks.
Send bundles with
rpc::RpcClient::send_bundle(&[&[u8]]), which returns a BundleAccepted (bundle_id and signatures). Poll bundle_statuses(&[&str]) for BundleStatus (state, landed_slot). Up to MAX_BUNDLE (4) members, exactly one tipped.Prelude
use orbitflare_apex::prelude::*; brings in everything needed to build, sign, and send a tipped transaction, so a program that uses the client does not depend on any solana-* crate directly. Each type is re-exported at the version the endpoint sends with, which removes the version-matching that otherwise breaks the build (the Solana crates mix wincode 0.5 and 0.6 across point releases).
The public-API types (
VersionedTransaction, Instruction, Keypair, Pubkey, Signature, Hash) are also available at the crate root. If you would rather build transactions with your own Solana crates, serialize them yourself and send the bytes with send_transaction_bytes, which shares none of the client’s dependency graph.
Options
ClientOptions implements Default, so set only what you need:
Keep-Alive and Reconnects
The connection stays open with a QUIC PING every second, against an idle timeout of 30 seconds on the Apex endpoint. On a warm connection a send is one stream open and one write. If the connection drops:- A background task notices and re-handshakes right away (
proactive_reconnect), so the next send usually finds a live connection. - A reconnect uses a cached session ticket and sends the waiting transaction in the handshake’s first flight (0-RTT). If the endpoint declines the early data, the client resends it after the handshake.
- A send that fails because the connection is gone reconnects and retries once (
auto_reconnect). Set it tofalseto handle that yourself. - Each reconnect looks the host name up again, so a client on
Region::Globalfollows the load balancer to the next nearest endpoint when its own one goes down, without a restart. The lookup happens in that background reconnect, not on a send, and if it fails or takes more than two seconds the client keeps the address it had. An IP address endpoint is never looked up.
health(), reconnects_total(), and zero_rtt_resumptions_total() show what happened. Export them to your metrics.
Errors
The HTTP helpers return
rpc::RpcError: Http for transport failures, Rpc { code, message } for a JSON-RPC or plain HTTP rejection, and BadResponse.
Examples in the Repository
All examples readAPEX_API_KEY, KEYPAIR_PATH (default payer.json), SOLANA_RPC_URL, and optionally APEX_REGION, APEX_QUIC, APEX_RPC, TIP_LAMPORTS, APEX_TX_VERSION (legacy or v1), APEX_MEMO_BYTES, and APEX_CU_LIMIT. Each sends a tipped memo and reports the slot it landed in.
What the Client Does Not Do
- Build or sign transactions, or choose your priority fee.
- Simulate or run preflight checks. Nothing between you and the leader does.