Skip to main content
charge() already handles a user who is short — Bankroll prompts them to add funds and your call rejects insufficient_funds. These two calls are for the cases where your app wants to act before that: show what the user has, and offer to top up on your own terms.
Prerelease. balances() and deposit() are still settling and their contract may change. Both need a current Bankroll host and are feature-detected, so an older one rejects with update_required rather than throwing — treat that as “this user can’t do it yet” and fall back to the flow you’d have shipped without them.

balances()

Your app’s view of the user’s value — and only yours. Undeclared mints and other apps’ credits are unreachable by construction, so this can’t be used to survey what a user holds elsewhere.
amount is whole tokens, not cents. App tokens are 9-decimal and one token to the dollar, so amount: 12 is twelve Acme Chips. The two cents fields are cents. Cents are truncated down — never show a user money they don’t have.
A mint you declare that the user has never held reads 0 rather than going missing, so you can render every token in your manifest without a presence check. name comes from your own manifest entry, which is what keeps a token’s display name consistent whether Bankroll or your page draws it. The host answers from the balance store it already keeps live — the same numbers its wallet renders. The call costs no upstream fetch, so polling it as a display heartbeat is fine.
This is a display value, read from the client. Never price an order, settle a bet, or release value against it. What a user can pay is decided by whether their charge() settles, and what they’re owed is decided by your own records — see Confirm on your server.

deposit()

Presents the host’s deposit UI. It resolves once the modal is presented — not when money arrives. The deposit itself runs in native UI and settles long after this call returns, so treat a resolved deposit() as “the user is now looking at the deposit sheet” and nothing more. To notice funds landing, read balances() again when the user comes back. method preselects a funding source. It is a hint: the host validates it and falls back to its default when the value is unknown or the user isn’t eligible, so an unrecognized string opens the sheet rather than failing. A coming-soon value is accepted today — the sheet opens on the host’s default source until that method ships, at which point the same preselection starts working with no change on your side.

App credits

For an app with credits, every card purchase opened from your app settles as your app’s credits: value scoped to your app, shown in the user’s wallet as yours, and readable back as creditsCents in balances(). There is nothing to select — card does it. The other sources (Cash App, an on-chain transfer, and the coming-soon set) top up the user’s own cash. This requires Bankroll to have provisioned credits for your app — a per-app setup on Bankroll’s side, keyed to your origin; contact the Bankroll team. Without it, the card sheet still opens but the purchase does not settle to your app. The resolution is always from your app’s verified origin, never from anything your page passes — so a page cannot route a purchase into another app’s account.

Together

The pattern these are for: decide with your own numbers, offer the top-up, and still let charge() be the thing that moves money.
Handle update_required from either call by skipping the pre-check entirely: charge() alone works on every host, and its insufficient_funds rejection already sends the user to add funds.