Zain Sahi
Zain Sahi

Reputation: 135

Contract undefined in thirdweb-dev/react

I am using thirdweb-dev/react to communicate with smart contract but the issue is it is giving me the contract undefined in my code with this error.

query.ts:444 Error: Could not resolve metadata for contract at 0xa2568839fCeE4A9dD05A69C811888cf021DC20B3 at fetchContractMetadataFromAddress

Here is my context file where I am logging the contract.

import { useContext,createContext } from "react";

import { useAddress,useContract,useMetamask,useContractWrite } from "@thirdweb-dev/react";
import { ethers } from "ethers";



// Creating a new context
const StateContext=createContext()



// To use the context, we need a provider that is a function which
// allow us to use the context functionalities in other parts of our app
export const StateContextProvider=({children})=>{

    // contract address 

const crowdFundedAddress='0xa2568839fCeE4A9dD05A69C811888cf021DC20B3';

    // Accessing the contract
    // Pass the contract address to useContract hook

    const {contract}=useContract('0xa2568839fCeE4A9dD05A69C811888cf021DC20B3')
   
    console.log(contract,)

    // In thirdweb, we can call the write functions as follow.
    // Write functions are those in which we pass some data to contract
    // Dummy variable names are also guiding you more

    const {mutateAsync:createProposal}=useContractWrite(contract,'createProposal')

    // Get address of Wallet

    const address=useAddress()

    // Connect the metamask Wallet

    const connect=useMetamask() 

    const publishProposal= async (title,desc,recipientAddress,amount,duration)=>{
        console.log(title,desc,'hi')

        try{

            const data= await createProposal(title,desc,recipientAddress,amount,duration)
        } catch(error){
            console.log(error)
        }


    }

    return(
        <StateContext.Provider value={{address,contract,publishProposal,connect}}>
            {children}

        </StateContext.Provider>
    )

}

export const useStateContext=()=>useContext(StateContext)

Here is index.js file

import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { ChakraProvider } from "@chakra-ui/react";
import { BrowserRouter } from "react-router-dom";
import { ThirdwebProvider,ChainId } from "@thirdweb-dev/react";
import { StateContextProvider } from "./context";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
      <ThirdwebProvider activeChain={ChainId.BinanceSmartChainTestnet}>
    <ChakraProvider>
      <BrowserRouter>
      <StateContextProvider>
        
        <App />
        </StateContextProvider>
      </BrowserRouter>
    </ChakraProvider>
        </ThirdwebProvider >
  </React.StrictMode>
);

Upvotes: 0

Views: 2849

Answers (7)

kihiuFrank
kihiuFrank

Reputation: 121

I had the same problem but using the Sepolia network as Goerli now requires you to have real ETH.

The problem you are facing is related to your network/chainId.

Step 1.

In your hardhat.config.js, have your defaultNetwork as Sepolia, and make sure you have the correct rpc. Thirdweb has provided one here, or copy below.

defaultNetwork: "sepolia",
    networks: {
      hardhat: {},
      sepolia: {
        url: "https://sepolia.rpc.thirdweb.com",
        accounts: [`0x${process.env.PRIVATE_KEY}`],
      },

Step 2

In your main.jsx, you need to import Sepolia from thirdweb dev chains, then set the activeChain as Sepolia. See how to get started with Sepolia.

import { Sepolia } from "@thirdweb-dev/chains";

...

<ThirdwebProvider activeChain={Sepolia}>
    <Router>
      <StateContextProvider>
        <App />
      </StateContextProvider>
    </Router>
  </ThirdwebProvider>

This is what worked for me.

UPDATE

The solution above worked fine but stopped at least for my case. I think it had something with thirdweb updating the SDK.

The issue was the contract metadata seemed not to be fetched. So I decided to copy the contract ABI from the dashboard and provide it to the second parameter of the useContract hook, as explained in the Thirdweb Docs Here.

So the code looks something like this;

Contants Folder / index.js

export const contractAbi = //your_abi_here;

Context Folder / index.jsx


import { contractAbi } from "../constants";

----------------------------------------------------------

 const { contract } = useContract(
    // smart contract address
    "0x2E4B485b4B58a9bd5Fc077CEf7bc1De6C597bA08",
    contractAbi
  );

And Horray!! It works again. Hope this is helpful to someone.

Upvotes: 1

Suraj Patil
Suraj Patil

Reputation: 23

  1. Go to your index.jsx file in the context folder.
  2. Change the code in the file to this one:
  const publishCampaign = async (form) => {
    try {
      const data = await createCampaign({
        args: [
          address, //owner
          form.title, // title
          form.description,  // description
          form.target, // target amount
          new Date(form.deadline).getTime(), // deadline
          form.image, // image
        ],
      });
      console.log("contract call success ", data);
    } catch (error) {
      console.log("contract call failed ", error);
    }
  }
  1. The problem lies in the const data = await createCampaign();. It will be solved with the use of {args: [ ]}

Upvotes: 0

dragon kirin
dragon kirin

Reputation: 1

bro ,I know the reason , first of all be sure your smart contract be deployed to the BSC TESTNET , modify your main.jsx

<ThirdwebProvider activeChain="BinanceSmartChainTestnet" clientId="97"> 

Upvotes: 0

Diyaa Daoud
Diyaa Daoud

Reputation: 86

just check that you have correctly set your chain in the ThirdwebProvider wrapper inside your root file (main.jsx) the documnetation says it must be as follows:

import { YOUR_CHOSEN_NETWORK } from "@thirdweb-dev/chains";
....
<ThirdwebProvider activeChain={YOUR_CHOSEN_NETWORK}>

Upvotes: 0

codetective
codetective

Reputation: 1

I had the same problem and stumbled on this question too.

The answer to your question can be found in the original documentation here useContract - Hook for connecting to a smart contract.

The part you need is this :

The ABI of the smart contract is resolved automatically for contracts deployed or imported using the dashboard.

and

Optionally, (if you don’t want to use the dashboard import feature), you can provide your smart contract’s ABI to the second parameter of the useContract hook. This is useful when developing on a local node, where it may be faster to use the ABI than to import the contract using the dashboard.

The ABI is only necessary if you have not deployed your contract with, or imported your contract to the thirdweb dashboard.

const { contract, isLoading, error } = useContract(
  "contract_address",
  contract_abi,
);

Hope that helps anyone with the same issue.

Upvotes: 0

Vinay Sharma
Vinay Sharma

Reputation: 1

Check your hardhat.config.js and check what is your network there goerli,polygon or any other. Change the chain-id accordingly. For example if polygon then do mumbai matic etc.

Upvotes: 0

Adnan Saif
Adnan Saif

Reputation: 19

I was getting the exact same error but changing the activeChainId did the job for me. In my case, it was defined as "ethereum" I changed it to "goerli" and the error disappeared.

Upvotes: 0

Related Questions