Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Connecting to a lattice

audience: integrators

You connect to a lattice the same way you connect to any mosaik service: build a Network against builder::UNIVERSE, bring your own discovery + transport config, and open organism handles against your compiled-in LatticeConfig.

This page is the reference for the connection side. The application side lives in Quickstart — submit, bid, read.

Default shape

use std::sync::Arc;
use mosaik::Network;
use builder::UNIVERSE;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let network = Arc::new(Network::new(UNIVERSE).await?);

    // ... open organism handles ...
    Ok(())
}

Network::new(UNIVERSE) applies the mosaik defaults: pkarr / Mainline DHT bootstrap, /mosaik/announce gossip, iroh QUIC transport, mDNS off, no explicit bootstrap peers. It works for most production agents on the open internet.

Bring-your-own-config

When you need specific discovery, transport, or metrics configuration, use the Network::builder:

use std::{net::SocketAddr, sync::Arc};
use mosaik::{Network, discovery};
use builder::UNIVERSE;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let network = Arc::new(
        Network::builder(UNIVERSE)
            // Bootstrap off a known peer for cold starts (optional).
            .with_discovery(
                discovery::Config::builder()
                    .with_bootstrap(vec![ /* known peer ids */ ])
            )
            // Expose prometheus metrics for your agent.
            .with_prometheus_addr("127.0.0.1:9100".parse::<SocketAddr>()?)
            // Turn mDNS on for local development.
            .with_mdns_discovery(cfg!(debug_assertions))
            .build()
            .await?,
    );

    // ... open organism handles ...
    Ok(())
}

Bootstrap peers are universe-level. Any reachable peer on builder::UNIVERSE — not specific to any lattice — is a valid bootstrap. Once bonded, the organism’s own discovery locates the specific committee peers via the shared catalog.

Identity

Your agent’s PeerId is derived from a secret key you control. The default — Network::new — generates an ephemeral key per process. That is fine for short-lived agents; long-running ones (trading bots, indexers) should pin a stable key so your peer catalog entries survive restarts:

use mosaik::SecretKey;

let secret  = SecretKey::from_hex(env::var("BUILDER_AGENT_SECRET")?)?;
let network = Arc::new(
    Network::builder(UNIVERSE)
        .with_secret_key(secret)
        .build()
        .await?,
);

See the mosaik getting-started for key rotation and secret-management guidance.

Ticketed admission

Some organisms in some lattices gate their read-side on a ticket. atelier is the common case on the read side (integrators reading block bodies); offer gates its write side on a searcher ticket. When the lattice operator issues you a ticket, install it on the network:

use mosaik::TicketValidator;

let network = Arc::new(
    Network::builder(UNIVERSE)
        .with_ticket(operator_issued_searcher_ticket)
        .build()
        .await?,
);

Ticket formats are per-organism and per-lattice; follow the operator’s handoff. Missing tickets surface as Attestation errors on the relevant organism’s verb() call, not as ConnectTimeout.

Local development

A lattice’s integration test harness is the deterministic path for iteration. If a lattice publishes a --test workspace (equivalent to zipnet’s e2e), prefer running that harness for integration tests rather than hitting a live lattice. Live lattices have the usual P2P cold-start latencies.

For agent-level development against a live lattice, expect:

  • First bond to any committee member: up to a minute on a cold agent over fresh iroh relays.
  • Subsequent verb() calls: sub-second once bonded.
  • ConnectTimeout after roughly 60 seconds if no committee member is reachable.

Troubleshooting

SymptomLikely causeCheck
ConnectTimeoutMismatched LatticeConfig or the organism is not runningCompare lattice_id() hex; ask the operator if the organism is up
WrongUniverseYou built Network against a non-builder universenetwork.network_id() == builder::UNIVERSE
AttestationMissing or stale ticketVerify with the operator; rotate if expired
Protocol("deferred")You called an organism verb that is not implemented in this versionCheck the organism’s own Roadmap

Next reading