A privacy-first parimutuel prediction market built on the Canton Network. Participants stake USDC.x on real-world outcomes with sub-second ledger settlement and absolute transaction privacy. Individual stake sizes remain opaque while outcomes are publicly verifiable.
┌────────────────────────────────────────────────┐
│ FRONTEND LAYER │
│ Next.js 16 · React 19 · Tailwind 4 │
│ MarketHero · GrokSidebar · CandidateVote │
│ useCantonWallet · usePulse · useRitual │
└──────────────────────┬─────────────────────────┘
│ REST + WebSocket (Socket.IO)
┌──────────────────────▼─────────────────────────┐
│ BACKEND LAYER │
│ NestJS 11 · TypeScript · MongoDB │
│ MarketService · SyncService (5s pulse) │
│ KalshiService (Oracle) · GrokService (AI) │
│ ResolverService · SettlementService │
└──────────────────────┬─────────────────────────┘
│ Canton JSON API (port 7575)
┌──────────────────────▼─────────────────────────┐
│ CANTON LEDGER LAYER │
│ Daml 3.4.11 Smart Contracts │
│ UsdcToken · WeeklyPool · MarketCandidate │
└────────────────────────────────────────────────┘
| Layer | Technology |
|---|---|
| Smart Contracts | Daml 3.4.11 on Canton |
| Backend | NestJS 11, Node.js, TypeScript |
| Frontend | Next.js 16, React 19, Tailwind CSS 4 |
| Database | MongoDB (historical archive & cache) |
| Oracle | Kalshi API |
| AI Insights | Grok (xAI) |
| Real-time | Socket.IO WebSockets |
| Wallet | @canton-network/dapp-sdk |
.
├── daml/ # Smart contracts
│ ├── contracts/
│ │ ├── Market.daml # UsdcToken & WeeklyPool templates
│ │ ├── MarketCandidate.daml # Community signaling template
│ │ └── Setup.daml # Ledger init script
│ └── daml.yaml # SDK version & dependencies
│
├── backend/ # NestJS API server
│ └── src/
│ ├── market/
│ │ ├── market.controller.ts
│ │ ├── market.service.ts
│ │ ├── market.gateway.ts # WebSocket gateway
│ │ ├── daml.service.ts # Canton JSON API client
│ │ ├── kalshi.service.ts # Oracle integration
│ │ ├── grok.service.ts # AI market insights
│ │ ├── resolver.service.ts
│ │ ├── settlement.service.ts
│ │ └── sync.service.ts # 5-second ledger pulse
│ └── schemas/ # MongoDB schemas
│
├── frontend/ # Next.js app
│ ├── app/ # App router pages
│ ├── components/ # UI components
│ │ ├── MarketHero.tsx
│ │ ├── GrokSidebar.tsx
│ │ ├── CandidateVote.tsx
│ │ ├── Ledgerlogs.tsx
│ │ └── ResolverTransparency.tsx
│ └── lib/
│ ├── useCantonWallet.ts # Canton wallet hook
│ ├── usePulse.ts # WebSocket heartbeat hook
│ └── useRitual.ts # Staking ritual hook
│
├── proposal.md # Canton development fund proposal
└── netlify.toml # Frontend deployment config
- Daml SDK 3.4.11 —
daml versionto verify - Node.js 20+
- MongoDB instance (local or Atlas)
- Kalshi API key
- Grok (xAI) API key
cd daml
daml start
# Canton Sandbox starts on :6865
# JSON API starts on :7575Backend — copy backend/.env.example to backend/.env:
PORT=8080
NODE_ENV=development
MONGODB_URI=mongodb://localhost:27017/eventualx
CANTON_JSON_API_URL=http://localhost:7575
LEDGER_PARTY_ORGANIZER=<organizer-party-id>
LEDGER_PARTY_RESOLVER=<resolver-party-id>
KALSHI_API_BASE_URL=https://trading-api.kalshi.com
KALSHI_API_KEY=<your-kalshi-key>
FRONTEND_URL=http://localhost:3000Frontend — edit frontend/.env:
NEXT_PUBLIC_API_BASE_URL=http://localhost:8080
CANTON_JSON_API_URL=http://localhost:7575
NEXT_PUBLIC_GROK_API_KEY=<your-grok-key>cd backend
npm install
npm run start:dev
# API available at http://localhost:8080cd frontend
npm install
npm run dev
# UI available at http://localhost:3000Represents a USDC.x balance. Supports atomic Split to separate a stake amount from change, ensuring non-custodial participation.
The core parimutuel pool for a single market week. Tracks totalYes / totalNo balances.
Stake— atomically splits a token and records a Yes/No positionResolveMarket— resolver-only choice that closes the market with a winning side
Community signaling contract. Participants upvote candidate questions to influence which markets get created next.
# Build DAR
cd daml && daml build
# Run init script
cd daml && daml script --dar .daml/dist/canton-prediction-market-0.0.1.dar \
--script-name Setup:setupMarket --ledger-host localhost --ledger-port 6865
# Run all tests
cd daml && daml testnpm run start:dev # Development (watch mode)
npm run start:prod # Production
npm run test # Unit tests
npm run test:e2e # End-to-end tests
npm run test:cov # Coverage reportThe frontend is configured for Netlify via netlify.toml. Deploy with:
# Install Netlify CLI
npm install -g netlify-cli
cd frontend
netlify deploy --prodThe backend can be deployed to any Node.js host. Set all environment variables from backend/.env.example in your host's config panel.
Ritual — A complete market lifecycle: Prophecy (question creation) → Staking → Resolution → Settlement.
Heartbeat — The SyncService polls the Canton ledger every 5 seconds and broadcasts live state to all connected clients over WebSocket.
Resolver — A designated Canton party with the authority to invoke ResolveMarket. The resolver's identity and the oracle signal it consumed are published on-chain for transparency.
Omen — An AI-generated market insight produced by Grok, displayed in the sidebar to provide sentiment context without influencing the on-chain outcome.