OwarineDocs
Open app
For builders

Run Owarine locally

Build the Daml packages, start a local Canton sandbox, bootstrap the venue, then run ops and the web app.

Reviewed 2026-10-06

Run these commands from the repository root, not from docs-site/. You need Node 22+, pnpm 11.24.0, JDK 21, dpm (Canton 3.5; the packages pin SDK 3.5.2) and an empty local Postgres database. Set JAVA_HOME to your JDK and put java and dpm on PATH; dpm normally installs in $HOME/.dpm/bin. Clone with full Git history so the capability and screenshot provenance checks can resolve historical evidence after internal notes leave the public tree.

pnpm install --frozen-lockfile
cp .env.example .env.local
cp services/ops/.env.example services/ops/.env.local
cp web/.env.example web/.env.local

# 1. Build the Daml packages, and optionally run the Daml tests
(cd daml && dpm build --all)
(cd daml/pm-tests && dpm test)

In a second terminal, leave the sandbox running:

dpm sandbox --json-api-port 7575

Back in the first terminal, upload the DARs, allocate the venue parties and create the Series, cash shards, reserves, arena and guest-seat pool:

LEDGER_JSON_API_URL=http://127.0.0.1:7575 LEDGER_AUTH_MODE=none \
  pnpm --filter @owarine/scripts exec tsx bootstrap-local.ts --seats 6

The bootstrap writes ~/.config/owarine/canton/parties.json. Fill the copied environment files before starting either service:

VariableWhereLocal value
DATABASE_URLWeb and opsThe same local Postgres connection URL
LEDGER_JSON_API_URLWeb and opshttp://127.0.0.1:7575
LEDGER_AUTH_MODEWeb and opsnone
OWARINE_PARTIES_FILEWeb and opsAbsolute path to the generated parties file; expand ~ to your home directory
OPS_INTERNAL_SECRETWeb and opsThe same random secret of at least 32 characters
OWARINE_SEAT_COOKIE_SECRETWebA separate random secret of at least 32 characters
OPS_INTERNAL_URLWebhttp://127.0.0.1:8080
OPS_HTTP_PORTOps8080; without this, the command defaults to 8787
DRY_RUNOps0
NEXT_PUBLIC_CANTON_NETWORKWeblocalnet
NEXT_PUBLIC_APP_ORIGINWeb and opshttp://localhost:3000
NEXT_PUBLIC_SITE_URLWebhttp://localhost:3000
NEXT_PUBLIC_DOCS_URLWebhttp://localhost:3153
NEXT_PUBLIC_PRICE_FEED_URLWebhttp://localhost:8080
NEXT_PUBLIC_LADDER_URLWebhttp://localhost:8080

Web values go in web/.env.local; ops values go in services/ops/.env.local. Generate each secret with node -e "console.log(require('node:crypto').randomBytes(32).toString('hex'))". The database package applies its schema automatically. Ops reads its own file before the root file, and explicitly exported shell variables take precedence.

In a third terminal, start operations:

pnpm ops:start

In a fourth terminal, start the web app:

pnpm dev

Then open /markets, take a guest seat and make a call. The crypto lanes (Coinbase, Kraken and Bitstamp candles) run around the clock. Stock lanes quote only while US markets trade, and need the Alpaca keys in services/ops/.env.local. A local run uses its own parties and its own database, and touches no shared network.

The fast gate is pnpm typecheck && pnpm invariants && pnpm test. After a change to a Daml package, regenerate the TypeScript bindings with pnpm codegen:daml; the generated files are never edited by hand.

The docs site has its own lockfile in docs-site/ and needs only Node 22+ and pnpm 11.24: from that folder, pnpm install --frozen-lockfile, then pnpm check. It renders without a seat, a ledger or provider credentials, and its check reads the app source from the parent directory.