Cardano Client Lib for Rust
The cardano-client-lib crate (imported as ccl) brings Cardano Client Lib (CCL)‘s offline Cardano operations — key derivation, address handling, transaction building and signing, Plutus data, governance keys — to Rust as a native library. No JVM at runtime: the crate links against libccl, a GraalVM native-image build of CCL fetched automatically at build time.
Documentation
Section titled “Documentation”| Document | Contents |
|---|---|
| API reference | Every type and method: Bridge, account, address, crypto, tx, plutus, script, gov, wallet, quicktx |
| Building transactions | The full workflow with worked examples: payments, staking, governance, minting, Plutus |
| Providers & evaluators | The providers feature: fetching UTXOs/protocol params from Yaci DevKit or Blockfrost; remote script-cost evaluation |
| Troubleshooting | Native library fetching, platform support, common errors |
| TxPlan (YAML) reference | The transaction description format used by quicktx().build — shared by all four language wrappers |
Installation
Section titled “Installation”Once published to crates.io:
[dependencies]cardano-client-lib = "0.1"# with the optional HTTP providers:# cardano-client-lib = { version = "0.1", features = ["providers"] }Until then, use a git dependency:
[dependencies]cardano-client-lib = { git = "https://github.com/bloxbean/cardano-client-bindings", package = "cardano-client-lib" }The import name is ccl regardless: use ccl::{Bridge, Network};.
First build needs network access: crates.io can’t host the ~50 MB native library, so build.rs downloads the prebuilt libccl for your platform from the project’s GitHub releases (once, cached in the build directory). An rpath is set automatically — no LD_LIBRARY_PATH/DYLD_LIBRARY_PATH needed at runtime. To build against a local library instead, set CCL_LIB_PATH — see troubleshooting.
Features:
| Feature | Default | Adds |
|---|---|---|
providers | off | ccl::providers module (Yaci/Blockfrost chain-data providers + evaluators, pulls in ureq) |
Quick start
Section titled “Quick start”use ccl::{Bridge, Network};
fn main() -> Result<(), Box<dyn std::error::Error>> { let bridge = Bridge::new()?; // torn down automatically on drop (RAII)
// Create a new account (24-word mnemonic, testnet addresses). let created = bridge.account().create(Network::Testnet)?; let account: serde_json::Value = serde_json::from_str(&created)?; println!("{}", account["base_address"]); // addr_test1... println!("{}", account["stake_address"]); // stake_test1...
// Restore it later from the mnemonic. let mnemonic = account["mnemonic"].as_str().unwrap(); let _restored = bridge.account().from_mnemonic(mnemonic, Network::Testnet, 0, 0)?; Ok(())}Build, sign, and inspect a transaction — fully offline
Section titled “Build, sign, and inspect a transaction — fully offline”Transactions are described as a TxPlan YAML document. You supply the UTXOs and protocol parameters (from any source — see providers for ready-made ones), and get back an unsigned transaction:
let yaml = format!(r#"version: 1.0transaction: - tx: from: {sender} intents: - type: payment address: {receiver} amounts: - unit: lovelace quantity: "5000000""#);
let result = bridge.quicktx().build(&yaml, &utxos, &protocol_params, None)?;// result.tx_cbor, result.tx_hash, result.fee
let signed = bridge.account().sign_tx(mnemonic, Network::Testnet, 0, 0, &result.tx_cbor)?;// submit `signed` with any HTTP client — the library never talks to the networkWith a provider (requires the providers feature), fetching the chain data is one call:
use ccl::providers::YaciProvider;
let provider = YaciProvider::default(); // local Yaci DevKitlet result = bridge.quicktx().build_with(&yaml, &provider, &sender, 0, None)?;Design in one paragraph
Section titled “Design in one paragraph”The native library is offline and stateless — it derives, builds, signs, hashes, and serializes, but never performs I/O. Anything that touches the network (fetching UTXOs, protocol parameters, submitting transactions, remote script evaluation) lives in the optional providers module or in your code, where you control HTTP. Plutus execution units are computed offline in-process (via Scalus) by default, so even script transactions build without a network connection.
Threading
Section titled “Threading”Bridge is deliberately !Send and !Sync: the underlying GraalVM isolate thread is bound to the OS thread that created it, so moving a bridge across threads would corrupt the VM. The compiler enforces this — create one Bridge per thread. Teardown is RAII (Drop); there is no close() to forget, and the borrow checker prevents use-after-free of the bridge by the API handles.
Networks
Section titled “Networks”pub enum Network { Mainnet, Testnet, Preprod, Preview }Every key-derivation method takes a typed Network — there is no integer API. Note the underlying values are CCL enum ordinals, which are the inverse of Cardano’s on-chain network id for mainnet/testnet (Mainnet → ordinal 0, but a mainnet address’s on-chain network_id is 1). See API reference → Networks.
Examples
Section titled “Examples”Runnable examples live in wrappers/rust/examples/:
account.rs— create/restore accounts, derive keys and DRep idprimitives.rs— mnemonics, Blake2b hashing, Ed25519 sign/verify, address parsingtransaction.rs— offline QuickTx build + signevaluator.rs— Plutus mint with offline Scalus units vs. remote Blockfrost evaluation (needs--features providers)
cargo run --example accountcargo run --example evaluator --features providers