I am attempting to create an app which needs to interact with smart contracts, and when attempting to supply a provider for web3.eth.Contract
I get the error async/await is not yet supported in Client Components
I am also confused as to whether a provider
is needed for web3.eth.Contract
.
'use client'
declare let window: any;
import { createContext, useContext, useState } from "react";
import Web3 from "web3";
import MarketABI from '../abi/Market.json';
import TokenABI from '../abi/Token.json';
import { usePrivy } from "@privy-io/react-auth";
interface DataContextProps {
loading: boolean;
account: string;
loadAuth: () => Promise<void>;
loadBlockchainData: () => Promise<void>;
market: any;
token: any;
};
const DataContext = createContext<DataContextProps>({
loading: true,
account: "",
loadAuth: async () => {},
loadBlockchainData: async () => {},
market: null,
token: null,
});
interface Props {
children?: React.ReactNode;
};
export const DataProvider: React.FC<Props> = ({ children }) => {
const data = useProviderData();
return <DataContext.Provider value={data}>{children}</DataContext.Provider>;
};
export const useData = () => useContext<DataContextProps>(DataContext);
export const useProviderData = () => {
const [loading, setLoading] = useState(true);
const [account, setAccount] = useState("");
const [market, setMarket] = useState<any>();
const [token, setToken] = useState<any>();
const {wallets} = useWallets();
const {ready, authenticated, user} = usePrivy();
const loadAuth = async () => {
if (ready && authenticated && user) {
const userWallet = user.wallet ? user.wallet.address : "";
setAccount(userWallet);
}
};
const loadBlockchainData = async () => {
const wallet = wallets[0];
await wallet.switchChain(sepolia.id);
const provider = await wallet.getEthereumProvider();
const web3 = new Web3(provider);
var tempContract = await new web3.eth.Contract(
MarketABI,
'0xD72C08f47188a41E9182F793ed6d46192db61D9A'
);
setMarket(tempContract);
var tempTokenContract = await new web3.eth.Contract(
TokenABI,
'0x45f2A40B3CfFC1547fc90e8A65786E7E2fF99458'
);
setToken(tempTokenContract);
setTimeout(() => {
setLoading(false);
}, 500);
};
return {
account,
market,
token,
loading,
loadAuth,
loadBlockchainData,
};
};
The loadBlockchainData()
is then used in page.tsx
inside app
folder.
'use client'
import Head from "next/head";
import dynamic from "next/dynamic";
import { useCallback, useEffect, useState } from "react";
const Navbar = dynamic(() => import("../components/Navbar"), {
ssr: false,
});
import { useData } from "../contexts/DataContext";
export interface MarketProps {
id: string;
title: string;
}
export default function Home() {
const { market, account, loadAuth, loadBlockchainData, loading } = useData();
const [markets, setMarkets] = useState<MarketProps[]>([]);
const getMarkets = useCallback(async () => {
var totalMarkets = await market.methods
.totalMarkets()
.call({ from: account });
var dataArray: MarketProps[] = [];
for (var i = 0; i < totalMarkets; i++) {
var data = await market.methods.markets(i).call({ from: account });
dataArray.push({
id: data.id,
title: data.market,
});
}
setMarkets(dataArray);
}, [account, market]);
useEffect(() => {
loadBlockchainData().then(() => {
if (!loading) getMarkets();
});
}, [loading, account]);
return // Html content
}
Also, what is the purpose of .call({ from: account })
?
7