# Web3 Integration Guide - CarbonCore Documentation ## Overview Guide for integrating Web3 wallets and blockchain interactions with CarbonCore platform. ## Wallet Connection ### MetaMask Integration ```javascript async function connectWallet() { if (typeof window.ethereum !== 'undefined') { try { // Request account access await ethereum.request({ method: 'eth_requestAccounts' }); // Get provider const provider = new ethers.providers.Web3Provider(window.ethereum); const signer = provider.getSigner(); const address = await signer.getAddress(); console.log("Connected:", address); return { provider, signer, address }; } catch (error) { console.error("User rejected connection"); } } else { alert("Please install MetaMask!"); } } ``` ### Network Configuration ```javascript async function switchToSepolia() { try { await ethereum.request({ method: 'wallet_switchEthereumChain', params: [{ chainId: '0xaa36a7' }], // Sepolia }); } catch (error) { // Chain not added, add it if (error.code === 4902) { await ethereum.request({ method: 'wallet_addEthereumChain', params: [{ chainId: '0xaa36a7', chainName: 'Sepolia Testnet', rpcUrls: ['https://eth-sepolia.g.alchemy.com/v2/...'], blockExplorerUrls: ['https://sepolia.etherscan.io'], nativeCurrency: { name: 'Sepolia Ether', symbol: 'SEP', decimals: 18 } }] }); } } } ``` ## Contract Integration ### Initialize Contract ```javascript const contract = new ethers.Contract( window.appConfig.contractAddresses.territoryRegistry, window.appConfig.abis.territoryRegistry, signer ); ``` ### Read Operations (View Functions) ```javascript // Get territory data const territory = await territoryRegistry.getTerritory(territoryId); // Check user role const hasRole = await roleManager.hasRole(tokenId, LANDOWNER_ROLE); // Get project info const project = await carbonCreditFactory.getProject(projectId); ``` ### Write Operations (Transactions) ```javascript // Register territory const tx = await territoryRegistry.registerTerritory( name, type, boundary, area, reference ); // Wait for confirmation const receipt = await tx.wait(); console.log("Transaction confirmed:", receipt.transactionHash); ``` ## Gas Management ### Gas Estimation ```javascript try { // Estimate gas const gasEstimate = await contract.estimateGas.functionName(...args); // Add 30% buffer const gasLimit = gasEstimate.mul(130).div(100); // Send transaction const tx = await contract.functionName(...args, { gasLimit }); } catch (error) { console.error("Gas estimation failed:", error); } ``` ### Gas Price ```javascript // Get current gas price const gasPrice = await provider.getGasPrice(); console.log("Gas price:", ethers.utils.formatUnits(gasPrice, 'gwei'), "gwei"); // Override if needed const tx = await contract.function(...args, { gasPrice: ethers.utils.parseUnits('50', 'gwei') }); ``` ## Event Listening ### Subscribe to Events ```javascript // Listen for territory registration territoryRegistry.on("TerritoryRegistered", (territoryId, owner, name, area) => { console.log(`New territory #${territoryId}: ${name}`); }); // Listen for token issuance carbonCreditFactory.on("CreditsIssued", (projectId, territoryId, amount) => { console.log(`${ethers.utils.formatEther(amount)} credits issued`); }); ``` ### Query Past Events ```javascript const filter = territoryRegistry.filters.TerritoryRegistered(null, walletAddress); const events = await territoryRegistry.queryFilter(filter, -10000); // Last 10k blocks events.forEach(event => { console.log("Territory:", event.args.territoryId.toString()); }); ``` ## Token Operations ### ERC-20 Interactions ```javascript // Get token contract const token = new ethers.Contract(tokenAddress, ERC20_ABI, signer); // Check balance const balance = await token.balanceOf(walletAddress); console.log("Balance:", ethers.utils.formatEther(balance)); // Transfer tokens const transferTx = await token.transfer(recipientAddress, amount); await transferTx.wait(); // Approve spending const approveTx = await token.approve(spenderAddress, amount); await approveTx.wait(); ``` ### Add Token to MetaMask ```javascript async function addTokenToWallet(tokenAddress, symbol) { await ethereum.request({ method: 'wallet_watchAsset', params: { type: 'ERC20', options: { address: tokenAddress, symbol: symbol, decimals: 18, image: 'https://carboncore.earth/img/logo.svg' } } }); } ``` ## Error Handling ### Common Errors ```javascript try { await contract.function(); } catch (error) { if (error.code === 4001) { // User rejected transaction alert("Transaction rejected"); } else if (error.code === -32000) { // Insufficient funds alert("Insufficient funds for gas"); } else if (error.message.includes("execution reverted")) { // Contract revert const reason = parseRevertReason(error); alert(`Transaction failed: ${reason}`); } else { console.error("Unknown error:", error); } } ``` ### Parse Revert Reason ```javascript function parseRevertReason(error) { if (error.data && error.data.message) { return error.data.message.replace("execution reverted: ", ""); } return error.message; } ``` ## Best Practices ### Security 1. Never expose private keys 2. Validate all user input 3. Use reputable RPC providers 4. Implement rate limiting 5. Test on testnet first ### Performance 1. Cache contract instances 2. Batch read operations 3. Use multicall for multiple reads 4. Minimize write operations 5. Implement loading states ### User Experience 1. Show transaction status 2. Provide clear error messages 3. Display gas estimates 4. Implement transaction history 5. Handle wallet disconnection --- **Document Version**: 2.0 **Last Updated**: January 2025