5. Load Contract EVM data
info
For this part you may have to be comfortable with web3.js, a library that facilitates tapping into web3.0
Make sure you read the documentation before you start.
For this part we will the JSON-RPC Relay. So make sure you have the endpoint in your config variables if you haven't done so already.
5.1 Map Solidity based data
Open @types/contract.ts
export interface Contract { contractRestApi: ContractRestApi; contractSolData: ContractSolData;}export interface ContractSolData { contractInfo: ContractSolInfo; fairTradeDonators?: ContractSolDataDonators[]; contractBalance: number;}export interface ContractSolInfo { creatorName: string; tokenAddress: string; tokenName: string; tokenSupply: string; tokenSymbol: string;}export interface ContractSolDataDonators { amount: string; from: string; message: string; name: string; timestamp: string;}
5.2 Setup the contract and get methods
- Go to handlers/contract.handler.ts
- Copy/verify this piece of code to get the data from the contract
See below how to load the contract in a variable and use
import { MetamaskService } from "./metamask.handler";import appConfig from "@/config/appConfig";import { ContractSolInfo } from "@/types/contracts";import Web3 from "web3";import { Contract } from "web3-eth-contract";// Main init varsconst providerUrl = appConfig.arkhiaApi.getJsonRpcUrl();const web3 = new Web3(providerUrl);// Abi from your compiled contractconst abi = `<YOUR_ABI_HERE>`;const contractjJson = JSON.parse(abi);// Get the evm const contractId = appConfig.demoValues.fairTradeValues.ftc_contract_solidity_id;// Web3 for metadataconst fairTradeContract = new web3.eth.Contract(contractjJson, contractId);// let fairTradeCoffeeDataCache: ContractSolInfo = { creatorName: ``, tokenAddress: ``, tokenName: ``, tokenSupply: ``, tokenSymbol: ``};const getContractBalance = async () => { const balance = await web3.eth.getBalance(contractId); const balanceHbars = Math.round(Number(Web3.utils.fromWei(balance.toString())) * 100) /100; return balanceHbars;};const getContractMetadata = async () : Promise<ContractSolInfo> => { fairTradeCoffeeDataCache = await fairTradeContract.methods.getContractMetadata().call(); return fairTradeCoffeeDataCache;};const getFairTradeBuyers = async () => { const getFairTradeBuyers = await fairTradeContract.methods.getFairTradeBuyers().call(); return getFairTradeBuyers;};const getFairTradeBuyerNumbers = async () => { const getFairTradeBuyerNumbers = await fairTradeContract.methods.getFairTradeBuyerNumbers().call(); return getFairTradeBuyerNumbers;};export const ContractHandler = { getContractBalance, getContractMetadata, getFairTradeBuyers, getFairTradeBuyerNumbers,};
5.3 Load the data under the FairTradeDemoExercise.jsx
Add a new React hook, and leverage useEffect() to load the contract api data. Something like this below.
// type created previously const [solContract, setSolContract] = useState<ContractSolData>(); const [loadingEvmContractData, setLoadingEvmContractData] = useState(false); const getEvmContractData = async () => { try { setLoadingEvmContractData(true); const contractInfo: ContractSolInfo = await ContractHandler.getContractMetadata(); const contractFairTradeBuyers = await ContractHandler.getFairTradeBuyers(); const contractBalance = await ContractHandler.getContractBalance(); const contractSol: ContractSolData = { contractInfo, contractBalance, fairTradeDonators: contractFairTradeBuyers }; setSolContract(contractSol); setLoadingEvmContractData(false); } catch(e) { console.error(e); setErrorMessage(errorMessageText); } };
Then under the jsx part render the contract after its loaded. See more fields and add what you may deemed necessary.
<Box display={`flex`} justifyContent={`center`}> { loadingEvmContractData ? <CircularProgress></CircularProgress> : <Button onClick={getEvmContractData}>Load EVM Contract Data</Button> } </Box>
info
Fetching data from the Contract stored on the EVM has more caveats to it.
Also be wary these calls will be potentially charged and slower.