Skip to content

Commit

Permalink
feat(wallet-connect): add support for wcv2 (#604)
Browse files Browse the repository at this point in the history
* feat(wallet-connect): add support for v2

* option config

* update cosmos

* clean up

* fix build

* update @web3-react/walletconnect-v2

* yarn-deduplicate

* fix: static process.env

* pr feedback

* yarn update

---------

Co-authored-by: Jordan Frankfurt <[email protected]>
Co-authored-by: Zach Pomerantz <[email protected]>
  • Loading branch information
3 people authored Jul 7, 2023
1 parent b0b3044 commit 7ca58ca
Show file tree
Hide file tree
Showing 7 changed files with 769 additions and 428 deletions.
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
"@web3-react/network": "^8.2.0",
"@web3-react/types": "^8.2.0",
"@web3-react/url": "^8.2.0",
"@web3-react/walletconnect": "^8.2.0",
"@web3-react/walletconnect-v2": "^8.3.6",
"ajv": "^8.11.0",
"ajv-formats": "^2.1.1",
"cids": "^1.0.0",
Expand Down Expand Up @@ -170,7 +170,6 @@
"@uniswap/v2-core": "1.0.0",
"@uniswap/v3-core": "1.0.0",
"@uniswap/v3-periphery": "^1.1.1",
"@walletconnect/ethereum-provider": "^1.7.8",
"babel-jest": "^27.5.1",
"babel-loader": "^8.2.5",
"babel-plugin-macros": "^3.1.0",
Expand Down
13 changes: 11 additions & 2 deletions src/cosmos/useProvider.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { initializeConnector } from '@web3-react/core'
import { MetaMask } from '@web3-react/metamask'
import { Connector } from '@web3-react/types'
import { WalletConnect } from '@web3-react/walletconnect'
import { WalletConnect } from '@web3-react/walletconnect-v2'
import { L1_CHAIN_IDS, L2_CHAIN_IDS, SupportedChainId } from 'constants/chains'
import { JSON_RPC_FALLBACK_ENDPOINTS } from 'constants/jsonRpcEndpoints'
import { useEffect, useState } from 'react'

Expand All @@ -12,15 +13,23 @@ enum Wallet {
WalletConnect = 'WalletConnect',
}
const [metaMask] = initializeConnector<MetaMask>((actions) => new MetaMask({ actions }))

const WALLET_CONNECT_PROJECT_ID = 'c6c9bacd35afa3eb9e6cccf6d8464395'
const [walletConnect] = initializeConnector<WalletConnect>(
(actions) =>
new WalletConnect({
actions,
options: {
rpc: Object.entries(JSON_RPC_FALLBACK_ENDPOINTS).reduce((rpcMap, [chainId, rpcUrls]) => ({
rpcMap: Object.entries(JSON_RPC_FALLBACK_ENDPOINTS).reduce((rpcMap, [chainId, rpcUrls]) => ({
...rpcMap,
[chainId]: rpcUrls.slice(0, 1),
})),
showQrModal: true,
projectId: WALLET_CONNECT_PROJECT_ID,
// this requires the connecting wallet to support eth mainnet
chains: [SupportedChainId.MAINNET],
optionalChains: [...L1_CHAIN_IDS, ...L2_CHAIN_IDS],
optionalMethods: ['eth_signTypedData', 'eth_signTypedData_v4', 'eth_sign'],
},
})
)
Expand Down
44 changes: 36 additions & 8 deletions src/hooks/web3/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import './polyfills' // must be imported first

import { JsonRpcProvider } from '@ethersproject/providers'
import { initializeConnector, Web3ReactHooks, Web3ReactProvider } from '@web3-react/core'
import { EIP1193 } from '@web3-react/eip1193'
import { MetaMask } from '@web3-react/metamask'
import { Network } from '@web3-react/network'
import { Connector, Provider as Eip1193Provider } from '@web3-react/types'
import { WalletConnect } from '@web3-react/walletconnect-v2'
import { useAsyncError } from 'components/Error/ErrorBoundary'
import { SupportedChainId } from 'constants/chains'
import { L1_CHAIN_IDS, L2_CHAIN_IDS, SupportedChainId } from 'constants/chains'
import { MetaMaskConnectionError } from 'errors'
import { PropsWithChildren, useEffect, useMemo, useRef } from 'react'
import { Layer } from 'theme'
import JsonRpcConnector from 'utils/JsonRpcConnector'
import { supportedChainId } from 'utils/supportedChainId'
import { WalletConnectPopup, WalletConnectQR } from 'utils/WalletConnect'
import { WalletConnectQR } from 'utils/WalletConnect'

import { Provider as ConnectorsProvider } from './useConnectors'
import {
Expand All @@ -27,7 +31,7 @@ type Web3ReactConnector<T extends Connector = Connector> = [T, Web3ReactHooks]
interface Web3ReactConnectors {
user: Web3ReactConnector<EIP1193 | JsonRpcConnector> | undefined
metaMask: Web3ReactConnector<MetaMask>
walletConnect: Web3ReactConnector<WalletConnectPopup>
walletConnect: Web3ReactConnector<WalletConnect>
walletConnectQR: Web3ReactConnector<WalletConnectQR>
network: Web3ReactConnector<Network>
}
Expand Down Expand Up @@ -159,23 +163,47 @@ function useWeb3ReactConnectors({ defaultChainId, provider, jsonRpcUrlMap }: Pro
}),
[throwAsync]
)

const walletConnectDefaultOptions = useMemo(
() => ({
rpcMap: urlMap,
projectId: 'c6c9bacd35afa3eb9e6cccf6d8464395',
// this requires the connecting wallet to support eth mainnet
chains: [SupportedChainId.MAINNET],
optionalChains: [...L1_CHAIN_IDS, ...L2_CHAIN_IDS],
optionalMethods: ['eth_signTypedData', 'eth_signTypedData_v4', 'eth_sign'],
qrModalOptions: {
themeVariables: {
'--wcm-z-index': Layer.DIALOG.toString(),
},
},
}),
[urlMap]
)

const walletConnect = useMemo(
() =>
initializeWeb3ReactConnector(WalletConnectPopup, {
options: { rpc: urlMap },
initializeWeb3ReactConnector(WalletConnect, {
options: {
...walletConnectDefaultOptions,
showQrModal: true,
},
defaultChainId,
onError: console.error,
}),
[defaultChainId, urlMap]
[defaultChainId, walletConnectDefaultOptions]
)
const walletConnectQR = useMemo(
() =>
initializeWeb3ReactConnector(WalletConnectQR, {
options: { rpc: urlMap },
options: {
...walletConnectDefaultOptions,
showQrModal: false,
},
defaultChainId,
onError: console.error,
}),
[defaultChainId, urlMap]
[defaultChainId, walletConnectDefaultOptions]
)
const network = useMemo(
() => initializeWeb3ReactConnector(Network, { urlMap: connectionMap, defaultChainId }),
Expand Down
7 changes: 7 additions & 0 deletions src/hooks/web3/polyfills.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
if (typeof global.process !== 'object') {
// WCv2 alters global.process, and other libs (eg jotai) depend on a static object.
// Avoid breaking jotai by setting it statically before it is first seen.
global.process = { env: {} } as any
}

export {}
5 changes: 3 additions & 2 deletions src/hooks/web3/useConnectors.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ import { useWeb3React } from '@web3-react/core'
import { EIP1193 } from '@web3-react/eip1193'
import { MetaMask } from '@web3-react/metamask'
import { Network } from '@web3-react/network'
import { WalletConnect } from '@web3-react/walletconnect-v2'
import { createContext, PropsWithChildren, useContext, useEffect } from 'react'
import invariant from 'tiny-invariant'
import JsonRpcConnector from 'utils/JsonRpcConnector'
import { WalletConnectPopup, WalletConnectQR } from 'utils/WalletConnect'
import { WalletConnectQR } from 'utils/WalletConnect'

export interface Connectors {
user: EIP1193 | JsonRpcConnector | undefined
metaMask: MetaMask
walletConnect: WalletConnectPopup
walletConnect: WalletConnect
walletConnectQR: WalletConnectQR
network: Network
}
Expand Down
14 changes: 3 additions & 11 deletions src/utils/WalletConnect.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,18 @@
import 'setimmediate'

import { URI_AVAILABLE, WalletConnect, WalletConnectConstructorArgs } from '@web3-react/walletconnect'
import { URI_AVAILABLE, WalletConnect, WalletConnectConstructorArgs } from '@web3-react/walletconnect-v2'
import QRCode from 'qrcode'

export class WalletConnectPopup extends WalletConnect {
constructor({ actions, options, defaultChainId, timeout, onError }: WalletConnectConstructorArgs) {
super({ actions, options: { ...options, qrcode: true }, defaultChainId, timeout, onError })
}
}

export class WalletConnectQR extends WalletConnect {
static SVG_AVAILABLE = 'svg_available'

svg?: string

constructor({ actions, options, defaultChainId, timeout, onError }: WalletConnectConstructorArgs) {
super({ actions, options: { ...options, qrcode: false }, defaultChainId, timeout, onError })
super({ actions, options: { ...options, showQrModal: false }, defaultChainId, timeout, onError })

this.events.once(URI_AVAILABLE, () => {
this.provider?.connector.on('disconnect', () => {
this.deactivate()
})
this.provider?.events.on('disconnect', this.deactivate)
})

this.events.on(URI_AVAILABLE, async (uri) => {
Expand Down
Loading

1 comment on commit 7ca58ca

@vercel
Copy link

@vercel vercel bot commented on 7ca58ca Jul 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

widgets – ./

widgets-seven-tau.vercel.app
widgets-uniswap.vercel.app
widgets-git-main-uniswap.vercel.app

Please sign in to comment.