Comment on page
Implement the Frontend
Here we learn how to connect the user's wallet with the web application and sign messages.
A completed version of this part can be found in the example repository (01_frontend). This example uses the browser console to print messages, so it should be actively monitored.
To sign in with Ethereum we only need to send two pieces of information:
- The message
- The signature of the message
On the previous page, we wrote a function that gives us the means to create messages, so now we only need the means to sign messages.
So we must first connect the web application and the user's wallet so that the application can request information about the Ethereum account and sign messages.
1. In order to do that we will need to add some new dependencies to our print project:
mkdir siwe-frontend && cd siwe-frontend/
yarn init --yes
mkdir src/
yarn add siwe \
ethers \
webpack-node-externals \
node-polyfill-webpack-plugin
yarn add -D html-webpack-plugin \
webpack \
webpack-cli \
webpack-dev-server \
bufferutil \
utf-8-validate
2. Create a new file
webpack.config.js
and add the following:const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const NodePolyfillPlugin = require("node-polyfill-webpack-plugin")
module.exports = {
mode: 'development',
entry: './src/index.js',
resolve: {
fallback: {
net: false,
tls: false,
fs: false,
}
},
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist')
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html'
}),
new NodePolyfillPlugin(),
]
};
3. Make sure that
package.json
has the scripts
section and match it to the following:{
"name": "siwe-frontend",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"start": "webpack serve"
},
"dependencies": {
"siwe": "^2.1.4",
"ethers": "^6.3.0",
"node-polyfill-webpack-plugin": "^2.0.1",
"webpack-node-externals": "^3.0.0"
},
"devDependencies": {
"bufferutil": "^4.0.7",
"html-webpack-plugin": "^5.5.1",
"utf-8-validate": "^6.0.3",
"webpack": "^5.80.0",
"webpack-cli": "^5.0.1",
"webpack-dev-server": "^4.13.3"
}
}
4. Populate
src/index.js
with the following:src/index.js
import { BrowserProvider } from 'ethers';
import { SiweMessage } from 'siwe';
const domain = window.location.host;
const origin = window.location.origin;
const provider = new BrowserProvider(window.ethereum);
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 signer = await provider.getSigner();
const message = createSiweMessage(
signer.address,
'Sign in with Ethereum to the app.'
);
console.log(await signer.signMessage(message));
}
// Buttons from the HTML page
const connectWalletBtn = document.getElementById('connectWalletBtn');
const siweBtn = document.getElementById('siweBtn');
connectWalletBtn.onclick = connectWallet;
siweBtn.onclick = signInWithEthereum;
5. Populate
src/index.html
with the following:src/index.html
<!DOCTYPE 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>
6. Now run the following command and visit the URL printed to the console. After you connect your wallet and sign the message, the signature should appear in the console.
yarn start
- ethers.js is a library that provides functionality for interacting with the Ethereum blockchain. We use it here for connecting the webpage to extension wallets.
- The Metamask extension injects the
window.ethereum
object into every webpage, and theethers
library provides a convenient provider class to wrap it. We then use this provider to connect to the wallet, and access signing capabilities:
const provider = new BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
- Running the
connectWallet
function below will send a request to the MetaMask extension to ask permission to view information about the Ethereum accounts that it controls. MetaMask will then show a window to the user asking them to authorize our application to do so. If they authorize the request then we've connected their account:
function connectWallet () {
provider.send('eth_requestAccounts', [])
.catch(() => console.log('user rejected request'));
}
- We can also now start signing requests with the following:
await signer.signMessage(message);
To disconnect an account, the user must do so from the MetaMask extension in this example.
Last modified 7mo ago