The build guide

Wire up an agentic money flow.

Thirty minutes from zero to the full lifecycle on your own machine: a shielded treasury, consensus-enforced budgets, invisible agent payroll, metered machine work, and a lawful disclosure. Every command below is real; nothing is pseudocode. The JSON-RPC reference is at the bottom — it's the same API this website and the explorer use.

OPEN SOURCE · NODE v0.19.3 · WALLET v0.15.0 · ANDROID v0.3.0LINUX / WSL2NO GPU — THE PUBLIC PROVER PROVES FOR YOUEVERY TX PAYS 100 MICRO, BURNED

0What you need

Linux or WSL2 with stable Rust — or nothing at all: on Windows the wallet does every step below behind a double-click. Shielded payments need a STARK proof; point at https://prover.hashkinetics.org (the wallet does by default) or run your own hk-prove on a CUDA card (~1.2 s per proof). Validating and everything transparent needs no GPU at all.

The protocol fee. Every transaction envelope on testnet-1 pays 100 micro (0.000100), debited before the payload runs, refunded in full if the payload is refused, burned if it succeeds. A transfer of n needs n + 100 available; a full-balance sweep is refused with have 249900, need 250000. The wallet and the CLI both know this; your own code should too — docs/FEES.md ↗.

0.5Get an account and test funds (self-custody, no ceremony)

# a keychain on your machine; the id is H(auth commitment) — squat-proof
hk-node account-new ~/my-account
hk-node account-info ~/my-account            # prints the id, the next nonce, and the "genesis auth" commitment
# fund it: paste the auth commitment at /faucet (0.100000 per address per day)
hk-node account-balance https://rpc.hashkinetics.org ~/my-account
hk-node account-send ~/my-account https://rpc.hashkinetics.org <TO-ID> 50000   # 0.05 + the 100-micro fee
hk-node account-create ~/my-account https://rpc.hashkinetics.org <THEIR-AUTH-COMMIT> 10000   # sponsor a friend's account

Every send signs with your own hash-based one-time key at the next ratchet index — the same discipline the validators live by. Refused transactions cost nothing and spend no index.

1Clone and build

git clone https://github.com/hashkinetics/hashkinetics
cd hashkinetics/chain
cargo build --release -p hk-node
cargo test   # 93 workspace tests (+17 in the circuit), all green expected

2Start the prover, then a local 4-validator chain

The prover serves verifying keys and builds STARKs for shielded traffic. Nodes fetch the vks at startup and refuse to start unless they match the hashes pinned in genesis — the proof system is a consensus constant, not an operator convenience.

# terminal A — the prover:
cd zkvm-bakeoff/sp1/script && cargo run --release --bin serve

# terminal B — four hash-signed BFT validators on localhost:
cd chain && ./devnet.sh --fresh -n 4 --prover-url http://127.0.0.1:9911
Startup log to look for, in order: verifying keys MATCH the genesis pins SP1 pool verifier wired Consensus is ready Committed block lines with matching app_hash across nodes.

3The whole economy, one command (recommended first run)

Before wiring your own flow, watch the reference one: a principal funds a fleet, agents buy and meter services, payroll goes stealth, a rogue agent gets refused by consensus, and a regulator gets exactly one answer. Six acts, ~5 minutes, real proofs throughout.

./target/release/hk-node demo-economy http://127.0.0.1:26000 http://127.0.0.1:9911

4Create the org's wallet and shield the treasury

The wallet binds to a chain account (the local chain's genesis ships org, agent-a/b/c, merchant). Shielding moves transparent balance into the pool as a hidden note under a real mint proof — from here, amounts and holders are invisible.

# B = ./target/release/hk-node
hk-node wallet init ~/org-wallet org
hk-node wallet shield ~/org-wallet 10   # $10 → the pool (GPU proof ~1.2 s)
hk-node wallet status ~/org-wallet      # transparent + shielded balances

5Write the budget into consensus — the MandateTree

A mandate is a consensus object, not a config row. The root pins the org's envelope; children attenuate it (rates, buffers, per-tx caps, expiry can only shrink). Today mandate authoring rides the RPC directly — the JSON below is the actual transaction payload shape; an SDK wrapper is on the roadmap (labeled plan).

// Tx::MandateCreate — the child leaf an agent will spend under
{
  "MandateCreate": {
    "id": "<derived-id>", "parent": "<root-id>", "holder": "<agent-account>",
    "asset": "<usd-id>", "rate_per_sec": "1000", "buffer_max": "20000000",
    "per_tx_max": "10000000", "initial_buffer": "10000000", "expiry": 1790000000, "tier": 0
  }
}
# submit via hk_submitTx · check headroom any time:
hk_mandateAvailable { leaf }{ available }
The rules the chain enforces from this moment: children may oversubscribe the parent on purpose, but every spend clears the entire ancestor chain; revoking any node kills its whole subtree next block; allowance drips per-second into a capped buffer — no midnight resets to game.

6Pay an agent — invisibly

The agent's wallet prints a stealth address; the org pays it with zero transparent trace. Discovery is cryptographic: the recipient's wallet scans the pool by trial decapsulation and finds its note — nobody else can.

hk-node wallet init ~/agent-wallet agent-a
hk-node wallet address ~/agent-wallet   # → hk1… stealth address

hk-node wallet pay ~/org-wallet <HK-ADDR> 3 "Q3 bonus"
hk-node wallet scan ~/agent-wallet
✓ DISCOVERED: $3 — memo: "Q3 bonus"
# a third wallet scanning the same pool sees: 0 notes

7Meter machine work — PayWord channels

For pay-per-call work (inference, retrieval, any API), the agent opens a channel under its mandate: escrow = price × max-steps, drawn through the ancestor chain once. Each call then costs one 32-byte hash preimage — no signature, no chain round-trip, verified by the merchant with a single hash. One settle transaction carries the whole session.

# the reference metered session (inside demo-economy, Act 2):
ChannelOpen { mandate, payee, unit_price: $0.01, max_steps: 500 }
# … 320 calls happen OFF-CHAIN at machine speed …
ChannelSettle { word: H^320, step: 320 }   → merchant +$3.20, ONE tx
Why this matters at scale: settles are transparent hash-checks — they never touch the proving farm. Effective payments/s = chain settles/s × channel depth. That is the 183,000/s line on the network page, and it is arithmetic on measured constants.

8Watch consensus refuse an overspend

Ask an agent to spend past its family envelope. Its own leaf allows it; the hierarchy doesn't. The refusal happens in the state machine on every validator, over balances none of them can see — and it comes back as a receipt.

# receipts are queryable by txid:
POST {"method":"hk_getReceipt","params":{"txid":"…"}}
→ rejected: mandate: insufficient buffer at depth 1 from leaf (have 7000000, need 10000000)

9Disclose exactly one payment — offline

When lawful process asks, the holder builds a one-time package for a single payment. Anyone can verify it with no chain access; the package key opens nothing else. This is the CVA model: confidential by default, disclosable by choice, no master key anywhere in the design.

hk-node wallet disclose ~/agent-wallet <COMMITMENT> disclosure.json
hk-node verify-disclosure disclosure.json   # pure offline verify
✓ DISCLOSURE VERIFIED — amount, memo, anchor-bound · opened 0 of N others

10Point it at the live testnet

Everything above also runs against testnet-1 — create an account (step 0.5), take a faucet drip, and every command pays its 100-micro fee from that balance. The public RPC is open, CORS and all (this website's live tiles call it straight from your browser). For your own always-on node, follow the join guide — the kit carries the genesis and the verifying keys, so your node verifies every proof locally (no prover, no environment variable), and since v0.15.2 it appears in the live roll call the moment it connects.

The API

JSON-RPC reference

Plain JSON-RPC 2.0 over HTTP POST — https://rpc.hashkinetics.org (public testnet) or http://127.0.0.1:26000 (your local chain). No keys, no auth, no SDK required.

All twenty-six methods the node answers, grouped. Full parameter and result shapes, limits and errors: docs/RPC.md ↗. Amounts are micro-units as decimal strings; ids are lowercase hex.

hk_chainInfoThe heartbeat: chain_id, genesis_digest, height, app_hash, signer{epoch, remaining, capacity} (this node's one-time-key budget), fee{micro, from_height, burned_micro}, history{disk_from, ram_window, indexed_txs}. Params: none.
hk_getValidators · hk_getMempoolThe validator set as of the tip (address, power, epoch, root key) · this node's pending admissions (count + up to 100 txids).
hk_getBlocks · hk_getBlockNewest-first block list (before, limit ≤ 50; returns earliest = the lowest height this node serves from disk) · one block in full: every tx's public summary and receipt, the aggregate flag, rotation certificates applied, the commit certificate.
hk_getTx · hk_getAccountTxs · hk_getReceiptA transaction by id (height, index, summary, receipt) · an account's transactions newest-first (limit ≤ 100) · the consensus receipt string for a txid — ok: n event(s) or rejected: <rule>, verbatim.
hk_getAccount · hk_balanceAccount record (found, nonce = next ratchet index, current auth commitment) · transparent balance for an account and asset.
hk_submitTxSubmit any signed envelope — transfers, account creation, MandateCreate/Spend/Revoke, channel open/settle/refund, shield, shielded spend (proof attached). Admission mirrors the state machine: nonce window, balance including the 100-micro fee, duplicate nullifiers. Accepted txs are gossiped to peers.
hk_mandateAvailable · hk_getChannelLive spendable headroom for a mandate leaf (drip, buffer cap, the whole ancestor chain, evaluated now) · a PayWord channel's full state.
hk_getPools · hk_getPoolInfo · hk_getPoolNotes · hk_getPoolLeaves · hk_getPoolPath · hk_nullifierSpentEvery pool at once (one per pool-eligible asset since height 190,000, v0.19.0; the legacy pool carries the test asset) · one pool's root, anchor, note count, nullifier count and conservation total · the note index a wallet scans by trial decryption (paged with from/limit since v0.16.1) · the commitment list · one Merkle path (incremental scans) · whether a nullifier is spent. All take an optional asset.
hk_getAsset · hk_getAssetsIssued assets (X1, v0.15.0): id, symbol, decimals, issuer, policy flags, supply, burned, paused — e.g. the bridged USDC.sep (0c3c3f40…), whose supply − burned equals the Sepolia vault's balance (/bridge) · the whole registry.
hk_getPeersThe node's live peer table with the version tag every node advertises (v0.15.2) — the roll call on /network.
hk_submitBundleProof-less pool transactions plus ONE aggregate STARK covering all of them — the aggregator path.
hk_submitRotation · hk_submitSetChange · hk_gossipTxsOperator surface: carry another validator's root-signed rotation certificate into this node's next proposal (the peer-carried revival path) · submit a validator-set change certificate (admit or remove a seat, V1, v0.14.0 — more than ⅔ of the seated roots) · peer ingress for transaction gossip (single hop; meant for validator-to-validator use).
# try it right now, no setup:
curl -s -X POST https://rpc.hashkinetics.org \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"hk_chainInfo","params":[]}'

Go deeper

The runbook covers the crash-kill drill, the demo suite, and troubleshooting; the storm harness reproduces the capacity numbers; the yellowpaper holds the invariants everything above rests on.