DEV Community

Cormac
Cormac

Posted on

8 4

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.

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay