Skip to main content

Login with Metamask

In this tutorial you will learn how you can integrate Metamask provider from the Catalog in your dapp and implement operations like login and logout

Requirements

For the tutorial you will need:

  • A extension of Metamask installed in the browser
  • node and npm need to be installed

How to install Catalog Provider

Firstable to install Catalog Provider you just need to run:

yarn add @nevermined-io/catalog-providers

Add the Metamask provider

Now in our app we need to add the Metamask provider as a parent of all the components that will use functionalities from it

import React from 'react';
import ReactDOM from 'react-dom';
import Example from 'examples';
import { MetaMask } from '@nevermined-io/catalog-providers';

ReactDOM.render(
<div>
<MetaMask.WalletProvider
correctNetworkId="0x13881"
nodeUri="https://matic-mumbai.chainstacklabs.com"
>
...
</MetaMask.WalletProvider>
</div>,
document.getElementById("root") as HTMLElement
);

Add login component

Let's create a component that contains a login button, which will login to the wallet once that it is clicked, and other button to logout

const LoginMetaMask = () => {
const { loginMetamask, walletAddress, logout} = MetaMask.useWallet();

return (
<>
{!walletAddress ?
<button onClick={loginMetamask}>Connect to Metamask</button>
:
<>
<div>{walletAddress}</div>
<button onClick={logout}>Logout</button>
</>
}
</>
);
};

In this component we have the loginMetamask and logout functions and the walletAddress state, if walletAddress is not empty means that the metamask is connected and will show the address and logout button otherwise will show the button to connect

Config your network (optional)

At least that you need to set differents networks for your dapp than polygon this file is not needed, anyway here we show you how should look the config file.

import { zeroX } from '@nevermined-io/nevermined-sdk-js/dist/node/utils';
import { acceptedChainId } from 'config';

const mumbaiChainId = zeroX((80001).toString(16));
const mainnetChainId = zeroX((137).toString(16));

const ChainConfig = {
mumbai: {
chainId: mumbaiChainId,
chainName: 'Polygon Testnet Mumbai',
nativeCurrency: {
name: 'Matic',
symbol: 'MATIC',
decimals: 18
},
rpcUrls: [
'https://matic-mumbai.chainstacklabs.com',
'https://rpc-endpoints.superfluid.dev/mumbai'
],
blockExplorerUrls: ['https://mumbai.polygonscan.com/'],
iconUrls: ['https://s2.coinmarketcap.com/static/img/coins/64x64/3890.png']
},
mainnet: {
chainId: mainnetChainId,
chainName: 'Polygon Mainnet',
nativeCurrency: {
name: 'Matic',
symbol: 'MATIC',
decimals: 18
},
rpcUrls: ['https://polygon-rpc.com'],
blockExplorerUrls: ['https://polygonscan.com/'],
iconUrls: ['https://s2.coinmarketcap.com/static/img/coins/64x64/3890.png']
},
returnConfig: (chainIdHex: string) => {
if (chainIdHex === mumbaiChainId) {
return ChainConfig.mumbai;
}
if (chainIdHex === mainnetChainId) {
return ChainConfig.mainnet;
}
return ChainConfig.mainnet;
}
};

export default ChainConfig;

Lets put everything together

In order to finish we need to call this component inside of the Metamask provider, this is the complete example

import React from 'react';
import ReactDOM from 'react-dom';
import { MetaMask } from '@nevermined-io/catalog-providers';
import { zeroX } from '@nevermined-io/nevermined-sdk-js/dist/node/utils';

const mumbaiChainId = zeroX((80001).toString(16));
const mainnetChainId = zeroX((137).toString(16));

const ChainConfig = {
mumbai: {
chainId: mumbaiChainId,
chainName: 'Polygon Testnet Mumbai',
nativeCurrency: {
name: 'Matic',
symbol: 'MATIC',
decimals: 18
},
rpcUrls: [
'https://matic-mumbai.chainstacklabs.com',
'https://rpc-endpoints.superfluid.dev/mumbai'
],
blockExplorerUrls: ['https://mumbai.polygonscan.com/'],
iconUrls: ['https://s2.coinmarketcap.com/static/img/coins/64x64/3890.png']
},
mainnet: {
chainId: mainnetChainId,
chainName: 'Polygon Mainnet',
nativeCurrency: {
name: 'Matic',
symbol: 'MATIC',
decimals: 18
},
rpcUrls: ['https://polygon-rpc.com'],
blockExplorerUrls: ['https://polygonscan.com/'],
iconUrls: ['https://s2.coinmarketcap.com/static/img/coins/64x64/3890.png']
},
returnConfig: (chainIdHex: string) => {
if (chainIdHex === mumbaiChainId) {
return ChainConfig.mumbai;
}
if (chainIdHex === mainnetChainId) {
return ChainConfig.mainnet;
}
return ChainConfig.mainnet;
}
};

const LoginMetamask = () => {
const { loginMetamask, walletAddress, logout} = MetaMask.useWallet();

return (
<>
{!walletAddress ?
<button onClick={loginMetamask}>Connect to Metamask</button>
:
<>
<div>{walletAddress}</div>
<button onClick={logout}>Logout</button>
</>
}
</>
);
};

ReactDOM.render(
<div>
<MetaMask.WalletProvider
externalChainConfig={ChainConfig}
correctNetworkId={mumbaiChainId}
nodeUri={ChainConfig.mainnet.rpcUrls[0]}
>
<LoginMetamask/>
</MetaMask.WalletProvider>
</div>,
document.getElementById("root") as HTMLElement
);

This config file represent all the networks that your dapp support, and a default one where metamask will ask to switch in case that the wallet is in some not supported network

Demo