React
Overview

Getting Started

W3Vm is an evm wallet connectors library for decentralized applications. It's inspired by Wagmi's references with the difference that it's eth-lib agnostic. (Eth-lib for ethereum libraries such as ethers.js, viem or web3.js).
It sets up for you a wallet connection infrastructure with a built-in store and React hooks to handle the wallet state and user's sessions.

Compatible with ethers.js, viem and Web3.js

Current supported protocols & wallets

The core package of this library supports injected (browser extension) and EIP-6963 compliant wallet.

Additional packages that can be installed:

  • WalletConnect connector
  • Coinbase SDK connector
  • MetaMask SDK connector

Install

npm i @w3vm/react

Install WalletConnect connector

npm i @w3vm/walletconnect

Init W3

initW3 must be called outside the root component to avoid unwanted rerenders.

import { W3, initW3, Injected } from '@w3vm/react'
import { WalletConnect } from '@w3vm/walletconnect'
 
/* Icons */
import walletconnect from 'public/walletconnect.svg'
import wallet from 'public/extension-wallet.png'
 
/* WalletConnect Project Id */
const projectId = 'YOUR_PROJECT_ID'
 
const w3props = initW3({
  connectors: [
    new Injected({ icon: wallet }), 
    new WalletConnect({ 
      projectId,
      icon: walletconnect,
      showQrModal: true,
      optionalChains:[1, 137]
    })
  ],
  defaultChain: 1, // Optional
  SSR: true, // Optional - For SSR Frameworks like Next.js
})
 
export default function App({ Component, pageProps }: AppProps) {
  return (
    <>
      <W3 {...w3props} /> { /* Required when SSR: true */ }
      <Component {...pageProps} />
    </>
  )
}

Create your WalletConnect Project ID at WalletConnect Cloud

Connect to a Wallet

Import the useConnect hook and map through the connectors array:

import { useConnect } from '@w3vm/react'
 
export default function Connect() {
 
  const { connectors, connectW3, disconnectW3, status } = useConnect()
  
  return (
    <>
      {connectors.map((connector) =>(
      <button key={connector.id} disabled={Boolean(status)} onClick={()=>connectW3({ connector })}>
        <img src={connector.icon} alt={connector.name} />
        {connector.name}
      </button>
      ))}
    </>
  )
}

Custom Hooks

import { getW3Chain, getW3Address, getW3Error } from '@w3vm/react'
 
export default function UserInfo(){
  
  const address = getW3Address()
  const chain = getW3Chain()
  const error = getW3Error()
  
  return (
    <div>
      address: {address}
      <br/>
      Chain ID: {chain}
      <br/>
      Error: {error}
    </div>
  )
}

Use with Ethers.js

import { BrowserProvider } from 'ethers'
import { getW3Provider } from '@w3vm/react'
 
export default function useEthersProvider(){
 
  const w3Provider = getW3Provider()
 
  function callContract(){
    if(!w3Provider) throw new Error('User not connected')
 
    const provider = new BrowserProvider(w3Provider)
    //...
  }
 
  //...
}

Use with Web3.js

import Web3 from 'web3'
import { getW3Provider } from '@w3vm/react'
 
export default function useWeb3Provider() {
 
  const w3Provider = getW3Provider()
 
  function callContract(){
    if(!w3Provider) throw new Error('User not connected')
 
    const provider = new Web3(w3Provider)
    //...
  }
 
  //...
}

Use with Viem

import { getW3Provider } from '@w3vm/react'
import { createWalletClient, custom } from 'viem'
import { mainnet } from 'viem/chains'
 
export default function useWalletClient() {
 
  const w3Provider = getW3Provider()
 
  function callContract(){
    if(!w3Provider) throw new Error('User not connected')
 
    const client = createWalletClient({
      chain: mainnet,
      transport: custom(w3Provider)
    })
    //...
  }
 
  //...
}