> ## Documentation Index
> Fetch the complete documentation index at: https://docs.joinbankroll.com/llms.txt
> Use this file to discover all available pages before exploring further.

# An existing app

> Add Bankroll to a Next.js app you already have — the SDK, the manifest, sessions, money, and the recovery files worth copying from the starter.

The [starter](https://github.com/inplayinnovation/bankroll-starter) is a
reference, not a requirement. An app you already run becomes a
Built-for-Bankroll app by serving a manifest and verifying sessions — this page
is that path for Next.js. On another stack, the [Quickstart](/build/quickstart)
shows the same steps framework-free.

## 1. Install

```bash theme={null}
npm install @joinbankroll/sdk
npm install -D @joinbankroll/cli
```

The CLI is for the [dev loop](/build/dev) and your [app tokens](/build/app-tokens);
the SDK is everything else.

## 2. Serve the manifest

One route file, and the SDK owns the format:

```ts app/.well-known/bankroll.jwt/route.ts theme={null}
import { manifestRoute } from "@joinbankroll/sdk/next";
import { treasuryAddress } from "@joinbankroll/sdk/server";

export const dynamic = "force-dynamic"; // built from the request's own host

export const GET = manifestRoute({
  name: () => "Acme Games",
  launch: "/app",              // where the host boots the app; "/" serves your site
  payments: treasuryAddress,   // null until a treasury key is set — declared once it exists
});
```

See [The manifest](/build/manifest) for every claim, and serve a square PNG at
`/.well-known/bankroll-icon.png` when you have one.

## 3. Verify sessions

Every route that matters reads the user from the verified token, never from the
request body:

```ts theme={null}
import { requireSession, requireIdentity, Unauthorized } from "@joinbankroll/sdk/next";

export const dynamic = "force-dynamic";

export async function POST(request: Request) {
  const session = await requireSession(request); // throws Unauthorized
  requireIdentity(session);                      // real money moves only for a verified person
  // session.user.wallet — the user's stable id, and payout target
}
```

On the client, [`bankrollFetch`](/build/react) (or
[`withBankrollToken(fetch)`](/build/session#send-it-to-your-server)) attaches
the token to every request.

## 4. Move money

The client calls [`charge()`](/build/payments); your server confirms with
`confirmCharge()` and checks **payee, mint, amount, and payer** before
releasing value, then records the signature so it can never be redeemed twice.
Payouts are [`pay()`](/build/payouts) from your treasury. If you already run a
database, a `UNIQUE` column on the signature is the replay guard; if you don't,
[the store](/build/store) exists so you don't have to provision one.

## 5. Copy the recovery machinery

A charge whose page dies before reporting back still settled — money at your
address that nothing points to. The pattern that recovers it (an intent written
before the charge, a `reference` carried on-chain, a sweep that finds what was
never reported) is described in
[Payments](/build/payments#recovering-a-lost-charge), and the starter ships a
working implementation. It is app code rather than SDK code today — copy it
(MIT) rather than rewrite it:

| Copy                    | What it is                                                                                    |
| ----------------------- | --------------------------------------------------------------------------------------------- |
| `src/lib/charges.ts`    | The settle checks both paths share — live and swept payments get identical scrutiny.          |
| `src/lib/store.ts`      | One document per charge and per intent, with the atomic create that is also the replay guard. |
| `src/lib/sweep.ts`      | Finds charges that settled without being reported, by their reference.                        |
| `src/app/api/charges/…` | The three routes: start an intent, confirm and list charges, pay one back out.                |

Adapt `charges.ts` to your own price and product; the shape is the part worth
keeping.

## 6. Wire the dev loop

`bankroll dev` tunnels your dev server so a phone can reach it (see
[Local development](/build/dev)). Next.js blocks cross-origin hot-reload by
default, so allow the tunnel in `next.config.ts`:

```ts theme={null}
const nextConfig: NextConfig = {
  allowedDevOrigins: ["*.trycloudflare.com"],
};
```

Then `npx bankroll dev` — or make it your `dev` script, as the starter does.
