ferdy-sdk
v0.3.0
Published
TypeScript SDK for Ferdy.bet on-chain casino on Avalanche and MegaETH
Maintainers
Readme
ferdy-sdk
TypeScript SDK for Ferdy.bet — a provably fair, on-chain casino on MegaETH and Avalanche.
Install
npm install ferdy-sdk
# or
pnpm add ferdy-sdkQuick Start
import { FerdyBet } from 'ferdy-sdk';
// Avalanche (default)
const ferdy = FerdyBet.fromPrivateKey(process.env.PRIVATE_KEY!);
// MegaETH
const ferdy = FerdyBet.fromPrivateKey(process.env.PRIVATE_KEY!, { chain: 'megaeth' });
const result = await ferdy.coinflip.play({
choices: ['HEADS', 'TAILS', 'HEADS'],
betPerRound: '0.01',
});
console.log(`Won: ${result.totalWon} ETH`);
console.log(`Profit: ${result.profit} ETH`);
result.rounds.forEach((round, i) => {
console.log(`Round ${i + 1}: ${round.win ? 'WIN' : 'LOSE'} (${round.payout} ETH)`);
});Supported Chains
| Chain | Chain ID | Native Currency | Status | |-----------|----------|-----------------|--------| | Avalanche | 43114 | AVAX | Default | | MegaETH | 4326 | ETH | Supported |
Pass { chain: 'megaeth' } to any factory method to use MegaETH. Avalanche is used when no chain is specified.
Games
All 8 games validate inputs before sending transactions and automatically calculate the 5% rake.
Coinflip
2x multiplier, 50% win chance.
const result = await ferdy.coinflip.play({
choices: ['HEADS', 'TAILS', 'HEADS'],
betPerRound: '0.01',
});Rock Paper Scissors
2x multiplier, 33% win chance.
const result = await ferdy.rps.play({
choices: ['ROCK', 'PAPER', 'SCISSORS'],
betPerRound: '0.01',
});Dice
Select face numbers (1-6). Fewer faces = higher multiplier.
| Faces | Multiplier | |-------|-----------| | 1 | 6x | | 2 | 3x | | 3 | 2x | | 4 | 1.5x | | 5 | 1.2x |
const result = await ferdy.dice.play({
selectedFaces: [1, 2], // Just pass the numbers — SDK handles the rest
numRounds: 5,
betPerRound: '0.01',
});Plinko
Drop 1-100 balls into 7-13 buckets.
const result = await ferdy.plinko.play({
roundCount: 10,
bucketCount: 9,
betPerRound: '0.001',
});Keno
Pick 1-10 numbers from 1-40.
const result = await ferdy.keno.play({
picks: [1, 8, 16], // Just pass the numbers — SDK handles bool[40]
numRounds: 1,
betPerRound: '0.01',
});Wheel
Bet on a color segment.
| Color | Multiplier | Slots | |--------|-----------|-------| | PURPLE | 48x | 1 | | GREEN | 6x | 8 | | YELLOW | 3x | 16 | | GRAY | 2x | 24 |
const result = await ferdy.wheel.play({
color: 'GREEN',
numRounds: 3,
betPerRound: '0.01',
});Slide
Pick a range from 1-95. Narrower range = higher multiplier.
const result = await ferdy.slide.play({
choices: [{ minMark: 1, maxMark: 25 }], // 4x multiplier
betPerRound: '0.01',
});Roulette
Full roulette table with 10 bet types.
const result = await ferdy.roulette.play({
bets: [
{ betAmount: '0.01', betType: 'RED_BLACK', betValue: 0 },
{ betAmount: '0.005', betType: 'NUMBER', betValue: 17 },
],
numRounds: 1,
});Bet types: NUMBER (36x), RED_BLACK (2x), ODD_EVEN (2x), THIRDS (3x), HALVES (2x), ROWS (3x), COLUMNS (12x), PAIR_H (18x), PAIR_V (18x), CORNERS (9x)
Setup
// From private key (Avalanche by default)
const ferdy = FerdyBet.fromPrivateKey('0x...');
// From private key on MegaETH
const ferdy = FerdyBet.fromPrivateKey('0x...', { chain: 'megaeth' });
// From ethers signer
const ferdy = FerdyBet.fromSigner(signer);
const ferdy = FerdyBet.fromSigner(signer, { chain: 'megaeth' });
// With a default referral code
const ferdy = FerdyBet.fromPrivateKey('0x...', {
defaultReferralCode: 'my-ref-code',
});
// Or pass provider + signer directly
const ferdy = new FerdyBet(provider, signer, { chain: 'megaeth' });VRF Methods
Every game accepts an optional vrfMethod to choose the random number source.
| Method | Name | Chains |
|--------|------------|---------------------|
| 1 | Ferdy RNG | Avalanche, MegaETH |
| 0 | Chainlink VRF | Avalanche only |
Ferdy RNG (1) is the default on all chains. On Avalanche you can opt into Chainlink VRF for an on-chain verifiable random source:
// Chainlink VRF (Avalanche only)
await ferdy.coinflip.play({
choices: ['HEADS'],
betPerRound: '0.025',
vrfMethod: 0,
});
// Ferdy RNG (default — works on all chains)
await ferdy.coinflip.play({
choices: ['HEADS'],
betPerRound: '0.025',
});Passing vrfMethod: 0 on MegaETH will throw an error.
Checking Limits
const maxBet = await ferdy.coinflip.getMaxBet(1);
const minBet = await ferdy.coinflip.getMinBet();
const maxRounds = await ferdy.coinflip.getMaxConsecutiveRounds();
const wheelMax = await ferdy.wheel.getMaxBet('PURPLE');
const diceMax = await ferdy.dice.getMaxBet([1, 2]);Multiplier Lookups
Static methods — no RPC calls needed.
import { Dice, Plinko, Slide, Keno, Wheel, Roulette } from 'ferdy-sdk';
Dice.getMultiplier(2); // 3
Plinko.getMultipliers(9); // [20.5, 4, 0.9, ...]
Slide.getMultiplier(1, 50); // 2
Keno.getMultiplier(3, 2); // 3.1
Keno.getPayoutTable(3); // [0, 1, 3.1, 10.4]
Wheel.getSegmentInfo('PURPLE'); // { color: 'purple', multiplier: 48, slots: 1 }
Roulette.getMultiplier('NUMBER'); // 36Bet Calculations
import { calculateTotalValue, calculateRake } from 'ferdy-sdk';
calculateTotalValue('0.01', 5); // Total wei to send (includes 5% rake)
calculateRake('0.01', 5); // Just the rake portionReferrals
// Register your code
await ferdy.setReferralCode('my-code');
// Per-game referral
await ferdy.coinflip.play({
choices: ['HEADS'],
betPerRound: '0.01',
referralCode: 'friend-code',
});
// Default referral for all games
const ferdy = FerdyBet.fromPrivateKey(key, { defaultReferralCode: 'partner' });Event Listening
Watch for game events across all contracts in real time.
ferdy.watch();
ferdy.on('gameStarted', (event) => {
console.log(`Game ${event.gameId} started on ${event.game}`);
console.log(`Bet: ${event.betPerRound} ETH × ${event.numRounds} rounds`);
});
ferdy.on('winnerPicked', (result) => {
console.log(`Game ${result.gameId}: won ${result.totalWon} ETH`);
result.rounds.forEach((r, i) => {
console.log(` Round ${i + 1}: ${r.win ? 'WIN' : 'LOSE'} (${r.payout} ETH)`);
});
});
ferdy.on('error', (err) => console.error(err));
// Stop watching
ferdy.unwatch();Batch Operations
Play multiple games in parallel. All results are returned, even if some fail.
const results = await ferdy.batch([
ferdy.coinflip.play({ choices: ['HEADS'], betPerRound: '0.01' }),
ferdy.dice.play({ selectedFaces: [1, 2], numRounds: 1, betPerRound: '0.01' }),
ferdy.wheel.play({ color: 'GREEN', numRounds: 1, betPerRound: '0.01' }),
]);
results.forEach((r) => {
if (r.status === 'fulfilled') {
console.log(`Won ${r.value.totalWon} ETH`);
} else {
console.error('Failed:', r.reason.message);
}
});Game Result
All play() methods return:
{
gameId: bigint;
rounds: [{
selected: number | number[]; // outcome value
win: boolean; // did this round win?
payout: string; // ETH paid out ('0' if loss)
}];
totalWon: string; // total ETH won
profit: string; // net profit/loss in ETH
}ABIs & Constants
import { CHAINS, ADDRESSES, COINFLIP_ABI, GAME_ABIS, MEGAETH_CHAIN_ID } from 'ferdy-sdk';
// Chain-specific addresses
CHAINS.avalanche.addresses.coinflip; // "0x7d812a58dd63eb3a7b3b84f9290bd84db148893f"
CHAINS.megaeth.addresses.coinflip; // "0xfac05d5F67BD01850378C0C08FB2bC7117045Aa6"
// Default chain addresses (Avalanche)
ADDRESSES.coinflip; // "0x7d812a58dd63eb3a7b3b84f9290bd84db148893f"
MEGAETH_CHAIN_ID; // 4326Networks
| Chain | Chain ID | RPC | Explorer |
|-----------|----------|-----------------------------------------|---------------------------------|
| MegaETH | 4326 | https://mainnet.megaeth.com/rpc | https://mega.etherscan.io |
| Avalanche | 43114 | https://api.avax.network/ext/bc/C/rpc | https://snowtrace.io |
License
MIT
