Project Setup

Before you set up make sure you've visited and gone through our Getting Started Guide
Make sure you have:
  1. The MetaMask Extension downloaded.
  1. Node.js Downloaded and Installed
  1. Clone/Download the Project Files from GitHub.

Open Project Folder

Open the project folder. Navigate to start->index.html, and look at the comment stating part 1. This is the UI for the Simple Dapp with all of the layout and buttons that will help us learn the basics of connecting to our MetaMask extension. We will be using/building off of this entire section for the first part of the tutorial.

Install Dependencies

Open a terminal and make sure your terminal is inside the base directory of the start/ folder. Inside the folder, the files should look like this:
plain text
. ├─ index.html ├─ contract.js ├─ metamask.css ├─ package.json └─ README.md
Open your terminal and navigate into the start folder. In this folder run:
bash
yarn install
Next run:
bash
yarn run serve

Basic Action

Now let's navigate into the contract.js file inside your start folder.
javascript
const forwarderOrigin = 'http://localhost:9010'; const initialize = () => { //You will start here }; window.addEventListener('DOMContentLoaded', initialize);
As soon as the content in the DOM is loaded we are calling our initialize function. Now before we start writing any code let's look at our task list for the first part of this app.

Connecting to the MetaMask Wallet

Getting Started with MetaMask

MetaMask Extension Check

We create a check function called isMetaMaskInstalled to see if the MetaMask extension is installed.
And, we need to create a MetaMaskClientCheck function to see if we need to change the button text based on if the MetaMask Extension is installed or not.
javascript
const initialize = () => { //Basic Actions Section const onboardButton = document.getElementById('connectButton'); //Created check function to see if the MetaMask extension is installed const isMetaMaskInstalled = () => { //Have to check the ethereum binding on the window object to see if it's installed const { ethereum } = window; return Boolean(ethereum && ethereum.isMetaMask); }; //------Inserted Code------\\ const MetaMaskClientCheck = () => { //Now we check to see if MetaMask is installed if (!isMetaMaskInstalled()) { //If it isn't installed we ask the user to click to install it onboardButton.innerText = 'Click here to install MetaMask!'; } else { //If it is installed we change our button text onboardButton.innerText = 'Connect'; } }; MetaMaskClientCheck(); //------/Inserted Code------\\ };

MetaMask "Not Installed" Dapp Flow

In our code block where MetaMask isn't installed and we ask the user to 'Click here to install MetaMask!', we need to ensure that if our button is clicked we:
  1. Redirect the user to the proper page to install the extension
  1. Disable the button
javascript
const MetaMaskClientCheck = () => { //Now we check to see if Metmask is installed if (!isMetaMaskInstalled()) { //If it isn't installed we ask the user to click to install it onboardButton.innerText = 'Click here to install MetaMask!'; //When the button is clicked we call this function onboardButton.onclick = onClickInstall; //The button is now disabled onboardButton.disabled = true; } else { //If it is installed we change our button text onboardButton.innerText = 'Connect'; } }; MetaMaskClientCheck();
💡
Tip
For this part we will be using the '@metamask/onboarding' library we installed during the npm install. To learn more visit here
Inside the onClickInstall function we want to:
  1. Change the text of the button to Onboarding in progress
  1. Disable the button
  1. Start the onboarding process
Above your MetaMaskClientCheck function write/insert this code.
javascript
//We create a new MetaMask onboarding object to use in our app const onboarding = new MetaMaskOnboarding({ forwarderOrigin }); //This will start the onboarding proccess const onClickInstall = () => { onboardButton.innerText = 'Onboarding in progress'; onboardButton.disabled = true; //On this object we have startOnboarding which will start the onboarding process for our end user onboarding.startOnboarding(); };
GREAT! Now if our end user doesn't have the MetaMask Extension they can install it. When they refresh the page the ethereum window object will be there and we can get on to connecting their MetaMask wallet to our Dapp!

MetaMask "Installed" Dapp Flow

Next we need to revisit our MetaMaskClientCheck function and create similar functionality that we did in our "MetaMask Not Installed" block in our "MetaMask Is Installed" block of code.
javascript
const MetaMaskClientCheck = () => { //Now we check to see if Metmask is installed if (!isMetaMaskInstalled()) { ... } else { //If MetaMask is installed we ask the user to connect to their wallet onboardButton.innerText = 'Connect'; //When the button is clicked we call this function to connect the users MetaMask Wallet onboardButton.onclick = onClickConnect; //The button is now enabled onboardButton.disabled = false; } }; MetaMaskClientCheck();
Inside the onClickConnect function we want to:
  1. Create an async function that will try to call the 'eth_requestAccounts' RPC method
  1. Catch any errors and log them to the console
Under your onClickInstall function write/insert this code.
javascript
const onClickConnect = async () => { try { // Will open the MetaMask UI // You should disable this button while the request is pending! await ethereum.request({ method: 'eth_requestAccounts' }); } catch (error) { console.error(error); } };
Great! Now once you click the button the MetaMask Extension will pop up and connect your wallet.

Get Ethereum Accounts

After this what we'd like to do next is whenever we press the eth_accounts button we'd like to get our Ethereum account and display it. Replace the existing const onboardButton at the top of the initialize() function with the following three buttons:
javascript
//Basic Actions Section const onboardButton = document.getElementById('connectButton'); const getAccountsButton = document.getElementById('getAccounts'); const getAccountsResult = document.getElementById('getAccountsResult');
Now that we've grabbed our eth_accounts button and our paragraph field to display it in we now have to grab the data.
Under our MetaMaskClientCheck() function let's write/insert the code below.
javascript
//Eth_Accounts-getAccountsButton getAccountsButton.addEventListener('click', async () => { //we use eth_accounts because it returns a list of addresses owned by us. const accounts = await ethereum.request({ method: 'eth_accounts' }); //We take the first address in the array of addresses and display it getAccountsResult.innerHTML = accounts[0] || 'Not able to get accounts'; });
If you have already connected to your wallet in the previous section of the tutorial, you can go into MetaMask's "Connected Sites" menu and remove the localhost connection. This will enable us to test both buttons again. If we refresh our page, and click the "ETH_ACCOUNTS" button, we should see 'eth_accounts result: Not able to get accounts'.
Let's go ahead and press the "Connect" button again, and confirm the "Connect With MetaMask" prompt and "Connect". Now we can click the "ETH_ACCOUNTS" button again and we should see our MetaMask account public address.
CONGRATULATIONS!
We have just completed building out our Simple Dapp. You know how to Connect to MetaMask, see your connected apps and remove them, as well as retrieve accounts.
Preview of the completed code up until this point of the tutorial:
javascript
const forwarderOrigin = 'http://localhost:9010'; const initialize = () => { //Basic Actions Section const onboardButton = document.getElementById('connectButton'); const getAccountsButton = document.getElementById('getAccounts'); const getAccountsResult = document.getElementById('getAccountsResult'); //Created check function to see if the MetaMask extension is installed const isMetaMaskInstalled = () => { //Have to check the ethereum binding on the window object to see if it's installed const { ethereum } = window; return Boolean(ethereum && ethereum.isMetaMask); }; //We create a new MetaMask onboarding object to use in our app const onboarding = new MetaMaskOnboarding({ forwarderOrigin }); //This will start the onboarding proccess const onClickInstall = () => { onboardButton.innerText = 'Onboarding in progress'; onboardButton.disabled = true; //On this object we have startOnboarding which will start the onboarding process for our end user onboarding.startOnboarding(); }; const onClickConnect = async () => { try { // Will open the MetaMask UI // You should disable this button while the request is pending! await ethereum.request({ method: 'eth_requestAccounts' }); } catch (error) { console.error(error); } }; const MetaMaskClientCheck = () => { //Now we check to see if Metmask is installed if (!isMetaMaskInstalled()) { //If it isn't installed we ask the user to click to install it onboardButton.innerText = 'Click here to install MetaMask!'; //When the button is clicked we call th is function onboardButton.onclick = onClickInstall; //The button is now disabled onboardButton.disabled = false; } else { //If MetaMask is installed we ask the user to connect to their wallet onboardButton.innerText = 'Connect'; //When the button is clicked we call this function to connect the users MetaMask Wallet onboardButton.onclick = onClickConnect; //The button is now disabled onboardButton.disabled = false; } }; //Eth_Accounts-getAccountsButton getAccountsButton.addEventListener('click', async () => { //we use eth_accounts because it returns a list of addresses owned by us. const accounts = await ethereum.request({ method: 'eth_accounts' }); //We take the first address in the array of addresses and display it getAccountsResult.innerHTML = accounts[0] || 'Not able to get accounts'; }); MetaMaskClientCheck(); }; window.addEventListener('DOMContentLoaded', initialize);