A prediction market for physical goods — powered by Solana and verified by AI.

KiwiMarket is a peer-to-peer on-demand marketplace where anyone can post a request, set a bounty in SOL, and have someone fulfill it for real. The core mechanic isn't simple bounty hunting — it's a dynamic prediction market. When a task goes live, a crowd betting pool opens alongside it: stakers take positions on whether the bounty will be legitimately completed, and odds shift in real time as SOL flows in. The market continuously prices trust, and AI photo verification removes the need for platform arbitration.


What Is This?

Most prediction markets live entirely on-chain and resolve via oracles. KiwiMarket is different: the "oracle" is physical reality, captured as a photo and judged by an AI vision model. This makes it suitable for hyper-local, spontaneous, and real-world bets that no data feed could ever resolve — finding a charger, solving a coding problem in front of you, delivering a specific item.

Core loop:

  1. Post a bounty — describe a physical challenge, set a SOL reward and expiry time
  2. Crowd bets YES or NO — liquidity pools form around both outcomes
  3. Someone tries to fulfill — submits a photo as proof
  4. Claude verifies — AI judges whether the proof matches the bounty
  5. Automatic payout — winners receive their share from the losing pool; the fulfiller gets the reward

Liquidity Pools and Pricing

Each bounty has two liquidity pools: YES and NO. When the bounty is created both pools are seeded at 1.0 SOL to bootstrap initial odds. Every bet adds to one of the pools.

yes_price = yes_pool / (yes_pool + no_pool)
no_price  = no_pool  / (yes_pool + no_pool)

These prices update in real-time as bets come in and are displayed as probability percentages. If yes_pool = 3.0 and no_pool = 1.0, YES is priced at 75% and NO at 25%.

Payout formula when bounty is fulfilled (YES wins):

  • Fulfiller receives: reward_sol × 0.95
  • Each YES bettor receives: bet_amount + (bet_amount / yes_pool) × no_pool × 0.95
  • NO bettors lose their stake

Payout formula when bounty expires (NO wins):

  • Poster is refunded: reward_sol
  • Each NO bettor receives: bet_amount + (bet_amount / no_pool) × yes_pool × 0.95
  • YES bettors lose their stake

A 5% platform fee is taken from the losing pool before distribution. All funds are held in an on-chain escrow wallet on Solana devnet and released by the backend on resolution.


Proof verification flow:

  1. Fulfiller uploads a photo; frontend sends it as base64 to /proof/upload
  2. Backend stores the proof and spawns an async task
  3. Task calls Claude's vision API with the image + bounty description
  4. Claude returns { "verdict": "YES" | "NO", "reasoning": "..." }
  5. On YES: backend calls resolve_bounty() → pays fulfiller + YES bettors via escrow
  6. Frontend polls /proof/status/{bounty_id} and shows the live verdict + reasoning

Expiry mechanism:

  • A background task runs every 60 seconds
  • Any bounty past its expiry_at with status open is marked expired
  • resolve_expired_bounty() immediately pays out NO bettors and refunds the poster

Tech Stack

Layer Technology
Frontend React 18, TypeScript, Vite
Routing React Router DOM v6
Wallet @solana/wallet-adapter (Phantom, Solflare)
On-chain @solana/web3.js, Solana Devnet
Backend FastAPI, Uvicorn, Python 3.11+
Database SQLite via SQLAlchemy (swappable via DATABASE_URL)
AI Judge Anthropic Claude (vision model)
Solana (backend) solders, base58

Built With

Share this project:

Updates