Skip to content

Sentriscloud/sdk-rs

Repository files navigation

sentrix-chain (sdk-rs)

CI License: MIT crates.io

Official Rust SDK for Sentrix Chain (chain ID 7119 mainnet, 7120 testnet).

Mirror of @sentrix/chain on the TypeScript side — same network spec, same canonical addresses, same tx signing semantics. Use this crate for Rust services (validators, indexers, bridges, monitoring agents) that need to talk to Sentrix without spinning up a Node process.

Surface

Module Feature flag Status What it does
network always on ✅ stable Chain spec types + MAINNET_SPEC / TESTNET_SPEC constants. Single source of truth for chain ID, RPC / REST / WS / gRPC URLs, explorer, faucet.
native native (default) ✅ alpha Typed REST client over reqwest for /chain/info, /staking/validators, /accounts/<addr>/nonce, POST /transactions.
wallet wallet ✅ alpha secp256k1 keypair + Ethereum-style address derivation + native tx signing.
evm evm ✅ alpha alloy-based EVM JSON-RPC client (Provider factory; reach for alloy directly for signing / contract bindings / event filters).
grpc grpc ✅ alpha tonic client over sentrix.v1.Sentrix — getBlock / getBalance / getValidatorSet / getSupply / getMempool / streamEvents. Generated proto types come from the published sentrix-proto crate (single source of truth, shared with the chain server). Consumers building from source need protoc installed (apt install protobuf-compiler or equivalent).
bft bft ✅ alpha WebSocket subscription manager for the 9 channels (newHeads, logs, sentrix_finalized, sentrix_jail, …) over tokio-tungstenite. Multiplexes everything on one socket; pings every 30 s + force-reconnects on 90 s stale; auto re-subscribes after reconnect. Mirror of @sentrix/chain/bft.

Trim what you actually use:

[dependencies]
sentrix-chain = { version = "0.1.0-alpha.0", default-features = false, features = ["native", "wallet"] }

Quick start

Read chain stats

use sentrix_chain::{Network, NativeClient};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let client = NativeClient::new(Network::Mainnet);
    let info = client.chain_info().await?;
    println!(
        "height={} validators={} mempool={} burned={}",
        info.height, info.active_validators, info.mempool_size, info.total_burned_srx
    );

    for v in client.validators().await? {
        println!("{} active={} self_stake={}", v.address, v.is_active, v.self_stake);
    }
    Ok(())
}

Sign + broadcast a native transfer

use sentrix_chain::{Network, NativeClient, SentrixWallet};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let w = SentrixWallet::from_private_key_hex(&std::env::var("PRIVATE_KEY")?)?;
    let client = NativeClient::new(Network::Mainnet);

    let nonce = client.next_nonce(&w.address).await?;
    let tx = w.build_and_sign_transfer(
        "0x0804a00f53fde72d46abd1db7ee3e97cbfd0a107",
        100_000_000, // 1 SRX in sentri
        10_000,      // 0.0001 SRX fee
        nonce,
        7119,
    )?;
    let txid = client.broadcast(&tx).await?;
    println!("broadcast: {}", txid);
    Ok(())
}

EVM read via alloy

use sentrix_chain::{Network, evm};
use alloy::providers::Provider;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let p = evm::http_provider(Network::Mainnet)?;
    let block = p.get_block_number().await?;
    println!("tip: {block}");
    Ok(())
}

Reach for alloy directly for tx signing, contract bindings, event filters — http_provider() returns alloy's standard RootProvider so the rest of the alloy ecosystem works unchanged.

gRPC read

use sentrix_chain::{Network, grpc::SentrixGrpcClient};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut c = SentrixGrpcClient::connect(Network::Mainnet).await?;
    let block = c.get_latest_block().await?;
    println!("tip: {} ({} txs)", block.index, block.transactions.len());

    // Server-stream chain events
    let mut stream = c.subscribe_events(vec![]).await?;
    while let Some(ev) = stream.message().await? {
        println!("event: {ev:?}");
    }
    Ok(())
}

connect() resolves the public TLS endpoint (grpc.sentrixchain.com:443) and attaches system-roots automatically. For dev sidecars use connect_url("http://localhost:50051").

Subscribe via WebSocket (BFT door)

use sentrix_chain::{Network, bft::{SubscriptionManager, Channel}};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mgr = SubscriptionManager::new(Network::Mainnet);

    let mut heads = mgr.subscribe(Channel::NewHeads).await?;
    let mut jail = mgr.subscribe(Channel::SentrixJail).await?;

    tokio::select! {
        Some(h) = heads.recv() => println!("new head: {h}"),
        Some(j) = jail.recv() => println!("jail event: {j}"),
    }
    Ok(())
}

Same socket carries both subscriptions; reconnects automatically with exponential backoff and re-subscribes everything. Pings every 30 s so middleboxes (Caddy idle_timeout, NAT, AWS ALB) don't drop quiet connections; if no frame arrives within 90 s the manager force-closes + reconnects (half-open guard).

Network spec — const-accessible

use sentrix_chain::network::{Network, get_spec};

const MAINNET: sentrix_chain::SentrixChainSpec = get_spec(Network::Mainnet);
println!("{}: {}", MAINNET.name, MAINNET.rpc_url);
// "Sentrix Chain: https://rpc.sentrixchain.com"

Status

v0.1.0-alpha.0 on crates.io. All six doors (network, native, wallet, evm, grpc, bft) compile and have working client paths against the public RPC + gRPC endpoints. Surface is alpha — expect breaking changes before 1.0 stabilises.

Roadmap

All six doors landed for v0.1.0-alpha.0:

  • network — chain spec, mainnet + testnet constants
  • native — REST read + tx broadcast
  • wallet — secp256k1 keypair + tx signing
  • evm — alloy-based provider (read; write via alloy direct)
  • grpc — tonic client over sentrix.v1.Sentrix (consumes sentrix-proto for the schema)
  • bft — WebSocket subscription manager (multiplex + keepalive ping + auto-reconnect, port of @sentrix/chain/bft)

Next: surface stabilisation toward 1.0 — naming review, error-type cleanup, optional EvmClient wrapper around alloy.

Decimals

Sentrix's underlying ledger is 8-decimal native (1 SRX = 100,000,000 sentri). The EVM tooling sees an 18-decimal view because eth_getBalance returns wei-scaled values for compatibility with MetaMask / ethers / viem. When you use NativeClient::balance(...) you get sentri (8-decimal); when the planned EvmClient ships you'll get wei (18-decimal). Don't mix the units across surfaces.

License

MIT — see LICENSE.

About

Official Rust SDK for Sentrix Chain — typed clients for native REST, EVM (alloy), gRPC (tonic), and secp256k1 wallet/signing.

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages