XRP
| Slug | xrp |
| Address format | Base58Check, r… (classic address) |
| Account path | m/44'/144'/0' — its own, not shared |
| Cloud stores | xpub |
| Derivation | ✅ M/0/{i} — public, no Edge required |
| Confirmations | 1 — deterministic finality at ledger close |
| Destination tag | None issued. See below |
| Tokens | Not supported |
| Explorer | https://xrpscan.com/tx/{txid} · https://xrpscan.com/account/{address} |
A unique address per customer, and no destination tag
This is a deliberate change from an earlier revision of this build, and it goes against how most exchanges do XRP, so it is worth the explanation.
The common XRP model is one funded account with destination tags distinguishing customers. It exists because every funded XRP account costs a base reserve, so one account for a million customers is much cheaper than a million accounts.
That argument was built on a reserve of 10 XRP. The reserve reduction that activated in late 2024 cut the base reserve to 1 XRP and the owner reserve to 0.2 XRP — so the cost figure the shared-account design was justified by was inflated tenfold.
At 1 XRP the trade goes the other way:
- A shared address couples every customer's deposits to one key.
- A per-customer sweep becomes impossible without moving everyone's funds through the same account.
- The burden of sending a correct tag falls on the depositor, and an untagged deposit is unattributable — which is a support problem with real money attached, and one you cannot resolve from the chain.
So ChainOS issues a unique address per customer on XRP like everywhere else, and emits no destination tag. A tag ChainOS did not ask for is a tag a depositor can safely omit.
{ "chain": "xrp",
"address": "rQ3fB7…",
"derivationPath": "m/44'/144'/0'/0/0",
"destinationTag": null }
destinationTag is present in the payload and always null. If a depositor sends one anyway it is
recorded and ignored.
The reserve
| Current value | |
|---|---|
| Base reserve | 1 XRP per funded account |
| Owner reserve | 0.2 XRP per owned ledger object |
An XRP account holding less than the base reserve is not activated and cannot receive.
The owner reserve is per object, not a flat addition. A plain address that owns nothing has a reserve of exactly 1 XRP; it becomes 1.2 once the address holds one trust line, which happens only if issued currencies are involved — and ChainOS does not support them, so in practice your addresses carry exactly 1 XRP of reserve.
ChainOS reports it:
{ "confirmed": "2000000", "available": "1000000", "reserved": "1000000", "decimals": 6 }
Those are drops: 1 XRP is 1,000,000 drops. Read available when deciding whether a send can
proceed; a send that would breach the reserve is refused with INSUFFICIENT_RESERVE.
The base and owner reserves are set by validator vote and have changed by amendment before —
which is exactly how they got to 1 and 0.2. server_info carries the live figures, and ChainOS
reads them when a spend decision depends on it. Do not hardcode 1 XRP in your own logic.
Reconcile against confirmed, not available, or every XRP address will report as 1 XRP short
forever. See Reconciliation.
No pre-funding needed — and a minimum first deposit
An XRP account does not exist until it is funded, and the payment that creates it must carry at least the base reserve. So:
- A first deposit below 1 XRP fails at the sender's end with
tecNO_DST_INSUF_XRP. The funds do not arrive and are not lost — the payment simply does not execute. - Every subsequent deposit of any size succeeds.
The depositor's own payment creates the account. What you need is therefore a published minimum first deposit — which is what exchanges do — not pre-funding.
Pre-funding each address instead would immobilise 1 XRP per address indefinitely. Ten thousand addresses is ten thousand XRP locked up for nothing.
State the minimum wherever you show an XRP deposit address, and state it as slightly above 1 XRP so a fee or a rounding difference does not make a first deposit fail at exactly the boundary.
address_activated
XRP is the reason this event exists. It fires when an address is funded past the reserve and becomes usable — which on XRP is a distinct on-chain state change rather than an implicit one.
Stellar makes the same distinction, for a stricter reason: an unfunded Stellar account does not exist on the ledger at all, so there the event marks the moment a first payment created the account.
On the other seven chains the same event fires on first use, where it is informational. On XRP and Stellar it is the signal that a customer's address is now able to receive.
Fees
fee = 12 drops, load-adjusted
| Field | |
|---|---|
baseFeeDrops | 12 drops nominal |
openLedgerFeeDrops | The current load-adjusted figure |
reserveDrops | The reserve, so the caller does not have to look it up |
Twelve drops is 0.000012 XRP — effectively free. Under load the open-ledger fee rises, sometimes sharply, and a transaction submitted below it queues rather than failing.
The fee is paid in XRP by the sending address. Since XRP is also the only asset on this chain, the
INSUFFICIENT_GAS case cannot arise — a shortfall is INSUFFICIENT_FUNDS or
INSUFFICIENT_RESERVE.
Confirmations
One. XRP has deterministic finality at ledger close, roughly every three to five seconds. A validated ledger does not reorganise, so there is no depth argument to make.
deposit_detected and deposit_confirmed therefore arrive close together, and a fintech can
reasonably credit on the second within seconds of a deposit.
No tokens
Issued currencies, trust lines, the AMM and the DEX are all out of scope. XRP support is the native asset only, which is why your addresses hold no ledger objects and carry exactly 1 XRP of reserve.
A trust line established against one of your addresses by a third party would add 0.2 XRP of owner reserve. ChainOS reports the reserve it reads rather than assuming, so this shows up correctly if it happens.
Operational notes
- Classic addresses, not X-addresses. ChainOS issues and accepts the
r…form. An X-address (X…) encodes a destination tag into the address, which is precisely the model this build moved away from; one supplied as a withdrawal destination fails validation. - Deleting an account to reclaim its reserve requires a 2 XRP fee and a sequence-number condition, which makes it uneconomic at a 1 XRP reserve. Do not plan on recovering reserves.
- Emptying an address below the reserve is refused, not "closed". A sweep must leave the 1 XRP. See Sweeps.
- XRP is one of the six chains with no configured RPC endpoint in the current deployment.
Derivation works; balances, fees and broadcast return
503 CHAIN_UNAVAILABLE.