Klaytn Docs Archive
Getting StartedBuild a dAppNode OperationDeveloper Hub
  • Klaytn Docs
  • -
    • Klaytn Overview
      • Why Klaytn
      • Klaytn Design
        • Consensus Mechanism
        • Accounts
        • Transactions
          • Basic
          • Fee Delegation
          • Partial Fee Delegation
          • Ethereum
        • Computation
          • Klaytn Smart Contract
          • Execution Model
          • Computation Cost
            • Computation Cost (Previous docs)
          • Klaytn Virtual Machine
            • Klaytn Virtual Machine (Previous docs)
        • Storage
          • State Migration
          • StateDB Live Pruning
        • Transaction Fees
          • Transaction Fees (Previous docs)
        • Klaytn native coin - KLAY
        • Token Economy
        • Governance
        • Multi-Channel
        • KNI
      • Scaling Solutions
    • Getting Started
      • Deploying Smart Contract Using Foundry
      • Deploying Smart Contract Using Hardhat
      • Deploying Smart Contract Using Thirdweb
      • Deploying Smart Contract Using KEN
        • Launch an Endpoint Node
        • Top up your Account
        • Install Development Tools
        • Deploy a Smart Contract
        • Check the Deployment
        • Account Management
          • Creating Accounts
          • Managing Accounts
      • Development Environment
      • Getting KLAY
    • Smart Contract
      • Solidity - Smart Contract Language
      • Precompiled Contracts
        • Precompiled Contracts (Previous docs)
      • IDE and Tools
        • Truffle
      • Sample Contracts
        • KlaytnGreeter
        • ERC-20
          • 1. Writing ERC-20 Smart Contract
          • 2. Deploying Smart Contract
          • 3. Interacting with ERC-20 token from Klaytn Wallet
        • ERC-721
          • 1. Writing ERC-721 Smart Contract
          • 2. Deploying Smart Contract
      • Testing Guide
      • Deployment Guide
      • Klaytn Compatible Tokens
      • Porting Ethereum Contract
    • Run a Node
      • Deployment
        • Endpoint Node
          • System Requirements
          • Installation Guide
            • Download
            • Installation Guide
            • Configuration
            • Startup the EN
            • Testing the Installation
          • ken CLI commands
          • JSON-RPC APIs
        • Core Cell
          • System Requirements
          • Network Configuration
          • Installation Guide
            • Download
            • Before You Install
            • Consensus Node Setup
              • Installation Guide
              • Configuration
              • Startup the CN
            • Proxy Node Setup
              • Installation Guide
              • Configuration
              • Startup the PN
            • Testing the Core Cell
          • Monitoring Setup
          • H/A Setup
        • Service Chain
          • Getting Started
            • Setting up a 4-node Service Chain
            • Connecting to Baobab
            • Cross-Chain Value Transfer
            • HA(High Availability) for ServiceChain
            • Nested ServiceChain
            • Value Transfer between Sibling ServiceChains
          • Reference Manuals
            • System Requirements
            • Download
            • SCN User Guide
              • Installation
              • Configuration
              • Starting/Stopping SCN
              • Checking Node Status
              • kscn commands
              • homi commands
            • SPN/SEN User Guide
              • Installation
              • Configuration
              • Starting/Stopping Node
              • Checking Node Status
            • Bridge Configuration
            • Anchoring
            • KAS Anchoring
            • Value Transfer
            • Configuration Files
            • Log Files
            • Genesis JSON
            • Upgrade & Hard Fork
          • How-To Guides
        • Download Node Packages
          • v1.12.0
          • v1.11.1
          • v1.11.0
          • v1.10.2
          • v1.10.1
          • v1.10.0
          • v1.9.1
          • v1.9.0
          • v1.8.4
          • v1.8.3
          • v1.8.2
          • v1.8.1
          • v1.8.0
          • v1.7.3
          • v1.7.2
          • v1.7.1
          • v1.7.0
          • v1.6.4
          • v1.6.3
          • v1.6.2
          • v1.6.1
          • v1.6.0
          • v1.5.3
          • v1.5.2
          • v1.5.1
          • v1.5.0
          • v1.4.2
          • v1.4.1
          • v1.4.0
          • v1.3.0
          • v1.2.0
          • v1.1.1
          • v1.0.0
          • v0.9.6
          • v0.8.2
    • Operation Guide
      • Configuration
      • Node Log
      • Log operation
      • Errors & Troubleshooting
      • Klaytn Command
      • Chaindata Change
      • Chaindata Migration
    • dApp Developers
      • JSON-RPC APIs
        • API references
          • eth
            • Caution
            • Account
            • Block
            • Transaction
            • Config
            • Filter
            • Gas
            • Miscellaneous
          • klay
            • Account
            • Block
            • Transaction
              • Working with Klaytn Transaction Types
            • Configuration
            • Filter
            • Gas
            • Miscellaneous
          • net
          • debug
            • Logging
            • Profiling
            • Runtime Tracing
            • Runtime Debugging
            • VM Tracing
            • VM Standard Tracing
            • Blockchain Inspection
          • admin
          • personal
          • txpool
          • governance
        • Service Chain API references
          • mainbridge
          • subbridge
        • Transaction Error Codes
      • RPC Service Providers
        • Public Endpoints
      • SDK & Libraries for interacting with Klaytn Node
        • caver-js
          • Getting Started
          • Sending a sample transaction
          • API references
            • caver.account
            • caver.wallet
              • caver.wallet.keyring
            • caver.transaction
              • Basic
              • Fee Delegation
              • Partial Fee Delegation
            • caver.rpc
              • caver.rpc.klay
              • caver.rpc.net
              • caver.rpc.governance
            • caver.contract
            • caver.abi
            • caver.kct
              • caver.kct.kip7
              • caver.kct.kip17
              • caver.kct.kip37
            • caver.validator
            • caver.utils
            • caver.ipfs
          • caver-js ~v1.4.1
            • Getting Started (~v1.4.1)
            • API references
              • caver.klay
                • Account
                • Block
                • Transaction
                  • Legacy
                  • Value Transfer
                  • Value Transfer Memo
                  • Account Update
                  • Smart Contract Deploy
                  • Smart Contract Execution
                  • Cancel
                • Configuration
                • Filter
                • Miscellaneous
              • caver.klay.net
              • caver.klay.accounts
              • caver.klay.Contract
              • caver.klay.KIP7
              • caver.klay.KIP17
              • caver.klay.abi
              • caver.utils (~v1.4.1)
            • Porting from web3.js
        • caver-java
          • Getting Started
          • API references
          • caver-java ~v1.4.0
            • Getting Started (~v1.4.0)
            • Porting from web3j
        • ethers.js
        • web3.js
      • Tutorials
        • Klaytn Online Toolkit
        • Fee Delegation Example
        • Count DApp
          • 1. Environment Setup
          • 2. Clone Count DApp
          • 3. Directory Structure
          • 4. Write Smart Contract
          • 5. Frontend Code Overview
            • 5-1. Blocknumber Component
            • 5-2. Auth Component
            • 5-3. Count Component
          • 6. Deploy Contract
          • 7. Run App
        • Klaystagram
          • 1. Environment Setup
          • 2. Clone Klaystagram DApp
          • 3. Directory Structure
          • 4. Write Klaystagram Smart Contract
          • 5. Deploy Contract
          • 6. Frontend Code Overview
          • 7. FeedPage
            • 7-1. Connect Contract to Frontend
            • 7-2. UploadPhoto Component
            • 7-3. Feed Component
            • 7-4. TransferOwnership Component
          • 8. Run App
        • Building a Buy Me a Coffee dApp
          • 1. Project Setup
          • 2. Creating a BMC Smart Contract
          • 3. Testing the contract using scripts
          • 4. Deploying BMC Smart contract
          • 5. Building the BMC Frontend with React and Web3Onboard
          • 6. Deploying Frontend code on IPFS using Fleek
          • 7. Conclusion
        • Migrating Ethereum App to Klaytn
        • Connecting MetaMask
        • Connecting Remix
        • Verifying Smart Contracts Using Block Explorers
      • Developer Tools
        • Wallets
          • Kaikas
          • Klaytn Wallet
          • Klaytn Safe
            • Klaytn Safe Design
            • Create a Safe
            • Add assets
            • Send assets
            • Contract Interaction
            • Transaction Builder
            • Points to Note
            • Frequently Asked Questions
          • SafePal S1
          • Wallet Libraries
            • Web3Auth
            • Web3Modal
            • Web3-Onboard
            • Particle Network
        • Oracles
          • Orakl Network
          • Witnet
          • SupraOracles
        • Indexers
          • SubQuery
        • Cross-chain
          • LayerZero
        • Block Explorers
          • Klaytnscope
          • Klaytnfinder
        • Klaytn Contracts Wizard
    • Glossary
  • ---
    • Klaytn Hard Fork History
    • Klaytn 2.0
      • Metaverse Package
      • Finality and Improvements
      • Ethereum Compatibility
      • Decentralizing Governance
      • Massive Eco Fund
    • FAQ
    • Open Source
    • Terms of Use
    • Languages
  • ℹ️Latest Klaytn Docs
Powered by GitBook
On this page
  • Integrate Web3-Onboard into a dApp
  • Introduction
  • Prerequisite
  • Getting Started
  • Setting up Onboard and Wallet Modules
  • Setting up Utils function
  • Connecting Wallet
  • Disconnecting Wallet
  • Accessing connection, account, network information
  • Switching Networks
  • Sending Native Transaction
  • Interacting with Smart Contracts
  • Troubleshooting
  • Next Step
  1. -
  2. dApp Developers
  3. Developer Tools
  4. Wallets
  5. Wallet Libraries

Web3-Onboard

PreviousWeb3ModalNextParticle Network

Last updated 2 years ago

Integrate Web3-Onboard into a dApp

Introduction

In this guide, you will use Web3-Onboard library to integrate multiple wallets (such as Coinbase Wallet, Metamask, WalletConnect, etc.) into your dApp built on the Klaytn Network.

Prerequisite

  • A working react project (by executing npx create-react-app project-name)

Getting Started

Web3-Onboard as a chain-agnostic wallet library, supports all EVM-compatible networks and also provides the flexibility of adding new networks to the library. In this guide, we'll use Web3-Onboard to add the Klaytn Mainnet Cypress and Klaytn Testnet Baobab to our dApp. With that said, let’s get started integrating multi-wallet compatibility using Web3-Onboard into your dApp built on Klaytn Network.

Setting up Onboard and Wallet Modules

Step 1: Install @web3-onboard/core

npm i @web3-onboard/core 

Step 2: Import and Instantiate Wallet Modules

npm install @web3-onboard/coinbase // Coinbase Wallet
npm install @web3-onboard/walletconnect // WalletConnect
npm install @web3-onboard/injected-wallets  // Used to connect to Metamask

In your App.js file, instantiate the wallet modules to integrate with your dApp. Note that each module has its own unique options parameters to pass in, such as a fallback JSON RPC URL or default chain ID.

import coinbaseWalletModule from "@web3-onboard/coinbase";
import walletConnectModule from "@web3-onboard/walletconnect";
import injectedModule from "@web3-onboard/injected-wallets";

const coinbaseWalletSdk = coinbaseWalletModule();
const walletConnect = walletConnectModule();
const injected = injectedModule();

const modules = [coinbaseWalletSdk, walletConnect, injected];

Step 3: Install and import ethers

npm install --save ethers

In your App.js file, import the ethers package like this:

import { ethers } from "ethers";

Step 4: Import and Setup Web3ReactProvider

In this step, you will instantiate Onboard with the created modules and a list of chains to be compatible with the library. Open up your App.js file and paste the code below:

import Onboard from "@web3-onboard/core";
const ETH_MAINNET_RPC_URL = `Paste ETH RPC URL`;
const KLAYTN_MAINNET_URL = `Paste KLAYTN MAINNET URL`
const KLAYTN_BAOBAB_URL = `Paste KLAYTN BAOBAB URL`

const onboard = Onboard({
  wallets: modules, // created in previous step
  chains: [
    {
      id: "0x1", // chain ID must be in hexadecimal
      token: "ETH",
      namespace: "evm",
      label: "Ethereum Mainnet",
      rpcUrl: ETH_MAINNET_RPC_URL
    },
    {
      id: "0x2019", // chain ID must be in hexadecimal
      token: "KLAY",
      namespace: "evm",
      label: "Klaytn Mainnet",
      rpcUrl: KLAYTN_MAINNET_URL
    },
    {
      id: "0x3e9", // chain ID must be in hexadecimel
      token: "KLAY",
      namespace: "evm",
      label: "Klaytn Testnet",
      rpcUrl: KLAYTN_BAOBAB_URL
    },
   // you can add as much supported chains as possible
  ],
  appMetadata: {
    name: "Klaytn-web3-onboard-App", // change to your dApp name
    icon: "https://pbs.twimg.com/profile_images/1620693002149851137/GbBC5ZjI_400x400.jpg", // paste your icon 
    logo: "https://pbs.twimg.com/profile_images/1620693002149851137/GbBC5ZjI_400x400.jpg", // paste your logo
    description: "Web3Onboard-Klaytn",
    recommendedInjectedWallets: [
      { name: "Coinbase", url: "https://wallet.coinbase.com/" },
      { name: "MetaMask", url: "https://metamask.io" }
    ]
  }
});

Setting up Utils function

In this guide, we will be making use of the utils functions such as truncateAddress() and toHex(). The truncateAddress() function takes in a valid address and returns a more readable format of the address passed in. While the toHex() function converts numbers to hexadecimal. The following steps below show how to set up and use the utils function in your project.

Step 1: Create a utils.js file in the src root folder.

Paste the following code in the newly created utils.js file.

export const truncateAddress = (address) => {
    if (!address) return "No Account";
    const match = address.match(
      /^(0x[a-zA-Z0-9]{2})[a-zA-Z0-9]+([a-zA-Z0-9]{4})$/
    );
    if (!match) return address;
    return `${match[1]}…${match[2]}`;
  };

  export const toHex = (num) => {
    const val = Number(num);
    return "0x" + val.toString(16);
  };

Step 2: Import the functions in your App.js file.

import { truncateAddress, toHex } from "./utils";

Connecting Wallet

Inside your App function in your App.js file, call the connectWallet() method on the onboard instance to initiate the onboard popup modal.

function App() {
    const connectWallet = async () => {
    try {
      const wallets = await onboard.connectWallet();
    } catch (error) {
      console.error(error);
    }
  };
  
  return (
    <div className="App">
      <button onClick={connectWallet}>Connect Wallet</button>  
    </div>
  );
}

Once you click your Connect Wallet button, you should see a modal that allows you to seamlessly connect to Coinbase Wallet and other instantiated wallets from your dApp.

Disconnecting Wallet

Disconnecting a connected wallet can be achieved by calling the disconnectWallet() method on the onboard instance along with the label of the user's primary wallet. Also, one good practice is to refresh the state to clear any previously stored connection data.

function App() {
    const connectWallet = async () => {
    try {
      const wallets = await onboard.connectWallet();
    } catch (error) {
      console.error(error);
    }
  };
    
  const disconnect = async () => {
    const [primaryWallet] = await onboard.state.get().wallets;
    if (primaryWallet) await onboard.disconnectWallet({ label: primaryWallet.label });
    refreshState();
  };

  // refresh state
  const refreshState = () => {
    setAccount("");
    setChainId("");
    setProvider();
    // make sure to add every other state declared here.
  };
  
  return (
    <div className="App">
           <button onClick={connectWallet}>Connect Wallet</button>  
          <button onClick={disconnect}>Disconnect</button>
    </div>
  );
}

Accessing connection, account, network information

Step 1: import React's useState

import { useState } from 'react';

Step 2: Modify code within your App function

function App() {
  const [provider, setProvider] = useState();
  const [account, setAccount] = useState();
  const [chainId, setChainId] = useState();
  const connectWallet = async () => {
    try {
      const wallets = await onboard.connectWallet();
      const { accounts, chains, provider } = wallets[0];
      
      setProvider(provider);
      setAccount(accounts[0].address);
      setChainId(chains[0].id);
     
    } catch (error) {
      console.error(error);
    }
  };
  
  ...
  
  return (
    <div className="App">
        <div>
            { !account ? ( <button  onClick={connectWallet}> Connect Wallet</button> ) : (
                <button onClick={disconnect}>Disconnect</button>
            )}
        </div>
     		
        <div>Wallet Address: ${truncateAddress(account)}</div>
        <div>Network Chain ID: ${chainId}</div>
    </div>
  );
}

Switching Networks

In order to prompt the user to switch networks in your dApps, Web3-Onboard provides a setChain method on an initialized instance of Onboard. Note that the target network must have been initialized with the onboard instance at the start of your application.

const switchNetwork = async () => {
await onboard.setChain({ chainId: toHex(1001) });
};

return (
    <div className="App">
        <button onClick={switchNetwork}>Switch Network</button>
    </div>
)

Sending Native Transaction

After successfully connecting to a wallet, you can store the provider object returned from the wallet connection in a state variable as done in connectWallet() function. You can therefore use this provider and signer object to send transactions to the blockchain.

 // add to the existing useState hook.
  const [txHash, setTxHash] = useState();

  const sendKlay = async () => {
    
    if (!provider) {
      console.log("provider not initialized yet");
      return;
    }
	
    // this guide uses ethers version 6.3.0.
    const ethersProvider = new ethers.BrowserProvider(provider);
    // for ethers version below 6.3.0.
    // const provider = new ethers.providers.Web3Provider(provider);

    const signer = await ethersProvider.getSigner();

    // Submit transaction to the blockchain and wait for it to be mined
    const tx = await signer.sendTransaction({
          to: "0x75Bc50a5664657c869Edc0E058d192EeEfD570eb",
          value: ethers.parseEther("0.1"),
          maxPriorityFeePerGas: "5000000000", // Max priority fee per gas
          maxFeePerGas: "6000000000000", // Max fee per gas
        })
    
        
    const receipt = await tx.wait();
    setTxHash(receipt.hash)
  }


return (
    <div className="App">
        <button onClick={sendKlay}>Send Klay</button>
        <div>Send-Klay Tx Hash :  {txHash ? <a href={`https://baobab.scope.klaytn.com/tx/${txHash}`} target="_blank">Klaytnscope</a> :  ' ' } </div>
    </div>
);

Interacting with Smart Contracts

With the Web3-Onboard provider and signer object, you can make contract interactions such as writing to and reading from a smart contract deployed on the blockchain.

// add to existing useState hook
  const [contractTx, setContractTx] = useState();
  const [contractMessage, setContractMessage] = useState();

  const writeToContract = async (e) => {
    e.preventDefault();
    if (!provider) {
      console.log("provider not initialized yet");
      return;
    }
  
     // this guide uses ethers version 6.3.0.
    const ethersProvider = new ethers.BrowserProvider(provider);
    // for ethers version below 6.3.0.
   // const provider = new ethers.providers.Web3Provider(provider);
    const signer = await ethersProvider.getSigner();
  
    // Paste your contractABI
    const contractABI = [
      {
        "inputs": [
          {
            "internalType": "uint256",
            "name": "_initNum",
            "type": "uint256"
          }
        ],
        "stateMutability": "nonpayable",
        "type": "constructor"
      },
      {
        "inputs": [],
        "name": "retrieve",
        "outputs": [
          {
            "internalType": "uint256",
            "name": "",
            "type": "uint256"
          }
        ],
        "stateMutability": "view",
        "type": "function"
      },
      {
        "inputs": [
          {
            "internalType": "uint256",
            "name": "num",
            "type": "uint256"
          }
        ],
        "name": "store",
        "outputs": [],
        "stateMutability": "nonpayable",
        "type": "function"
      }
    ]
  
     // Paste your contract address
    const contractAddress = "0x3b01E4025B428fFad9481a500BAc36396719092C";
  
    // const contract = new Contract(contractAddress, contractABI, provider);
    const contract = new ethers.Contract(contractAddress, contractABI, signer);
  
    const value = e.target.store_value.value;
  
    // Send transaction to smart contract to update message
    const tx = await contract.store(value);
  
    // Wait for transaction to finish
    const receipt = await tx.wait();
    const result = receipt.hash;
  
    setContractTx(result)
  }

  const readFromContract = async () => {
    if (!provider) {
      console.log("provider not initialized yet");
      return;
    }
  	
	
    // this guide uses ethers version 6.3.0.
    const ethersProvider = new ethers.BrowserProvider(provider);
    // for ethers version below 6.3.0.
    // const provider = new ethers.providers.Web3Provider(provider);
  
    // paste your contract ABI
    const contractABI = [
      {
        "inputs": [
          {
            "internalType": "uint256",
            "name": "_initNum",
            "type": "uint256"
          }
        ],
        "stateMutability": "nonpayable",
        "type": "constructor"
      },
      {
        "inputs": [],
        "name": "retrieve",
        "outputs": [
          {
            "internalType": "uint256",
            "name": "",
            "type": "uint256"
          }
        ],
        "stateMutability": "view",
        "type": "function"
      },
      {
        "inputs": [
          {
            "internalType": "uint256",
            "name": "num",
            "type": "uint256"
          }
        ],
        "name": "store",
        "outputs": [],
        "stateMutability": "nonpayable",
        "type": "function"
      }
    ]
  
     // paste your contract address
    const contractAddress = "0x3b01E4025B428fFad9481a500BAc36396719092C"; 
  
    // const contract = new Contract(contractAddress, contractABI, provider);
    const contract = new ethers.Contract(contractAddress, contractABI, ethersProvider)
  
    // Read message from smart contract
    const contractMessage = await contract.retrieve();
    setContractMessage(contractMessage.toString())
  }


  return (

    <div className="App">
         <form onSubmit={writeToContract}>
                  <input  name="store_value" placeholder="Set contract value" required/>
                  <input  type="submit" value="Store"/>
        </form> 
        <button onClick={readFromContract}>Read From Contract</button> 
        <div>Write-to-contract Tx Hash: ${contractTx}</div>
        <div>Read-from-contract Message: ${contractMessage}</div>
    </div>

  )

Troubleshooting

Polyfill node core module error

BREAKING CHANGES: webpack<5 used to include polyfills for node.js core modules by default.

Next Step

Leveraging a tool like , projects and developers may quickly integrate multiple wallets into their decentralized applications (dApps). With the help of Web3-Onboard, user onboarding has been simplified. Web3-Onboard does have different features, ranging from support for several wallets to the ability for users to connect their accounts to different chains or networks and receive real-time transaction notifications, et cetera.

Install the necessary wallets (, ).

RPC Endpoint: you can get this from one of the supported .

Test KLAY from : fund your account with sufficient KLAY.

In this step, you can add as many wallets to be supported in your dApp using the wallet modules. But for this guide, you will add Coinbase Wallet, WalletConnect, Injected Wallets to your web3-Onboard implementation. Refer to this for a list of wallet modules that can be added to your dApp using Web3-Onboard.

The Web3-Onboard provider can be used with libraries like and . In this guide, we will use ethers.js to make Klaytn blockchain calls like getting the user's account, fetch balance, sign transaction, send transaction, read from and write to the smart contract.

After successfully connecting your wallet, you can use the method to fetch the state of your connection stored through the onboard instance. You can also fetch the state during the initial connection. Now you can modify the connectWallet() method to return a list of wallet states that you can store in your state and use throughout the application.

This error occurs when you use webpack version 5. In this version, NodeJS polyfills is no longer supported by default. To solve this issue, refer to this .

For more in-depth guides on Web3-Onboard, please refer to and . Also, you can find the full implementation of the code for this guide on .

Web3-Onboard
Coinbase Wallet
Metamask
endpoint providers
Faucet
docs
ethers.js
web3.js
onboard.state.get()
guide
Blocknative Docs
Blocknative Github repository
GitHub