QUIC-to-QUIC Relay for Solana

Priority Lane Access
for Solana Transactions

Skip the congested 20% lane. Moon Land relays your transactions through staked validator connections, giving you access to Solana's 80% SWQoS priority capacity.

<1ms
Relay Overhead
80%
Priority Capacity
QUIC-Native
Protocol

You're Stuck in the
Slow Lane

Solana's leader nodes reserve 80% of transaction capacity for validators with stake-weighted connections. Without running your own validator, your transactions compete for the remaining 20% — alongside everyone else.

During high congestion, unstaked transactions face severe packet loss and dramatically lower landing rates. Your bot is fast, but the network bottleneck isn't your code — it's your connection.

80%
Staked / SWQoS Lane
Reserved for stake-weighted QUIC connections
20%
Unstaked Lane
Everyone else fights for scraps
Sub-Millisecond Overhead
Your transactions are forwarded with negligible added latency. The relay introduces less than 1ms of processing time.
Staked QUIC Connections
Transactions are forwarded through validator connections with real stake weight, granting access to the 80% priority lane.
No Validator Required
Skip the hassle of running and maintaining your own validator node. Get SWQoS access through Moon Land's infrastructure.

Your Shortcut to the
Priority Lane

Moon Land acts as a QUIC-to-QUIC relay that sits between your application and Solana's leader nodes. You connect to us via QUIC, and we forward your transactions through our staked validator connections.

The result: your transactions enter the 80% SWQoS lane without you needing to run a single validator. It's the fastest path from your bot to the block.

Three Steps to
Priority Access

Integration is straightforward. Connect, authenticate, and send — your transactions land in the priority lane.

1

Connect via QUIC

Establish a native QUIC connection to Moon Land's relay endpoint. No HTTP wrappers, no WebSockets — pure QUIC.

Request access via Telegram
2

Authenticate Once

Open a bidi stream, send your API key, get an OK response. One-time handshake per connection — no per-tx overhead.

bidi → send key → 0x00 OK
3

Send Transactions

Fire your serialized transactions with a small tip (≥ 0.001 SOL). Moon Land forwards them to the current leader via staked QUIC — into the 80% lane.

Tip-based · No subscription

Built for Speed
and Reliability

Every component is engineered for low-latency, high-throughput transaction forwarding.

QUIC-Native Protocol
End-to-end QUIC from your app to the leader TPU. No protocol translation overhead or serialization layers.
Sub-ms Latency
Transaction forwarding adds less than 1 millisecond of overhead. Your speed edge stays intact.
Staked Forwarding
Transactions routed through validator connections with real stake weight for SWQoS priority access.
Configurable Rate Limiting
Per-key rate limits with burst support. Control your throughput and manage multiple trading strategies.
Auto-Reconnect
Automatic connection recovery with exponential backoff. Your relay connection stays alive through network hiccups.
Pre-Warmed Connections
Leader connections are established ahead of time via the leader schedule. Zero cold-start latency on slot transitions.

Simple, Fast,
Direct Path

Your transactions take the shortest route from your application to the leader's TPU port — through a single trusted relay hop.

YOUR APP
Your Bot / App
QUIC client
QUIC stream
RELAY
Moon Land
auth + forward
staked QUIC
LEADER
Leader TPU
80% SWQoS lane
Pre-warmed connections Leader schedule tracking Automatic failover

QUIC Transaction
Submission

Connect once, authenticate via bidirectional handshake, then send raw transaction bytes on unidirectional streams. Fire-and-forget.

Cargo.toml

[dependencies]
quinn = "0.11"
rustls = { version = "0.23", default-features = false, features = ["ring", "std"] }
tokio = { version = "1", features = ["full"] }
arc-swap = "1"
anyhow = "1"
bincode = "1"

moonland_client.rs — copy into your project

use anyhow::{Context as _, Result};
use arc_swap::ArcSwap;
use quinn::{
    crypto::rustls::QuicClientConfig, ClientConfig, Connection, Endpoint,
    IdleTimeout, TransportConfig,
};
use std::net::SocketAddr;
use std::sync::Arc;
use std::time::Duration;
use tokio::sync::Mutex;

const ALPN: &[u8] = b"moonland/1";
const SERVER_NAME: &str = "moonland";
const KEEP_ALIVE: Duration = Duration::from_secs(5);
const MAX_IDLE: Duration = Duration::from_secs(30);
const AUTH_OK: u8 = 0x00;

pub struct MoonLandClient {
    endpoint: Endpoint,
    client_config: ClientConfig,
    addr: SocketAddr,
    api_key_hex: String,
    connection: ArcSwap<Connection>,
    reconnect: Mutex<()>,
}

impl MoonLandClient {
    /// Connect and authenticate. Contact @MoonLandSol on Telegram for endpoint and API key.
    pub async fn connect(server_addr: &str, api_key_hex: &str) -> Result<Self> {
        let addr: SocketAddr = server_addr.parse()?;

        let mut crypto = rustls::ClientConfig::builder()
            .dangerous()
            .with_custom_certificate_verifier(Arc::new(SkipServerVerification))
            .with_no_client_auth();
        crypto.alpn_protocols = vec![ALPN.to_vec()];

        let client_crypto = QuicClientConfig::try_from(crypto)?;
        let mut client_config = ClientConfig::new(Arc::new(client_crypto));
        let mut transport = TransportConfig::default();
        transport.keep_alive_interval(Some(KEEP_ALIVE));
        transport.max_idle_timeout(Some(IdleTimeout::try_from(MAX_IDLE)?));
        client_config.transport_config(Arc::new(transport));

        let mut endpoint = Endpoint::client("0.0.0.0:0".parse()?)?;
        endpoint.set_default_client_config(client_config.clone());
        let connection = endpoint.connect(addr, SERVER_NAME)?.await?;

        // Auth handshake: bidi stream → send API key → read 1-byte response
        Self::do_auth(&connection, api_key_hex).await?;

        Ok(Self {
            endpoint, client_config, addr,
            api_key_hex: api_key_hex.to_string(),
            connection: ArcSwap::from_pointee(connection),
            reconnect: Mutex::new(()),
        })
    }

    /// Send raw serialized transaction bytes. Auto-reconnects on failure.
    pub async fn send_transaction(&self, tx_bytes: &[u8]) -> Result<()> {
        let connection = self.connection.load_full();
        if Self::try_send(&connection, tx_bytes).await.is_ok() {
            return Ok(());
        }
        self.reconnect().await?;
        let connection = self.connection.load_full();
        Self::try_send(&connection, tx_bytes).await
    }

    async fn do_auth(connection: &Connection, api_key_hex: &str) -> Result<()> {
        let (mut send, mut recv) = connection.open_bi().await
            .context("failed to open auth stream")?;
        send.write_all(api_key_hex.as_bytes()).await
            .context("failed to send API key")?;
        send.finish().context("failed to finish auth stream")?;

        let mut response = [0u8; 1];
        recv.read_exact(&mut response).await
            .context("failed to read auth response")?;
        if response[0] != AUTH_OK {
            anyhow::bail!("authentication rejected (code: {})", response[0]);
        }
        Ok(())
    }

    async fn try_send(conn: &Connection, tx_bytes: &[u8]) -> Result<()> {
        let mut stream = conn.open_uni().await?;
        stream.write_all(tx_bytes).await?;
        stream.finish()?;
        Ok(())
    }

    async fn reconnect(&self) -> Result<()> {
        let _guard = self.reconnect.lock().await;
        let current = self.connection.load_full();
        if current.close_reason().is_none() { return Ok(()); }
        let connection = self.endpoint
            .connect_with(self.client_config.clone(), self.addr, SERVER_NAME)?
            .await?;
        // Re-authenticate on new connection
        Self::do_auth(&connection, &self.api_key_hex).await?;
        self.connection.store(Arc::new(connection));
        Ok(())
    }
}

// TLS: skip server cert verification (self-signed relay)
#[derive(Debug)]
struct SkipServerVerification;
impl rustls::client::danger::ServerCertVerifier for SkipServerVerification {
    fn verify_server_cert(&self, _: &rustls::pki_types::CertificateDer,
        _: &[rustls::pki_types::CertificateDer], _: &rustls::pki_types::ServerName,
        _: &[u8], _: rustls::pki_types::UnixTime,
    ) -> Result<rustls::client::danger::ServerCertVerified, rustls::Error> {
        Ok(rustls::client::danger::ServerCertVerified::assertion())
    }
    fn verify_tls12_signature(&self, _: &[u8],
        _: &rustls::pki_types::CertificateDer, _: &rustls::DigitallySignedStruct,
    ) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
        Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
    }
    fn verify_tls13_signature(&self, _: &[u8],
        _: &rustls::pki_types::CertificateDer, _: &rustls::DigitallySignedStruct,
    ) -> Result<rustls::client::danger::HandshakeSignatureValid, rustls::Error> {
        Ok(rustls::client::danger::HandshakeSignatureValid::assertion())
    }
    fn supported_verify_schemes(&self) -> Vec<rustls::SignatureScheme> {
        rustls::crypto::ring::default_provider()
            .signature_verification_algorithms.supported_schemes()
    }
}

Note on TLS: The relay uses a self-signed certificate. SkipServerVerification is safe here — your transactions are already signed with your private key and cannot be modified in transit. Authentication is via API key over the encrypted QUIC connection.

Usage

// At startup — connect once, auth is automatic
let client = MoonLandClient::connect(
    "<endpoint>",     // Regional endpoint — provided by Moon Land team
    "<api-key>",      // 32 hex chars — provided by Moon Land team
).await?;

// Per transaction — fire and forget
let tx_bytes = bincode::serialize(&my_signed_transaction)?;
client.send_transaction(&tx_bytes).await?;

// Each transaction must include a tip: System Program transfer
// of >= 0.001 SOL to a Moon Land tip address.
// Tip addresses provided with your API key.

Protocol Details

ALPN: moonland/1 Auth: bidi handshake (one-time per connection) Transactions: raw bytes on uni streams Tip: ≥ 0.001 SOL Max tx size: 1232 bytes Idle timeout: 30s Keep-alive: 5s
Error Code Name When It Happens
0 OK Normal closure
1 UNKNOWN_API_KEY API key not recognized — check your key is valid and active
2 AUTH_TIMEOUT Auth handshake not completed within 2 seconds
3 PROTOCOL_VIOLATION Extra bidirectional stream opened after auth

Rate limiting: When exceeded, the server silently drops excess transactions. The connection stays alive. Monitor your landing rate to detect rate limiting.

Tip Addresses — each transaction must include a SOL transfer of ≥ 0.001 SOL to one of these addresses. Click to copy:

moon54DmZ775AepMCPLg1wxGqDNbG3G6CQu3rALggRFclick to copy
moonwDUA7UjNWiYQFUkymrV21JUw4yEG3rQsTi8kxLqclick to copy
moonhMCQ4DrQDMwmqZFD34m4t9MsTkeCWqEfx6mZEXnclick to copy
moonAb4fx2gtqTymPNwSWHmGtTYHJRMz8UJZgWcnMktclick to copy

Randomly pick one per transaction (same pattern as Jito tip addresses).

Ready to Skip
the Line?

Get in touch to set up your Moon Land relay access. API keys are provisioned within minutes.

Telegram: @MoonLandSol