Sign in with Ethereum

Sep 2
ยท

Sign-In with Ethereum is a new form of authentication that enables users to control their digital identity with their Ethereum account and ENS profile instead of relying on a traditional intermediary. Already used throughout Web3, this effort standardizes the method with best practices and makes it easy to adopt securely.

Requirements:

Create a new node project

Lets create an empty node project

Terminal
mkdir siwe-frontend
cd siwe-frontend
npm init -y

Install siwe and ethers js

Terminal
npm install --save siwe ethers

Create src folder

Also create index.html and index.js files

Terminal
mkdir src
cd src
touch index.html
touch index.js

Add the following code in index.html

src/index.html
  <html>
  <head>
    <meta charset="utf-8" />
    <title>SIWE Quickstart</title>
  </head>
 
  <body>
    <div><button id='connectWalletBtn'>Connect wallet</button></div>
    <div><button id='siweBtn'>Sign-in with Ethereum</button></div>
  </body>
  </html>

The js code for index.js

Here we import ethers and siwe and below instanciate a web3 provider to get the signer and use this to sign the message using the SiweMessage instance.

src/index.js
import { ethers } from 'ethers';
import { SiweMessage } from 'siwe';
 
const domain = window.location.host;
const origin = window.location.origin;
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
 
function createSiweMessage(address, statement) {
    const message = new SiweMessage({
        domain,
        address,
        statement,
        uri: origin,
        version: '1',
        chainId: '1'
    });
    return message.prepareMessage();
}
 
function connectWallet() {
    provider.send('eth_requestAccounts', [])
        .catch(() => console.log('user rejected request'));
}
 
async function signInWithEthereum() {
    const message = createSiweMessage(
        await signer.getAddress(),
        'Sign in with Ethereum to the app.'
    );
    console.log(await signer.signMessage(message));
}
 
const connectWalletBtn = document.getElementById('connectWalletBtn');
const siweBtn = document.getElementById('siweBtn');
connectWalletBtn.onclick = connectWallet;
siweBtn.onclick = signInWithEthereum;

Install webpack

Terminal
npm install --save webpack webpack-cli webpack-dev-server html-webpack-plugin

Webpack config

This is to create the entry point of our app (src/index.js) and compile as main.js to get working in development mode.

webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
 
module.exports = {
  mode: 'development',
  entry: './src/index.js',
  resolve: {
    fallback: {
      fs: false,
      path: false,
      util: false
    }
  },
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist')
  },
 
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      filename: 'index.html'
    }),
  ]
};

And this is all, you have to add this script in the scripts section in your package.json file:

package.json
  "scripts": {
    "dev": "webpack serve"
  }

Running this command (npm run dev) you will see in your web browser the page at localhost and you can sign in first using metamask and then sign a message with siwe