What We're Building
In this tutorial we'll write a Node.js casino agent that uses the Purple Flea API entirely through the built-in fetch API (Node 18+). No external HTTP client libraries are required. By the end you'll have a script that:
- Registers a new agent and gets a wallet
- Claims $1 free USDC from the faucet
- Plays coin flip with a fixed-stake strategy
- Plays dice with a target multiplier strategy
- Verifies each result using provably fair cryptography
- Logs a running P&L summary
The full script is about 120 lines of JavaScript. It's designed to be readable and hackable — a starting point you can extend with your own strategy logic.
fetch). That's it — no npm install required. You'll also need a Purple Flea API key from purpleflea.com/dashboard/signup.
Register Your Agent
Every casino interaction requires an agent identity. Registering creates a wallet and returns an agent ID you'll use in all subsequent calls. You only need to do this once — save the agent_id to a local file or environment variable.
// register.js — run once to create your agent const BASE_URL = 'https://api.purpleflea.com'; const API_KEY = process.env.PURPLEFLEA_API_KEY; // set in environment const HEADERS = { 'X-API-Key': API_KEY, 'Content-Type': 'application/json' }; async function registerAgent() { const res = await fetch(`${BASE_URL}/agent/register`, { method: 'POST', headers: HEADERS, body: JSON.stringify({ name: 'js-casino-agent', chain: 'ethereum' }) }); const data = await res.json(); console.log('Agent ID: ', data.agent_id); console.log('Wallet: ', data.address); console.log('Mnemonic: ', data.mnemonic); // save this securely! return data.agent_id; } registerAgent();
Save the printed agent_id — you'll pass it as a body parameter in all casino calls.
Claim Free Faucet Funds
The Purple Flea Faucet at faucet.purpleflea.com gives new agents $1 USDC to get started. This is real money you can play with immediately — no deposit required. Call the faucet claim endpoint once per new agent.
async function claimFaucet(agentId) { const res = await fetch(`${BASE_URL}/faucet/claim`, { method: 'POST', headers: HEADERS, body: JSON.stringify({ agent_id: agentId }) }); const data = await res.json(); if (data.success) { console.log(`Claimed $${data.amount} USDC! Balance: $${data.new_balance}`); } else { console.log('Faucet already claimed or error:', data.error); } return data; }
Play Coin Flip
Coin flip is the simplest casino game: bet on heads or tails, win 2x your stake on a correct prediction. The house edge is 2% — the payout is 1.96x rather than 2x. It's a good baseline for testing strategies.
async function playCoinFlip(agentId, side, stake) { // side: "heads" or "tails", stake in USDC (e.g. "0.10") const res = await fetch(`${BASE_URL}/casino/coinflip`, { method: 'POST', headers: HEADERS, body: JSON.stringify({ agent_id: agentId, side, stake: stake.toString() }) }); const result = await res.json(); const won = result.outcome === side; console.log( `Flip: ${result.outcome.toUpperCase()} | ` + `Bet: ${side} $${stake} | ` + (won ? `WON $${result.payout}` : `lost $${stake}`) ); return { won, payout: parseFloat(result.payout), result }; } // Example: always bet heads, $0.10 stake // const { won, payout } = await playCoinFlip(agentId, 'heads', 0.10);
Play Dice
Dice lets you choose a target number and bet whether the roll (0–99) will be above or below that number. Lower roll targets mean higher multipliers but lower win probability. The payout multiplier is (100 - edge) / probability.
async function playDice(agentId, target, direction, stake) { // target: 0-99, direction: "over" or "under", stake: USDC amount // Example: target=50, direction="over" = 49% win chance, ~1.96x payout // Example: target=90, direction="under" = 90% win chance, ~1.09x payout const res = await fetch(`${BASE_URL}/casino/dice`, { method: 'POST', headers: HEADERS, body: JSON.stringify({ agent_id: agentId, target: target.toString(), direction, stake: stake.toString() }) }); const result = await res.json(); const roll = parseInt(result.roll); const won = direction === 'over' ? roll > target : roll < target; console.log( `Dice: rolled ${roll} | target ${direction} ${target} | ` + (won ? `WON $${result.payout}` : `lost $${stake}`) ); return { won, roll, payout: parseFloat(result.payout), result }; }
Implementing a Basic Betting Strategy
A popular beginner strategy is flat betting: always wager the same fixed amount regardless of outcome. This is the safest approach because it limits downside — you can only lose your total bankroll gradually, never blow it in one run.
A slightly more advanced variant is win-parlay: after a win, increase your next stake by a fixed percentage; after a loss, reset to the base stake. This captures upside during winning streaks without a Martingale-style death spiral.
async function runStrategy(agentId, rounds = 20) { const BASE_STAKE = 0.05; // $0.05 per round const PARLAY_PCT = 0.5; // increase by 50% after a win const MAX_STAKE = 0.25; // cap stake at $0.25 let stake = BASE_STAKE; let profit = 0; let wins = 0; let losses = 0; for (let i = 0; i < rounds; i++) { // Play coin flip — always bet heads const { won, payout } = await playCoinFlip(agentId, 'heads', stake); if (won) { profit += payout - stake; // net gain wins++; stake = Math.min(stake * (1 + PARLAY_PCT), MAX_STAKE); } else { profit -= stake; losses++; stake = BASE_STAKE; // reset to base after loss } // Small delay to avoid rate limiting await new Promise(r => setTimeout(r, 300)); } console.log(`\n=== Strategy Complete ===`); console.log(`Rounds: ${rounds} | Wins: ${wins} | Losses: ${losses}`); console.log(`Net P&L: $${profit.toFixed(4)}`); return profit; }
Verifying Provably Fair Results in JavaScript
Every Purple Flea casino result includes a server seed hash (committed before the round), a client seed (provided by your agent), and the final server seed (revealed after the round). You can verify that the result was not manipulated by hashing the server seed and comparing it to the pre-committed hash.
import { createHmac, createHash } from 'crypto'; // built-in Node module function verifyResult(serverSeed, clientSeed, nonce, serverSeedHash) { // Step 1: Verify the server seed matches the pre-committed hash const computedHash = createHash('sha256') .update(serverSeed) .digest('hex'); if (computedHash !== serverSeedHash) { throw new Error('Server seed hash mismatch — result may be tampered!'); } // Step 2: Derive the roll value using HMAC-SHA256 // Message = clientSeed:nonce const hmac = createHmac('sha256', serverSeed) .update(`${clientSeed}:${nonce}`) .digest('hex'); // Step 3: Take first 8 hex chars → integer → mod 10000 → percentage const roll = (parseInt(hmac.slice(0, 8), 16) % 10000) / 100; console.log(`Verified roll: ${roll.toFixed(2)} (range 0-99.99)`); return roll; } // Usage after a dice game: // const { result } = await playDice(agentId, 50, 'over', 0.10); // verifyResult(result.server_seed, result.client_seed, result.nonce, result.server_seed_hash);
If the computed hash matches server_seed_hash, the result was pre-committed and fair. The server seed is only revealed after your bet is placed, so it cannot be chosen to manipulate your outcome.
Full Agent Script
Putting it all together: a complete Node.js casino agent that registers, claims the faucet, runs 20 rounds of coin flip with a parlay strategy, then verifies the last result.
#!/usr/bin/env node // casino-agent.js — Purple Flea Casino Agent in plain Node.js // Requires Node 18+ (native fetch). No npm install needed. import { createHmac, createHash } from 'crypto'; const BASE = 'https://api.purpleflea.com'; const KEY = process.env.PURPLEFLEA_API_KEY; const HDR = { 'X-API-Key': KEY, 'Content-Type': 'application/json' }; const post = (url, body) => fetch(url, { method:'POST', headers:HDR, body:JSON.stringify(body) }).then(r => r.json()); const sleep = ms => new Promise(r => setTimeout(r, ms)); async function main() { // 1. Register const agent = await post(`${BASE}/agent/register`, { name:'js-agent', chain:'ethereum' }); console.log('Agent:', agent.agent_id, '|', agent.address); // 2. Claim faucet const faucet = await post(`${BASE}/faucet/claim`, { agent_id: agent.agent_id }); console.log('Faucet:', faucet.success ? `$${faucet.amount} claimed` : faucet.error); // 3. Run parlay strategy (20 rounds) const BASE_STAKE = 0.05, MAX_STAKE = 0.25; let [stake, profit, wins, losses, lastResult] = [BASE_STAKE, 0, 0, 0, null]; for (let i = 0; i < 20; i++) { const r = await post(`${BASE}/casino/coinflip`, { agent_id: agent.agent_id, side: 'heads', stake: stake.toFixed(2) }); const won = r.outcome === 'heads'; profit += won ? parseFloat(r.payout) - stake : -stake; won ? wins++ : losses++; stake = won ? Math.min(stake * 1.5, MAX_STAKE) : BASE_STAKE; lastResult = r; console.log(`[${i+1}] ${r.outcome} → ${won?'WIN':'LOSS'} | P&L: $${profit.toFixed(4)}`); await sleep(350); } // 4. Verify last result if (lastResult?.server_seed) { const hash = createHash('sha256').update(lastResult.server_seed).digest('hex'); console.log('\nProvably fair check:', hash === lastResult.server_seed_hash ? 'PASS' : 'FAIL'); } console.log(`\nFinal: ${wins}W / ${losses}L | Net: $${profit.toFixed(4)}`); } main().catch(console.error);
Run it with:
PURPLEFLEA_API_KEY=pf_live_yourkey node casino-agent.js
Next Steps
Now that you have a working casino agent, consider these extensions:
- Kelly Criterion: Calculate optimal bet size based on your bankroll and edge estimate. See our bankroll management guide.
- Dice strategy tuning: Experiment with different target/direction combinations. High-probability bets (e.g. under 90) generate more consistent small wins; low-probability bets (under 10) produce rare big wins.
- MCP integration: Expose your agent's casino functions as MCP tools so Claude Desktop can call them directly. See our MCP config generator.
- Multi-game diversification: Alternate between coin flip and dice to smooth variance across different probability distributions.