digdigdig3 0.3.13

Unified async Rust API for 47 exchange connectors (REST + WebSocket). The core layer — pure ExchangeHub + connectors. Higher-level builder, persistence, replay, OB tracker live in `digdigdig3-station`.
Documentation
[package]
name = "digdigdig3"
version.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
homepage.workspace = true
keywords.workspace = true
categories.workspace = true
description = "Unified async Rust API for 47 exchange connectors (REST + WebSocket). The core layer — pure ExchangeHub + connectors. Higher-level builder, persistence, replay, OB tracker live in `digdigdig3-station`."
documentation = "https://docs.rs/digdigdig3"
readme = "../../README.md"
exclude = [
    # Internal research / workflow / audit notes — never ship to crates.io
    "**/research/**",
    "contributing/**",
    "**/AUDIT*.md",
    "**/ARCHITECTURE_AUDIT.md",
    "**/IMPLEMENTATION*.md",
    "**/FIX_SUMMARY.md",
    "**/PROBLEM_ANALYSIS.md",
    "**/API_TESTING_REPORT.md",
    "**/AUTHENTICATION_SETUP.md",
    "**/CRYPTO_NO_AUTH.md",
    "**/QUICK_START.md",
    "**/integration_test_guide.md",
    # Local harness artefacts — already gitignored, defence in depth
    "e2e_smoke_*.txt", "deep_smoke_*.txt", "smoke_*.txt", "*.log",
    "e2e_trace*/", "liq_capture/", "liq_trace_new/",
    "dig3_storage/", "target/",
]

[lib]
name = "digdigdig3"
path = "src/lib.rs"

[features]
default = ["onchain-evm"]
websocket = []
# Canonical on-chain feature flags
# onchain-evm: EIP-712 signing via k256+sha3 (HyperLiquid auth)
onchain-evm = ["dep:k256", "dep:sha3"]
onchain-cosmos = ["dep:cosmrs"]
onchain-starknet = ["dep:starknet-crypto"]
# Backward-compat alias — onchain-ethereum is now onchain-evm
onchain-ethereum = ["onchain-evm"]
grpc = ["dep:tonic", "dep:prost"]
k256-signing = ["dep:k256", "dep:sha3"]
# Legacy alias — starknet feature now maps to onchain-starknet
starknet = ["onchain-starknet"]

# ─── Shared dependencies (compile on BOTH targets) ────────────────────────────

[dependencies]
# Serialization
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

# Async foundations (target-split below for tokio itself)
async-trait = "0.1"
futures-util = "0.3"

# HTTP — reqwest 0.12 targets wasm32 automatically via its own cfg; it uses
# browser fetch underneath on wasm32 so NO TLS feature is wanted there.
# We declare it here without any tls feature and add tls features only on
# the native target block below.
reqwest = { version = "0.12", features = ["json"], default-features = false }

# Error handling
thiserror = "1.0"

# Logging
tracing = "0.1"

# Crypto (HMAC signatures — pure-Rust, compile on both targets)
hmac = "0.12"
sha2 = "0.10"
hex = "0.4"
base64 = "0.22"

# Time (OKX ISO timestamps — pure-Rust, compile on both targets)
# "now" enables Utc::now(); "wasmbind" is added in wasm block for the wasm impl.
chrono = { version = "0.4", default-features = false, features = ["std", "now", "clock"] }

# Binary parsing (Dhan WebSocket binary format)
byteorder = "1.5"

# UUID generation (client order IDs) — getrandom js feature needed on wasm
uuid = { version = "1.0", features = ["v4"] }

# Compression (BingX, HTX, Dukascopy)
flate2 = "1.0"
lzma-rs = "0.3"

# URL encoding (HTX auth, Polygon)
url = "2.5"
urlencoding = "2.1"
percent-encoding = "2.3"

# Base58 (Raydium pubkey parsing)
bs58 = "0.5"

tracing-subscriber = "0.3.22"

# TOTP (Angel One 2FA)
totp-rs = "5.6"

# Concurrent hashmap (ConnectorPool)
dashmap = "5.5"

# Decimal arithmetic
rust_decimal = "1"

# TOML config
toml = "0.8"

# Cryptographic signing (feature-gated — native-only libs gated via features)
k256 = { version = "0.13", features = ["ecdsa-core", "ecdsa"], optional = true }
sha3 = { version = "0.10", optional = true }
starknet-crypto = { version = "0.6", optional = true }

# Cosmos SDK (native-only via optional + cfg gate on dep site)
cosmrs = { version = "0.22", optional = true, default-features = false, features = ["bip32"] }

# gRPC (native-only via optional)
tonic = { version = "0.12", features = ["tls", "tls-native-roots"], optional = true }
prost = { version = "0.13", optional = true }

# ─── Native-only dependencies ─────────────────────────────────────────────────
# Everything that requires std::net, native TLS, or tokio I/O goes here.

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
# Full tokio runtime for native
tokio = { version = "1.0", features = ["full"] }

# tokio-tungstenite: native WS. NOT available on wasm32.
tokio-tungstenite = { version = "0.24", features = ["rustls-tls-webpki-roots"] }

# tokio-stream: used for stream combinators in transport.rs
tokio-stream = { version = "0.1", features = ["sync"] }

# Explicit rustls dep to pin ring as process-level CryptoProvider.
rustls = { version = "0.23", default-features = false, features = ["ring"] }

# reqwest native TLS features — only valid when not wasm
# (rustls-tls cannot compile to wasm32-unknown-unknown)
reqwest = { version = "0.12", features = ["rustls-tls"], default-features = false }

# JWT + ECDSA signing (Coinbase auth, Angel One TOTP) — trading is native-only.
# ring requires native assembly (clang), cannot compile to wasm32.
jsonwebtoken = "9.3"
ring = "0.17"
rand = "0.8"

# ─── wasm32-only dependencies ─────────────────────────────────────────────────

[target.'cfg(target_arch = "wasm32")'.dependencies]
# Tokio sync-only: broadcast, mpsc, oneshot, Mutex, RwLock compile on wasm.
# Do NOT enable "full", "net", "time", "io-util" — they pull in mio which
# does not compile for wasm32-unknown-unknown.
# We use sync + macros only. rt is NOT enabled because we delegate to
# wasm_bindgen_futures::spawn_local for task spawning.
tokio = { version = "1.0", default-features = false, features = ["sync", "macros", "time"] }

# tokio-stream: sync feature is wasm-compatible (no I/O)
tokio-stream = { version = "0.1", default-features = false, features = ["sync"] }

# wasm-bindgen core
wasm-bindgen = "0.2"
wasm-bindgen-futures = "0.4"
js-sys = "0.3"

# gloo-timers: replaces tokio::time::sleep / interval on wasm.
# The "futures" feature pulls in futures-core + futures-channel (pure Rust).
gloo-timers = { version = "0.3", features = ["futures"] }

# gloo-net: provides WebSocket API wrapping web_sys, used by WasmWsConn actor.
# Alternative to tokio-tungstenite on the browser side.
gloo-net = { version = "0.6", features = ["websocket"] }

# futures-channel: mpsc + oneshot channels inside JS closures (which are sync,
# not async). Explicitly declared even though gloo-timers pulls it transitively,
# so our direct use of `futures_channel::mpsc::unbounded` + `oneshot::channel`
# in rt/wasm.rs does not depend on a transitive dep only.
futures-channel = "0.3"

# web-sys: low-level browser API bindings.
web-sys = { version = "0.3", features = [
    "WebSocket",
    "MessageEvent",
    "BinaryType",
    "CloseEvent",
    "ErrorEvent",
    "Window",
    "Performance",
    "Blob",
    "FileReader",
] }

# getrandom js feature — required for uuid v4 on wasm32-unknown-unknown.
# Without this getrandom panics at runtime ("unsupported platform").
getrandom = { version = "0.2", features = ["js"] }

# uuid js feature — uuid 1.22+ requires this explicitly on wasm32-unknown-unknown
# in addition to getrandom/js. Cargo merges features from both dependency declarations.
uuid = { version = "1.0", features = ["v4", "js"] }

# chrono wasmbind + now — enables Utc::now() on wasm32 via JS Date.now().
# "now" enables the Utc::now() method; "wasmbind" provides the wasm32 impl
# via js_sys::Date. Without both, chrono::Utc::now() is a compile-time error.
chrono = { version = "0.4", default-features = false, features = ["std", "now", "wasmbind"] }

# Monotonic clock drop-in for wasm32. std::time::Instant panics at runtime on
# wasm32-unknown-unknown; this crate re-exports a wasm-compatible Instant backed
# by js_sys::Date::now(). Used via crate::core::rt::clock::Instant.
instant = { version = "0.1", features = ["wasm-bindgen"] }

# ─── Dev dependencies ─────────────────────────────────────────────────────────

[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
tokio-test = "0.4"

[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
wasm-bindgen-test = "0.3"