How to request a signature with the user's wallet using web3 JS

In this guide, we are going to learn how to request a signature on the user's connected wallet using Web3 JS and how to verify a signature

In this guide, we are going to learn how to request a signature on the user's connected wallet using Web3 JS and how to verify a signature.

You might want to ask users to sign data to make sure that they have access to the wallet that's connected and that it's some a hacker trying to get access to your app on behalf of that account.

The most common use case of that is to create a sign-in flow without a password, using only an Ethereum wallet.

Here, we're just going to learn how to sign data and verify the signature. By verifying the signature I mean checking that it was generated with the correct address.

How to sign data from a connected wallet

To request a signature on the user's wallet we can use the web3.eth.personal.sign function of Web3 JS. It will display a pop-up on the user's wallet asking to sign the message you want and the user will choose to sign it or not:

web3.eth.personal.sign(
    "Hello world",
    "0x5b8f1310A956ee1521A7bB56160451C786289aa9"
)
.then((signature) => {
    // do something here with the signature
    console.log(signature)
});

(assuming you have a wallet connected on your website and you created an instance of Web3)

In the code above, we sign the data "Hello world" using the address of the connected wallet, which is "0x5b8f1310A956ee1521A7bB56160451C786289aa9".

To get the address of the connected account (instead of hardcoding it) you can use this code:

const address = (await web3.eth.getAccounts())[0]

And then you can pass address in the second parameter of the function instead of hardcoding the address.

Signature will then be something like:

0x6acb11320d2caba7e4ba0fec6e84d90663d24ef15645dfedf6d954b9f2cd489c134268e9a9c6079d830529868b8727a887a3835911d56a1ee96941317a7c87751b

On MetaMask, it will display a pop-up like this:

How to verify a signature from a wallet

You can verify a signature using Web3 JS without having to do the complicated cryptography behind it.

That way you will know what address signed the data and generated the signature so you can compare it with the user's address to see if it matches.

For that, you can use the web3.eth.accounts.recover function and pass in the data that was signed as the first parameter and the signature in the second parameter:

web3.eth.accounts.recover('Hello world', '0x6acb11320d2caba7e4ba0fec6e84d90663d24ef15645dfedf6d954b9f2cd489c134268e9a9c6079d830529868b8727a887a3835911d56a1ee96941317a7c87751b')
.then((addressThatSignedData) => {
    // do something with the address that signed the data
    console.log(addressThatSignedData)
})

In our case, we signed the data with 0x5b8f1310A956ee1521A7bB56160451C786289aa9 so that's what addressThatSignedData will contain.

Changing the signature will change the address that the recover function is going to return so make sure you pass in the correct signature.

If you want to learn more about signatures, you can read this Wikipedia page about Digital signatures and the cryptography behind it.

If you want to do the verification part in a Solidity smart contract, it's going to be slightly different. If you want to learn how to do this, check out this tutorial on how to verify a signature with Solidity:

How to verify a signature in a smart contract in Solidity
We are going to learn how to verify signatures in a Solidity smart contract and learn how to get the address that generated the signature.

You'll have to split the signature into smaller chunks of specific sizes as explained at the end of this tutorial.

If you want to learn how to implement a sign in with Ethereum flow with this kind of signature and verification (and don't have to manage passwords) follow this tutorial:

How to implement a sign in with Ethereum wallet flow Web3 JS
In this guide, we are going to learn how to implement an authentication system that allows users to log in using an Ethereum wallet with Web3 JS.

And that's it 🎉

Thank you for reading this article, if you want to go further and get better at blockchain development, leave your email below and you'll get:

  • access to the private Discord of a community of Web3 builders
  • access to free guides that will teach you a subject from scratch like the Web3 JS Cheat Sheet