HD derivation
Everything ChainOS issues comes from one BIP-39 mnemonic through BIP-32 hierarchical deterministic derivation. This page is the reference for the paths, and the explanation of the one asymmetry the whole product rests on.
The asymmetry
A BIP-32 extended key is a key plus a 32-byte chain code. From an extended private key you can derive child private keys and child public keys. From an extended public key you can derive child public keys — and therefore addresses — but not child private keys.

Ziklag Cloud is given the bottom row, and nothing else.
Cloud holds the bottom row. It can derive every address you will ever issue and cannot produce a single signature. That is arithmetic, not a policy Ziklag adopted.
The one caveat: this only holds for non-hardened child derivation. Hardened
derivation (paths with ') deliberately requires the parent private key, which is why the
account level is hardened and the branch below it is not.
The paths
| Chain | Account path | Curve | Cloud stores | Public derivation |
|---|---|---|---|---|
| Bitcoin | m/84'/0'/0' | secp256k1 | zpub | ✅ M/0/{i} |
| Ethereum | m/44'/60'/0' | secp256k1 | xpub | ✅ M/0/{i} |
| BSC | m/44'/60'/0' | secp256k1 | shares Ethereum's | ✅ M/0/{i} |
| Polygon | m/44'/60'/0' | secp256k1 | shares Ethereum's | ✅ M/0/{i} |
| Avalanche | m/44'/60'/0' | secp256k1 | shares Ethereum's | ✅ M/0/{i} |
| Base | m/44'/60'/0' | secp256k1 | shares Ethereum's | ✅ M/0/{i} |
| TRON | m/44'/195'/0' | secp256k1 | xpub | ✅ M/0/{i} |
| XRP | m/44'/144'/0' | secp256k1 | xpub | ✅ M/0/{i} |
| Solana | m/44'/501'/{i}'/0' | Ed25519 | address pool | ❌ Edge only |
| Stellar | m/44'/148'/{i}' | Ed25519 | address pool | ❌ Edge only |
| Edge identity | m/83696968'/0'/0' | Ed25519 | public key only | ❌ Edge only |
Bitcoin uses BIP-84 (84') because ChainOS issues native segwit addresses; the other
secp256k1 chains use BIP-44.
83696968' is BIP-85's namespace — the standard for deriving other keys from a BIP-32
master — which is where the Edge identity key belongs rather than in a coin-type slot.
Coin types are not interchangeable
ETH, BSC, Polygon, Avalanche and Base genuinely share m/44'/60'/0', so one extended public
key serves all five and one address receives on all five. That is correct and intended.
Note that this is a fact about the coin type, not a list of five chains somebody maintains. Avalanche and Base make the point from opposite ends: one is not an Ethereum network at all — separate L1, separate consensus, separate validators — and the other is a rollup that settles to Ethereum. Neither needed derivation code of its own; both joined by declaring the same path. Sharing an address model is not sharing a chain, and it is emphatically not sharing a balance: the same address holds ETH on Ethereum, AVAX on Avalanche and a different ETH balance on Base, and funding any one does nothing for the others.
Base is the case where that is easiest to miss, because it shares Ethereum's asset symbol as well as its address — see Base.
TRON at 195', XRP at 144' and Stellar at 148' do not share it, and treating any
of them as if they did would be a serious bug: an aliasing defect in a key-derivation
library once made TRON's extended public key byte-identical to Ethereum's, which would have
monitored TRON deposits at a key derived for a different chain. There is now a contract
test that asserts both the sharing and the not-sharing, because "these three are the same
and those three are not" is exactly the kind of invariant that decays silently.
The two branches
The child index after the account level is the BIP-44 change branch:
M/0/{i}— receive. Every customer deposit address. Cloud allocates the nextifrom a per-account, per-chain counter.M/1/0— change. Where the gas tank lives, one per chain, carryingrole = gas_tankin the address table.
Putting the tank on the change branch is structural rather than conventional: Cloud only ever derives the receive branch when allocating an address, so a tank is impossible to issue to a customer by accident. Reusing a deposit address for it would attribute gas spend to a customer and make reconciliation report a permanent discrepancy against them, and it would put two contradictory policies on one address — a sweep wants to empty a deposit address, and a tank must never be emptied.
Why Solana and Stellar have pools
Ed25519 has no public-key-only child derivation. There is no such thing as a Solana or a Stellar extended public key, so Cloud cannot derive addresses on either chain at all — not as a limitation of this implementation, but as a property of the curve. The two chains take the pool path for one reason, and the code selects it on the curve rather than on the chain, which is why a third Ed25519 chain would need no new mechanism.
So the Edge derives a batch of addresses per pooled chain (1000 by default, EDGE_POOL_SIZE), sends the
public addresses to Cloud, and Cloud allocates from that pool with
SELECT … FOR UPDATE SKIP LOCKED — which is what lets a hundred concurrent allocations
produce a hundred distinct addresses without serialising the table.
The two pools are independent: separate index sequences, separate low-water thresholds, and different path shapes. Solana's index sits at the account level with a further change segment below it, while SEP-0005 stops at the account — so index 7 on one chain has nothing to do with index 7 on the other. Both are fully hardened, which Ed25519 requires.
When a pool drops below 20% the readiness indicator for that chain turns orange and Cloud
asks the Edge for more over the open stream. If no Edge is connected and the pool is
exhausted, allocation fails with 423 EDGE_OFFLINE rather than issuing an address nobody
holds a key for.
Practical consequence: Solana and Stellar address issuance needs a live Edge; the other seven chains do not. See Solana and Stellar.
derivationPath is absolute
Every address reports its full path from the master:
{ "address": "bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu",
"derivationPath": "m/84'/0'/0'/0/0" }
Absolute, not M/0/0. A relative path is expressed against an account extended public key
you never receive, so it cannot be used to recover a key — which defeats the only reason
this field exists.
Recovering funds without ChainOS
This is the property that makes the whole arrangement safe to depend on. With your mnemonic
and an address's derivationPath, any standard BIP-32 tool recovers the key. No ChainOS,
no Ziklag, no API.
# Export your addresses and their paths first — while you still have an account.
curl -s "$EDGE/addresses?size=1000" \
-H "X-API-Key: $CHAINOS_EDGE_KEY" \
| jq -r '.data.content[] | [.chain, .address, .derivationPath, .userRef] | @csv' \
> chainos-addresses.csv
Keep that export beside your mnemonic backup and refresh it periodically. The mnemonic alone is enough to recover funds, since the paths are deterministic and documented above; the export is what lets you recover the mapping from address to customer, which is yours and which ChainOS is the only holder of.
Then, offline, with a tool of your choosing:
mnemonic + "m/84'/0'/0'/0/0" → private key → sign → broadcast
The two Ed25519 chains recover the same way, with one caveat: their paths are fully hardened
and the key derives under SLIP-0010 rather than BIP-32's secp256k1 rules. Any Solana or
Stellar wallet that accepts a BIP-39 mnemonic and a custom path — m/44'/501'/{i}'/0' and
m/44'/148'/{i}' respectively, the latter being SEP-0005 — does this correctly.
Address reuse
One address per customer per chain, indefinitely. ChainOS does not rotate deposit addresses, because a fintech's customer keeps the account number they were given and a rotating deposit address produces deposits to addresses your customer saved months ago.
All ten chains work this way, including XRP and Stellar — see XRP for why that is a change from an earlier revision that used one shared account with destination tags, and Stellar for the same argument made against memo IDs.
Further reading
- Non-custodial — what the asymmetry above does and does not buy you.
- Mnemonic management — generating, storing and rotating.
- Identity rotation — what happens when the mnemonic changes.
- Solana — the pool in operational detail.