Titandocs

Local setup

Bring the whole stack up in the right order, and know what each step should look like when it works.

Five processes. Order matters — each one depends on the previous being ready.

PortService
5433Postgres (titanadmin)
7575Canton ledger API
5003Canton wallet gateway
8080Engine (+ admin UI)
4000BFF
3000Interface
3100These docs

1 — Infrastructure

cd server
docker compose up -d          # postgres, redis, canton

Postgres runs on 5433, not 5432, with user titanadmin. Every DATABASE_URL in the stack must match. A mismatch does not error loudly — candles and market data come back empty, which reads as "quiet market" rather than "wrong connection".

2 — Contracts

cd server/contracts
daml build
# upload the DAR, create the Vault, seed counters

3 — Indexer

cd server/indexer
make proto        # one-off: generate gRPC stubs
make migrate      # MUST run before the api
make run

Confirm migrations 0014_tpsl_v2 and 0015_fired_limit applied. The BFF reads columns that only exist afterwards, and will fail on its first request without them.

4 — Oracle

cd server/oracle
npm install
npm run once      # sanity check — no Redis writes, no HTTP port
npm run start

If any asset prints "m":"na", no venue delivered a usable frame for it. Fix that before starting the engine — without an index price the engine cannot compute a mark price.

5 — Engine

cd server/engine
go build -o ./engine ./cmd/engine       # one package at a time, with -o
ADMIN_TOKEN=dev-token ./engine

Then seed test users and deposits, and restart the enginekeys.json is read at startup only.

go build -o ./simulator ./cmd/simulator
./simulator                              # drive synthetic activity

6 — BFF

cd api
cp .env.example .env
npm install
npm run dev

Set at minimum:

DATABASE_URL='postgres://titanadmin:<password>@localhost:5433/titan'
ENGINE_BASE_URL='http://localhost:8080'
ENGINE_ADMIN_TOKEN='dev-token'

Verify:

curl -s http://localhost:4000/readyz | jq
# { "ok": true, "db": "ok", "engine": "ok", "engineMaxSeq": … }

db: "ok" with engineMaxSeq: 0 means the SSE bridge never started — usually a missing or mismatched ENGINE_ADMIN_TOKEN. REST reads will work; nothing live will arrive.

7 — Interface

cd interface
npm install
npm run dev       # :3000, proxies /v1 (+ws) → :4000

8 — Docs (this site)

cd docs
npm install
npm run dev       # :3100

Checkpoints

Work down this list; the first failure localises the problem.

curl localhost:4000/healthz → 200. The BFF process is up.

curl localhost:4000/readyzdb: ok, engine: ok. Both dependencies reachable.

curl 'localhost:4000/v1/orderbook?depth=5' → non-empty. The engine has a book (run simulator if not).

curl 'localhost:4000/v1/users/<party>/positions' → the projection is populated. If empty while the simulator is running, the indexer is not consuming.

Open http://localhost:3000 → the trade terminal renders live data.

Reset

cd server/engine
go build -o ./flatten ./cmd/flatten && ./flatten    # close every position

On this page