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.
balances()
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.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.
deposit()
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 ascreditsCents 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 letcharge() be the thing that moves money.
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.