Build Crypto & Stable Coin Products with ease
ChainOS gives developers the API infrastructure to power exchanges, fintechs, and payment platforms. Generate wallet addresses, monitor deposits, settle withdrawals and consolidate funds across ten blockchains into a single treasury — without ever handing over your keys.
- 10
- chains, one interface
- 0
- private keys held by Ziklag
- 1
- container to run on your side
curl -X POST http://localhost:8787/v1/addresses \
-H "X-API-Key: $CHAINOS_EDGE_KEY" \
-H "Content-Type: application/json" \
-d '{
"chain": "eth",
"userRef": "cust_88213",
"tag": "deposit",
"label": "Main NGN wallet"
}'const res = await fetch("http://localhost:8787/v1/addresses", {
method: "POST",
headers: {
"X-API-Key": process.env.CHAINOS_EDGE_KEY,
"Content-Type": "application/json"
},
body: JSON.stringify({
chain: "eth",
userRef: "cust_88213",
tag: "deposit"
})
});
const { data } = await res.json();
console.log(data.address, data.derivationPath);var req = HttpRequest.newBuilder()
.uri(URI.create("http://localhost:8787/v1/addresses"))
.header("X-API-Key", System.getenv("CHAINOS_EDGE_KEY"))
.header("Content-Type", "application/json")
.POST(BodyPublishers.ofString("""
{ "chain": "eth", "userRef": "cust_88213", "tag": "deposit" }
"""))
.build();
var res = http.send(req, BodyHandlers.ofString());body := `{"chain":"eth","userRef":"cust_88213","tag":"deposit"}`
req, _ := http.NewRequest("POST",
"http://localhost:8787/v1/addresses",
strings.NewReader(body))
req.Header.Set("X-API-Key", os.Getenv("CHAINOS_EDGE_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)Ten chains, one interface
Address derivation, native and token balances, confirmation thresholds and fee models are normalised per chain. Your integration code does not branch.
Three steps to your first deposit
Run the Edge container
One static binary in your own network. It reads your BIP-39 mnemonic from a mounted secret, derives your extended public keys, and registers them with Cloud over a signed channel. It enrols once; every boot after that resumes.
PASS_PHRASE_FILE=/run/secrets/mnemonicPoint your core at localhost
The Edge terminates the full ChainOS API on port 8787 and issues its own keys. Your banking application never holds a Ziklag credential and never calls Ziklag directly.
X-API-Key: zkl_live_…Receive signed events
Deposits and confirmations arrive as HMAC-signed webhooks, delivered Cloud to Edge to your endpoint. You need no public ingress, and an offline Edge means late events, never lost ones.
deposit_confirmed · threshold 12
The mnemonic never crosses the line
Your application talks to the Edge. The Edge talks to Cloud. The seed, every child private key and the Edge identity key exist only in Edge process memory, mlocked and zeroed after each use.
Cloud stores extended public keys and one Ed25519 public key. An xpub permits derivation of public keys and addresses only — a property of BIP-32, not a policy commitment.
Every request is signed by a key derived from your mnemonic and pinned on first sync. A different mnemonic fails authentication before any payload is read, quarantines the new xpubs, and pages your account owner. Addresses derived from prior xpubs stay monitored forever.
- Derive receive addresses from your stored xpubs
- Observe on-chain activity for those addresses
- Construct unsigned transactions
- Broadcast what your Edge has already signed
- Derive any private key
- Sign any transaction
- Move any funds
- Reconstruct your mnemonic
Possession of an xpub reveals the transaction graph of every address derived from it. We can see balances and flows. That is unavoidable wherever a provider performs monitoring, which is why xpubs are encrypted at rest, never logged, and never rendered beyond an eight-and-four character preview.
Nine events, at-least-once, signed
Deliveries are durably queued with a tiered retry ladder — 2m, 5m, 30m — then a portal-visible dead letter queue you can replay. Ordering is guaranteed per address. Consumers must be idempotent on the event id.
- 3
- retries, then a replayable DLQ
- 7 days
- replay window
- 0
- public ingress required
{
"event": "deposit_confirmed",
"id": "evt_01J8XK9",
"environment": "live",
"confirmations": 12,
"threshold": 12,
"timestamp": "2026-08-15T10:32:00Z",
"data": {
"chain": "eth",
"txid": "0xf9e1a2b3…",
"outputIndex": 0,
"address": "0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD",
"counterparty": "0x8a1c…",
"amount": "1000000",
"amountFormatted": "1.00",
"decimals": 6,
"tokenSymbol": "USDT",
"tokenContract": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
"blockNumber": 21456789,
"userRef": "cust_88213",
"tag": "deposit",
"destinationTag": null
}
}Capacity you commit to, transactions you settle
A band is a committed purchase, not a measurement. Sweeps, failed transactions, balance queries, address generation and all sandbox activity are never billed.
| Capability | Free | Premium | Ultimate |
|---|---|---|---|
| Chains | 2 | all 10 | all 10 |
| Active addresses | 100 | band | band |
| Settled tx / month | 100 | band | band |
| Webhooks | 1 | 25 | unlimited |
| Concurrent Edge sessions | 1 | 5 | unlimited |
| SSO / SAML | — | yes | yes |
| HSM / KMS keystore | — | — | yes |
| Audit retention | 7 d | 90 d | unlimited + export |
| Support | community | priority, 24 h | dedicated, 4 h SLA |
One container on your own network. It reads your recovery phrase from a mounted secret, derives your keys, signs every transaction and terminates the ChainOS API on port 8787. The phrase never leaves it.
- You operate
- 1 container
- Inbound ports
- none
- We can see
- xpubs only
Hosted at chainos.cloud. We operate Cloud, the chain indexers and the message bus, and we pay for the chain access behind them. You are billed a band fee plus settled transactions, and nothing else.
- Billing
- band fee + settled tx
- Chain access
- included
- You operate
- nothing
Monitoring never stops. A commercial dispute, a suspended account or an expired card blocks API access — it does not stop us watching your addresses or delivering your webhooks, because a deposit nobody sees is a deposit somebody loses.
Read the docs before you talk to us
Guides for every chain and every failure mode, a reference generated from OpenAPI 3.1, and a sandbox that derives real addresses from a real xpub without touching a chain. Free and unmetered.
# free, unmetered, no chain contacted
curl -X POST $EDGE/v1/sandbox/simulate-deposit \
-H "X-API-Key: zkl_test_…" \
-d '{ "address": "0x3fC9…7FAD",
"chain": "eth",
"amount": "100.50",
"autoConfirm": true,
"confirmAfterSeconds": 5 }'
# → deposit_detected, then deposit_confirmed at 12