Get started
Project structure
Every file a full-stack scaffold creates, what it does, and which ones are yours to change.
This is what --starter full-stack --capabilities wallet-login,signed-requests writes, minus create-vite's own assets and lint config. Other starters produce a subset: react is the client/ half at the project root, and express is the server/ half.
The tree#
my-app/
├── AGENTS.md # how each capability works, for humans and AI agents
├── bsv-scaffold.json # what was generated (read by later `add` runs)
├── package.json # root runner: dev, build, install:apps
├── scripts/
│ └── run-apps.mjs # starts client + server together
├── client/ # Vite + React + TypeScript (from create-vite)
│ ├── package.json
│ ├── vite.config.ts
│ └── src/
│ ├── main.tsx # wraps <App/> in <WalletProviders>
│ ├── App.tsx # routes: /, /login, /signed-demo
│ └── bsv/
│ ├── config.ts # API_BASE_URL, BSV_NETWORK (from VITE_* env)
│ ├── apiClient.ts # the one fetch wrapper: bounded, no redirects
│ ├── auth.ts # createAuthProof / verifyAuthProof
│ ├── serverIdentity.ts # getServerIdentity() → GET /api/identity
│ ├── walletAcquisition.ts # desktop wallet via WalletClient('auto')
│ ├── WalletConnectionContext.tsx # mobile QR relay session
│ ├── WalletContext.tsx # useWallet(): status, wallet, identityKey
│ ├── WalletProviders.tsx # both providers in one component
│ ├── ConnectWallet.tsx # the button + "no wallet" dialog
│ ├── Home.tsx # demo hub
│ ├── WalletLogin.tsx # /login demo (wallet-login)
│ ├── useWalletLogin.tsx # login() hook (wallet-login)
│ ├── SignedRequestDemo.tsx # /signed-demo demo (signed-requests)
│ ├── signedRequest.ts # createSignedRequest (signed-requests)
│ ├── useSignedRequest.ts # signedFetch() hook (signed-requests)
│ └── bsv.css # minimal demo styles
└── server/ # Express 5 + TypeScript, run with tsx
├── package.json
└── src/
├── index.ts # routes, CORS, wallet relay, listen()
└── bsv/
├── config.ts # SERVER_PRIVATE_KEY, PORT, CLIENT_ORIGIN, BSV_NETWORK
├── auth.ts # same proof helpers as the client
├── nonceStore.ts # single-use nonces (in memory)
├── loginRoute.ts # POST /api/login (wallet-login)
└── verifySignedRequest.ts # framework-agnostic (signed-requests)What runs where#
| What | Client | Server |
|---|---|---|
| Dev command | vite |
tsx watch src/index.ts |
| Dev URL | http://localhost:5173 | http://localhost:3000 |
| Build | tsc -b && vite build → client/dist |
tsc → server/dist |
| Start in production | any static host | node dist/index.js |
From the project root, npm run dev runs both dev commands, npm run build builds both, and npm run install:apps reinstalls both. Each app also works on its own: cd client && npm run dev is fine.
Client and server are separate packages with their own package.json, lockfile and node_modules. You can deploy them to different hosts, and add a database driver to the server without touching the client.
Server routes#
| Route | From | What it does |
|---|---|---|
GET /health |
base | { "status": "ok" } for load balancers |
GET /api/identity |
wallet-connect | the server's public identity key |
GET /api/session, /ws |
wallet-connect | mobile wallet pairing (QR relay) |
POST /api/login |
wallet-login | verifies a login proof, returns { identityKey } |
POST /api/echo |
signed-requests | verifies a signed request, echoes the signer |
Which files are yours?#
All of them. Nothing is hidden in a package or framework. That said, they fall into three groups:
- Edit freely:
App.tsx,main.tsx,server/src/index.ts,Home.tsx, the demo pages andbsv.css. These are starting points, and the demo pages are there to delete. - Read before you edit:
config.ts,apiClient.ts,auth.ts,nonceStore.ts,serverIdentity.ts. They're small but security-sensitive. See Security model for what each one guarantees. - Don't hand-edit:
bsv-scaffold.json. Lateraddruns read it to decide what's already installed.
Deep diveWhy are client and server auth.ts identical?
The proof format is the same on both sides. Shipping one tiny file to each package keeps them independently deployable, with no shared workspace package and no build step. Both wrap @bsv/auth (opens in a new tab).
Read AGENTS.md next#
Every scaffold writes an AGENTS.md at the project root. For each installed capability it covers how it works, how it's used (exact function signatures and files) and future integrations. It's written for coding agents, and it's the best quick reference for humans too.