LayerHopdocs

SDKs & tools

Rust SDK

The layerhop crate — an async reqwest (rustls) client with serde models, a typed error enum, a watch Stream and webhook verification.

Open in ClaudeOpen in ChatGPT

The layerhop crate is an async client for the REST API that mirrors the TypeScript SDK. It is built on reqwest (rustls, no OpenSSL), tokio and serde.

Source: github.com/layerhop/layerhop-rust — source repository (opens at launch).

The SDK never holds keys. It returns unsigned transactions; your wallet library (alloy, solana-sdk, a KMS…) signs and broadcasts them.

Install#

Terminal
cargo add layerhop
cargo add tokio --features macros,rt-multi-thread
cargo add futures-util   # StreamExt for watch()

Quickstart#

Amounts are integer strings in base units ("100000000" = 100 USDC).

rust
use futures_util::StreamExt;
use layerhop::{BuiltTx, LayerHop, QuoteParams, WatchOptions};

let lh = LayerHop::builder().build(); // .api_key(..).base_url("http://localhost:8787")

// 1. Quote
let q = lh.quote(&QuoteParams {
    src_chain: "base".into(), src_token: "USDC".into(), amount: "100000000".into(),
    dst_chain: "solana".into(), dst_token: "SOL".into(),
    sender: "0xYourEvmAddress".into(), recipient: "YourSolanaAddress".into(),
    slippage_bps: None,
}).await?;

// 2. Build the unsigned transaction
let tx = lh.build_tx(&q.best.quote_id).await?;

// 3. Sign + send with YOUR wallet library
let tx_hash = match tx {
    BuiltTx::Evm(evm) => sign_evm(evm).await?,   // send evm.approval first when Some
    BuiltTx::Svm(svm) => sign_svm(svm).await?,   // submit_via_api == Some(true) → lh.submit(..)
};

// 4. Report the broadcast
lh.report_submitted(&q.best.quote_id, &tx_hash).await?;

// 5. Watch until filled / refunded / failed
let mut updates = Box::pin(lh.watch(&q.best.provider, &tx_hash, WatchOptions::default()));
while let Some(status) = updates.next().await {
    println!("{}", status?.state);
}

Methods#

Method Endpoint
health() · chains() · tokens(chain) GET /v1/health · /v1/chains · /v1/tokens
quote(&QuoteParams) GET /v1/quote
build_tx(quote_id) POST /v1/orders → BuiltTx::Evm / BuiltTx::Svm
simulate(quote_id) POST /v1/simulate
submit(quote_id, signed_base64) POST /v1/orders/submit (Solana submit_via_api only)
report_submitted(quote_id, tx_hash) POST /v1/orders/{quoteId}/submitted
status(provider, id) GET /v1/orders/{provider}/{id}
watch(provider, id, WatchOptions) A Stream of state changes; ends when final, yields Error::Timeout after 30 min by default
list_orders(&ListOrdersParams) GET /v1/orders

Builder options: base_url, api_key, channel, integrator, integrator_fee_bps, http_client.

Errors#

layerhop::Error::Api { code, message, status, request_id } for non-2xx responses, where code is one of the stable error codes; err.code() returns it. The other variants are Error::Http (transport), Error::Decode (unexpected body) and Error::Timeout (watch).

Webhooks#

rust
layerhop::webhook::verify(&secret, &raw_body, signature_header)?; // 300 s tolerance

The header is t=<unix>,v1=<hex HMAC-SHA256(secret, "<t>.<raw body>")>. webhook::verify_signature takes an explicit tolerance and clock.