prediction-market
AI-resolved, proof-anchored prediction market. Lifecycle: open → bet → resolve (via
ai-oracle) → settle. Composesai-oracleso applyingprediction-marketauto-appliesai-oraclefirst. Resolution receipts are signed by the operator key (✓ signature verified — not TEE-quote) and anchored to 0G Storage (or on-chain opt-in).
What it does
The prediction-market kit adds a full prediction market lifecycle to your
0G app:
- Open — create a market with a question and deadline.
- Bet — participants place YES/NO positions.
- Resolve — at deadline, the kit calls
resolveOracle(from the composedai-oraclelib) to get a signed, anchored AI verdict. - Settle —
resolveMarketmarks the market settled and stores the signed resolution receipt in 0G Storage for auditability (immutable content-addressed commitment). SetOG_ANCHOR_ONCHAIN=1to also write the root on-chain viaAnchor.sol.
Because prediction-market declares "composes": ["ai-oracle"], running
0g add prediction-market applies ai-oracle first, then the market overlay,
and merges dependencies from both kits into package.json.
Compatible bases
react-app · chat · tee-attested-api
Apply
# scaffold-time (applies ai-oracle automatically)
npm create 0gkit-app -- --kits prediction-market
# add to an existing project
0g add prediction-market
Environment variables
Inherits all ai-oracle env vars, plus:
| Variable | Example | Notes |
|---|---|---|
OG_COMPUTE_MODEL | neuralmagic/Meta-Llama-3.1-70B-Instruct-FP8 | Model for resolution oracle (optional) |
OG_PRIVATE_KEY | 0x... | Operator key for signing resolution receipts |
OG_RPC_URL | https://evmrpc-testnet.0g.ai | 0G chain RPC endpoint |
OG_ANCHOR_ONCHAIN | 1 | Set to 1 to commit resolution receipts on-chain (default: 0G Storage) |
OG_ANCHOR_ADDRESS | 0x... | Deployed Anchor.sol address — required when OG_ANCHOR_ONCHAIN=1 |
OG_STORAGE_NAMESPACE | prediction-market | Namespace prefix for market blobs in 0G Storage |
Quick start
0g add prediction-market # composes ai-oracle — applied automatically first
openMarket / placeBet / resolveMarket drive the lifecycle over an injected
MarketStorage. resolveMarket delegates to the composed
ai-oracle resolveOracle for the settlement answer:
import { Storage } from "@foundryprotocol/0gkit-storage";
import {
createMarketStore,
openMarket,
placeBet,
resolveMarket,
type MarketStorage,
} from "./lib/market.js";
import { resolveOracle } from "./lib/oracle.js"; // co-located by composition
const storage = new Storage({
privateKey: process.env.OG_PRIVATE_KEY as `0x${string}`,
rpcUrl: process.env.OG_RPC_URL!,
});
// Content-addressed → mutable-namespace bridge (persist `roots` in production).
const roots = new Map<string, string>();
const marketStorage: MarketStorage = {
async putBlob(ns, data) {
const { root } = await storage.upload(new TextEncoder().encode(data));
roots.set(ns, root);
},
async getBlob(ns) {
const root = roots.get(ns);
if (!root) return undefined;
const bytes = await storage.download(root);
return bytes ? new TextDecoder().decode(bytes) : undefined;
},
};
const store = createMarketStore(marketStorage);
const market = await openMarket(store, {
question: "Will 0G mainnet launch in 2026?",
closesAt: Date.now() + 86_400_000,
});
await placeBet(store, {
marketId: market.id,
bettor: "0xYou",
prediction: "YES",
amount: 10,
});
// `oracleDeps` = { infer, attestor, anchor, model } — see the ai-oracle quick start.
const boundOracle = (_deps: unknown, question: string) =>
resolveOracle(oracleDeps, question);
const { market: settled, receipt } = await resolveMarket(
{ resolveOracle: boundOracle, storage: marketStorage },
market.id
);
console.log(settled.state, receipt.answer, receipt.commitment);
Honesty caveat: resolution uses the composed
ai-oraclesigned receipt (operator key signsdigestJson(receipt), verified viarecoverSigner) — not a TEE-quote. Settle is folded intoresolveMarket; there is no separatesettleMarket.
Tiers
- lib —
lib/market.ts(portableMarket,Bet,Resolutiontypes,openMarket/placeBet/resolveMarkethelpers; settle is folded into resolve — there is no separatesettleMarket). - adapters — one per base (
app/api/markets/route.tsfor Next.js,src/routes/markets.tsfor Express). - ui —
app/markets/page.tsx(market list page),components/MarketBoard.tsx,components/CreateMarketForm.tsx(React bases only).
Composition
prediction-market composes ai-oracle. The engine resolves the full
closure deps-first (deduped, cycle-safe) before writing any files, so both
kits' files land in the project and both kits' package.json dependencies
are merged.
Honesty note
Resolution uses resolveOracle from the composed ai-oracle lib, which
produces an operator-signed receipt: digestJson(receipt) signed via
EIP-191 personal-sign (signMessage); the signer is recovered with
recoverSigner. There is no TEE quote verification. The badge is
"✓ signature verified". The Attestor interface is injected so a real
TEE-quote verifier can slot in later without changing market code.