Predict “Yes / No” with AI-assisted picks.
PolySwarms is a Solana-native prediction market. Users create and trade binary (YES/NO) markets. An optional agent analyzes signals and nudges the best side with transparent confidence and reasoning. Settlements are instant after resolution.
Overview
Key features
- Binary markets with SOL escrow and receipt logs.
- AI hints: side recommendation, confidence, suggested stake.
- Creators can open markets; Resolvers finalize outcomes.
- Auditable events & receipts for indexers/analytics.
State model (high level)
- Account:
Market(PDA) — metadata, status, close time, resolver. - Account:
Pool(PDA) — YES/NO escrowed SOL. - Account:
Bet(PDA) — per user per market per side. - Authority:
Resolver— signs resolution; anyone can verify.
Quickstart
Run the reference dapp locally and connect Phantom. Start with intent mode (signMessage) and switch to on-chain once the Anchor program is deployed.
Clone & run the dapp
# 1) Clone
git clone https://github.com/your-org/polyswarms-dapp.git
cd polyswarms-dapp
# 2) Configure environment (see <Environment> section)
cp .env.example .env
# 3) Start (Vite/Next/Static)
npm i && npm run dev
Without the on-chain program, the dapp still shows AI hints and signed bet intents (great for UX tests and receipts).
Install toolchain
Solana CLI
sh -c "$(curl -sSfL https://release.solana.com/stable/install)"
solana --version
solana config set --url https://api.mainnet-beta.solana.com # mainnet
# or testnet:
solana config set --url https://api.testnet.solana.com
Rust & Anchor (macOS)
# Rust toolchain
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env
rustc --version
# Anchor
npm i -g @coral-xyz/anchor-cli
anchor --version
Program architecture
Accounts
- Market — creator, resolver, status {Open,Closed,Resolved}, fee_bps.
- Pool — PDA per market per side; holds SOL until resolution.
- Bet — user stake and claim status.
Instructions
create_market— init market + pools (YES/NO).place_bet— transfer SOL → pool; update user bet.close— stop new bets, awaiting resolution.resolve— resolver sets outcome {Yes|No}.claim— winners withdraw pro-rata (minus fee).
Before program live, attach a Memo with bet intent so indexers can track decisions while contracts iterate.
Market lifecycle
- Create — market parameters, resolver, cutoff time.
- Open — users place YES/NO bets.
- Close — betting stops; waiting oracle/resolver.
- Resolve — resolvers post the outcome; event emitted.
- Claim — winners withdraw; fees go to fee vault.
Fees
- Protocol fee: 100 bps (1%) from winners on claim.
- Creator fee (optional): 25 bps.
- Resolver fee (optional): 25 bps.
Security
- SOL flows via PDAs; no arbitrary transfers.
- Close time checks; re-entrancy safe patterns.
- Resolver set on creation (optionally multi-sig).
- Events for every move → indexable/auditable.
Smart contracts (Anchor)
Compact skeleton for core instructions. Expand into programs/polyswarms.
// programs/polyswarms/src/lib.rs
use anchor_lang::prelude::*;
declare_id!("YourProgram1111111111111111111111111111111111");
#[program]
pub mod polyswarms {
use super::*;
pub fn create_market(ctx: Context<CreateMarket>, params: CreateParams) -> Result<()> { /* ... */ Ok(()) }
pub fn place_bet(ctx: Context<PlaceBet>, side: Side, amount: u64) -> Result<()> { /* ... */ Ok(()) }
pub fn close(ctx: Context<AuthMarket>) -> Result<()> { /* ... */ Ok(()) }
pub fn resolve(ctx: Context<AuthMarket>, outcome: Side) -> Result<()> { /* ... */ Ok(()) }
pub fn claim(ctx: Context<Claim>) -> Result<()> { /* ... */ Ok(()) }
}
#[account] pub struct Market { /* creator, resolver, status, fee_bps, close_ts, outcome */ }
#[account] pub struct Bet { /* user, market, side, amount, claimed */ }
#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq, Eq)] pub enum Side { Yes, No }
#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq, Eq)] pub enum Status { Open, Closed, Resolved }
Build & deploy
anchor build
solana address -k target/deploy/polyswarms-keypair.json
anchor deploy
IDL & program ID
Expose IDL at /idl/polyswarms.json and place PROGRAM_ID in the dapp .env.
Dapp integration
- Intent mode (default early): sign a structured message for a verifiable bet intent.
- On-chain mode: call Anchor
place_betand send the tx.
Intent mode (signMessage)
// Typed "bet intent" via Phantom
const msg = `PolySwarms Bet | market=${marketId} | side=${side} | amount=${amount} SOL | ts=${Date.now()}`;
const enc = new TextEncoder();
const { signature } = await window.solana.signMessage(enc.encode(msg), 'utf8');
On-chain mode (Anchor)
import { Program, AnchorProvider, web3, BN, Idl } from "@project-serum/anchor";
import idl from "./idl/polyswarms.json";
const provider = new AnchorProvider(new web3.Connection(RPC_URL, "confirmed"), window.solana, {});
const program = new Program(idl as Idl, PROGRAM_ID, provider);
await program.methods.placeBet({ side: { yes: {} }, amount: new BN(lamports) })
.accounts({ /* market, pool, bet, user, systemProgram */ })
.rpc();
AI Assist API
Endpoint
POST /api/ai/hint
Content-Type: application/json
{ "marketId":"m3", "question":"Will SOL daily active wallets exceed 2M this month?" }
Response
{ "side":"YES", "confidence":0.67, "oddsYes":0.65, "stake":0.12, "reason":"Momentum + inflows ..." }
Environment
.env (frontend)
VITE_PROGRAM_ID=<YourProgram1111111111111111111111111111111111>
VITE_RPC_URL=<https://api.mainnet-beta.solana.com>
VITE_AI_API=/api/ai/hint
Server (optional)
// Express example
app.post('/api/ai/hint', async (req,res) => {
const { question } = req.body || {};
return res.json({ side:"YES", confidence:0.63, oddsYes:0.61, reason:"Signals favor YES" });
});
Troubleshooting
Phantom popup doesn’t show
- Ensure Phantom installed & unlocked.
- Call
window.solana.connect()before signing.
RPC / balance issues
- Use your own endpoint (Helius/Alchemy/QuickNode).
- Match cluster with wallet network.
Anchor build errors
rustup default stable- Upgrade Anchor CLI.
FAQ
Is AI mandatory?
No. Markets function without AI. Hints are opt-in and transparent.
Who resolves a market?
The resolver set on creation (governance/oracle compatible).
When on-chain?
Once the Anchor program is deployed. UI already supports the swap.
Changelog
- 2025-11-07 · Docs v2. TOC moved to top, single-column, compact typography.
PolySwarms