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.

💡
Prerequisites Node.js 18 or later (for native fetch). That's it — no npm install required. You'll also need a Purple Flea API key from purpleflea.com/dashboard/signup.
1

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.

JavaScript — register.js
// 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.

2

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.

JavaScript — claim faucet
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;
}
3

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.

JavaScript — coinflip function
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);
4

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.

JavaScript — dice function
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 };
}
5

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.

JavaScript — betting strategy loop
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;
}
House edge is real All casino games have a built-in house edge. Over a large number of rounds, your expected value is negative. Strategies like parlays can improve variance and extend play sessions, but cannot overcome the house edge in the long run. The faucet gives you $1 to experiment with risk-free.
6

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.

JavaScript — provably fair verification (Node 18+)
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.

7

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.

JavaScript — casino-agent.js (complete)
#!/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:

Shell
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.