Skip to main content

Signing messages with MetaMask

Sign in with MetaMask is a great way to authenticate users on your site. It's also a great way to sign messages with a user's Ethereum address. This is useful for a variety of reasons, including:

  • Proving ownership of an Ethereum address
  • Proving ownership of an Ethereum address to a smart contract
  • Proving ownership of an Ethereum address to a smart contract and executing a function call on that smart contract in the same transaction

Besides the above use cases, signing messages with a user's Ethereum address is a great way to authenticate users to your site without sending them through an OAuth flow. This is because signing a message with a user's Ethereum address proves that the user is in control of the private key associated with the public address, without sending any transactions.

So a good dApp will always provide the ability to authenticate users using Sign In with MetaMask.

Signing messages with MetaMask

To sign a message with MetaMask, we will using some utils method from ethers.js.

Import ethers.js

import { ethers } from "ethers";

Setup a provider and signer.

const provider = new ethers.providers.Web3Provider(window.ethereum);
await provider.send("eth_requestAccounts", []);

Sign a message

const signer = provider.getSigner();
const message = "Hello World";
const signature = await signer.signMessage(message);

Verify a signature

const recoveredAddress = ethers.utils.verifyMessage(message, signature);

Verify message using remote API

Usually when implementing a authentication method, we need to send the signature to a remote API to verify it. After that, the server will return a JWT token that we can use to authenticate the user on subsequent requests.

We provide a remote API endpoint to simulate this process.

https://functions.video2.trade/api/metamask/signIn

This endpoint takes the following request body:

export interface Message {
message: string;
signature: string;
address: string;
}

The endpoint will verify the signature and return a JWT token if the signature is valid.

export interface Token {
accessToken: string;
}

Example

The following example shows how to sign a message with MetaMask and verify it using the remote API.

Live Editor
Result
Loading...