Skip to main content

Crate triton_preconfs_client

Crate triton_preconfs_client 

Source
Expand description

Client for the Triton Preconfs streams.

Preconfs are preconfirmed Solana transactions: the Harmonic and BAM feeds deliver them while the slot is still being built, before the transaction lands on chain. This crate connects to a Triton Preconfs server, builds validated filters and turns each stream into typed Events, resubscribing when a connection drops.

use solana_pubkey::Pubkey;
use triton_preconfs_client::{Connector, Event, Feed, Filter, Filters, Region, parse};

let client = Connector::new("https://preconfs.rpcpool.com")
    .x_token(Some("my-token"))
    .connect()
    .await?;

let token_program: Pubkey = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA".parse()?;
let region = Region::parse(Feed::Harmonic, "ams")?;
let filters = Filters::single(Filter::new().accounts([token_program]));

let mut stream = client.subscribe_harmonic(region, filters).await?;
while let Some(event) = stream.next().await {
    match event? {
        Event::Transaction(matched) => {
            let signature = parse::parse_signature(&matched.transaction.transaction)?;
            println!("slot {} {signature}", matched.transaction.slot);
        }
        Event::SlotEnd { slot } => println!("slot {slot} complete"),
        Event::Reconnected { attempts } => println!("reconnected after {attempts} attempts"),
        _ => {}
    }
}

§Streams

A stream serves one feed in one region and yields Events. On the Harmonic feed every transaction sits between its slot’s SlotStart and SlotEnd; after SlotEnd the program holds everything its filters matched for that slot. BAM has no framing, each transaction names its slot. Pings are consumed by the stream. Transactions withheld because an account is over its coverage share are announced with Event::Clip, never silent.

§Reconnect

Points of presence restart on every deploy, so a long lived stream will drop. By default the stream resubscribes with a backoff and yields Event::Reconnected so the program knows it missed the data produced in between (preconfs from the gap cannot be replayed). Errors that retrying cannot fix end the stream: a bad token, a refused filter, a region the server does not serve. Tune it with Connector::reconnect or turn it off with Connector::no_reconnect.

§Errors

One error type per step: ConnectError from connecting, SubscribeError from opening a stream, StreamError from a stream that ended. Wrap them with anyhow or Box<dyn Error> for one top level type.

Re-exports§

pub use connect::Client;
pub use connect::Connector;
pub use error::ConnectError;
pub use error::StreamError;
pub use error::SubscribeError;
pub use feed::Feed;
pub use feed::Region;
pub use feed::RegionError;
pub use filter::Filter;
pub use filter::FilterError;
pub use filter::Filters;
pub use filter::InstructionFilter;
pub use filter::Memcmp;
pub use reconnect::Reconnect;
pub use stream::BamEvent;
pub use stream::BamStream;
pub use stream::Event;
pub use stream::HarmonicEvent;
pub use stream::HarmonicStream;
pub use stream::Matched;
pub use triton_preconfs_proto as proto;

Modules§

connect
Connecting to a Triton Preconfs server: TLS for https endpoints, the x-token on every request, keepalive tuned for a stream that can be quiet between leader windows, an optional dial override to reach one point of presence behind the anycast address, and the reconnect policy the streams follow.
error
Error types, one per domain: building the connection, opening a stream, and a stream failing. A program that wants one top level error wraps them with anyhow or Box<dyn Error>.
feed
Feeds and regions. A stream serves exactly one feed in one region; the region names are the ones the server reports and the endpoint list uses.
filter
Subscribe filters, validated against the server’s limits before the request leaves the client, so a mistake fails here with a clear error instead of an INVALID_ARGUMENT from the other side.
parse
Transaction-byte parsing: the first signature and the static account keys the filters and the monitors need, from the raw bytes of a legacy, v0 or v1 (SIMD-0385) transaction. The bytes must be one whole transaction, as on the wire.
reconnect
Resubscribing after a stream drops.
stream
Typed event streams over the raw gRPC streams, with reconnect.