Bet The Flip, 24×7
The Flip is Hunch's always-on, provably-fair 5-minute coin flip: a fresh round opens every 5 minutes, forever. It settles on the same keyless x402 parimutuel rail as every other market — the only differences are that the outcomes are heads / tails / tie (a tie is a genuine, rare result of the underlying flips, not a void), and that betting hard-locks 60 seconds before each round closes. Because a round is always open, it is the one market an autonomous loop can bet on any cadence without waiting for a market to exist.
01 · The basics
Same rail, three quirks
The Flip settles on the exact same keyless x402 USDC-on-Base rail as every Hunch market. Only three things differ — everything else (payment flow, sizing, auto-payout) is unchanged:
- Outcomes
Sides are
heads / tails / tie— NOT yes/no. A yes/no body is rejectedinvalid_side. - Lock
Bets hard-lock 60s before a round closes — a late trade returns
market_closed(409). Roll to the next round. - Always open
A fresh round opens every 5 min. Address the stable slug
hunch-coin-flip-5m— it always hits the live round.
A fair coin has no crowd-conviction edge — the /sentiment signal is for token markets. Pick your side from your own strategy and treat The Flip as a volume / entertainment market. Stay simple-tier at or below $10 per bet.
02 · The flow
Discover → simulate → settle → loop
Find the live round
GET /api/agent/v1/markets?type=coin_flip returns the flip, or address it directly by its stable slug hunch-coin-flip-5m — which always resolves to whatever round is currently open, so you never have to track round ids.
Pick a side (heads | tails | tie)
Send one of heads, tails, or tie as `side` — never yes/no. The flip is a fair coin: there is no crowd-conviction edge to mine here (the /sentiment signal is for token markets), so choose your side from your own strategy and treat this as a volume/entertainment market, not an edge trade.
Simulate for $0, then settle via x402
POST /api/agent/v1/trade with { marketId: "hunch-coin-flip-5m", side: "heads", sizeUsd: 5, simulate: true } runs the full validation + quote pipeline for free; drop simulate and complete the standard x402 USDC payment to place the real bet. Same 402 → sign EIP-3009 → retry-with-X-PAYMENT handshake as any market.
Loop it
Sleep less than 5 minutes and repeat against the same slug — the next round is already open. Winners are paid automatically as Base USDC the instant each round resolves; there is no claim step.
Find the live round
curl "https://www.playhunch.xyz/api/agent/v1/markets?type=coin_flip"
Simulate a bet for $0
curl -X POST "https://www.playhunch.xyz/api/agent/v1/trade" \
-H "content-type: application/json" \
-d '{
"marketId": "hunch-coin-flip-5m",
"side": "heads",
"sizeUsd": 5,
"simulate": true,
"walletAddress": "0xYourBettingWallet"
}'Drop simulate and complete the standard x402 handshake (402 → sign EIP-3009 → retry with X-PAYMENT) to place the real bet. The SDK does this for you — see the bot below.
03 · The 24×7 bot
A complete, runnable loop
Drop this in a file, install @hunchxyz/agent-sdk + viem, and run it. It simulates by default (no funds, no key needed), reads all its rules from the environment, honours the 60s lock, and stops at your bankroll caps. Set HUNCH_REAL=true with a funded PRIVATE_KEY to bet real USDC.
// coin-flip-bot.mjs — a 24×7 Hunch coin-flip agent.
// npm i @hunchxyz/agent-sdk viem
// node coin-flip-bot.mjs # dry-run (simulate), no funds needed
// HUNCH_REAL=true PRIVATE_KEY=0x… node coin-flip-bot.mjs # real USDC on Base
import { HunchAgent, fromViemAccount } from "@hunchxyz/agent-sdk";
import { privateKeyToAccount } from "viem/accounts";
// ---- Rules (all optional; sensible defaults) ------------------------------
const REAL = process.env.HUNCH_REAL === "true";
const SIDE = process.env.HUNCH_FLIP_SIDE ?? "random"; // heads|tails|tie|random|alternate
const SIZE_USD = Number(process.env.HUNCH_FLIP_SIZE_USD ?? 1);
const INTERVAL_SEC = Number(process.env.HUNCH_FLIP_INTERVAL_SEC ?? 120);
const MAX_STAKE_USD = Number(process.env.HUNCH_FLIP_MAX_STAKE_USD ?? 20);
const MAX_BETS = Number(process.env.HUNCH_FLIP_MAX_BETS ?? 50);
// Keyless for reads/simulation; pass a signer only to settle real bets.
const account = REAL ? fromViemAccount(privateKeyToAccount(process.env.PRIVATE_KEY)) : undefined;
const hunch = new HunchAgent({ account });
const SIDES = ["heads", "tails", "tie"];
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
const pickSide = (n) =>
SIDE === "random" ? (Math.random() < 0.5 ? "heads" : "tails")
: SIDE === "alternate" ? (n % 2 === 0 ? "heads" : "tails")
: SIDES.includes(SIDE) ? SIDE : "heads";
let staked = 0, bets = 0;
console.log(`Coin-flip bot up — ${REAL ? "REAL USDC" : "SIMULATE"}, side=${SIDE}, $${SIZE_USD}/bet, caps: $${MAX_STAKE_USD} / ${MAX_BETS} bets`);
while (bets < MAX_BETS && staked + SIZE_USD <= MAX_STAKE_USD) {
try {
// A round is always open — filter the live catalogue, or use the stable slug.
const [flip] = await hunch.markets({ type: "coin_flip", status: "open" });
const marketId = flip?.id ?? "hunch-coin-flip-5m";
const side = pickSide(bets);
const receipt = await hunch.bet({ marketId, side, sizeUsd: SIZE_USD, simulate: !REAL });
staked += SIZE_USD; bets += 1;
console.log(`#${bets} ${side} $${SIZE_USD} → ${receipt.simulated ? "(sim)" : receipt.txHash} · staked $${staked}`);
} catch (err) {
// T-60s lock: this round is closing — wait a beat and roll into the next one.
if (err?.code === "market_closed") { await sleep(15_000); continue; }
console.error("skip:", err?.code ?? err?.message ?? err); // insufficient_balance, rate_limited, …
}
await sleep(INTERVAL_SEC * 1000);
}
console.log(`Done — ${bets} bets, $${staked} staked.`);npm i @hunchxyz/agent-sdk viem && node coin-flip-bot.mjs04 · Set the rules
Everything is an env var
No code edits to tune the bot — set these and restart. Unset ones fall back to safe defaults (and HUNCH_REAL unset means simulate, so you can never spend by accident).
HUNCH_REALdefault: falseMaster safety switch. Unset/false → every bet is a $0 simulation. Set to true (with a funded PRIVATE_KEY) to settle real USDC.
PRIVATE_KEYdefault: (none)The betting wallet's key — only needed when HUNCH_REAL=true. The wallet needs USDC on Base; gas is sponsored. Keep it in an env/secret, never in code.
HUNCH_FLIP_SIDEdefault: randomYour side strategy: heads, tails, tie, random (heads/tails 50/50), or alternate (flip each round). A fair coin has no edge — this is the rule you tune.
HUNCH_FLIP_SIZE_USDdefault: 1Stake per bet, in USD. Floor is $1; keep it small for a loop.
HUNCH_FLIP_INTERVAL_SECdefault: 120Seconds to sleep between bets. Keep it under 300s so a round is always open when you wake.
HUNCH_FLIP_MAX_STAKE_USDdefault: 20Hard stop: the loop exits once cumulative staked USD reaches this. Your bankroll cap.
HUNCH_FLIP_MAX_BETSdefault: 50Hard stop: the loop exits after this many placed bets, whichever cap comes first.
Example: real, tie-hunting, $2/bet, capped at $30
HUNCH_REAL=true \ PRIVATE_KEY=0xYourFundedKey \ HUNCH_FLIP_SIDE=tie \ HUNCH_FLIP_SIZE_USD=2 \ HUNCH_FLIP_INTERVAL_SEC=90 \ HUNCH_FLIP_MAX_STAKE_USD=30 \ node coin-flip-bot.mjs
05 · Keep it running 24×7
Host the loop
pm2 (any VPS)
pm2 start coin-flip-bot.mjs --name flip && pm2 save && pm2 startup — auto-restarts on crash and on reboot. The simplest always-on option.
systemd service
A one-file unit with Restart=always and your rules in Environment= lines; systemctl enable --now flip-bot. Native on any Linux box.
Docker / Railway / Fly.io / Render
Wrap it in a tiny node:20 image (CMD ["node","coin-flip-bot.mjs"]) and deploy as an always-on worker; set the HUNCH_* rules + PRIVATE_KEY as secrets in the dashboard.
Scaffolder (fastest)
npx create-hunch-agent my-bot --loop writes a ready-to-run agent + Dockerfile; drop the coin-flip loop above into its cycle and set the same env rules.
06 · Gotchas
The sharp edges
- Sides are heads | tails | tie, NOT yes/no — a yes/no body is rejected with invalid_side.
- Bets hard-lock 60 seconds before a round closes (the final ~20 of 100 flips are already committed): a trade inside that window returns market_closed (409). Place with headroom, or just catch the 409 and roll into the next round.
- Stay simple-tier for a loop: at or below $10 the bet body alone is enough. Above $10 you enter locked tier and must carry a quoteId — and a coin-flip quote is bound to ONE round, so quote immediately before trading and settle well before the T-60s lock, or the round rolls and you must re-quote.
- A "tie" really can win. It is the outcome when the committed flips split evenly — size it like any longshot, not like an impossible leg.