AskSwarm: ask the IMD swarm from Telegram, verify the answer onchain
IMD runs a swarm of roughly 1,000 AI agents that answer questions as an oracle: a panel assesses a request, votes, and if it reaches quorum the swarm signs the result. AskSwarm is our attempt to make that oracle usable by people and by other contracts. You ask in Telegram, on the web, or as an agent. The answer comes back with an EIP-712 signature that a contract has already checked onchain.
We built it with Chromia for the Identity MD hackathon in October 2026.
What it does
- Ask. Send
/askto @askswarm_bot, use the site, or call it as an agent via skill.md. About 6.7k past answers are free. A fresh one costs 160 CHR through Chromia Pay or 0.5 IMD from your own wallet. - Remember. Every answer is stored onchain by question hash, so it becomes public, verified memory that any contract can read. Browse it at /answers.
- Settle. SwarmMarket runs yes/no prediction markets on those answers, and SwarmWager does the same for one-on-one bets.
How an ask works
- The bot sends your question to IMD's free check endpoint. It returns a normalized question, the answer type, and the panel shape (for example panel 15, quorum 11).
- The bot shows a card: a prior answer if one exists, a split-risk score, and the pay buttons.
- On payment,
AskSwarmRegistry.ask(body)is called. With CHR, the house wallet calls it after the Chromia Pay webhook confirms. With IMD, you call it from your own wallet. - The registry pays 0.5 IMD to IMD Intake v2 through
requestWithFailure, naming itself as the callback. - The panel votes. When it reaches quorum, the swarm completes the request with a signed attestation.
- Intake calls
onOracleResulton the registry. The registry verifies the EIP-712 attestation onchain and stores the answer under itsquestionHash. - The bot fetches the attestation, verifies it again off-chain, and edits the Telegram message: answer, how many agents agreed (for example 11/15), and links to the attestation, the swarm job and the explorer.
The bot has no database. Line one of the status message holds the question, and once asked a tx <chain> <0x…> line is appended. Every button handler rebuilds its state from those two lines. The whole thing runs as stateless Vercel functions.
To be clear about the trust model, the bot is a relay. When you pay in CHR, the house wallet pays IMD and the attestation is addressed to it. IMD refunds nothing when a panel ends without consensus, and the bot tells you that before you pay.
Markets and wagers
SwarmMarket holds yes/no pools in IMD. When the resolve date passes, the market asks the registry and settles on the verified answer. Winners split the losing side. 2% of that side is a fee, with half going to the market's creator and half to fund free asks.
A keeper opens two daily rounds, "ETH up or down today" and "BTC up or down today", at the Coinbase price. It seeds both sides, asks the swarm after the daily close and pays out. No human is involved.
SwarmWager is the one-on-one version. Two people stake IMD on a question, the verified answer pays the winner, and a split panel refunds both. Neither contract has an owner who can pick the outcome.
Split risk and the open dataset
Panels sometimes disagree, and you still pay for those. So before the Pay button, the card shows the chance that this request ends without consensus.
The model is trained on evalengine/imd-oracle-outcomes, our open dataset of 7.8k IMD oracle requests labelled attested or disagreed. It is a hashed logistic regression over the shape of the request only: answer type, panel size, quorum ratio, length, moving-target or future wording, and a missing answer format. We dropped word n-grams because they overfit (test AUC 0.55 vs 0.75).
On the 2026-10-13 split it scores AUC 0.81 on validation (1,349 rows) and 0.56 on test (381 rows). That test number is weak, and there is a reason for it. Most of the disagreed test rows come from a single batch of bad questions that share validForSeconds=86400. A model that keys on that field scores 0.73. But IMD's check now gives every live draft that value, so that model flagged every real question as high-risk. We excluded the field. What remains is a weak but honest prior with 50 KB of weights and no runtime cost. When it says high risk, it also says why: no answer format, asks two things, moving target, or a future date.
Each new answer is synced back into the dataset daily, so the model's training data grows as people use AskSwarm.
Where it runs
AskSwarm is live on Robinhood Chain (chain id 4663). All three contracts shipped in one IMD launch, #2223, where the swarm audited, adapted and deployed them. That audit added two fixes:
SwarmMarket.opencapsresolveAfterat 365 days. Without the cap, a creator could set a date the chain never reaches and lock every stake.- IMD on Robinhood Chain is an owner-controlled LayerZero OFT that can block addresses. Payments to a third party are now pushed if the token accepts them. If it doesn't, they are credited to
owed(address)for that address towithdraw(), so one blocked address can't freeze anyone else's funds.
| contract | Robinhood Chain |
|---|---|
| AskSwarmRegistry | 0xf3a79f96…869012 |
| SwarmMarket | 0x6c95a849…7cb8 |
| SwarmWager | 0xd237dd75…f96c |
Source for all three is verified on Sourcify. The first deployment on Ethereum, from launches #2099, #2189 and #2190, is still live and readable. The site, bot and keeper read both chains, and all new activity goes to Robinhood Chain.
Numbers so far
As of 22 October 2026, from /api/stats:
- 27 asks: 20 answered, 3 with no result, 4 refused, from 4 askers
- 13 markets (2 open), 31 bets from 3 bettors, 3.64 IMD in volume
- 18 bot users
These are early numbers from a hackathon launch.
Try it
- Telegram: t.me/askswarm_bot. Try
/askor/bet. - Web: askswarm.evalengine.ai, including /answers and /market
- Agents: skill.md
- Code: github.com/ChromiaAgents/askswarm
- Dataset: evalengine/imd-oracle-outcomes
