Clyma is a climate-risk prediction market on Solana Devnet. It combines an interactive geographic globe with a pooled binary market program: users explore climate scenarios generated by Gemini AI, inspect evidence and resolution rules, connect a Phantom-compatible wallet, and trade YES or NO positions in Devnet SOL.
A demo/prod mode toggle lets you switch between curated example markets with rich price history and live Gemini-generated markets backed by MongoDB.
Prototype only. Clyma is not a production financial service. Devnet SOL has no monetary value.
npm install
cp .env.example .env
# Fill in GEMINI_API_KEY and MONGODB_URI in .env
npm run devOpen http://localhost:3000.
To set up on-chain markets, run the seed script:
solana airdrop 2
node scripts/setup.mjsA toggle in the sidebar switches between:
- Prod mode (default): Gemini-generated climate markets served from MongoDB. Markets are mapped to on-chain PDAs at IDs 2001–2024.
- Demo mode: Curated example markets with scaled volume (10x), 7-point price history charts, evidence links, and simulated trades. Ideal for demos and testing. No on-chain verification in this mode.
| Area | Implementation |
|---|---|
| Web application | Next.js App Router, React, TypeScript, Tailwind CSS |
| Globe | D3 orthographic canvas projection with local Natural Earth data |
| Charts | Recharts |
| Wallet | Phantom browser extension |
| Solana client | @solana/web3.js, Anchor instruction encoding, deterministic PDAs |
| Program | Anchor 0.30.1 Rust program (programs/climate_market) |
| Database | MongoDB with typed repositories |
| Market data | Gemini API (prod) or bundled demo catalogue (demo) |
| Validation | Zod schemas |
| Tests | Vitest + Testing Library + Anchor local-validator |
app/api/ REST API routes
components/globe/ Interactive globe
components/markets/ Market list, details, chart
components/trading/ Purchase review, settlement
components/providers/ Market, wallet, position, globe state
hooks/ AI forecasts, market program hooks
lib/markets/ Types, calculations, Gemini, demo data
lib/solana/ Config, encoding, PDAs, IDL, instructions
lib/db/ MongoDB connection, collections, repositories
programs/climate_market/ Anchor program
scripts/ DB seeding, on-chain market setup
YES and NO deposits enter one program-owned market vault. Before resolution:
YES probability = total YES pool / total market pool
NO probability = total NO pool / total market pool
After an authorized resolver records an outcome, each winning wallet receives a proportional share:
user payout = user winning position × total market pool ÷ total winning-side pool
The program uses u128 arithmetic with checked math, rounding down to whole
lamports. Cancelled markets allow reclaiming original deposits.
Program Derived Addresses for:
| PDA | Purpose |
|---|---|
protocol |
Authority, resolver, market count |
market |
Market ID, question hash, pool state |
vault |
Pooled SOL vault |
yes_position |
Per-wallet YES position |
no_position |
Per-wallet NO position |
claim |
Per-wallet claim record per market |
initialize_protocol, create_market, fund_market, buy_yes, buy_no,
close_market, resolve_market, claim_winnings, refund_cancelled
Requirements: Node.js 22.13+, npm, Phantom browser extension (optional).
cp .env.example .env
npm install
npm run devNEXT_PUBLIC_SOLANA_NETWORK=devnet
NEXT_PUBLIC_SOLANA_RPC_URL=
NEXT_PUBLIC_PROGRAM_ID=EkcwkAzNUCGRcKCA5WJc7GCtUXooubkm3ktesBWQXPBt
MONGODB_URI=
GEMINI_API_KEY=
GEMINI_MODEL=gemini-3.5-flash
GEMINI_MARKET_COUNT=24| Variable | Purpose |
|---|---|
NEXT_PUBLIC_SOLANA_NETWORK |
Must be devnet |
NEXT_PUBLIC_SOLANA_RPC_URL |
Optional; defaults to public Devnet endpoint |
NEXT_PUBLIC_PROGRAM_ID |
Deployed Solana program address |
MONGODB_URI |
MongoDB connection string |
GEMINI_API_KEY |
Google Gemini API key for market generation |
GEMINI_MODEL |
Model for generation (default: gemini-3.5-flash) |
GEMINI_MARKET_COUNT |
Markets to generate (default 24, max 40) |
FREESOLO_API_KEY |
Freesolo/Modal endpoint key for AI oddsmaker |
GRPO_ADAPTER_ID |
Deployed GRPO adapter run ID (e.g. flash-XXXX) |
TAVILY_API_KEY |
Optional; Tavily search API for live news context |
Prod mode requires MONGODB_URI and GEMINI_API_KEY. Demo mode works without
either — it serves the bundled demo catalogue.
npm run format:check
npm run lint
npm run typecheck
npm test
npm run buildOr run all:
npm run checkThe program is pinned to Anchor 0.30.1. Install the toolchain:
cargo install --git https://github.com/solana-foundation/anchor --tag v0.30.1 avm --locked
avm install 0.30.1
avm use 0.30.1
solana-install init 1.18.8Run Anchor tests:
anchor build
npm run test:anchor-
Fund a Devnet wallet:
solana config set --url devnet solana airdrop 2 -
Deploy the program:
anchor deploy --provider.cluster devnet
-
Initialize protocol, create markets, and seed MongoDB:
node scripts/setup.mjs
-
Set
NEXT_PUBLIC_PROGRAM_IDin.envand start the app.
TerraForm incorporates a fine-tuned GRPO (Group Relative Policy Optimization) climate forecasting engine trained on meteorological resolution rules and historical probability outcomes.
| Metric | Base SFT Model (4B) | MiniMax-M3 (Frontier SoTA) | Our Fine-Tuned GRPO Model (4B) |
|---|---|---|---|
| Inverted Brier Score ( |
0.7326 |
0.7768 |
0.8048 (Higher is Better)
|
| Expected Calibration Error (ECE ↓) | 0.1316 |
0.2913 |
0.1167 (Lowest Error)
|
| Mean Predicted Probability ( |
0.6010 (Prior Bias) |
0.4513 (S-Curve) |
0.4033 (Base-Rate Calibrated)
|
| Format-Fail Rate (↓) | 0.00% |
0.00% |
0.00% (100% Strict JSON)
|
-
Brier Accuracy Gain: Our 4B fine-tuned GRPO model achieves
0.8048Inverted Brier, outperforming both the un-tuned Base SFT Model (0.7326) and MiniMax-M3 (0.7768). -
60% Lower Calibration Error: Reduces Expected Calibration Error (ECE) from
0.2913down to0.1167, remaining tightly aligned to the ideal$y=x$ calibration diagonal. - RAG & Real-Time Evidence: Integrated with Tavily web retrieval to fetch live news context, URLs, and snippets prior to probability generation.
GET /api/markets
GET /api/markets/:id
GET /api/markets/:id/history
GET /api/markets/region/:continent
POST /api/markets/create
POST /api/predict
GET /api/users/:wallet/positions
GET /api/users/:wallet/activity
POST /api/index-transaction
GET /api/auth/challenge
POST /api/auth/verify
GET /api/me/positions
GET /api/me/activity
- No private keys or seed phrases are requested or stored
- Wallet signatures remain inside the browser adapter
- Deterministic PDAs with Anchor constraints
- Checked arithmetic on all pool operations
- On-chain state is authoritative — not browser storage or API metadata
- Resolution is permissioned; no oracle or dispute process
- No order book or limit orders (pooled model only)
- Integer settlement can leave sub-lamport dust in vaults
- Only Phantom wallet and native SOL are wired
- Anchor tests require Rust, Solana CLI, and a local validator
- Durable event indexing and on-chain pool snapshots
- Stablecoin settlement
- Multisig/oracle resolution with dispute window
- Additional wallet adapters
- Production observability and independent program review
