Local development
Bachelier is a pnpm + turbo monorepo (Node 20+, 22 recommended).
Setup
corepack enable && corepack prepare pnpm@10.33.0 --activate
pnpm install
pnpm test # all tests: contracts + services + web
Quickstart (local devnet)
# 1. start the chain (terminal A) — requires Docker
cd contracts && clarinet devnet start
# the deployment plan publishes all contracts and wires bcshare-token.set-vault
# 2. postgres + indexer + api (terminal B)
docker compose up postgres indexer api
# or natively:
# docker compose up postgres -d
# pnpm --filter @bachelier/db migrate && pnpm --filter @bachelier/db seed
# pnpm --filter @bachelier/indexer dev # :4001
# pnpm --filter @bachelier/api dev # :4000
# 3. keeper (terminal C) — drives rounds, uses the devnet deployer key
cp .env.example .env # uncomment KEEPER_PRIVATE_KEY (devnet deployer)
pnpm --filter @bachelier/keeper dev # :4002
# 4. web (terminal D)
pnpm --filter @bachelier/web dev # :5173
The web app shows a devnet Faucet button (mock sBTC/USDC mints). Every
package reads .env / environment — see .env.example for the full matrix.
Tests
pnpm test # everything (turbo)
pnpm --filter @bachelier/contracts test # 78 Clarity tests incl. BS parity + cost gate
pnpm --filter @bachelier/shared test # TS Black–Scholes mirror
cd contracts && clarinet check # static analysis
Highlights enforced by the suite: the BS reference vector table, a 216-point
TS↔Clarity parity grid, full round lifecycle for both settlement branches,
and an execution-cost gate on buy-call.
Demo-user scripts
Two scripts under contracts/scripts/ reproduce the on-chain demo:
# deploy everything to testnet (idempotent)
NODE_OPTIONS="--dns-result-order=ipv4first" pnpm tsx scripts/deploy-testnet.ts
# create N funded demo users that each deposit (default 60)
DEMO_USERS=60 NODE_OPTIONS="--dns-result-order=ipv4first" pnpm tsx scripts/demo-users.ts
demo-users.ts is rate-limit aware (global throttle + backoff against the Hiro
public API) and resumable by on-chain nonce, so an interrupted run continues
cleanly. Results land in contracts/deployments/demo-users-tx.json; wallet keys
in contracts/deployments/demo-users.json (gitignored). See Test Users.
Security checklist (enforced)
- Post-conditions on every user-facing token transfer; canonical-token asserts
(
u112);try!-guarded SIP-010 calls. - Oracle staleness + positivity guards; settlement price must postdate expiry.
- Pausable in a user-protective way (withdrawals/claims/settlement/exercise stay open).
- Owner/keeper RBAC with events on every change; keeper key isolated and rotatable.
- Fixed-point overflow review with 128-bit headroom per operation;
fp-expclamped. - First-depositor inflation attack mitigated by
MIN_DEPOSIT+ internal accounting. - Indexer idempotent by
(tx_id, event_index); reorg rollback; API rate-limited; no key custody.