this is my first post here. I have spent the requisite day+ on my own trying all I know with my limited abilities at present, but all to no avail. I come here seeking aid with the following issue then:
I have finished a web3 development site. Everything is good to go except actually making the transactions submit to the blockchain when I click the 'send payment' button. To do that part I was following this tutorial: https://www.youtube.com/watch?v=Wn_Kb3MR_cU. That tutorial uses React however, I am using NextJS.
I have been using ethers but went so far as to completely go another route using web3 and detectEthereumProvider npm package.
I have console logged and seen that I am in fact getting a provider and a contract, everything seems to be working, however every time I click the little blue payment button I get the same deflating response - Error: No Ethereum Object!
Please help me to get this last piece of my puzzle in place, it is quite a keystone as it turns out.
My code is below, with unnecessary filler removed such as unrelated UI imports, tailwinds CSS classes, ect. Thank you very much for helping me and taking the time out of your busy day's (or nights). I look forward to becoming an active member of this community.
I KNOW that the window object is not available on NextJS - I am using NextJS so please keep that in mind with any assistance given and thank you very much again and apologies if my code here looks busted/ugly!!!
import { createContext, useEffect, useState } from "react";
import {ethers} from 'ethers'
import { contractABI, contractAddress } from "@utils/constants";
export const TransactionContext = createContext()
const getEthereumContract = () => {
const provider = new ethers.providers.Web3Provider(window.ethereum)
console.log(ethereum);
const signer = provider.getSigner()
const transactionContract = new ethers.Contract(contractAddress, contractABI, signer)
return transactionContract
}
export const TransactionProvider = ({children}) => {
const [currentAccount, setCurrentAccount] = useState("");
const [formData, setFormData] = useState({
addressTo: "",
amount: "",
message: ""
})
const [isLoading1, setIsLoading1] = useState(false)
const [transactionCount, setTransactionCount] = useState(0)
const handleChange = (e, name) => {
setFormData((prevState) => ({
...prevState,
[name]:e.target.value }))
}
useEffect(() => {
if(typeof window.ethereum !== 'undefined' || (typeof window.web3 !== "undefined")){
const {ethereum} = window
}
},[])
const checkIfWalletIsConnected = async () => {
try {
if(!ethereum) return alert("You must install MetaMask.")
const accounts = await ethereum.request({method: 'eth_accounts'})
if(accounts.length){
setCurrentAccount(accounts[0])
}
//get all TXs
} catch (error) {
throw new Error("No ethereum object!")
}
}
const sendTransaction1 = async () => {
try {
if(!ethereum) return alert("You must install MetaMask.")
const { addressTo, amount, message} = formData
const transactionContract = getEthereumContract()
const parsedAmount = ethers.utils.parseEther(amount)
await ethereum.request({
method: 'eth_sendTransaction',
params: [{
from: currentAccount,
to: addressTo,
gas: '0x5208',//hex form
value: parsedAmount._hex,
}]
})
const transactionHash = await transactionContract.addToBlockchain(addressTo, parsedAmount, message)
setIsLoading1(true)
console.log(`Loading ${transactionHash.hash}`);
await transactionHash.wait()
setIsLoading1(false)
console.log(`Success ${transactionHash.hash}`);
const transactionCount = await transactionContract.getTransactionCount()
setTransactionCount(transactionCount.toNumber())
} catch (error) {
throw new Error("No ethereum object!")
}
}
useEffect(()=>{
checkIfWalletIsConnected()
},[])
return (
<TransactionContext.Provider value={{formData, setFormData, handleChange, sendTransaction1}}>
{children}
</TransactionContext.Provider>
)
}
That is all the relevant code from the TransactionContext.jsx file. Now you can see the code inside the Hero.jsx where I am importing the context values and trying to use them along with the button and handleSubmit function shown below:
import { useContext, useState} from 'react'
import { TransactionContext } from '@components/providers/TransactionContext'
const Hero = () => {
const {formData, sendTransaction1, handleChange} = useContext(TransactionContext)
const handleSubmit = (e) => {
const { addressTo, amount} = formData
e.preventDefault()
if(!addressTo || !amount ) return
console.log("Hello");
sendTransaction1()
return (
<ButtonSend
disabled={formState.isDisabled}
type="button"
onClick={handleSubmit}
>
Send Now
</ButtonSend>
)
}
}
That is all of the code - now you can view the live website to see the issue in real time as well - Where to see the problem bodiaugustus.com
If for any reason the inputs are needed please let me know and I will redit this posting.