@joinbankroll/sdk. This page is the per-version history — check it to see when a feature landed or what changed between the version you have and the latest. Install the latest with:
August 19, 2026
haptics() — the physical half of your UI. bankroll.haptics({ type })
plays a typed vibration through the phone’s engine: impacts (light / medium /
heavy), outcomes (success / warning / error), or selection. An omitted
or unknown type plays the host default, a heavy impact.Decoration only, so unlike every other capability it never rejects — in a
plain browser, under an old host, or on any bridge failure it resolves having
done nothing. Needs a Bankroll host at client version 4+, feature-detected; no
new manifest claim, and no re-consent for already-connected apps.Offers on your tile. Serve /.well-known/bankroll-status
and Bankroll rings your tile with your headline when you have something on
offer for the person asking — per user when they’ve connected you, your
generic new-user offer when they haven’t. Opening from the offer hands its
key back to your app as ?offer=. Decorative only; nothing to install.Bankroll Verified. The green ✓ after an app’s name means Bankroll reviewed
what the origin serves and signed its manifest. What it means, what it
unlocks, how to get it — and it is now what makes play in
your app count toward a friend’s referral.Referral links, in numbers. Share links now state the
program your playLink({ referrer }) feeds: new user attributed at signup, 10 each to both sides — and $10
to a verified app’s treasury per qualifying referral from its links.August 18, 2026
Know a payout’s signature before you broadcast it.
buildAndSignPayout() builds and signs
in one call, returning the transaction, its deterministic signature, and its
expiry with nothing sent — so your payout row stores the signature in the same
write that locks it, and recovery is always a question the chain can answer.
signPayout() does the signing half for bytes you built separately, and a
custom PaymentSigner can opt in with signTransaction.Purely additive — no existing call changes behavior. The payout lifecycle docs
now teach the full order: build → sign → store → send → confirm.August 18, 2026
iconDigest on manifestRoute. manifestRoute()
takes an optional iconDigest — a Subresource Integrity hash of your icon’s
bytes. A changed digest is a manifest change, which is what carries a
replaced icon to users who
already connected. Omitted, like supportUrl, whenever it resolves to nothing.August 18, 2026
Find a charge your page never reported.
createReference()
mints an id your server stores with the order and passes to charge(). The
payment carries it on-chain, so when the page dies between the charge settling
and the request that would have reported it,
findChargeByReference() still
finds the charge — by an id that existed before it did. ConfirmedCharge now
carries the payment’s signature, so a recovered charge settles through the
same code as a reported one.expiresInSeconds bounds a stale
price. A charge left sitting on the pay sheet rejects charge_expired rather
than settling against a price that has moved — nothing signed, nothing moved.
It defaults to 90 seconds, and the host counts it down on the sheet.Passing a reference needs a current Bankroll app — older ones reject with
update_required.August 13, 2026
sendPush() — notify your users through Bankroll. From your server, sign a
short-lived request with your push key and Bankroll delivers a notification to
one of your users, titled with your app’s name; tapping it opens your app at
the path you choose. pushAddress() derives the public key your manifest
declares — manifestRoute’s new push entry.Push is permissioned: it works once Bankroll has signed your manifest, which
attests the key, and only toward users who have opened your app. The push key
is its own secret (BANKROLL_PUSH_KEY) — pushing and paying are different
powers, so it is deliberately not the treasury key.August 13, 2026
Share links carry a referrer.
playLink(url, { referrer })
appends the wallet of the Bankroll user sharing the link, so an app can
piggyback on Bankroll’s referral program instead of building its own — pass
session.user.wallet and a new Bankroll user who opens the link is attributed
to them.The referrer must be a real Bankroll user’s wallet; the program is person to
person, so an app’s own treasury is attributed to nobody. An unrecognized
referrer costs the attribution, never the link.August 7, 2026
balances() and deposit() — prerelease. bankroll.balances()
returns your app’s view of the user’s value — their cash, your app’s credits,
and the balances of every mint your manifest declares. bankroll.deposit()
presents the host’s deposit UI, optionally preselecting a funding source.Both are feature-detected and need a current Bankroll host; an older one rejects
with update_required. Prerelease — the contract may still change.July 31, 2026
supportUrl on manifestRoute. manifestRoute()
takes an optional supportUrl and omits the claim when it resolves to nothing —
an empty claim is still a claim, and would re-ask every connected user for
consent once it gained a value.July 29, 2026
Breaking:
publicOrigin() is gone. It read BANKROLL_DEV_TUNNEL_ORIGIN so a
development landing page could render a link a phone could reach; in production
it was getOrigin() with extra steps. Call getOrigin().Removing it is what lets the development CLI start your server first and read
launch from your live manifest, so the QR code it prints opens your app rather
than your landing page.July 28, 2026
Breaking:
manifestRoute’s appTokens is a map. It took a single mint; it
now takes Record<mint, { name?, description? }>, matching the
manifest claim and letting an app issue several tokens
that each carry their own display strings.July 28, 2026
Three new entry points, all optional — the pieces every Built-for-Bankroll
app was writing itself.
@joinbankroll/sdk/next—getOrigin(),getSession()/requireSession(),requireIdentity(), andmanifestRoute(), which serves/.well-known/bankroll.jwtso you never hand-assemble the format. Plus the treasury:treasuryAddress()derives your payment address fromBANKROLL_TREASURY_KEY, so what your manifest advertises can’t drift from the wallet that signs.@joinbankroll/sdk/store— durable JSON with an atomic create and compare-and-swap, so a payment signature can’t be redeemed twice without provisioning a database. Filesystem and Vercel Blob backends behind one interface;@vercel/blob(>= 2.3.0) is an optional peer.@joinbankroll/sdk/react—useBankrollStatus()/useBankrollChecked()that agree across hydration,bankrollFetch,verifyIdentity(), and a development overlay.react(>= 18) is an optional peer.
SOLANA_RPC_URL is now optional. Unset, the server half falls back to
Solana’s public endpoint and warns once per process instead of failing, so an app
can take its first payment before configuring an RPC. usingPublicRpc() reports
whether the fallback is in play.July 25, 2026
App tokens.
charge() and pay() take an optional token — a mint you issue yourself, declared in your manifest’s appTokens — so you can sell and pay out in your own promo credit with the same calls you use for real money. Declaring your mints is also a limit: your app can charge HSUSD or those mints, and nothing else.Every asset a charge settles in carries HSUSD’s scale — 9 decimals, one token to the dollar — so amounts stay in whole US cents throughout. Bankroll refuses a mint of any other shape before it signs.July 24, 2026
iconDigest manifest claim. Added the OPTIONAL iconDigest claim — a Subresource Integrity hash (sha256-<base64>) of your icon’s bytes. Declare it so a replaced icon reaches users who have already connected your app, instead of staying cached.July 20, 2026
ConfirmedCharge.slot. confirmCharge() now returns the slot the transfer landed in — a chain-assigned, monotonic number. Use it as a stable ordering key for a purchase listing without giving up signature-keyed idempotency.July 20, 2026
More reliable payout reconciliation.
confirmPayout() now searches the transaction ledger instead of only the recent status cache, so confirming a long-since-landed payout resolves correctly.When you reconcile old payouts, confirm against an endpoint with full transaction history — a pruned endpoint can report a landed transaction as
expired, and paying again on that signal would double-pay.July 19, 2026
Dependency hardening. Inlined the token-transfer instructions the SDK builds, removing a transitive dependency that carried an unfixable security advisory. No API changes.
July 18, 2026
Payout lifecycle. The single-call payout became a three-step lifecycle —
buildPayout → sendPayout → confirmPayout — with a caller-owned payout-row state machine (created → submitted → confirmed | failed | expired) and confirmPayout() as the reconciliation primitive. pay() remains as their composition.July 18, 2026
Server-side charge confirmation, and paying a user.
- Added
confirmCharge(signature)— read a settled charge’s facts from chain ({ payer, payee, amountCents, memo }) and verify them before releasing value. - Added a server payout:
pay({ to, amountCents, memo? }, { signer }), signed with aPaymentSigner—keypairSigner(secretKey)orprivySignerfrom@joinbankroll/sdk/privy.
July 16, 2026
Charge error codes. Added
idempotency_conflict (an idempotencyKey reused with different parameters) and payment_denied (the host declined at the pay sheet), and documented idempotencyKey on the charge input.July 14, 2026
session(). The identity capability is now session(); identity() remains as a deprecated alias for older hosts. Added the BankrollSession type on the server entry.July 9, 2026
Initial release. The Build-on-Bankroll client and server-side session-token verification (
verifyToken).