Developer Guide

Developer Integration Guide

Complete integration guide with real-world examples and best practices

Quick Start

Prerequisites

  • Node.js 16+ and npm/yarn
  • Web3 wallet (MetaMask, WalletConnect)
  • Basic knowledge of Ethereum and smart contracts
  • Understanding of the Diamond Pattern (EIP-2535)

Installation

npm
npm install ethers

Basic Setup

JavaScript Setup
import { ethers } from 'ethers';

// Contract addresses (replace with actual deployed addresses)
const DIAMOND_ADDRESS = '0x...';
const BETTING_CORE_ABI = []; // ABI for BettingCoreFacet

// Connect to provider
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();

// Create contract instance
const bettingContract = new ethers.Contract(DIAMOND_ADDRESS, BETTING_CORE_ABI, signer);
Core Integration Patterns

1. Event Management

Creating Events (Admin Only)

async function createEvent(eventData) {
    try {
        const eventId = ethers.utils.formatBytes32String(eventData.id);
        const startTime = Math.floor(eventData.startTime / 1000);
        const endTime = Math.floor(eventData.endTime / 1000);
        
        const tx = await bettingContract.createEvent(
            eventId,
            eventData.description,
            startTime,
            endTime
        );
        
        const receipt = await tx.wait();
        console.log('Event created:', receipt.transactionHash);
        
        return { success: true, txHash: receipt.transactionHash };
    } catch (error) {
        console.error('Failed to create event:', error);
        return { success: false, error: error.message };
    }
}

// Usage
await createEvent({
    id: 'MATCH_001',
    description: 'Arsenal vs Chelsea - Premier League',
    startTime: Date.now() + 3600000, // 1 hour from now
    endTime: Date.now() + 7200000    // 2 hours from now
});

Listening for Event Creation

// Listen for EventCreated events
bettingContract.on('EventCreated', (eventId, description, startTime, endTime) => {
    console.log('New event created:', {
        eventId: ethers.utils.parseBytes32String(eventId),
        description,
        startTime: new Date(startTime * 1000),
        endTime: new Date(endTime * 1000)
    });
});

Fetching Event Details

async function getEventDetails(eventId) {
    try {
        const eventIdBytes = ethers.utils.formatBytes32String(eventId);
        const event = await bettingContract.getEvent(eventIdBytes);
        
        return {
            id: ethers.utils.parseBytes32String(event.eventId),
            description: event.description,
            startTime: new Date(event.startTime * 1000),
            endTime: new Date(event.endTime * 1000),
            status: event.status, // 0=Created, 1=Active, 2=Ended, 3=Settled, 4=Cancelled
            totalPool: ethers.utils.formatEther(event.totalPool),
            isResolved: event.isResolved,
            result: event.result
        };
    } catch (error) {
        console.error('Failed to fetch event:', error);
        return null;
    }
}

2. Bet Placement

Placing Bets

async function placeBet(eventId, betType, amount, minOdds) {
    try {
        const eventIdBytes = ethers.utils.formatBytes32String(eventId);
        const betAmount = ethers.utils.parseEther(amount.toString());
        
        // Get current odds first
        const currentOdds = await getCurrentOdds(eventId, betType);
        if (currentOdds < minOdds) {
            throw new Error(`Current odds ${currentOdds} below minimum ${minOdds}`);
        }
        
        const tx = await bettingContract.placeBet(
            eventIdBytes,
            betType, // 0 = Against, 1 = For
            minOdds,
            { value: betAmount }
        );
        
        const receipt = await tx.wait();
        
        // Extract bet ID from events
        const betPlacedEvent = receipt.events?.find(e => e.event === 'BetPlaced');
        const betId = betPlacedEvent?.args?.betId;
        
        return {
            success: true,
            betId: betId,
            txHash: receipt.transactionHash
        };
    } catch (error) {
        console.error('Failed to place bet:', error);
        return {
            success: false,
            error: error.message
        };
    }
}

// Usage
const result = await placeBet('MATCH_001', 1, 0.1, 15000); // Bet 0.1 ETH on "For" with min odds 1.5x

Claiming Winnings

async function claimWinnings(betId) {
    try {
        const tx = await bettingContract.claimWinnings(betId);
        const receipt = await tx.wait();
        
        return {
            success: true,
            txHash: receipt.transactionHash
        };
    } catch (error) {
        console.error('Failed to claim winnings:', error);
        return {
            success: false,
            error: error.message
        };
    }
}

3. Market Data Integration

Getting Current Odds

async function getCurrentOdds(eventId, betType) {
    try {
        const ammContract = new ethers.Contract(DIAMOND_ADDRESS, AMM_ABI, provider);
        const eventIdBytes = ethers.utils.formatBytes32String(eventId);
        
        const prices = await ammContract.getMarketPrices(eventIdBytes);
        
        return betType === 1 ? prices.oddsFor : prices.oddsAgainst;
    } catch (error) {
        console.error('Failed to get odds:', error);
        return 0;
    }
}
Error Handling & Best Practices

Input Validation

function validateEventId(eventId) {
    if (!eventId || typeof eventId !== 'string') {
        throw new Error('Event ID must be a non-empty string');
    }
    if (eventId.length > 31) {
        throw new Error('Event ID too long (max 31 characters)');
    }
    return true;
}

function validateBetAmount(amount) {
    if (!amount || amount <= 0) {
        throw new Error('Bet amount must be positive');
    }
    if (amount > 100) { // Reasonable maximum
        throw new Error('Bet amount too large');
    }
    return true;
}

Safe Contract Interactions

async function safeContractCall(contract, method, args = [], options = {}) {
    // Check if contract exists
    const code = await contract.provider.getCode(contract.address);
    if (code === '0x') {
        throw new Error('Contract not deployed at this address');
    }
    
    // Validate method exists
    if (!contract[method]) {
        throw new Error(`Method ${method} not found on contract`);
    }
    
    // Execute with timeout
    const timeoutMs = options.timeout || 30000;
    
    return Promise.race([
        contract[method](...args, options),
        new Promise((_, reject) => 
            setTimeout(() => reject(new Error('Transaction timeout')), timeoutMs)
        )
    ]);
}