This content originally appeared on DEV Community and was authored by fangjun
When playing with Web3-UI, an in-development Web3 UI Component library by DeveloperDAO and dhaiwat.eth, I found the an Ethereum Signin (Account) Component is commonly needed for web3.
There is a React Component <Account>
in open-source project Proof-Of-Competence (poc.quest) which does this job very well. I talked with Wesley(@wslyvh), the developer of PoC, and proposed to write an article recording my experiment of taking all the related code to an empty project to test whether it is possible to reuse this component.
So, this Web3-UI Working Note #03 is not about using or developing Web3-UI, it is about an experiment for a component instead. And it is a learning note, not a how-to guide.
From my point of view, a Web3 UI Component library needs:
- Separation between logic and UI.
- Robust logic for connecting blockchain.
- Handy UI components developers can use in their project.
1. Basics
Two things are needed to be done by an Ethereum Account UI Component:
No.1 Connect to Ethereum network through:
- Wallet (MetaMask, WalletConnect, or in-wallet provider)
- Javascript API (web3.js, etheres.js)
- Endpoint to Ethereum network (Infura, Alchemy)
No.2 UI for users
- Connect Button
- Connected User Info
- Keep login status
- Logout
It would be much better if the UI Component can support:
- ENS
- ENS avatar
- Identicon Blockie
The Account
React component in PoC project can do all of the above.
It is based on packages/libraries:
- Ethers.js
- Web3-react
- Chakra-UI
Currently, this PoC <Account>
component is in the project. Let's try whether we can take it out and use it in an empty project.
There are several files related to it. To make it simple, we will just copy the related code from PoC project without changing anything. There are some constants, configures which are not used in <Account>
component.
components/
account.tsx
hooks/
useInitialConnect.tsx
useAvatar.tsx
uitls/
web3.ts
constants.ts
config.ts
Proof-of-Competence(PoC) Repositary by @wslyvh: https://github.com/wslyvh/proof-of-competence
2. Using <Account>
UI Component in an empty project
STEP 1: Create Next.js project
Create a Next.js project accountsample:
yarn create next-app accountsample --typescript
cd accountsample
yarn dev
We will use src
directory to store the source code:
mkdir src
mv pages src/pages
mv styles src/styles
Add a configuration in tsconfig.json
:
"baseUrl": "./src",
STEP 2: Install dependencies
Install "Ethers.js", "Chakra UI", "Web3-React", and "ethereum-blockies-base64".
//ethers
yarn add @ethersproject/providers @ethersproject/bignumber @ethersproject/units
//Chakra UI
yarn add @chakra-ui/react @chakra-ui/icons @emotion/react @emotion/styled framer-motion
//Web3-React
yarn add @web3-react/core @web3-react/injected-connector @web3-react/walletconnect-connector
//ethereum-blockies-base64
yarn add ethereum-blockies-base64
Please note that @web3-react
changes a little. @web3-react/injected-connector
and @web3-react/walletconnect-connector
are used here. But maybe we should update with @web3-react
. Please find: https://github.com/NoahZinsmeister/web3-react
STEP 3: Copy <Account>
related files
Add three directories:
add components hooks utils
Copy 7 files from PoC project: https://github.com/wslyvh/proof-of-competence to respective directories
components/
header.tsx
account.tsx
hooks/
useInitialConnect.tsx
useAvatar.tsx
uitls/
web3.ts
constants.ts
config.ts
Please note that we also copy <Header>
Component for usage. Do comment out the unrelated import in "header.tsx":
//import journey from 'pages/api/journey'
We will try to use <Account>
as well as <Header>
in the following steps.
STEP4: Add Chakra provider and Web3ReactProvider
In pages/_app.tsx
, add Chakra provider and Web3ReactProvider:
import '../styles/globals.css'
import type { AppProps } from 'next/app'
import { ChakraProvider } from "@chakra-ui/react"
import { Web3ReactProvider } from '@web3-react/core'
import { getProvider } from 'utils/web3'
function MyApp({ Component, pageProps }: AppProps) {
return (
<ChakraProvider>
<Web3ReactProvider getLibrary={getProvider}>
<Component {...pageProps} />
</Web3ReactProvider>
</ChakraProvider>
)
}
export default MyApp
STEP 5: Add user.tsx
page and use <Account>
Add user.tsx
page:
touch src/pages/user.tsx
// src/pages/user.tsx
import { Account } from 'components/account'
export default function UserPage() {
return (
<Account />
)
}
Run yarn dev
and go to "http://localhost:3000/user".
It works.
STEP 6: Add <Header>
to index.tsx
Edit index.tsx
and add:
import Header from 'components/header'
...
<Header />
...
It works.
Note: Currently, this code base can only support network: Mainnet and testnet Ropsten, Rinkeby and Goerli. Connecting to other networks without ENS will get error like Error: network does not support ENS (operation="ENS", network="kovan", code=UNSUPPORTED_OPERATION, version=providers/5.5.2)
Note: I also found that MetaMask popup a warning about window.web3: We noticed that the current website tried to use the removed window.web3 API. If the site appears to be broken, please click here for more information.
More info: https://medium.com/metamask/no-longer-injecting-web3-js-4a899ad6e59e
3. Under the hood: Code and logic
In this section, we will dive into the code. Write down several learning notes quickly just for reference. Please read the source code at: https://github.com/wslyvh/proof-of-competence
Note 001: display of <Account>
<Account>
uses useWeb3React
Hook from '@web3-react/core
.
When not connected: Connect button
When connected: Account info (Address, Identicon, ENS)
Note 002: connect using MetaMask
To connect using MetaMask or in-wallet explorer, <Account>
use InjectedConnector
from @web3-react/injected-connector
.
Code snippet from account.tsx
and uitls/web.ts
function connect() {
web3Connect.activate(injected, (error) => {
if (error instanceof UserRejectedRequestError) {
// ignore user rejected error
} else {
web3Connect.setError(error)
}
}, false)
}
...
export const injected = new InjectedConnector({
supportedChainIds: [1, 3, 4, 5, 10, 42, 42161]
})
Note 003: useInitialConnect
At the beginning of <Account>
, it call useInitialConnect()
to keep login status.
await web3Connect.activate(injected, (error) => {
web3Connect.setError(error)
setTried(true)
}, false)
To dig deeper, go to Web3-React Managers at: https://github.com/NoahZinsmeister/web3-react/blob/v6/packages/core/src/manager.ts.
Note: Currently the logout feature is not working correctly. Fix needed. Or does there need a logout for web3 APP? It seems that currently only wallet can disconnect from a web3 APP.
So perhaps the next stop of learning is:
Web3-React
, a libary by NoahZinsmeister.ethers.js
. We may go back to ethers.js / web3.js for a clear understanding about connecting, provider etc.
If you find this note useful, please follow my twitter @fjun99. DM is open.
This content originally appeared on DEV Community and was authored by fangjun
fangjun | Sciencx (2022-01-27T04:46:48+00:00) Web3-UI Working Note #03: An Account Component. Retrieved from https://www.scien.cx/2022/01/27/web3-ui-working-note-03-an-account-component/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.