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.5xasync 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)
)
]);
}