[Ethereum] How to use web3.js to send a transaction in React using MetaMask

javascriptreactweb3js

I'm trying to use Web3.js to prompt the user to pay an amount in MetaMask.

This is the code I'm using, which is failing with the error message in the payMeta catch section ('payment fail').

async function connectMeta(accounted, msged) {
    let ethereum = window.ethereum;
    try {
    const accounts = await ethereum.request({ method: 'eth_requestAccounts' });
    const account = accounts[0];
    accounted(account);
    } catch {
    console.log("connect fail!");
    msged(<><p>Please install MetaMask and reload this page.</p></>);
    }
}

async function payMeta(sender, receiver, strEther, msged) {
    console.log(`payWithMetamask(receiver=${receiver}, sender=${sender}, strEther=${strEther})`)
    let ethereum = window.ethereum;
    try {
       await ethereum.enable();
       const params = [{
        from: sender,
        to: receiver,
        value: strEther
       }];
       if (ethereum) {
            window.web3 = new Web3(window.ethereum);
            window.ethereum.enable();
            const sendHash = window.web3.eth.sendTransaction(params);
            console.log('txnHash is ' + sendHash);
       }
    } catch {
    console.log("payment fail!");
    msged(<p>Can't connect MetaMask. Please check MetaMask.</p>);   
    }

}

You can see it's very similar to the mostly equivalent ethers.js code, which I used earlier & which I can confirm works:

async function payMeta(sender, receiver, strEther, msged) {
    console.log(`payWithMetamask(receiver=${receiver}, sender=${sender}, strEther=${strEther})`)

    let ethereum = window.ethereum;
    try {
    await ethereum.enable();
    let provider = new ethers.providers.Web3Provider(ethereum);
    const params = [{
        from: sender,
        to: receiver,
        value: strEther
    }];
    const transactionHash = await provider.send('eth_sendTransaction', params)
    console.log('transactionHash is ' + transactionHash);
    } catch {
    console.log("payment fail!");
    msged(<p>Can't connect MetaMask. Please check MetaMask.</p>);   
    }

}

What do I need to change in the code to get this to work?

Best Answer

I figured it out after looking at the event error message with (catch (e) { console.log(e) }) and cleaing up the code a bit (e.g., removing brackets around params).

This code is confirmed to work.

async function payMeta(sender, receiver, strEther, msged) {
    console.log(`payWithMetamask(receiver=${receiver}, sender=${sender}, strEther=${strEther})`)
    try {
    const params = {
        from: sender,
        to: receiver,
        value: strEther,
        gas: 39000
    };
        await window.ethereum.enable();
        window.web3 = new Web3(window.ethereum);    
        const sendHash = window.web3.eth.sendTransaction(params);
        console.log('txnHash is ' + sendHash);
    } catch(e) {
        console.log("payment fail!");
        console.log(e);
        msged(<p>Can't connect MetaMask. Please check MetaMask.</p>);   
    }
}