Skip to main content

Wallet Balance

Wallet Balance answers a different question than the Ledger does. The Ledger is Ishtaran's own economic accounting — Available, Pending, Reserved, Payable, Delivered — populated exclusively by real Payment/Settlement/Payout flows. Wallet Balance is an observation of chain state: how many tokens actually sit, right now, at an Account's registered self-custody address. Simulated in Sandbox, real on-chain in Production.

Never sum the two, never substitute one for the other. An Account can have a large Ledger Payable and a Wallet Balance of 0 at the same time — nothing has been paid out on-chain yet. Or a wallet can hold funds the Ledger has no opinion about at all — its owner moved money in from outside any Ishtaran-mediated flow entirely.

A concrete example

Say an Account's wallet holds 100 USDT on-chain right now (Wallet Balance), while its Ledger shows Payable: 30, Reserved: 10, Delivered: 25 from unrelated Settlement activity. These are five separate numbers answering five separate questions — never add them together, and never report one as if it were the other:

FieldSourceQuestion it answers
Wallet Balance: 100 USDTObserved chain state"How many tokens sit at this address right now?"
Ledger Payable: 30Settlement (not yet paid out)"How much has Ishtaran settled to this Account but not yet moved on-chain?"
Ledger Reserved: 10Transaction reserve (in flight)"How much is locked against a Transaction still in progress?"
Ledger Delivered: 25Payout (already moved on-chain)"How much has Ishtaran already paid out to this Account historically?"

A Wallet Balance of 100 does not mean 30 of it is "the Payable"; the wallet may hold that 100 from a completely unrelated deposit, an earlier Payout, or funds moved in from outside Ishtaran entirely. Conversely, a Payable of 30 does not mean the wallet is guaranteed to show +30 once paid out — on-chain timing, network fees, and partial payouts all mean the two numbers move independently. Show both, labeled separately, never merged into one displayed balance.

Why this exists

Every Account with a registered ExecutionDestination already has a real, addressable wallet — Self-Custody requires one before any Settlement leg can execute. Wallet Balance answers the question that address itself always implicitly raises: "how much is actually there?" — without requiring a Settlement, a Withdrawal, or any other Ledger-affecting event to have happened first.

Reading a balance

  • Snapshot readGET /v1/accounts/{accountId}/wallet-balances returns the platform's last known observation: the address, the balance, when it was last observed, and whether that observation is stale. This call never itself queries the blockchain — safe to call on every page load.
  • Authoritative refreshPOST /v1/accounts/{accountId}/wallet-balances/refresh asks the platform to check the real chain state right now. The platform enforces its own short (~30 second) freshness/single-flight guard server-side — calling this more often than needed is always safe, never an error, never extra provider cost. Check the response's stale/ refreshSuppressed fields to see whether a real check actually happened.
  • Multi-asset aggregateGET /v1/accounts/{accountId}/wallet-balances/aggregate sums balance across several AssetNetworks the caller already knows about (for example USDT across multiple networks), grouped by Asset, with a per-network breakdown in the result. Never sums across different Assets.

Kept fresh automatically

The platform keeps a wallet's balance current on its own — a Settlement, Payout, or Withdrawal confirming under Self-Custody triggers an event-driven refresh for the affected address, alongside a periodic background reconciliation sweep. A client does not need to poll aggressively for correctness.

A client MAY independently observe a real chain itself (Production only — there is no independent chain to read against in Sandbox) as a cheap, optional signal for when to call the refresh endpoint sooner. That observation is only ever a hint: the platform always re-verifies for itself and never accepts a client-reported balance as authoritative.

Send vs Pay

Both move funds out of a wallet, but they mean structurally different things to the platform:

  • Send is a direct, sender-initiated wallet-to-wallet transfer. It never creates a Transaction, PaymentIntent, or Settlement — it's a peer paying another peer, full stop.
  • Pay is the fulfillment of an existing Payment Request (a PaymentIntent tied to a specific Transaction). It drives the real Transaction → PaymentIntent → Settlement pipeline described in Transaction, Settlement, Split, and Refund — Split, Fee, and Ledger accounting all apply the way they do for any other Settlement.

A request to preview what a payment will cost (fees, recipient amount) should never, by itself, create anything real — no Transaction, no PaymentIntent. Only an explicit confirmation should move to Pay's real pipeline.

Receive

Receiving is not a distinct capability so much as two different things an Account can do:

  • Accept a direct Send — nothing to set up in advance; any registered self-custody address can receive a transfer.
  • Issue a Payment Request — create a PaymentIntent ahead of time (an amount, an optional description, an expiry) so a payer can fulfill it via Pay. The payer never needs an account relationship with the requester beyond the shared Transaction the request represents.

Routes