DEV Community

Cormac
Cormac

Posted on

How to send Ether or Matic using Ethers

If you're building a dapp you'll probably need to implement a solution for users to send tokens to one another.

Here's how to send ethers or any ERC-20 token from the frontend using ethers and web3.

First we'll need these three libraries: web3, web3modal and ethers

yarn add ethers web3 web3modal

Then we need to request to connect to Metamask or any other Ethereum web wallet a user is using.

const connectToMetamask = async () => {
    const web3Modal = new Web3Modal()
    const connection = await web3Modal.connect()
    const provider = new ethers.providers.Web3Provider(connection)
    const signer = provider.getSigner()
    const address = await signer.getAddress()
    if (!address || !signer || !provider) {
      console.log("ERROR couldn't connect to metamask")
    } 
  }
Enter fullscreen mode Exit fullscreen mode

The function above collects the user's address and signer which allows us to request a transaction to the network. In this case I will demonstrate how to send Matic on Polygon.

const requestPolygonTransaction = async (signer, address, provider) => {
    // check validity of addresses
    if (
      !web3.utils.isAddress(address) || !web3.utils.isAddress(process.env.NEXT_PUBLIC_OWNER_WALLET)
    ) {
      console.log('ERROR invalid wallet addresses provided')
      return
    }

    const transactionParameters = {
      from: address, // sender wallet address
      to: process.env.NEXT_PUBLIC_OWNER_WALLET,  // receiver address
      data: '0x',
      value: ethers.utils.parseEther(polygonAmount),
      gasLimit: ethers.utils.hexlify(10000),
      gasPrice: ethers.utils.hexlify(parseInt(await provider.getGasPrice())),
    }

    await signer
      .sendTransaction(transactionParameters)
      .then((transaction) => {
        isModalVisible = false
        Modal.success({
          title: 'Transaction success!',
      })
      .catch((e) => {
        console.log('failed!')
        Modal.error({
          title: 'Oops transaction failed!',
          content: 'please double check the amount and try again',
        })

        return
      })
  }
Enter fullscreen mode Exit fullscreen mode

To help with things I'm using a Polygon node endpoint provided by Alchemy.

Putting things all together this is what my final code looks like to send matic on polygon using ethers.

import { Modal, Input, Tooltip } from 'antd'
import { ethers } from 'ethers'
import Web3 from 'web3'
import Web3Modal from 'web3modal'
import utilStyles from '../styles/utils.module.css'
import 'antd/dist/antd.css'

const web3 = new Web3(process.env.NEXT_PUBLIC_ALCHEMY_ENDPOINT)

export default function CryptoCheckout({
  isModalVisible,
  handleOk,
  handleCancel,
  polygonAmount,
  updateAmount,
}) {
  const connectToMetamask = async () => {
    const web3Modal = new Web3Modal()
    const connection = await web3Modal.connect()
    const provider = new ethers.providers.Web3Provider(connection)
    const signer = provider.getSigner()
    const address = await signer.getAddress()
    if (address && signer && provider) {
      requestPolygonTransaction(signer, address, provider)
    } else {
      console.log("ERROR couldn't connect to metamask")
    }
  }

  const requestPolygonTransaction = async (signer, address, provider) => {
    // check validity of addresses
    if (
      !web3.utils.isAddress(address) ||
   !web3.utils.isAddress(process.env.NEXT_PUBLIC_OWNER_WALLET)
    ) {
      console.log('ERROR invalid wallet addresses provided')
      return
    }

    const transactionParameters = {
      from: address,
      to: process.env.NEXT_PUBLIC_OWNER_WALLET, 
      data: '0x',
      value: ethers.utils.parseEther(polygonAmount),
      gasLimit: ethers.utils.hexlify(10000),
      gasPrice: ethers.utils.hexlify(parseInt(await provider.getGasPrice())),
    }

    await signer
      .sendTransaction(transactionParameters)
      .then((transaction) => {
        isModalVisible = false
        Modal.success({
          title: 'Tx Success!'
      })
      .catch((e) => {
        console.log('failed!')
        Modal.error({
          title: 'Oops transaction failed!',
          content: 'please double check the amount and try again',
        })

        return
      })
  }

  return (
    <>
      <Modal
        title="Crypto Checkout"
        visible={isModalVisible}
        onOk={handleOk}
        onCancel={handleCancel}
        footer={[
          <button
            key="submit"
            className={`${utilStyles.primaryButton}`}
            onClick={connectToMetamask}
          >
            Submit
          </button>,
        ]}
      >
        <p>Enter amount in polygon (MATIC) you'd like to send</p>

        <Input
          prefix=""
          className={`${utilStyles.input}`}
          value={polygonAmount}
          onChange={updateAmount}
          placeholder="50"
          suffix="matic"
        />
      </Modal>
    </>
  )
}

Enter fullscreen mode Exit fullscreen mode

That's it! You can also use the same method to send ether and any other Ethereum based token.

Top comments (0)