Skip to main content

Crate xenith_core

Crate xenith_core 

Source
Expand description

§xenith

Cross-chain state sync for Rust — transport-agnostic, divergence-explicit, bot-first.

§The Problem

Multi-chain protocols share state across EVM networks using ad-hoc messaging (LayerZero, CCIP, Axelar), but there is no standardized primitive that sits above those transports. Every team ends up rewriting the same glue: serializing state updates into message payloads, tracking in-flight message IDs, comparing observed values across chains, and deciding what to do when two chains disagree. The absence of a shared abstraction means teams are locked into a single messaging protocol from day one, and divergence bugs — where different chains hold silently inconsistent state — are caught only when a liquidation misfires or an arbitrage reverts.

§What xenith is

xenith is a transport-agnostic, Rust-native library that treats cross-chain state sync as a first-class primitive. You plug in any messaging transport (LayerZero, CCIP, or your own), and xenith handles local persistence, message dispatch, and read-back under a ReadStrategy you choose. Diverged state is never silently resolved — SyncStatus::Diverged surfaces to the caller who is always in control of conflict resolution. The MultiChainReader issues parallel RPC reads across chains so keeper bots and arbitrage engines get consistent snapshots without blocking on sequential calls.

§Quick Start

Add the crates you need to Cargo.toml:

[dependencies]
xenith-core      = "0.1"
xenith-layerzero = "0.1"
xenith-sync      = "0.1"

Push a state value from Ethereum to Arbitrum, then read it back:

use std::sync::Arc;
use bytes::Bytes;
use xenith_core::{ChainId, InMemoryStore, ReadStrategy, StateKey};
use xenith_layerzero::LayerZeroTransport;
use xenith_sync::{SyncConfig, SyncEngine};

#[tokio::main]
async fn main() -> xenith_core::Result<()> {
    // LayerZero endpoint IDs: Ethereum mainnet = 30101, Arbitrum = 30110
    let transport = Arc::new(LayerZeroTransport::new(
        [0u8; 20], // endpoint contract address on the source chain
        vec![
            (ChainId::from(1),     30101),
            (ChainId::from(42161), 30110),
        ],
    ));

    let engine = SyncEngine::new(
        transport,
        Arc::new(InMemoryStore::default()),
        SyncConfig::default(),
    );

    let key = StateKey::new("uniswap", "pool", "0xabc123");

    // Store locally and broadcast to Arbitrum.
    let receipt = engine
        .push(
            key.clone(),
            Bytes::from_static(b"price=3400"),
            vec![ChainId::from(42161)],
            ChainId::from(1), // source chain
            None,             // no on-chain metadata needed for this push
        )
        .await?;

    println!("dispatched to {} chain(s)", receipt.successes.len());

    // Read back; Ethereum is the declared source of truth.
    let state = engine
        .read(key, ReadStrategy::SourceOfTruth(ChainId::from(1)))
        .await?;

    println!("status: {:?}", state.status); // SyncStatus::Synced
    println!("data:   {:?}", state.value.data);

    Ok(())
}

§Crate Overview

CrateDescription
xenith-coreTransport-agnostic traits, domain newtypes, XenithError, InMemoryStore, and ConflictResolver. No external deps beyond alloy-primitives, async-trait, thiserror, and bytes.
xenith-layerzeroLayerZero v2 MessagingTransport implementation; stub behaviour by default, real endpoint calls behind the live feature flag.
xenith-syncSyncEngine — the primary API surface. Composes a transport and a store to provide push, read, and resolve.
xenith-readMultiChainReader — issues parallel RPC reads across many chains simultaneously and reports storage-slot divergence.

§Transport Support

TransportStatusNotes
LayerZero v2v0.1Stub impl ships now; live feature gates real endpoint calls
Chainlink CCIPv0.2 plannedxenith-ccip crate
Axelarv0.3 plannedxenith-axelar crate

§Contributing

PRs are welcome. Before submitting, run:

cargo clippy --workspace -- -D warnings
cargo fmt
cargo test --workspace

All three must pass clean. Clippy warnings are treated as errors; the formatter is non-negotiable. If you are adding a new transport, implement the transport_compliance_tests! macro suite from xenith-core to verify conformance.

Stability: xenith follows Semantic Versioning. While on 0.x.y, minor version bumps may include breaking changes. Patch bumps are always backwards compatible. Subscribe to releases on GitHub to be notified of breaking changes.

Publishing: Crates are published manually by the maintainer after each release tag. To publish for the first time, the semver CI job must be initialized: tag a v0.0.1 release with the current codebase as the baseline before making any API changes.

Re-exports§

pub use conflict::ConflictResolver;
pub use conflict::LatestVersionResolver;
pub use error::XenithError;
pub use signer::NoopSigner;
pub use signer::TransactionSigner;
pub use store::InMemoryStore;
pub use store::KeyMetadata;
pub use store::StateStore;
pub use transport::MessagingTransport;
pub use transport::SendOptions;
pub use types::*;

Modules§

conflict
error
signer
store
testing
transport
types
wire

Macros§

transport_compliance_tests
Generates the standard transport compliance test suite for any crate::MessagingTransport implementation.

Type Aliases§

Result
Convenience alias — all fallible xenith functions return this.