Complete integration guide with real-world examples and best practices
npm install ethers
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);
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 });
// 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) }); });
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; } }
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
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 }; } }
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; } }
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; }
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) ) ]); }