Tips

Handle invalid network

Since errors get minified in production, the only way to know that the error is coming from an invalid network, is to check if chainId property exists.

import { Modal } from 'w3r-modal'
import { useMemo } from 'react'
import { useWeb3State } from '../hooks'
import { wallets } from '../wallets'
import type { ChainIdNotAllowedError } from '@web3-react/store'

export function Example(props: JSX.IntrinsicElements['div']) {
  const { isConnected, connect, disconnect, error } = useWeb3State()

  const isInvalidNetwork = useMemo(() => {
    return (error as ChainIdNotAllowedError)?.chainId
  }, [error])

  return (
    <div className={styles.row} {...props}>
      <button
        className={styles.button}
        onClick={async () => {
          if (isInvalidNetwork) {
            // @ts-ignore
            await window.ethereum?.send('wallet_switchEthereumChain', [
              {
                chainId: `0x1`
              }
            ])
          } else if (isConnected) disconnect()
          else connect(wallets[0])
        }}
      >
        {isInvalidNetwork ? 'switch to ethereum' : isConnected ? 'disconnect' : 'connect'}
      </button>
    </div>
  )
}

Setup for projects using vanilla-extract

// sprinkles.css.ts
import type { Theme as W3RTheme, defaultTheme } from 'w3r-modal'
import { createGlobalThemeContract } from '@vanilla-extract/css'
import { ThemeVars } from '@vanilla-extract/css/dist/declarations/src/types'
import { createSprinkles, defineProperties } from '@vanilla-extract/sprinkles'

// sprinkles setup

const theme = {
  ...defaultTheme
  // ...
}

type Theme = typeof theme

export const themeVars: ThemeVars<Theme> = createGlobalThemeContract(theme, (_, path) => `dapp-${path.join('-')}`)

// serialize a theme object

export const serializedTheme = cssStringFromTheme(theme, themeVars)
import type { AppProps } from 'next/app'
import 'w3r-modal/style.css'
import { cssStringFromTheme } from 'w3r-modal'
import { Nav } from '../components/Nav'
import { Footer } from '../components/Footer'
import Head from 'next/head'
import { serializedTheme } from '../css/sprinkles.css'

const App = ({ pageProps, Component }: AppProps) => {
  return (
    <>
      <Head>
        <meta property="og:url" content="https://www.w3r-modal.vercel.app" />
        <meta property="og:type" content="website" />
        <meta property="og:image" content="/preview.jpg" />
        <meta name="twitter:card" content="summary_large_image" />
        <meta name="twitter:image" content="/preview.jpg" />
        <meta property="og:description" content="Simple Web3 wallet modal library based on web3-react." />
      </Head>
      <style jsx global>
        {`
          :root {
            ${serializedTheme}
          }
        `}
      </style>
      <Nav />
      <Component {...pageProps} />
      <Footer />
    </>
  )
}

export default App