cow-sdk 0.1.0-alpha.10

Facade crate for CoW Protocol Rust SDK surfaces
Documentation

cow-sdk

Primary Rust SDK facade for CoW Protocol.

⚠️ Alpha — 0.1.0-alpha. Pre-release and not security-audited; the public API may change before 0.1.0. It is published as a pre-release, so Cargo selects it only when you opt in (cow-sdk = "0.1.0-alpha.10"). Review it yourself before relying on it with real funds.

cow-sdk is the curated first-touch entry point of the cow-rs crate family. It re-exports the core types, signing helpers, contract helpers, orderbook client, app-data helpers, and the high-level trading orchestration surface from one place.

The cow-named identity and numeric primitive types (Address, Hash32, AppDataHash, HexData, OrderUid, Amount) re-export through the facade as cow-owned #[repr(transparent)] newtypes over alloy_primitives per ADR 0052.

Install

[dependencies]
cow-sdk = "0.1.0-alpha.10"

Feature flags

Every optional surface is off by default (default = []); enable only what you use. The HTTP retry, rate-limit, and Retry-After transport policy is always on.

Feature Enables
subgraph Read-only subgraph analytics as cow_sdk::subgraph; lifts SubgraphError into CowError.
cow-shed COW Shed account-abstraction hooks as cow_sdk::cow_shed (proxy derivation, EIP-712 hook signing, factory calldata).
alloy-provider Native Alloy read-only Provider adapter as cow_sdk::alloy_provider.
alloy-signer Native Alloy local-key Signer adapter as cow_sdk::alloy_signer.
alloy The composed native Alloy client as cow_sdk::alloy; implies alloy-provider and alloy-signer.
testing In-memory test doubles (MockOrderbook, MockSigner, MockProvider) as cow_sdk::testing for downstream integration tests. Dev-dependency only.
tracing tracing spans and structured events across the SDK; see the Observability guide.
[dependencies]
cow-sdk = { version = "0.1.0-alpha.10", features = ["subgraph", "cow-shed"] }

Native default example

The shortest ready-state path uses the native default orderbook transport. Browser targets use the same trading API but must inject a browser transport; see the workspace Getting Started guide for that wiring.

use cow_sdk::core::SupportedChainId;
use cow_sdk::trading::Trading;

let _trading = Trading::builder()
    .chain_id(SupportedChainId::Sepolia)
    .app_code("your-app-code")
    .build()
    .unwrap();

Once constructed, a single call quotes, signs, and posts a swap. The order owner defaults to the signer's address:

# use std::error::Error;
use cow_sdk::core::{address, Address, Amount, SupportedChainId};
use cow_sdk::trading::Trading;

// Tokens are compile-time validated `Address` literals, not raw strings. The
// literal is the lowercase wire form; a mixed-case literal rejects at build time.
const WETH: Address = address!("0xfff9976782d46cc05630d1f6ebab18b2324d6b14");
const COW: Address = address!("0x0625afb445c3b6b7b929342a04a22599fd5dbb59");
#
# async fn run<S>(signer: &S) -> Result<(), Box<dyn Error>>
# where
#     S: cow_sdk::core::Signer,
#     S::Error: std::fmt::Display + cow_sdk::core::UserRejection,
# {
let trading = Trading::builder()
    .chain_id(SupportedChainId::Sepolia)
    .app_code("your-app-code")
    .build()?;

// The named setters keep the sell and buy legs from being transposed, and
// `execute` becomes callable only once both tokens and an amount are set. The
// owner defaults to the signer address and slippage uses the quote-aware
// tolerance unless either is set.
let posted = trading
    .swap()
    .sell_token(WETH)
    .buy_token(COW)
    .sell_amount(Amount::parse_units("0.1", 18)?)
    .execute(signer)
    .await?;

println!("https://explorer.cow.fi/sepolia/orders/{}", posted.order_id);
# Ok(())
# }

For allowance, approval, pre-sign, or on-chain cancellation that does not need an app code, call the crate's free functions directly — cow_protocol_allowance, approval_transaction, pre_sign_transaction, and onchain_cancel_order — without constructing a trading client. The native wrap_transaction and unwrap_transaction builders resolve the chain's wrapped-native token from the chain id and need neither a client nor a provider.

Handling errors

Every fallible call returns a typed error. The facade aggregates the per-crate errors into CowError, and every error type — facade or leaf — exposes a coarse ErrorClass (Validation, Transport, Remote, RateLimited, Signing, Cancelled, Internal) for telemetry. Orderbook failures add a status-precise retry verdict: is_retryable() returns the same decision the SDK's own transport retry loop reaches, and backoff_hint() surfaces the server's Retry-After cooldown when present.

use std::time::Duration;
use cow_sdk::{CowError, ErrorClass};

/// Decide whether a failed SDK call should be retried, and how long to wait.
fn retry_delay(error: &CowError) -> Option<Duration> {
    // `class()` is the coarse telemetry bucket; `is_retryable()` is the
    // status-precise retry decision — a retryable `503` and a non-retryable
    // `400` are both `ErrorClass::Remote`, so class alone cannot tell them apart.
    let _telemetry_bucket: ErrorClass = error.class();
    error
        .is_retryable()
        .then(|| error.backoff_hint().unwrap_or(Duration::from_millis(500)))
}

CowError is the convenience aggregate for consumers that ?-propagate every SDK call into one type. A consumer with its own error type — or that needs rejection-specific handling — matches the leaf error directly instead: each leaf carries the same class() and is_retryable(), plus the finer-grained OrderbookRejection::category() that names the action a rejection calls for. The native error_classification example walks every ErrorClass bucket and the category() refinement end to end.

On-chain submission has its own verdict. The receipt-wait helpers return WaitError, which is generic over the caller's signer and provider error types, so it stays out of CowError; use WaitError::reverted() to tell a real on-chain revert from a transient broadcast, lookup, timeout, or cancellation.

Examples

The workspace ships runnable, deterministic scenarios for every facade workflow — quoting, posting, signing, app-data, transport, subgraph access, and the Alloy adapters — cataloged by goal in Examples. Getting Started walks the recommended first session.

Where to next

License

Licensed under GPL-3.0-or-later. See the workspace LICENSE file for the full text.