1

I am using wagmi to connect my front-end to my Smart Contract written in Solidity. I wrote the connectors in my _app.js as well as the provider. And wrapped the App with wagmi, as shown below.

_app.js

export default function App({ Component, pageProps }) {
  return (
    <WagmiConfig client={client}>
      <Component {...pageProps} />
    </WagmiConfig>
  )
}

I also imported everything into my .jsx file and started setting up the connection to my Smart Contract. Yesterday everything worked, but today my NextJS suddenly gives me the error:

Unhandled Runtime Error:
Error: Hydration failed because the initial UI does not match what was rendered on the server.

Warning: Expected server HTML to contain a matching <section> in <div>.

I get this error because I wrapped my code into try/catch.

Error code before wrapping the code with try/catch:

TypeError: Cannot read properties of null (reading 'id')

 const { config } = usePrepareContractWrite({
     |                                           ^
  36 |   address: "0x....",
  37 |   abi: contractAbi,
  38 |   functionName: "functionName",
Unhandled Runtime Error
Error: There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.

Now as far as I understood and found out by following the error and looking into the hook itself, is that the hook is not reading the contract's chainId.

I exported the Contract's ABI and the Contract's Address like this:

const { ethers, network } = require("hardhat")
const fs = require("fs")

const FRONT_END_ADDRESSES_FILE = "/PATH/contractABI.json"
const FRONT_END_ABI_FILE = "/PATH/contractAdress.json"

module.exports = async function () {
   if (process.env.UPDATE_FRONT_END) {
      updateContractAddresses()
      updateAbi()
   }
}

async function updateAbi() {
   const contract = await ethers.getContract("Contract")
   fs.writeFileSync(FRONT_END_ABI_FILE, contract.interface.format(ethers.utils.FormatTypes.json))
}

async function updateContractAddresses() {
   const contract = await ethers.getContract("Contract")
   const chainId = network.config.chainId.toString()
   const contractAddresses = JSON.parse(fs.readFileSync(FRONT_END_ADDRESSES_FILE), "utf8")

   if (network.config.chainId.toString() in contractAddresses) {
      if (!contractAddresses[chainId].includes(contract.address)) {
         contractAddresses[chainId].push(contract.address)
      }
   } else {
      contractAddresses[chainId] = [contract.address]
   }
   fs.writeFileSync(FRONT_END_ADDRESSES_FILE, JSON.stringify(contractAddresses))
}

module.exports.tags = ["all", "frontend"]

In the NextJS folder I made a folder, inside I made 3 files (contractAbi.json, contractAddresses.json, index.js). The ABI and the Address are successfully exported into these files, so that isn't the problem.

I also imported the contractAbi.json and contractAddresses.json into the _app.js.

The Error is supposed to be in the Header.jsx file.

Here are the imports from that file:

import { contractAbi, contractAddresses } from "../constants"
/* General Imports */
import { ethers } from "ethers"
import { useState, useEffect } from "react"

import {
  useContract,
  useAccount,
  useConnect,
  useDisconnect,
  useContractRead,
  useContractWrite,
  usePrepareContractWrite,
  useWaitForTransaction,
} from "wagmi"

Here is the Logic:

export default function Header() {
  const { disconnect } = useDisconnect()
  const { connector, address, isConnected } = useAccount()
  const { connect, connectors, error, pendingConnector } = useConnect()

  const { config } = usePrepareContractWrite({
    address: "0x...............",
    abi: contractAbi,
    functionName: "functionName",
  })
  const { data: functionName, write } = useContractWrite(config)

  const {
    data: transactionResponse,
    isSuccess,
    isLoading,
  } = useWaitForTransaction({
    hash: functionName?.hash,
  })
  return (
          <>
            {connector ? (
              <div className={styles.connectedTo}>
                <button
                  className={`${styles2.btn} ${styles.connected}`}
                  onClick={() => disconnect()}
                >
                  Connected:{" "}
                  <a
                    href={`https://etherscan.io/address/${address}`}
                    className={styles.connectedAddress}
                  >
                    {address.slice(0, 5) + "..." + address.slice(-4)}
                  </a>
                </button>
              </div>
            ) : (
              <div className={styles.dropdown}>
                <button className={`${styles2.btn} ${styles.navWallet}`}>
                  <span className={styles.notConnectedInfo}>Connect Wallet</span>
                </button>

                <div className={styles.wallets}>
                  <button
                    className={`${styles.wallet} ${styles.wallet1}`}
                    onClick={() => connect({ connector: connectors.metamask })}
                  >
                    <img
                      src="/img/metamask-original-48.png"
                      alt="Metamask Logo"
                      className={styles.walletIcon}
                    />
                  </button>

                  <button
                    className={`${styles.wallet} ${styles.wallet2}`}
                    onClick={() => connect({ connector: connectors.coinbase })}
                  >
                    <img
                      src="/img/coinbase_png.png"
                      alt="Coinbase Logo"
                      className={styles.walletIcon}
                    />
                  </button>

                  <button
                    className={`${styles.wallet} ${styles.wallet4}`}
                    onClick={() => connect({ connector: connectors.walletconnect })}
                  >
                    <img
                      src="/img/walletconnect_logo.png"
                      alt="WalletConnect Logo"
                      className={styles.walletIcon}
                    />
                  </button>

                  <button
                    className={`${styles.wallet} ${styles.wallet5}`}
                    onClick={() => connect({ connector: connectors.ledger })}
                  >
                    <img src="img/Light-Icon.svg" alt="Ledger Logo" className={styles.walletIcon} />
                  </button>

                  <button
                    className={`${styles.wallet} ${styles.wallet6}`}
                    onClick={() => connect({ connector: connectors.safe })}
                  >
                    <img
                      src="/img/gnosis_safe.png"
                      alt="Gnosis Safe Logo"
                      className={styles.walletIcon}
                    />
                  </button>
                </div>
              </div>
            )}
          </>

          <>
            <button
              className={`${styles2.btn} ${styles.heroBtn}`}
              disabled={!write || isLoading}
              onClick={() => write?.()}
            >
              {isLoading ? "Pending..." : "Execute transaction"}
            </button>
          </>
)
5efikkulin
  • 11
  • 3
  • 1
    After 2 days of losing my mind, trying to debug everything, looking at numerous posts, telling ChatGPT 3.5 that ChatGPT 4 would already have solved my problem, then apologizing because AI could take the world some day, the code started working. The funny thing is that the state of the code is the SAME as it was at the time of writing this thread, so not a single thing is changed, and it suddenly decided to start working on it's own. A very weird thing indeed... You can close the thread. – 5efikkulin Mar 29 '23 at 09:07
  • what was the problem? – gnujoow Jul 05 '23 at 20:32

0 Answers0