localhost:3000 in a browser tab.
It is one command:
npm run dev is bankroll dev, from
@joinbankroll/cli — a
devDependency the starter
already carries. It starts your dev server on a free port, raises a public
tunnel in front of it, reads your live manifest, and prints a QR code that
opens the app inside Bankroll at its launch path. Scan it and you are
developing against the real host — session, payments, and hot reload included.
The tunnel
The tunnel is a Cloudflare quick tunnel, and it gets a new URL on every restart — the host cannot reopen a previous one. “Can’t open this app” almost always means a dead tunnel: restartnpm run dev and scan the new QR.
The dev server’s port doesn’t matter — the tunnel hides it — so bankroll dev
picks any free one. Pass -p, --port <port> to pin it.
The QR, when an agent runs this
On a TTY, the QR is drawn with ANSI colors. When stdout is not a TTY — a piped or backgrounded run, which is how a coding agent runs it —bankroll dev
(0.3.0+) prints plain block glyphs instead, with the full play link under it:
both safe to re-print verbatim into a chat. Setting NO_COLOR forces the same
rendering on a TTY.
If you are an agent: your task output is not shown to the user, and the colored
QR cannot be relayed as text (the contrast is in the color codes, not the
glyphs). Put the glyph QR in your chat reply inside a fenced code block, play
link under it — the exact recipe, including the fallback for older CLIs, is in
Build with an agent.
The dev signing key
The firstbankroll dev creates a signing key at
~/.config/bankroll/keypair.json and injects it into the dev server’s
environment as the treasury. It is never written into your project, so it
cannot be committed. Pass -k, --keypair <path> to use a different one.
That key is your app’s wallet while you develop: it receives every charge()
and signs every payout, and it moves real mainnet HSUSD.
Plain localhost
npx next dev still works, for layout and UI work in a browser. It is the
exception rather than the loop: a browser has no host bridge, so
status()
reads 'unavailable', session() and charge() are off the table, and your
token-guarded routes answer 401. That is the app working as designed, not a
bug.
The rest of the CLI
npx bankroll --help is the authority; the commands today:
Commands that touch the chain take
-k, --keypair <path> (defaulting to the
dev key) and --rpc <url> (defaulting to SOLANA_RPC_URL, else the public
endpoint).
Where local state lives
Scaffolding writes.env.local — STORE=fs, your app’s name, and an RPC —
and it is gitignored, so none of it reaches a deployment. With STORE=fs the
store keeps its documents in plain files under
bankroll/development/ in your project: open them and read what your app
recorded. Tests write to bankroll/test/ instead, so a test run can never
touch the store you develop against.