Skip to main content

XRP

Slugxrp
Address formatBase58Check, r… (classic address)
Account pathm/44'/144'/0'its own, not shared
Cloud storesxpub
DerivationM/0/{i} — public, no Edge required
Confirmations1 — deterministic finality at ledger close
Destination tagNone issued. See below
TokensNot supported
Explorerhttps://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 reserve1 XRP per funded account
Owner reserve0.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.

These are current values, not protocol invariants

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 earlier revision of this documentation said pre-funding was required. It was wrong.

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
baseFeeDrops12 drops nominal
openLedgerFeeDropsThe current load-adjusted figure
reserveDropsThe 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.