Skip to main content
An app token is a token you create and hand out for free: promo credit, a welcome bonus, or funds for exercising your money loop without spending real money. It is worth nothing outside your app, which is the point — you can give away as much as you like and it can never be cashed out. Bankroll shows it as your app’s funds, and charge() and pay() settle in it with the same calls they use for HSUSD. The only difference is one field.
An app token costs you nothing to create, so never release HSUSD-priced value for one. Check which asset actually paid, and pay back in the asset that paid. Below.

Mint it

Your token must be 9 decimals, with one token worth one dollar inside your app. That is the only shape charges settle in — Bankroll refuses any other scale before it signs, so this is not a preference. Create the mint with your treasury as the mint authority, and mint the supply to your treasury: it needs to hold the supply to pay anyone back.
Creating a mint costs about 0.0035 SOL in one-time, refundable account rent — supply is a number, so a million tokens cost the same as one. Skip the freeze authority: a token nobody can freeze is easier to reason about, and freezing your own users’ balances is a footgun.
The starter ships the CLI for this: npx bankroll token create --name "Acme Credits" does all of the above with the treasury key it already has, and writes the mint into app-tokens.json — the appTokens claim your manifest serves, which is what names the token inside Bankroll. The Metaplex metadata below is still yours to add: it is what names the token everywhere else.

Name it

A mint holds no name, symbol, or logo. Those live in a separate Metaplex metadata account, and spl-token create-token does not create one — you add it with a CreateMetadataAccountV3 instruction signed by your mint authority, pointing at JSON you host:
Bankroll does not read any of it — the wallet names your token from the appTokens entry in your manifest, so it displays correctly with or without this. Everywhere else does read it: with no metadata account your token is “Unknown Token” in explorers, in other wallets, and in your users’ own transaction history. Host the JSON somewhere you control long term; the URI is capped at 200 characters and changing it later costs an on-chain update, while editing the JSON behind a stable URI costs nothing.
Do not reach for Token-2022’s NonTransferable extension to stop people moving your token around. A charge settles as a transfer to your payment address, so a non-transferable token cannot be spent in your app at all — and you would lose refunds, support credits, and every treasury operation with it. Bankroll already refuses to buy, sell, or send app tokens in the wallet.

Declare it

Add the mint to your manifest under appTokens. This is what lets a charge settle in it, and what makes Bankroll show it as your app’s funds rather than an unattributed holding.
The keys are the mints. Declaring them is also a limit: Bankroll lets your app charge HSUSD or the mints you declared, and nothing else — so a page that gets hijacked can reach your own token, never a user’s unrelated holdings.

Charge in it

Name the mint on charge(). Omit token and the charge settles in HSUSD, as before.
The user sees which asset they are spending on the payment sheet, so a charge in your token is never mistaken for one in real money.

Check which asset paid

confirmCharge reports the mint that paid. Checking it is not optional. The signature is supplied by the client, so anything settled on-chain reaches your server — including a worthless token the sender minted themselves, which passes every other check.
Node.js

Pay it out

pay() takes the same field. Pay back in the asset that paid — if you sell something for tokens and pay out HSUSD, you have built a way to turn free credit into real money.
Node.js
Your treasury needs a balance of the token to pay out, the same way it needs HSUSD — mint yourself more whenever you like; you hold the mint authority.

What users see

A declared token appears in the user’s Bankroll wallet under App Tokens, with your app’s name and icon and the name you declared, valued at a dollar a token. It is grouped apart from tradeable holdings because that is what it is: money that spends in your app and nowhere else. Users only see it while your app is connected. Disconnect, and it becomes an ordinary token in their wallet.