Skip to content

docs(graphql): state units and nullability for Wallet.balance - #512

Merged
islandbitcoin merged 3 commits into
mainfrom
docs/wallet-balance-units
Sep 23, 2026
Merged

islandbitcoin merged 3 commits into
mainfrom
docs/wallet-balance-units

Conversation

@islandbitcoin

Copy link
Copy Markdown
Contributor

Why

Sweep finding Backend 16: every Wallet.balance is typed FractionalCentAmount, including BTCWallet, whose description says "A balance stored in BTC." The generated API reference and guides/examples.md ("sats for BTC") imply units the API does not return.

What the code does (origin/main cbd9e26aa)

Type Resolver Value on the wire Null?
UsdWallet shared/types/object/usd-wallet.ts cents float, asCents(8); USDT-backed balances go through usdtMicrosToUsdCents null when type === External
UsdtWallet usdt-wallet.ts cents float, up to 4 decimal places (usdtMicrosToUsdCents) no null branch
BTCWallet btc-wallet.ts null for external wallets. For a non-external BTC wallet it returns the USDAmount object from getBalanceForWallet unconverted (see below). null when type === External

No path returns sats. getBalanceForWallet → Ibex.getAccountDetails → parseAccountBalance yields USDAmount.dollars(...) for any currency except USDT.

Change

Descriptions only, on Wallet.balance, BTCWallet.balance, UsdWallet.balance and UsdtWallet.balance. The FractionalCentAmount scalar description is shared with inputs, so it is unchanged. There are no type, nullability or resolver changes, so flash-mobile is unaffected (the diff in the regenerated schema files is description lines only).

Not changed: needs a decision

A non-external BTC wallet would serialize balance as an object ({"money":["12.34","USD"],"currencyCode":"USD"}), not a float. I confirmed this with graphql 16.14.2 default scalar serialization, using a stand-in object shaped like USDAmount. On main, account creation only creates Checking wallets for initialWallets (default ["USD","USDT"]) plus the required cash currencies, and BTC wallets are only created through upsertExternal. So I did not find a live path to this, but I could not check data: the read-only Mongo MCP failed to connect, and I have not queried TEST or PROD. Fixing it would be a behavior change and is out of scope here.

Validation (commit 7bde387)

  • yarn write-sdl: regenerated public, admin and supergraph schemas
  • yarn tsc-check: pass
  • yarn eslint-check: pass
  • yarn check:sdl: pass

🤖 Generated with Claude Code

bobodread876 and others added 3 commits September 15, 2026 12:04
Every wallet balance resolves in US cents (FractionalCentAmount), not
sats, and external wallets return null. The BTCWallet description
claimed a BTC-denominated balance. Descriptions only; no wire type or
resolver change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Do not promise a float for every wallet type: a non-external BTC wallet
resolves an unconverted amount object, and UsdtWallet has no external
null branch. Point readers to the concrete wallet type instead.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Review fix: the description promised up to 4 decimal places, but the
resolver's USDAmount branch returns up to 8. State both cases explicitly
and regenerate the SDL files via yarn write-sdl.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@islandbitcoin
islandbitcoin merged commit b637343 into main Sep 23, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants