A training frontend project for Tailwindcss
, Web3
and Metamask
integrations.
Deploy the example using Vercel
Click on the logo to test the demo deployed with Vercel
This is the way web3 is instantiated.
Replace givenProvider
by a custom RCP URI if needed.
import Web3 from "web3";
const web3 = new Web3(Web3.givenProvider);
There are the main functions to setup for a minimal Metamask Onboarding.
- Checking if the extension is installed
- Connect the user
- And get the accounts: address and balance
More documentation about Metamask Onboarding here.
const checkAccounts = async () => {
//we use eth_accounts because it returns a list of addresses owned by us.
if (typeof window !== undefined) {
const mmAccounts = await window.ethereum.request({method: 'eth_accounts'});
setAccounts(mmAccounts);
dispatch({
type: 'SET_ACCOUNTS',
payload: {
accounts: mmAccounts,
},
});
await getBalance();
} else {
setAccounts(await []);
}
};
//This will start the onboarding proccess
const onClickInstall = () => {
//On this object we have startOnboarding which will start the onboarding process for our end user
onboarding.startOnboarding();
};
//This will request a connection to Metamask and launch checkAccounts()
const onClickConnect = async () => {
try {
// Will open the MetaMask UI
if (typeof window !== undefined) await window.ethereum.request({method: 'eth_requestAccounts'});
await checkAccounts();
} catch (error) {
console.error(error);
}
};
//This will provide the balances on accounts' update (via useEffect)
const getBalance = async () => {
let address: any, wei, mmBalance;
address = accounts[0];
wei = promisify((cb: any) => web3.eth.getBalance(address, cb));
try {
mmBalance = web3.utils.fromWei(await wei as string, 'ether');
setBalance(mmBalance);
} catch (error) {
console.log(error);
}
};
useEffect(() => {
if(accounts.length > 0 && typeof window !== undefined){
(async function() {
try {
await getBalance();
} catch (e) {
console.error(e);
}
})();
}
}, [accounts]);
Util function used to resolve and manage web3 Promises.
const promisify = (inner: any) =>
new Promise((resolve, reject) =>
inner((err: any, res: any) => {
if (err) {
reject(err);
} else {
resolve(res);
}
})
);
NextJs uses SSR and SSG. While serving the frontend, on the SSR phase, there is no window
element, like on a client's browser.
Hence the turnaround.
if (typeof window !== undefined)
Function to use o get balances for other ERC20 tokens on the connected wallet (where ERC20_JSON
is the JSON interface).
async function checkERC20Amount(web3: any, userAddress: string, erc20Address: string) {
const erc20Json = new web3.eth.Contract(ERC20_JSON, erc20Address);
const balanceRightNow = await erc20Json.methods.balanceOf(userAddress).call().then((e: any) => e);
return web3.utils.fromWei(balanceRightNow);
}