During Summer 2019 (North American edition), I took part in Truffle University's inaugural cohort for two months of advanced Ethereum development education. One of the recommended assignments was to submit a pull request for an open source project of our choosing.
My contribution arose out of a personal pain point encountered while developing my decentralized dollar cost averaging dApp (Vulcan Swap) on Drizzle.
The Problem: detecting a user's web3 network
At the time, there was no way for a Drizzle-built dApp to communicate to a user that their Metamask (or other provider) is connected to an unsupported network.
dApps are applications built to interact with smart contracts on a decentralized (or at least distributed) network, such as Ethereum. The thing is: there are lots of Ethereum testnets in addition to mainnet, and a developer must deploy a smart contract to each chain where they want dApps to be able to build on it.
Returning to the problem, it will often be the case - granted, for developers and super early adopters mostly - that a user opens a dApp while connected to an Ethereum chain (say Ropsten) where that dApps' smart contracts don't exist (say Rinkeby and mainnet).
In this case, there should be a way for the developer to signal to the user that they should switch to a supported network.
To combat this issue, I ended up diving deep down the Drizzle rabbit hole of Redux sagas with the help of my mentor Amal Sudama, a Drizzle core dev who has been an incredible resource and enthusiastic cheerleader to boot.
The Solution
I contributed to two separate modules of Drizzle's monorepo, one with the core logic to discriminate based on user network, and the other as a simple out-of-box sample implementation.
1. The networkWhitelist
(Drizzle core functionality)
I added a new Drizzle configuration option (i.e., drizzleOptions
) that allows a developer to define a networkWhitelist
. This whitelist is an array of Ethereum chain IDs on which the developer wants to make their dApp available for public use.
// Signifies that the dApp is accessible on...
networkWhitelist = [
1, // Ethereum mainnet and
4 // Rinkeby testnet
]
If the user in this example accesses the dApp from Ropsten (chain id: 2), Drizzle will fire a Redux action that sets a networkMismatch
flag in Drizzle's store. It is then up to the developer to handle how this information is relayed to the user.
Pull request: https://github.com/trufflesuite/drizzle-legacy/pull/235
2. A network-aware LoadingContainer
(a Drizzle React component)
As an example of how this networkMismatch
flag might be used (and to provide an out-of-box implementation), I modified the existing LoadingContainer
from Drizzle's react-components
module with some additional logic:
if (this.props.drizzleState.web3.networkMismatch) {
if (this.props.networkMismatchComp) {
return this.props.networkMismatchComp;
}
return (
<main className="container network-warning">
<div className="pure-g">
<div className="pure-u-1-1">
<h1>⚠️</h1>
<p>This dapp does not support this network.</p>
</div>
</div>
</main>
);
}
This snippet allows for a developer to either display a default network mismatch message, or to optionally add their own by passing a React component to the LoadingContainer
as a networkMismatchComp
property.
For example, in my own Vulcan Swap dApp (a decentralized cost averaging investment tool), I provided some custom feedback formatted with Bootstrap markup to give a look more consistent with the theme:
import React from 'react';
const NetworkMismatchBlock = () =>
<div className="networkMismatchBlock">
<div className="alert alert-danger" role="alert">
<div className="container">
To "Go Long and Prosper", switch to the Rinkeby Network"
</div>
</div>
</div>
export default NetworkMismatchBlock;
Pull request: https://github.com/trufflesuite/drizzle/pull/9
Network Whitelist Demo
For a quick visual run-through of the networkWhitelist
functionality, check out the video below: