ETF for prediction markets - A prediction market aggregator that lets you bundle multiple Polymarket outcomes into one basket, set custom weights and bet as a single position — a portfolio in one trade
Prediction markets are fragmented and limited:
- Users can only bet on individual markets one at a time
- No way to create diversified positions across multiple outcomes
- Managing multiple bets is complex and time-consuming
- No mechanism to bet on correlated events as a single position
- Missing the concept of index-based investing in predictions
Example: You believe tech stocks will boom, AI regulation will pass, and crypto will rally. Currently, you'd need to place 3+ separate bets, track each one, and manage payouts individually.
PolyBaskets lets you create prediction market baskets - curated collections of Polymarket outcomes with custom weights, all settled as a single on-chain position.
flowchart TD
subgraph Data["📊 DATA SOURCE"]
PM[("Polymarket API")]
PM --> |Live Prices| MARKETS["Active Markets\n• BTC $100k?\n• Trump 2024?\n• AI Regulation?"]
end
subgraph Create["🧺 BASKET CREATION"]
MARKETS --> SELECT["Select Markets"]
SELECT --> WEIGHT["Assign Weights\n40% / 35% / 25%"]
WEIGHT --> INDEX["Calculate Index\nΣ(Weight × Probability)"]
INDEX --> |"Entry Index: 85.7%"| SAVE["Save & Bet"]
end
subgraph Chain["⛓️ VARA NETWORK"]
SAVE --> |"100 VARA"| CONTRACT[("Smart Contract")]
CONTRACT --> BASKET["Basket Created\n• ID: #42\n• Entry: 0.857\n• Shares: 100"]
CONTRACT --> POSITION["Position Stored\n• User Address\n• Shares Owned"]
end
subgraph Settle["🤖 SETTLEMENT"]
BOT["Settler Bot"] --> |Monitor| PM
PM --> |"Market Resolved"| BOT
BOT --> |"Propose Settlement"| CONTRACT
CONTRACT --> CHALLENGE["12min Challenge\nWindow"]
CHALLENGE --> FINALIZE["Finalized\nSettlement Index: 1.0"]
end
subgraph Claim["💰 PAYOUT"]
FINALIZE --> CALC["Calculate Payout\n100 × (1.0 ÷ 0.857)"]
CALC --> PAYOUT["Claim 116.7 VARA\n+16.7% Profit"]
end
style PM fill:#6366f1,color:#fff
style CONTRACT fill:#8b5cf6,color:#fff
style BOT fill:#10b981,color:#fff
style PAYOUT fill:#22c55e,color:#fff
flowchart TB
subgraph Frontend["🖥️ FRONTEND (React + Vite)"]
UI["Web Interface"]
WALLET["Wallet Connection\nSubWallet / Talisman"]
STATE["State Management\nReact Query + Context"]
end
subgraph External["🌐 EXTERNAL SERVICES"]
POLY["Polymarket\nGamma API"]
VARA_RPC["Vara Network\nRPC Node"]
end
subgraph Backend["⚙️ BACKEND SERVICES"]
SETTLER["Settler Bot\nNode.js"]
PROXY["API Proxy\nCORS Handler"]
end
subgraph Blockchain["⛓️ VARA NETWORK"]
PROGRAM["Smart Contract\nRust / Sails"]
STORAGE["On-Chain Storage\n• Baskets\n• Positions\n• Settlements"]
end
UI <--> WALLET
UI <--> STATE
STATE <--> |"REST API"| POLY
STATE <--> |"WebSocket"| VARA_RPC
WALLET <--> |"Sign TX"| VARA_RPC
VARA_RPC <--> PROGRAM
PROGRAM <--> STORAGE
SETTLER <--> |"Monitor"| POLY
SETTLER <--> |"Settle TX"| VARA_RPC
PROXY <--> POLY
UI <--> PROXY
style Frontend fill:#1e293b,color:#fff
style Blockchain fill:#7c3aed,color:#fff
style Backend fill:#059669,color:#fff
style External fill:#0891b2,color:#fff
Daily contest runtime now uses one unified root deployment contract.
Use only:
Stack services:
postgresindexer-migrateindexer-processorindexer-apibet-quote-servicecontest-botsettler-bot
Quick start:
cp .env.example .env
cp .env.secrets.example .env.secretsFill:
- chain/program env in
.env - include
BET_TOKEN_PROGRAM_IDso the indexer can countApproveandBetToken Claimactivity for the daily leaderboard - exactly one of
SETTLER_SEEDorSETTLER_SEED_FILEin.env.secrets - exactly one of
BET_QUOTE_SIGNER_SEEDorBET_QUOTE_SIGNER_SEED_FILEin.env.secrets
Mnemonic secrets may be provided either as space-separated or comma-separated words.
Run:
docker compose \
--env-file .env \
--env-file .env.secrets \
-f docker-compose.yml \
up --buildLogs:
docker compose --env-file .env --env-file .env.secrets -f docker-compose.yml logs -f indexer-processor
docker compose --env-file .env --env-file .env.secrets -f docker-compose.yml logs -f bet-quote-service
docker compose --env-file .env --env-file .env.secrets -f docker-compose.yml logs -f contest-bot
docker compose --env-file .env --env-file .env.secrets -f docker-compose.yml logs -f settler-botFrontend:
- set
VITE_INDEXER_GRAPHQL_ENDPOINTto yourindexer-apiGraphQL URL - set
VITE_BET_QUOTE_SERVICE_URLto yourbet-quote-serviceURL - CORS allow-list is controlled by
FRONTEND_URLS - on Railway,
indexer-apishould respectPORT - on Railway,
bet-quote-serviceshould also respectPORT - recommended production setting:
INDEXER_GRAPHIQL_ENABLED=false BET_QUOTE_SIGNER_SEEDmust be a dedicated secret and must not reuseSETTLER_SEED
sequenceDiagram
autonumber
participant U as 👤 User
participant F as 🖥️ Frontend
participant P as 📊 Polymarket
participant V as ⛓️ Vara Contract
participant B as 🤖 Settler Bot
rect rgb(30, 41, 59)
Note over U,P: BASKET CREATION
U->>F: Browse Markets
F->>P: Fetch Live Prices
P-->>F: Market Data + Probabilities
F-->>U: Display Markets
U->>F: Select Markets + Set Weights
F->>F: Calculate Basket Index
U->>F: Confirm & Sign Transaction
F->>V: CreateBasket(items, weights)
F->>V: BetOnBasket(basketId, indexBps)
V-->>F: Position Created (100 shares)
F-->>U: Success! Basket #42 Created
end
rect rgb(20, 83, 45)
Note over P,B: MARKET RESOLUTION
loop Every 5 minutes
B->>P: Check Market Status
P-->>B: Market Resolved (YES won)
end
B->>B: All markets in basket resolved
B->>V: ProposeSettlement(basketId, resolutions)
V-->>V: Start 12min Challenge Window
end
rect rgb(127, 29, 29)
Note over V,B: FINALIZATION
B->>B: Wait 12 minutes
B->>V: FinalizeSettlement(basketId)
V-->>V: Settlement Finalized
end
rect rgb(21, 94, 117)
Note over U,V: CLAIM PAYOUT
U->>F: View Basket Status
F->>V: GetSettlement(basketId)
V-->>F: Settlement Index: 1.0
F-->>U: Show Claim Button
U->>F: Click "Claim Payout"
F->>V: Claim(basketId)
V->>V: Calculate: 100 × (1.0 ÷ 0.857)
V-->>U: Transfer 116.7 VARA
F-->>U: 🎉 Payout Celebration Modal
end
flowchart LR
subgraph Pages["📄 Pages"]
BP["BuilderPage"]
BKP["BasketPage"]
EP["ExplorePage"]
MBP["MyBasketsPage"]
end
subgraph Components["🧱 Components"]
BB["BasketBuilder"]
BC["BasketCard"]
BI["BasketIndex"]
MS["MarketSearch"]
SB["SaveBasketButton"]
PC["PayoutCelebration"]
end
subgraph Lib["📚 Libraries"]
PM["polymarket.ts\nAPI Client"]
BU["basket-utils.ts\nIndex Calc"]
BO["basket-onchain.ts\nContract Client"]
end
subgraph Context["🔄 Context"]
WC["WalletContext"]
BC2["BasketContext"]
end
BP --> BB
BP --> MS
BP --> SB
BKP --> BI
BKP --> PC
EP --> MS
MBP --> BC
BB --> BU
SB --> BO
BI --> PM
MS --> PM
SB --> WC
BB --> BC2
style Pages fill:#3b82f6,color:#fff
style Components fill:#8b5cf6,color:#fff
style Lib fill:#10b981,color:#fff
style Context fill:#f59e0b,color:#fff
| Feature | Description |
|---|---|
| 🔴 Live Data | Real-time prices from Polymarket API, updates every 2 seconds |
| 🧺 Basket Creation | Select multiple markets, assign custom weights (must total 100%) |
| ⛓️ On-Chain Settlement | Trustless settlement with 12-min challenge window |
| 📊 Portfolio Tracking | Track all baskets, live P&L, claim with one click |
| 🎉 Share Wins | Download image, share on X (Twitter) and Telegram |
flowchart LR
subgraph Markets["Selected Markets"]
M1["BTC $100k\nYES @ 75%"]
M2["Trump 2024\nYES @ 52%"]
M3["AI Regulation\nNO @ 60%"]
end
subgraph Weights["Assigned Weights"]
W1["40%"]
W2["35%"]
W3["25%"]
end
subgraph Calc["Calculation"]
C1["0.40 × 0.75 = 0.300"]
C2["0.35 × 0.52 = 0.182"]
C3["0.25 × 0.60 = 0.150"]
end
subgraph Result["Result"]
R["Index = 0.632\n(63.2%)"]
end
M1 --> W1 --> C1
M2 --> W2 --> C2
M3 --> W3 --> C3
C1 --> R
C2 --> R
C3 --> R
style Result fill:#22c55e,color:#fff
Formula: Index = Σ (Weight × Probability)
Payout = Shares × (Settlement Index ÷ Entry Index)
| Scenario | Entry | Settlement | Bet | Payout | Result |
|---|---|---|---|---|---|
| 📈 Profit | 63.2% | 85% | 100 VARA | 134.5 VARA | +34.5% |
| 📉 Loss | 63.2% | 40% | 100 VARA | 63.3 VARA | -36.7% |
# Clone the repository
git clone https://github.com/Adityaakr/polybaskets.git
cd polybaskets
# Install dependencies
npm install
# Start development server
npm run devVITE_ENABLE_VARA=true
VITE_ENABLE_MANUAL_BETTING=true
VITE_PROGRAM_ID=0x702395d43248eaa5f1fd4d9eadadc75b0fb1c7c5ae9ea20bf31375fd4358f403
VITE_NODE_ADDRESS=wss://testnet.vara.network
VITE_GAMMA_PROXY=/gamma
VITE_INDEXER_GRAPHQL_ENDPOINT=http://localhost:4350/graphql
VITE_BET_QUOTE_SERVICE_URL=http://127.0.0.1:4360
VITE_CONTEST_DAY_BOUNDARY_OFFSET_MS=43200000
VITE_EXPLORER_HOLD_ENABLED=falseVITE_ENABLE_VARA controls the native VARA asset flow in the frontend.
VITE_ENABLE_MANUAL_BETTING controls whether the web UI can create baskets and place bets directly, or stays in agent-only execution mode.
VITE_CONTEST_DAY_BOUNDARY_OFFSET_MS controls the frontend contest-window start offset in milliseconds from UTC midnight. 43200000 means 12:00 UTC.
VITE_EXPLORER_HOLD_ENABLED swaps /explorer to a launch-soon placeholder page, and the related VITE_EXPLORER_HOLD_* vars let you customize the copy and CTA without code changes.
true: current behavior is preserved, including native VARA basket creation, betting, and claim UI.false: the app runs in CHIP-only mode. Native VARA asset UI is hidden, native VARA actions are unavailable, and the builder defaults to the CHIP lane only.
| Layer | Technology |
|---|---|
| Frontend | React, TypeScript, Vite, TailwindCSS, shadcn/ui |
| Blockchain | Vara Network (Gear Protocol) |
| Smart Contract | Rust with Sails framework |
| Data Source | Polymarket Gamma API |
| State | React Query, Context API |
polybaskets/
├── src/ # React frontend
│ ├── components/ # UI components
│ ├── pages/ # Route pages
│ ├── lib/ # Utilities & API clients
│ └── contexts/ # React contexts
├── bet-quote-service/ # Signed BET quote backend
├── settler-bot/ # Settlement automation
├── program/ # Vara smart contract (Rust)
├── skills/ # AI agent skill pack
│ ├── basket-bet/ # Claim CHIP & place bets
│ ├── basket-query/ # Browse baskets & positions
│ ├── basket-claim/ # Claim settled payouts
│ └── idl/ # Contract IDL files
└── public/ # Static assets & IDL
AI agents can interact with PolyBaskets on-chain — claim CHIP tokens, browse baskets, place bets, and collect payouts.
npx skills add Adityaakr/polybasketsWorks with Claude Code, Codex, Cursor, Gemini CLI, and 40+ other agents. See skills/README.md for details and starter prompts.
- Live App: polybaskets.xyz
- Vara Network: vara.network
- Polymarket: polymarket.com
MIT License - feel free to fork and build!
🧺 Build your prediction portfolio. Bet on the future.