Skip to content

Advanced DApp Concepts: WalletConnect

Ananthan edited this page May 25, 2024 · 3 revisions

Introduction

WalletConnect is a utility provider that can be leveraged to integrate wallet applications with DApps.

WalletConnect provides SDKs that can be integrated into various platforms, such as web, mobile, and desktop applications, and utilize native features.

Create a Project

To work with WalletConnect, we need to create a 'Project ID', which is required to connect our app to the wallets.

Go to cloud.walletconnect. Either connect your wallet or sign in using your Google account.

Click on 'Create Project'.

Provide a name for the app, and select 'App'. Since we don't have a secure HTTP link, leave it blank.

Finally, we have successfully created a project using WalletConnect. Please take a look at the newly generated 'Project ID'. We require that in our DApp.

Now, let's create a web app.

Web3Modal

WalletConnect provides multiple SDKs for various implementations. Here, we use Web3Modal to connect our web application with the wallets.

Initially, we need to create a web application. Here, we use 'React + Vite'.

npm create vite@latest

Choose 'React' and 'JavaScript'.

Install WalletConnect web3modal SDK and ethers.

npm i @web3modal/ethers ethers

Edit 'main.jsx' to include the configuration for the Web3Modal. Remember to paste your WalletConnect 'Project ID' as well.

// 1. Get projectId
const projectId = '<your-walletconnect-project-id>'

// 2. Set chains
const mainnet = {
  chainId: 1,
  name: 'Ethereum',
  currency: 'ETH',
  explorerUrl: 'https://etherscan.io',
  rpcUrl: 'https://cloudflare-eth.com'
}

// 3. Create a metadata object
const metadata = {
  name: '<your-dapp-name>',
  description: '<your-dapp-description>',
  url: '<your-dapp-url>', // origin must match your domain & subdomain
  icons: ['<your-dapp-icons-url>']
}

// 4. Create Ethers config
const ethersConfig = defaultConfig({
  /*Required*/
  metadata,

  /*Optional*/
  enableEIP6963: true, // true by default
  enableInjected: true, // true by default
  enableCoinbase: true, // true by default
  rpcUrl: '...', // used for the Coinbase SDK
  defaultChainId: 1, // used for the Coinbase SDK
})

// 5. Create a Web3Modal instance
createWeb3Modal({
  ethersConfig,
  chains: [mainnet],
  projectId,
  enableAnalytics: true // Optional - defaults to your Cloud configuration
})

Connecting Wallet with DApp

To create a Web3Modal, we first need to import useWeb3Modal, useWeb3ModalProvider from @web3modal/ethers/react and BrowserProvider from ethers in 'App.jsx'.

import { BrowserProvider } from 'ethers'
import { useWeb3Modal, useWeb3ModalProvider } from '@web3modal/ethers/react'

Inside the App() function, define two utilities from the aforementioned packages.

const { open } = useWeb3Modal()
const { walletProvider } = useWeb3ModalProvider()

Create a button inside the return statement, which utilizes the open function. Clicking the button will open the WalletConnect modal for connection (as the name suggests).

<button onClick={() => open()}>Connect</button>

Now, choose an option. If you select 'WalletConnect', scan the QR code to connect your wallet with our DApp. If we click the button again, we can see the connected account and provided network.

Signing with WalletConnect

ethers provides a utility to leverage a signing mechanism for the app. First, import useWeb3ModalProvider from @web3modal/ethers/react and use the walletProvider from it.

import { useWeb3ModalProvider } from '@web3modal/ethers/react'
const { walletProvider } = useWeb3ModalProvider()

Then, we import the BrowserProvider class from ethers to create a connection object by passing in the walletProvider.

const provider = new BrowserProvider(walletProvider)

After that, we fetch a signer from the given provider and ask them to 'sign a message'. This message could be any string. What we get in return is a 'signature' signed by the account's private key, which is a hex value. This hex value depends on the message and the account's private key, meaning the signature is unique for each individual. By storing the signature, we can authenticate the user without needing a username-password pair.

const signature = await signer?.signMessage('Welcome to Certificate DApp. Kindly sign this message for verification.')
console.log(signature)

We will wrap this logic into a function and assign it to a button. The final code will be as follows.

import { BrowserProvider } from 'ethers'
import { useWeb3Modal, useWeb3ModalProvider } from '@web3modal/ethers/react'

function App() {
  const { open } = useWeb3Modal()
  const { walletProvider } = useWeb3ModalProvider()

  const onSignMessage = async () => {
    const provider = new BrowserProvider(walletProvider)
    const signer = await provider.getSigner()
    const signature = await signer?.signMessage(
      'Welcome to Certificate DApp. Kindly sign this message for verification.'
    );
    console.log(signature);
  }
  
  return (
      <div>
        <button onClick={() => open()}>
            <span>Connect</span>
        </button>
        <button onClick={() => onSignMessage()}>
            <span>Sign</span>
        </button>
      </div>
  );
}

export default App

When we click the 'Sign' button, we must authenticate the connected wallet. After signing, we can view the signature by inspecting the browser console.



Clone this wiki locally