quantus-cli 2.3.0

Command line interface and library for interacting with the Quantus Network
[package]
authors = ["Quantus Network"]
categories = ["api-bindings", "command-line-utilities", "cryptography"]
description = "Command line interface and library for interacting with the Quantus Network"
edition = "2021"
homepage = "https://quantus.com"
keywords = ["blockchain", "cli", "crypto", "quantum", "quantus-network"]
license = "Apache-2.0"
name = "quantus-cli"
readme = "README.md"
repository = "https://github.com/Quantus-Network/quantus-cli"
version = "2.3.0"

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

[[bin]]
name = "quantus"
path = "src/main.rs"

[features]
default = ["camera"]
# Camera capture + QR decoding for cold-wallet signing. Disable for headless
# builds; UR input via --cold-response-in <file|-> keeps working without it.
camera = ["dep:minifb", "dep:nokhwa", "dep:rxing"]

[dependencies]
# CLI and async runtime
clap = { version = "4.5", features = ["derive"] }
tokio = { version = "1.46", features = ["full"] }

# Cold-wallet QR signing: UR encoding shared with the mobile/cold wallet apps
# (1.6.0). Keystone firmware still encodes 1.4.0; the wire format is compatible.
quantus_ur = "1.6.0"
# Terminal QR rendering (string renderers only; image/svg not needed)
qrcode = { version = "0.14", default-features = false }
# Camera capture (AVFoundation / MSMF / V4L2) + pure-Rust QR decoding.
# rxing (ZXing port) over rqrr: its adaptive binarizer decodes the defocused
# frames a fixed-focus Mac camera produces at phone-scanning distance.
minifb = { version = "0.28", optional = true }
nokhwa = { version = "0.10", features = ["input-native"], optional = true }
rxing = { version = "0.8", default-features = false, features = ["encoding_rs"], optional = true }

# Serialization and configuration
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
toml = "0.9"

# Error handling
thiserror = "2.0"

# Terminal UI
colored = "3.0"
# Kept at 0.18 to share a single indicatif build with `self_update` (no duplicate).
indicatif = "0.18"

# Additional utilities
chrono = { version = "0.4", features = ["serde"] }
dirs = "6.0"
hex = "0.4"
rpassword = "7.4"
sha2 = "0.10"

# Quantum-Safe Encryption
aes-gcm = "0.10" # AES-256-GCM (quantum-safe with 256-bit keys)
argon2 = "0.5"   # Password-based key derivation (quantum-safe)
rand = "0.9"

# Quantus crypto dependencies (aligned with chain / dilithium-crypto 0.6.1).
qp-dilithium-crypto = { version = "0.6.1", features = ["serde"] }
qp-human-checkphrase = "2.2.1"
qp-rusty-crystals-dilithium = { version = "4.1.1", features = ["ml-dsa-65", "ml-dsa-87"] }
qp-rusty-crystals-hdwallet = { version = "4.1.1", features = ["ml-dsa-65"] }
# The pre-March-2026 BIP32 tree ("Bitcoin seed" master HMAC key, soft child
# support): historical Dilithium accounts and wormhole entropies in
# cli/airdrop.rs derive through it. Same crate qp-rusty-crystals-hdwallet
# < 2.1.0 used internally.
nam-tiny-hderive = { version = "=0.3.1-nam.1", default-features = false }

# HTTP client for Subsquid queries
blake3 = "1.8"
reqwest = { version = "0.12", features = ["json", "rustls-tls"], default-features = false }

# Self-update: download and replace the running binary from GitHub releases.
# 1.0.0-rc.x is required for quick-xml >= 0.41 (RUSTSEC-2026-0194 / 0195); stable
# 0.44 still pins quick-xml ^0.38. Pulls reqwest 0.13 alongside our 0.12.
self_update = { version = "1.0.0-rc.6", default-features = false, features = [
	"archive-tar",
	"archive-zip",
	"compression-tar-gz",
	"compression-zip-deflate",
	"github",
	"progress-bar",
	"reqwest",
	"rustls",
] }
# 1.0 stopped re-exporting these; the update flow uses them directly.
self-replace = "1"
tempfile = "3"

# Force patched version of bytes (RUSTSEC-2026-0007)
bytes = "1.11.1"

# Force patched version of quinn-proto (RUSTSEC-2026-0037)
quinn-proto = "0.11.14"

# Force patched version of rustls-webpki (RUSTSEC-2026-0098, RUSTSEC-2026-0099, RUSTSEC-2026-0104)
rustls-webpki = "0.103.13"

# Force patched event-listener (RUSTSEC-2026-0221); smoldot allows ^5.3
event-listener = "5.4.2"

# Blockchain deps: align with chain workspace
codec = { package = "parity-scale-codec", version = "3.7", features = ["derive"] }
jsonrpsee = { version = "0.24", features = ["client"] }
# Resolving a metadata type id to its `TypeDef`, to tell a real byte run from a `Vec` of
# structs. subxt re-exports scale-value and scale-decode but not scale-info.
scale-info = { version = "2.11", default-features = false }
sp-core = { version = "39.0.0" }
sp-runtime = { version = "45.0.0" }

# Subxt: latest 0.44.x (bug fixes; compatible with sp-core 39 / scale-codec 3.6)
subxt = "0.44"
subxt-metadata = "0.44"

# ZK proof generation (aligned with chain)
anyhow = "1.0"

# Building blocks of qp-poseidon-core 0.9.5's hasher. The local v09 sponge in
# cli/airdrop.rs hashes the secret preimage from a borrowed slice because the
# 0.9.5 crate's hash_no_pad consumes its Vec and frees it unscrubbed.
p3-field = { version = "0.3.0", default-features = false }
p3-goldilocks = { version = "0.3.0", default-features = false }
p3-symmetric = { version = "0.3.0", default-features = false }
qp-ownership-circuit = { version = "=4.4.0", default-features = false, features = ["std"] }
qp-ownership-prover = { version = "=4.4.0", default-features = false, features = ["std"] }
qp-plonky2 = { version = "1.5.5", default-features = false, features = ["rand", "std"] }
qp-plonky2-verifier = { version = "1.5.5", default-features = false }
qp-poseidon-core = "3.1.0"
rand_chacha = { version = "0.9", default-features = false }
# Resonance-era (v0.9.x) permutation constants differ from the current ones.
qp-poseidon-core-v09 = { package = "qp-poseidon-core", version = "=0.9.5" }
qp-wormhole-aggregator = { version = "=4.4.0", default-features = false, features = ["rayon", "std"] }
qp-wormhole-circuit = { version = "=4.4.0", default-features = false, features = ["std"] }
qp-wormhole-circuit-builder = "=4.4.0"
qp-wormhole-inputs = { version = "=4.4.0", default-features = false, features = ["std"] }
qp-wormhole-prover = { version = "=4.4.0", default-features = false, features = ["std"] }
qp-wormhole-verifier = { version = "=4.4.0", default-features = false, features = ["std"] }
qp-zk-circuits-common = { version = "=4.4.0", default-features = false, features = ["std"] }

[target.'cfg(unix)'.dependencies]
libc = "0.2"

[build-dependencies]
hex = "0.4"
qp-poseidon-core = "3.1.0"
qp-wormhole-circuit-builder = "=4.4.0"
sha2 = "0.10"

[dev-dependencies]
jsonrpsee = { version = "0.24", features = ["server"] }
qp-poseidon-core = "3.1.0"
serial_test = "3.1"
tempfile = "3.8.1"

# Optimize build scripts and their dependencies in dev mode.
# This is critical for circuit generation which is CPU-intensive.
# Without this, circuit generation takes ~10 minutes instead of ~30 seconds.
[profile.dev.build-override]
opt-level = 3

[profile.release.build-override]
opt-level = 3