Building Web3 frontend for your dApp

What you'll learn

You'll learn how to get started with Web3 frontend development and how to access blockchain nodes to send transactions or interact with deployed contracts through your front-end.

What you'll get

You'll get the production grade template to get you started.  

TL;DR:

Web3 Starter Kit boilerplate template to get you started:

GitHub - eth-salt-lake/web3-starter-kit: Web3 Starter Kit is flexible production grade Web3 boilerplate with Next.js, React, Material Design and Typescript
Web3 Starter Kit is flexible production grade Web3 boilerplate with Next.js, React, Material Design and Typescript - GitHub - eth-salt-lake/web3-starter-kit: Web3 Starter Kit is flexible production...

Not long ago I had an opportunity to build a Web3 boilerplate from scratch for the Ethereum Salt Lake City meetup group. Little did I know how treacherous the path is going to be figuring out which library to use and how node providers fit in.

Main libraries chosen for the template

  • Next.js mainly for Pre-Rendering (generates HTML for each page in advance so the browser doesn't have to: Static Site Generation or Server Side Rendering)
  • React for easier modularization of the project and for it's popularity
  • Material-UI for concise layering of the UI elements and non-invasive style modifications
  • Redux Toolkit used for state management (although we don't strictly use it in our template, but it's there)
  • Web3Modal for simpler wallet connecting code
  • ethers.js for interacting with Ethereum like blockchains and its ecosystems

Main Web3 concepts

  • Provider object that includes the connection protocol and the address/port of the blockchain node you're going to connect to.
  • Node Provider This can be to your locally running node, such as Geth or if you don't want to run your own node then use a third-party providers such as Infura or Alchemy. Of course those charge a fee after the free requests is used up.
  • Wallet There are 2 main types of wallets: Cold storage wallets and hot wallets. We're mainly dealing with hot wallets although Web3Modal connectors offer access to hardware wallets too.
  • Web3 is a font-end portion of the application
  • Deployed contract/Contract is our dApp back-end, but not in traditional sense obviously.
  • dApp is the whole deal. Our Web3 front-end calling methods on a blockchain running a Contract.

Template components and structure

To stay focused on the web3 portion of the template we're skipping all other components and setup of the Web3 Started Kit.  

Web3 Template Diagram - shows how the template components work together. 

First, we need a wallet. Although Web3Modal supports bunch of wallets for simplicity's sake let's focus only on a hot wallet from Metamask. Metamask is a browser plugin /extension. There is also an iOS and Android apps. Our Web3 Template should work with all of them. Metamask injects a complex object into your browser (named ethereum) and couple of methods as specified in various EIPs.

ethereum complex object

Web3Modal connects to the wallet by utilizing injected complex object by the Metamask. Web3Modal is compatible with ethers.js which requires a Provider (ethers.js compatible Web3Provider in our case).

Web3 Context is Web3 Starters Kit custom context. There is also a webhook for simple access to web3 context.

Next Web3Provider is injected into Web3 Context. Web3Provider is used by Web3 Context as a first step to communicating with the blockchain over ethers.js library.  

const { connect, connectTo, disconnect, wallet, provider } = useWeb3();
Web3 hook

As you can see we can connect, disconnect, get the wallet and web3 provider with on simple line of code.

From this point on the ethers.js v5 documentation is your friend for everything else you might need. You can utilize ethers.js to do various interactions with Blockchains, such as sending transactions and interacting with your deployed contracts.

For a simple example you can also look into the Web3 Context file, the method getWeb3Account. The methods loads users wallet into Web3 Context and optionally other details, such as ENS name and ENS avatar picture by calling ethers.js methods:

const signer = provider.getSigner();
const address = await signer.getAddress();
const ensName = await provider.lookupAddress(address);
If you're familiar with Next.js, Material-UI and React development, this is where you can stop reading this post.

Other important dependencies

  • date-fns - Utils to parse date and time
  • @mui/lab - Material theme components
  • @mui/material - Material basic theme components
  • react - Core framework
  • next - Core framework
  • @emotion/react - Styling
  • redux-thunk - Middleware to enable Redux async actions
  • redux - State manager
  • axios - HTTP client

Routing

Next.js has a file-system based router built on the concept of pages. When a file is added to the pages directory it's automatically available as a route.

Index routes

The router will automatically route files named index to the root of the directory.

  • pages/index.js/
  • pages/blog/index.js/blog

Nested Routes

he router supports nested files. If you create a nested folder structure, files will automatically be routed in the same way still.

  • pages/blog/first-post.js/blog/first-post
  • pages/dashboard/settings/username.js/dashboard/settings/username

Dynamic route segments

To match a dynamic segment, you can use the bracket syntax. This allows you to match named parameters.

  • pages/blog/[slug].js/blog/:slug (/blog/hello-world)
  • pages/[username]/settings.js/:username/settings (/foo/settings)
  • pages/post/[...all].js/post/* (/post/2020/id/title)

Check out the Dynamic Routes documentation to learn more about how they work.

Themes with Material

Customize MUI with your theme. You can change the colors, the typography and much more.

Theme configuration

A wrapper was created over the createTheme. You can setup light or dark theme option through config.ts along with other non theme related options:

// config.ts
import CoinbaseWalletSDK from '@coinbase/wallet-sdk';
import WalletConnectProvider from '@walletconnect/web3-provider';

export const ETHERSCAN_URL = 'https://etherscan.io/';
export const NETWORK_COIN_SYMBOL = 'ETH';
export const DEFAULT_CHAIN_ID = 1; // check the docs for more info
export const APP_NAME = "dApp Started Kit"
export const DEFAULT_APP_THEME: 'light' | 'dark' = 'light'; // light, dark

// list of providers for web3 modal
export const web3ProviderOptions = {
    walletconnect: {
        display: {
            name: "Mobile"
        },
        package: WalletConnectProvider,
        options: {
            infuraId: "INFURA_ID" // required
        }
    },
    walletlink: {
        package: CoinbaseWalletSDK,
        options: {
            appName: APP_NAME,
            infuraId: "INFURA_ID" // required
        },
    },
};

If you'd like to change the desired theme options you can do so in theme/base-theme-options.ts

Redux

Redux is a pattern and library for managing and updating application state, using events called "actions". It serves as a centralized store for state that needs to be used across your entire application, with rules ensuring that the state can only be updated in a predictable fashion.

I suggest your read more about Redux here.

The Start Kit contains an example implementation of the Redux in its store folder. Check store/example-store.ts for complete example.

Settings

The settings context is used mainly to store user selection for dark or light user interface option.

API Routes  and Axios Http Client

API routes provide a solution to build your API with Next.js.

Any file inside the folder pages/api is mapped to /api/* and will be treated as an API endpoint instead of a page. They are server-side only bundles and won't increase your client-side bundle size.

The backend API is implemented under pages/api/transactions/[walletaddress.ts]

The API uses axios http client to retrieve users 50 latest blockchain transactions from the blockchain by querying etherscan.

To find backend API configurations check the environment file .env.example and GitHub documentation:

GitHub - eth-salt-lake/web3-starter-kit: Web3 Starter Kit is flexible production grade Web3 boilerplate with Next.js, React, Material Design and Typescript
Web3 Starter Kit is flexible production grade Web3 boilerplate with Next.js, React, Material Design and Typescript - GitHub - eth-salt-lake/web3-starter-kit: Web3 Starter Kit is flexible production...