TypeScript companion services for the OttoChain metagraph — providing API gateway, transaction bridge, and indexing for the Agent Identity Platform.
┌─────────────────────────────────────────────────────────────┐
│ CLIENTS │
│ Explorer UI │ Discord Bot │ Telegram Bot │ SDKs │
└───────┬────────┴───────┬───────┴───────┬────────┴──────────┘
│ │ │
└────────────────┴───────┬───────┘
│
┌────────────▼────────────┐
│ API GATEWAY │
│ (GraphQL + WS) │
│ Port 4000 │
└────────────┬────────────┘
│
┌──────────────────┼──────────────────┐
│ │ │
┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐
│ POSTGRES │ │ BRIDGE │ │ INDEXER │
│ (indexed │ │ (Port 3030) │ │ (Port 3031) │
│ state) │ └──────┬──────┘ └──────┬──────┘
└──────▲──────┘ │ │
│ │ │
│ ┌──────▼─────────────────▼──────┐
└───────────┤ METAGRAPH │
│ (OttoChain GL0/ML0/DL1) │
└───────────────────────────────┘
| Service | Port | Description |
|---|---|---|
| Gateway | 4000 | GraphQL API + WebSocket subscriptions |
| Bridge | 3030 | Wallet management, transaction signing & submission |
| Indexer | 3031 | Webhook receiver, snapshot processing, DB indexing |
- Node.js 20+
- pnpm 9+
- Docker & Docker Compose
- Running OttoChain metagraph (local or remote)
# Install dependencies
pnpm install
# Generate Prisma client
pnpm db:generate
# Start Postgres
pnpm docker:up
# Push schema to database
pnpm db:push
# Start all services in dev mode
pnpm dev# Create shared network (required — shared with ottochain-deploy stack)
docker network create ottochain 2>/dev/null || true
# Start services (Gateway, Bridge, Indexer + Redis/Postgres)
make up
# Or manually:
docker compose -f compose.base.yml -f compose.services.yml up -d
# With traffic generator for testing
make traffic| File | Purpose |
|---|---|
compose.base.yml |
Infrastructure (Redis, Postgres) |
compose.services.yml |
App services (Gateway, Bridge, Indexer) |
compose.traffic.yml |
Traffic generator (testing) |
For monitoring, see ottochain-monitoring. For full orchestration, see ottochain-deploy.
Create .env in the root:
DATABASE_URL=postgresql://ottochain:ottochain@localhost:5432/ottochain_identity
# Metagraph endpoints
METAGRAPH_ML0_URL=http://localhost:9100
METAGRAPH_DL1_URL=http://localhost:9400
# Service ports
GATEWAY_PORT=4000
BRIDGE_PORT=3030
INDEXER_PORT=3031The Gateway exposes a GraphQL API at http://localhost:4000/graphql.
# Get agent by address
query {
agent(address: "DAG123...") {
address
displayName
reputation
state
platformLinks {
platform
platformUserId
}
}
}
# Leaderboard
query {
leaderboard(limit: 10) {
address
displayName
reputation
}
}
# Network stats
query {
networkStats {
totalAgents
activeAgents
totalContracts
completedContracts
lastSnapshotOrdinal
}
}# Watch for new activity
subscription {
activityFeed {
eventType
timestamp
agent {
displayName
}
action
reputationDelta
}
}The Indexer receives push notifications from ML0 when snapshots are finalized.
curl -X POST http://localhost:9100/data-application/v1/webhooks/subscribe \
-H "Content-Type: application/json" \
-d '{"callbackUrl": "http://localhost:3031/webhook/snapshot"}'{
"event": "snapshot.finalized",
"ordinal": 12345,
"hash": "abc123...",
"timestamp": "2026-02-03T21:30:00.000Z",
"stats": {
"updatesProcessed": 42,
"stateMachinesActive": 156
}
}Test the full pipeline: Metagraph → Webhook → Indexer → PostgreSQL.
- tessellation repo cloned
- ottochain repo cloned
- Java 21 (via SDKMAN)
- Docker running
# Set paths (or use defaults in ~/.openclaw/workspace/)
export TESSELLATION_DIR=~/repos/tessellation
export OTTOCHAIN_DIR=~/repos/ottochain
# Run the test suite
pnpm test:integrationThe script will:
- Start PostgreSQL container
- Push database schema
- Start local metagraph cluster
- Start the indexer service
- Register webhook with ML0
- Verify snapshot → webhook → indexer → postgres flow
- Report results and cleanup
For testing just the webhook flow (assumes metagraph already running):
# Start indexer
DATABASE_URL="postgresql://ottochain:ottochain@localhost:5432/ottochain_identity" \
METAGRAPH_ML0_URL="http://localhost:9200" \
INDEXER_PORT=3031 \
node packages/indexer/dist/index.js
# In another terminal, run the webhook test
npx tsx scripts/test-webhook.ts# Check ML0 status
curl http://localhost:9200/node/info | jq .
# Check current checkpoint
curl http://localhost:9200/data-application/v1/checkpoint | jq .
# Register webhook
curl -X POST http://localhost:9200/data-application/v1/webhooks/subscribe \
-H "Content-Type: application/json" \
-d '{"callbackUrl": "http://YOUR_IP:3031/webhook/snapshot"}'
# Check indexer status
curl http://localhost:3031/status | jq .
# Check indexed snapshots in DB
docker compose exec postgres psql -U ottochain -d ottochain_identity \
-c 'SELECT * FROM "IndexedSnapshot" ORDER BY ordinal DESC LIMIT 5;'ottochain-services/
├── packages/
│ ├── gateway/ # Apollo GraphQL server
│ ├── bridge/ # Transaction signing
│ ├── indexer/ # Snapshot processor
│ └── shared/ # Common types, DB client
├── prisma/
│ └── schema.prisma # Database schema
├── docker-compose.yml
└── package.json
pnpm build # Build all packages
pnpm dev # Start all in dev mode
pnpm lint # Lint all packages
pnpm test # Run tests
pnpm db:studio # Open Prisma Studio
pnpm db:migrate # Run migrations- ottochain — Metagraph (Scala)
- ottochain-sdk — TypeScript SDK
- identity-landing — Explorer UI
Apache-2.0