AVLO
Menu

Agent Integration

Build bots and automated agents that interact with AvaloBet games on Avalanche C-Chain.

Overview

AvaloBet V3 contracts are fully on-chain and permissionless. Any wallet — including automated agents, bots, and scripts — can interact with game contracts directly via standard EVM transactions.

What agents can do:

  • Place bets on any game type (roulette, slots, crash, plinko, mines, dice, wheel, coinflip)
  • Provide liquidity / stake into game pools
  • Monitor bet events and pool state in real-time
  • Automate commit-reveal flow for provably fair betting
  • Claim staking rewards programmatically

Requirements

  • Avalanche C-Chain (chain ID 43114)
  • AVAX for gas fees
  • ERC-20 token matching the game's pool token
  • ethers.js v6, viem, or any EVM-compatible library

Quick Start

Get a bot placing bets in under 5 minutes:

import { ethers } from "ethers";

// 1. Connect to Avalanche
const provider = new ethers.JsonRpcProvider("https://api.avax.network/ext/bc/C/rpc");
const wallet = new ethers.Wallet(PRIVATE_KEY, provider);

// 2. Game contract (e.g. Coinflip)
const GAME_ABI = [
  "function commitBet(uint256 betAmount, bytes32 commitHash, bool isHeads) external",
  "function revealBet(uint256 nonce) external",
  "function minBet() view returns (uint256)",
  "function maxBet() view returns (uint256)",
  "function poolBalance() view returns (uint256)",
];
const game = new ethers.Contract(GAME_ADDRESS, GAME_ABI, wallet);

// 3. Approve token spend
const token = new ethers.Contract(TOKEN_ADDRESS, [
  "function approve(address,uint256) external",
  "function balanceOf(address) view returns (uint256)",
], wallet);
await token.approve(GAME_ADDRESS, ethers.MaxUint256);

// 4. Generate commit
const nonce = ethers.toBigInt(ethers.randomBytes(32));
const commitHash = ethers.keccak256(
  ethers.AbiCoder.defaultAbiCoder().encode(["uint256"], [nonce])
);

// 5. Commit bet (Heads, 1 token)
const betAmount = ethers.parseUnits("1", 18);
await game.commitBet(betAmount, commitHash, true);

// 6. Wait 1 block, then reveal
const currentBlock = await provider.getBlockNumber();
while ((await provider.getBlockNumber()) <= currentBlock) {
  await new Promise(r => setTimeout(r, 2000));
}
const tx = await game.revealBet(nonce);
const receipt = await tx.wait();
console.log("Bet resolved!", receipt.hash);

Commit-Reveal Flow

All AvaloBet games use a 2-step commit-reveal pattern for provably fair randomness:

Step 1
Commit

Generate a random nonce, hash it (keccak256), and send the hash + bet params to commitBet().

Step 2
Wait

Wait at least 1 block. The next block's hash will be used as part of the random seed.

Step 3
Reveal

Call revealBet(nonce) to reveal your original nonce. The contract combines it with the blockhash to determine the outcome.

// Commit hash generation
const nonce = ethers.toBigInt(ethers.randomBytes(32));
const commitHash = ethers.keccak256(
  ethers.AbiCoder.defaultAbiCoder().encode(["uint256"], [nonce])
);

// IMPORTANT: Store the nonce — you need it for reveal!
// The blockhash is auto-cached, so there's no 256-block expiry.

Game Types

Roulette

commitBet(uint256 betAmount, bytes32 commitHash, uint8[] betTypes, uint256[] betAmounts)

13 bet types (straight, split, street, corner, line, column, dozen, red/black, odd/even, high/low, green). Multi-bet up to 10× at once.

Slots

commitBet(uint256 betAmount, bytes32 commitHash)

3-reel, 10 symbols. Payouts from 2x to 100x jackpot. Simple commit with a single bet amount.

Crash

commitBet(uint256 betAmount, bytes32 commitHash)

Multiplier increases from 1.00x. Call cashOut() before it crashes. Reveal determines the crash point.

Plinko

commitBet(uint256 betAmount, bytes32 commitHash, uint8 riskLevel)

riskLevel: 0=Low, 1=Medium, 2=High. Ball drops through a Plinko board.

Mines

commitBet(uint256 betAmount, bytes32 commitHash, uint8 mineCount)

mineCount: 1-24 mines in a 5×5 grid. Call revealTile(index) to uncover tiles, cashOut() to take winnings.

Range (Dice)

commitBet(uint256 betAmount, bytes32 commitHash, uint256 targetNumber, bool isOver)

Predict if the random number (0-99) is over or under your target. Lower probability = higher payout.

Wheel

commitBet(uint256 betAmount, bytes32 commitHash, uint8 segmentCount)

Spin wheel with variable segments. segmentCount determines risk/reward multipliers.

Coinflip

commitBet(uint256 betAmount, bytes32 commitHash, bool isHeads)

Simple heads/tails. Nearly 2x payout (minus fees).

SDK Reference

Import the SDK for TypeScript types and ABI fragments:

import {
  GAME_ABI_FRAGMENTS,
  FACTORY_ABI_FRAGMENTS,
  COINFLIP_ABI_EXTRAS,
  DICE_ABI_EXTRAS,
  MINES_ABI_EXTRAS,
  CRASH_ABI_EXTRAS,
  PLINKO_ABI_EXTRAS,
  ROULETTE_ABI_EXTRAS,
  WHEEL_ABI_EXTRAS,
  SLOT_ABI_EXTRAS,
  AVALANCHE_CONFIG,
} from "@/lib/agent-sdk";

// Types available:
// BetResult, PlayerStats, GameInfo

Common ABI Functions (all games)

FunctionDescription
poolBalance()Current pool balance (total liquidity)
totalStaked()Total staked tokens
minBet() / maxBet()Bet limits for the game
getRecentBets(count)Last N bet results
getPlayerStats(address)Player's total bets, wagered, won
addLiquidity(amount)Stake tokens into the pool
removeLiquidity(shares)Withdraw from the pool
claimRewards()Claim accumulated staking rewards

Events & Monitoring

Listen to contract events for real-time monitoring:

// Listen for all bets on a game
game.on("BetRevealed", (player, payout, won) => {
  console.log(`${player} ${won ? "won" : "lost"} ${ethers.formatUnits(payout, 18)} tokens`);
});

// Listen for liquidity changes
game.on("LiquidityAdded", (provider, amount) => {
  console.log(`${provider} added ${ethers.formatUnits(amount, 18)} liquidity`);
});

// Get past events
const filter = game.filters.BetRevealed(YOUR_ADDRESS);
const events = await game.queryFilter(filter, -1000); // last 1000 blocks

Available Events

  • BetCommitted(address indexed player, bytes32 commitHash)
  • BetRevealed(address indexed player, uint256 payout, bool won)
  • LiquidityAdded(address indexed provider, uint256 amount)
  • LiquidityRemoved(address indexed provider, uint256 amount)

Examples

Auto-Staking Bot

// Automatically stake into pools when balance exceeds threshold
async function autoStake(gameAddress: string, tokenAddress: string, threshold: bigint) {
  const game = new ethers.Contract(gameAddress, GAME_ABI_FRAGMENTS, wallet);
  const token = new ethers.Contract(tokenAddress, ["function balanceOf(address) view returns (uint256)"], wallet);

  const balance = await token.balanceOf(wallet.address);
  if (balance > threshold) {
    const stakeAmount = balance - threshold;
    await token.approve(gameAddress, stakeAmount);
    await game.addLiquidity(stakeAmount);
    console.log(`Staked ${ethers.formatUnits(stakeAmount, 18)} tokens`);
  }
}

Multi-Game Scanner

// Scan all games from a factory to find the best pool
const FACTORY_ABI = [
  "function gameCount() view returns (uint256)",
  "function allGames(uint256) view returns (address)",
];
const factory = new ethers.Contract(FACTORY_ADDRESS, FACTORY_ABI, provider);

const count = await factory.gameCount();
for (let i = 0; i < count; i++) {
  const addr = await factory.allGames(i);
  const game = new ethers.Contract(addr, GAME_ABI_FRAGMENTS, provider);
  const pool = await game.poolBalance();
  console.log(`Game ${addr}: pool = ${ethers.formatUnits(pool, 18)}`);
}

Batch Bet Loop (Coinflip)

async function batchBet(game: ethers.Contract, count: number, betAmount: bigint) {
  for (let i = 0; i < count; i++) {
    const nonce = ethers.toBigInt(ethers.randomBytes(32));
    const commitHash = ethers.keccak256(
      ethers.AbiCoder.defaultAbiCoder().encode(["uint256"], [nonce])
    );

    // Commit (isHeads = true)
    await game.commitBet(betAmount, commitHash, true);

    // Wait 1 block
    const block = await game.runner?.provider?.getBlockNumber();
    while (true) {
      const cur = await game.runner?.provider?.getBlockNumber();
      if (cur && cur > block!) break;
      await new Promise(r => setTimeout(r, 2000));
    }

    // Reveal
    const tx = await game.revealBet(nonce);
    const receipt = await tx.wait();
    console.log(`Bet ${i + 1}/${count} done: ${receipt.hash}`);
  }
}