The example app
A small Next.js app on mainnet that registers, deposits, pays privately and withdraws, and how to run it.
apps/nimbus-example is a small Next.js App Router app built on the SDK. It runs on mainnet with
real funds. It covers what every app needs: connect, register, deposit, Private Send, withdraw,
balances, history and recovery.
Each file is short and maps onto a page of these docs. Read them side by side.
Run it
The app lives in the Nimbus monorepo and uses the SDK from source. Build the SDK's WebAssembly and files first, then start the app.
Build the SDK and its files
From the repository root, install, then build the three WebAssembly modules the SDK ships:
pnpm install
just build-nimbus-primitives-wasm
just build-umbra-prover-wasm
just build-witness-graph-wasmThen build the SDK, and gather its files into its assets/ folder:
pnpm --filter "@umbra/nimbus-example^..." run build
pnpm --filter @umbra/nimbus-solana-web run build:assetsSet the environment
Copy .env.example to .env.local in apps/nimbus-example. Both settings are optional:
| Variable | What it does |
|---|---|
NEXT_PUBLIC_NIMBUS_RPC | A Solana RPC to use in place of the preset's public one. |
NEXT_PUBLIC_NIMBUS_GATEWAY_TOKEN | The gateway token every session sends. Without it, accounts open and read, and every payment fails unauthorized. |
Next.js writes both into the page, so every visitor can read the token. To get a token, email dev@umbraprivacy.com or reach out to any Umbra team member.
Copy the files and start
cd apps/nimbus-example
pnpm assets
pnpm devpnpm assets runs nimbus-solana-web copy-assets public/nimbus. next.config.mjs sends the two
cross-origin isolation headers with every route.
Its other scripts are pnpm build and pnpm start for a production build, and pnpm typecheck.
pnpm tokens rewrites the token list, as the table below explains.
Where each feature lives
| Feature | Files | Docs |
|---|---|---|
| Loading the SDK once, in the browser | components/app-provider.tsx, lib/nimbus/load.ts | Use it with React |
| Listing wallets and connecting one | components/connect-card.tsx | Wallets |
| Opening a session, and where its sign-in is kept | lib/nimbus/session.ts, components/connect-card.tsx | Sessions |
| Registering before the first deposit | components/account-gate.tsx, components/register-card.tsx, lib/nimbus/register.ts | Registration |
| Deposit, withdraw and Private Send on one card | components/action-card.tsx, components/flow-form.tsx | Deposit, Withdraw, Transfer |
| Each payment, in one small function | lib/nimbus/deposit.ts, lib/nimbus/withdraw.ts, lib/nimbus/private-send.ts | The function template |
| One description of a withdrawal or Private Send result | lib/nimbus/spend.ts | Results and errors |
| A message for each progress stage | lib/progress.ts, components/keep-tab-open.tsx | Show progress |
| Syncing, and balances grouped per token | components/use-account.ts, lib/nimbus/account.ts | Balances, Sync |
| Reserved funds with a Release button | components/balances-panel.tsx, lib/nimbus/account.ts | Reserved funds |
| History, ten entries a page | components/activity-list.tsx, lib/nimbus/history.ts, lib/activity.ts | History |
| A pending deposit, and a refund of a stuck one | components/recovery-card.tsx, lib/nimbus/recovery.ts | If the deposit is still pending |
| Token names and logos | lib/tokens.ts, scripts/fetch-tokens.ts | Tokens |
The token logos are saved under public/tokens/, because a cross-origin isolated page shows images
from another site only when that site allows it. pnpm tokens fetches them again when the preset's
tokens change.
What it leaves out
The example keeps to the basics. It runs only on mainnet, and asks each service directly rather than through the coordinator. It does not sync in the background. Use it with React shows how to add that.
Next
Last updated