One Rust client for Casper CEP-18, CEP-78, CEP-85, and CEP-95, with a ceps-client-cli, ceps-rust-ts-client-mcp, and WASM packs so the same client can run from shell, agents, Node, or the browser.
It replaces the separate TypeScript client-js packages that lived next to each CEP contract. Instead of per-CEP JS clients, you use one library: CEP18Client / CEP78Client / CEP85Client / CEP95Client, on top of casper-rust-wasm-sdk.
CEP-18 client-js ─┐
CEP-78 client-js ─┼─→ ceps-client (Rust) + ceps-client-cli + ceps-rust-ts-client-mcp + ceps-client-wasm
CEP-85 client-js ─┤
CEP-95 JS client ─┘
| Piece | Name | Role | In-tree path |
|---|---|---|---|
| Rust library | ceps‑client |
CEP API for native Rust apps | ceps-client/ |
| CLI | ceps‑client‑cli |
Status and common queries from the shell | ceps-client-cli/ |
| MCP server | ceps-rust-ts-client-mcp |
Full CEP agent tools (stdio / HTTP :6790) | mcp/ |
| Client JS packs | ceps‑client‑wasm |
Same CEP classes for Node and browsers (replaces per-CEP client-js) |
ceps-client-wasm/pkg / pkg-nodejs |
| Demo contract WASMs | ceps‑contracts |
On-chain bytecode for install (demo tips) |
tests/wasm/{cep18,cep78,cep85,cep95}/ |
Release downloads use the same names: ceps-client-cli-*-linux-x86_64, ceps-rust-ts-client-mcp-*-linux-x86_64, ceps-client-wasm-*.tgz, and ceps-contracts-*.tgz. The library / CLI / MCP / JS packs are this client; ceps-contracts is sample contract bytecode, not the JS library.
| CEP | Standard | Typical flow |
|---|---|---|
| 18 | Fungible token | install → bind hash → name / balance_of → transfer / mint / burn |
| 78 | Enhanced NFT | install → bind hash → mint → owner_of / balance_of |
| 85 | Multi-token | install → bind hash → mint / burn → balance_of(account, id) |
| 95 | NFT (Odra tip) | install → bind_odra_install → mint → owner_of / approve |
Defaults talk to local NCTL (http://127.0.0.1:11101, SSE …:18101/events, chain casper-net-1).
Needs a running node, a secret-key PEM, and on-chain contract .wasm bytes (your own build, or the demo tips via make wasm-from-ceps).
install → named keys cep18_contract_hash_* / package_*
→ set_contract_hash
→ name / symbol / balance_of
→ transfer | mint | burn
use ceps_client::cep18::InstallArgs;
use ceps_client::{CEP18Client, TransactionParams, EventsMode, Verbosity};
let mut client = CEP18Client::new(
"http://127.0.0.1:11101",
Some("http://127.0.0.1:18101/events".into()),
Some("casper-net-1".into()),
Some(Verbosity::Low),
)?;
let put = client
.install(
&InstallArgs::new("MyToken", "MTK", 9, "1000000000")
.with_events_mode(EventsMode::CES)
.with_mint_and_burn(true),
&contract_wasm_bytes,
&TransactionParams::new(&secret_pem, "400000000000"),
)
.await?;
client.set_contract_hash(&contract_hash, Some(&package_hash))?;
let bal = client.balance_of("account-hash-…").await?;Details: docs/cep18/ · example: cargo run -p ceps-client --example cep18_install
install → named keys cep78_contract_hash_* / package_*
→ set_contract_hash
→ mint → owner_of / balance_of
use ceps_client::cep78::InstallArgs;
use ceps_client::{CEP78Client, TransactionParams, EventsMode78, Verbosity};
let mut client = CEP78Client::new(/* rpc, sse, chain, verbosity */)?;
client
.install(
&InstallArgs::new("MyNft", "NFT", 100).with_events_mode(EventsMode78::CES),
&contract_wasm_bytes,
&TransactionParams::new(&secret_pem, "600000000000"),
)
.await?;
client.set_contract_hash(&contract_hash, Some(&package_hash))?;
client
.mint(
"account-hash-…",
r#"{"name":"token-1"}"#,
None,
&TransactionParams::new(&secret_pem, "5000000000"),
)
.await?;
let owner = client.owner_of(&token_id).await?;Details: docs/cep78/ · example: cargo run -p ceps-client --example cep78_install
install → named keys cep85_contract_hash_* / package_*
→ set_contract_hash
→ mint / burn → balance_of(account, id)
use ceps_client::cep85::InstallArgs;
use ceps_client::{CEP85Client, TransactionParams, EventsMode, Verbosity};
let mut client = CEP85Client::new(/* rpc, sse, chain, verbosity */)?;
client
.install(
&InstallArgs::new("MyMulti", "https://example.com/{id}.json")
.with_events_mode(EventsMode::CES)
.with_enable_burn(true),
&contract_wasm_bytes,
&TransactionParams::new(&secret_pem, "550000000000"),
)
.await?;
client.set_contract_hash(&contract_hash, Some(&package_hash))?;
client.mint(&owner, "1", "10", None, &TransactionParams::new(&secret_pem, "5000000000")).await?;
let bal = client.balance_of(&owner, "1").await?;Details: docs/cep85/ · example: cargo run -p ceps-client --example cep85_install
install (odra_cfg_package_hash_key_name) → bind_odra_install
→ name / symbol / balance_of / owner_of
→ mint | burn | transfer_from | approve*
use ceps_client::cep95::InstallArgs;
use ceps_client::{CEP95Client, TransactionParams, Verbosity};
let mut client = CEP95Client::new(/* rpc, sse, chain, verbosity */)?;
client
.install(
&InstallArgs::new("MyNft", "MNFT", "cep95_pkg_demo"),
&contract_wasm_bytes,
&TransactionParams::new(&secret_pem, "600000000000"),
)
.await?;
client.bind_odra_install(&installer_public_key, "cep95_pkg_demo").await?;
client.mint(&owner, "1", None, &TransactionParams::new(&secret_pem, "5000000000")).await?;
let owner_of = client.owner_of("1").await?;Details: docs/cep95/ · example: cargo run -p ceps-client --example cep95_install
cargo run -p ceps-client-cli -- status
cargo run -p ceps-client-cli -- cep18 info
cargo run -p ceps-client-cli -- cep78 balance --contract-hash <hash> --account <account-hash-…>
cargo run -p ceps-client-cli -- cep85 balance --contract-hash <hash> --account <…> --id 1
cargo run -p ceps-client-cli -- cep95 owner-of --contract-hash <hash> --token-id 1Mutations are on the library / examples today. Flags: docs/cli.md.
make prepare && make build
make wasm-from-ceps # copy demo tip contract WASMs into tests/wasm/
# NCTL running + SECRET_KEY_USER_1 set to a PEM:
cargo run -p ceps-client --example cep18_installMore setup: docs/getting-started.md.
ceps-client-wasm is the Rust CEP client compiled for JavaScript (the replacement for per-CEP client-js). Use it from Node or the browser for the same CEP18Client / CEP78Client / CEP85Client surface.
It is not on-chain contract bytecode (that is tests/wasm/ / ceps-contracts-*.tgz).
| Target | In-tree (committed) | Typical use |
|---|---|---|
| Node | ceps-client-wasm/pkg-nodejs/ |
Backend / scripts / Vitest |
| Web | ceps-client-wasm/pkg/ |
Bundled frontends |
Rebuild locally with make pack (or make nodejs / make web). Details: docs/wasm-ts.md · docs/releases.md.
Or fetch a published pack (no local wasm-pack):
TAG=v1.0.0 # or dev-preview
LABEL=${TAG#v}
curl -fsSL -o ceps-client-wasm-nodejs.tgz \
"https://github.com/Interchouette-ITC/ceps-rust-ts-client/releases/download/${TAG}/ceps-client-wasm-nodejs-${LABEL}.tgz"
mkdir -p ceps-client-wasm && tar -xzf ceps-client-wasm-nodejs.tgz -C ceps-client-wasm
# -> ceps-client-wasm/pkg-nodejs/import { CEP18Client } from "ceps-client-wasm"; // file:./ceps-client-wasm/pkg-nodejs after unpack
const client = new CEP18Client(
"http://127.0.0.1:11101",
"http://127.0.0.1:18101/events",
"casper-net-1",
0,
);
client.setContractHash(contractHash, packageHash);
const name = await client.name();
const bal = await client.balanceOf("account-hash-…");Install from JS takes contract bytes as Uint8Array and returns JSON { transactionHash, hasExecutionResult }. Bound methods today are a subset of the Rust API (see docs/wasm-ts.md); full parity is on ceps-client.
This client is not a contract repo. You pass on-chain .wasm into install.
In-tree: the last staged demo tip builds ship under tests/wasm/{cep18,cep78,cep85,cep95}/ (same idea as committing pkg / pkg-nodejs). Load with ceps_client::wasm::load("cep18") under CEPS_WASM_ROOT (default tests/wasm), or refresh with make wasm-from-ceps.
Or download the release bundle (no tip checkout / no contract build):
TAG=v1.0.0
LABEL=${TAG#v}
curl -fsSL -o ceps-contracts.tgz \
"https://github.com/Interchouette-ITC/ceps-rust-ts-client/releases/download/${TAG}/ceps-contracts-${LABEL}.tgz"
mkdir -p tests/wasm && tar -xzf ceps-contracts.tgz -C tests/wasmTips are short-lived entity-era builds for demos/CI, not a claim of "the" upstream CEP tip forever. Sources:
| CEP | Demo tip repo | Branch | What you get |
|---|---|---|---|
| 18 | Interchouette-ITC/cep-18 | ceps-client-test |
Fungible contract WASM |
| 78 | Interchouette-ITC/cep-78-enhanced-nft | ceps-client-test |
NFT + session WASMs |
| 85 | Interchouette-ITC/cep-85 | ceps-client-test |
Multi-token WASM |
# after checking out those tips and building contracts there:
make wasm-from-ceps # → tests/wasm/{cep18,cep78,cep85}/Override checkout roots with CEP18_PRODUCT / CEP78_PRODUCT / CEP85_PRODUCT. Pins and SHAs: docs/contributing.md. All release downloads: docs/releases.md.
| Doc | Description |
|---|---|
| Getting started | Build, NCTL defaults, first run |
| Architecture | How lib / CLI / WASM sit on the SDK |
| docs/cep18/ · cep78/ · cep85/ | Per-CEP guides |
| CLI · WASM / TS | Surfaces |
| Testing · CI / CD · Releases · Docker | Verify and ship |
| Contributing · SDK | Tips, pins, upgrades |
| SECURITY.md | Keys and reporting |
make doc |
rustdoc → docs/api-rust/ |
make release-cli-bin && make docker-build IMAGE_TAG=local
docker run --rm ceps-rust-ts-client:local --help
docker pull interchouette/ceps-rust-ts-client:devSee docs/docker.md.
GPL-3.0. See LICENSE and docs/SECURITY.md.