diff --git a/example/components/Card.tsx b/example/components/Card.tsx index 3ea766d..64582b5 100644 --- a/example/components/Card.tsx +++ b/example/components/Card.tsx @@ -1,9 +1,10 @@ -import { CoinbaseWallet } from '@web3-react/coinbase-wallet' -import { Web3ReactHooks } from '@web3-react/core' -import { GnosisSafe } from '@web3-react/gnosis-safe' -import { MetaMask } from '@web3-react/metamask' -import { Network } from '@web3-react/network' -import { WalletConnect as WalletConnectV2 } from '@web3-react/walletconnect-v2' +import type { CoinbaseWallet } from '@web3-react/coinbase-wallet' +import type { Web3ReactHooks } from '@web3-react/core' +import type { GnosisSafe } from '@web3-react/gnosis-safe' +import type { MetaMask } from '@web3-react/metamask' +import type { Network } from '@web3-react/network' +import type { WalletConnect } from '@web3-react/walletconnect' +import type { WalletConnect as WalletConnectV2 } from '@web3-react/walletconnect-v2' import { getName } from '../utils' import { Accounts } from './Accounts' @@ -12,7 +13,7 @@ import { ConnectWithSelect } from './ConnectWithSelect' import { Status } from './Status' interface Props { - connector: MetaMask | WalletConnectV2 | CoinbaseWallet | Network | GnosisSafe + connector: MetaMask | WalletConnect | WalletConnectV2 | CoinbaseWallet | Network | GnosisSafe activeChainId: ReturnType chainIds?: ReturnType[] isActivating: ReturnType diff --git a/example/components/ConnectWithSelect.tsx b/example/components/ConnectWithSelect.tsx index 939551a..d113140 100644 --- a/example/components/ConnectWithSelect.tsx +++ b/example/components/ConnectWithSelect.tsx @@ -3,6 +3,7 @@ import type { Web3ReactHooks } from '@web3-react/core' import { GnosisSafe } from '@web3-react/gnosis-safe' import type { MetaMask } from '@web3-react/metamask' import { Network } from '@web3-react/network' +import { WalletConnect } from '@web3-react/walletconnect' import { WalletConnect as WalletConnectV2 } from '@web3-react/walletconnect-v2' import { useCallback, useEffect, useState } from 'react' @@ -49,7 +50,7 @@ export function ConnectWithSelect({ error, setError, }: { - connector: MetaMask | WalletConnectV2 | CoinbaseWallet | Network | GnosisSafe + connector: MetaMask | WalletConnect | WalletConnectV2 | CoinbaseWallet | Network | GnosisSafe activeChainId: ReturnType chainIds?: ReturnType[] isActivating: ReturnType @@ -86,7 +87,11 @@ export function ConnectWithSelect({ if (desiredChainId === -1 || connector instanceof GnosisSafe) { await connector.activate() - } else if (connector instanceof WalletConnectV2 || connector instanceof Network) { + } else if ( + connector instanceof WalletConnectV2 || + connector instanceof WalletConnect || + connector instanceof Network + ) { await connector.activate(desiredChainId) } else { await connector.activate(getAddChainParameters(desiredChainId)) diff --git a/example/components/ProviderExample.tsx b/example/components/ProviderExample.tsx index 00d56e2..8721d33 100644 --- a/example/components/ProviderExample.tsx +++ b/example/components/ProviderExample.tsx @@ -1,17 +1,20 @@ -import { CoinbaseWallet } from '@web3-react/coinbase-wallet' +import type { CoinbaseWallet } from '@web3-react/coinbase-wallet' import { useWeb3React, Web3ReactHooks, Web3ReactProvider } from '@web3-react/core' -import { MetaMask } from '@web3-react/metamask' -import { Network } from '@web3-react/network' -import { WalletConnect as WalletConnectV2 } from '@web3-react/walletconnect-v2' +import type { MetaMask } from '@web3-react/metamask' +import type { Network } from '@web3-react/network' +import type { WalletConnect } from '@web3-react/walletconnect' +import type { WalletConnect as WalletConnectV2 } from '@web3-react/walletconnect-v2' import { coinbaseWallet, hooks as coinbaseWalletHooks } from '../connectors/coinbaseWallet' import { hooks as metaMaskHooks, metaMask } from '../connectors/metaMask' import { hooks as networkHooks, network } from '../connectors/network' -import { hooks as walletConnectV2Hooks, walletConnectV2 } from '../connectors/walletConnect' +import { hooks as walletConnectHooks, walletConnect } from '../connectors/walletConnect' +import { hooks as walletConnectV2Hooks, walletConnectV2 } from '../connectors/walletConnectV2' import { getName } from '../utils' -const connectors: [MetaMask | WalletConnectV2 | CoinbaseWallet | Network, Web3ReactHooks][] = [ +const connectors: [MetaMask | WalletConnect | WalletConnectV2 | CoinbaseWallet | Network, Web3ReactHooks][] = [ [metaMask, metaMaskHooks], + [walletConnect, walletConnectHooks], [walletConnectV2, walletConnectV2Hooks], [coinbaseWallet, coinbaseWalletHooks], [network, networkHooks], diff --git a/example/components/connectorCards/WalletConnectCard.tsx b/example/components/connectorCards/WalletConnectCard.tsx index 464fe58..cf1e69b 100644 --- a/example/components/connectorCards/WalletConnectCard.tsx +++ b/example/components/connectorCards/WalletConnectCard.tsx @@ -1,12 +1,9 @@ -import { URI_AVAILABLE } from '@web3-react/walletconnect-v2' +import { URI_AVAILABLE } from '@web3-react/walletconnect' import { useEffect, useState } from 'react' -import { MAINNET_CHAINS } from '../../chains' -import { hooks, walletConnectV2 } from '../../connectors/walletConnect' +import { hooks, walletConnect } from '../../connectors/walletConnect' import { Card } from '../Card' -const CHAIN_IDS = Object.keys(MAINNET_CHAINS).map(Number) - const { useChainId, useAccounts, useIsActivating, useIsActive, useProvider, useENSNames } = hooks export default function WalletConnectCard() { @@ -23,23 +20,22 @@ export default function WalletConnectCard() { // log URI when available useEffect(() => { - walletConnectV2.events.on(URI_AVAILABLE, (uri: string) => { + walletConnect.events.on(URI_AVAILABLE, (uri: string) => { console.log(`uri: ${uri}`) }) }, []) // attempt to connect eagerly on mount useEffect(() => { - walletConnectV2.connectEagerly().catch((error) => { - console.debug('Failed to connect eagerly to walletconnect', error) + walletConnect.connectEagerly().catch(() => { + console.debug('Failed to connect eagerly to walletconnect') }) }, []) return ( { + walletConnectV2.events.on(URI_AVAILABLE, (uri: string) => { + console.log(`uri: ${uri}`) + }) + }, []) + + // attempt to connect eagerly on mount + useEffect(() => { + walletConnectV2.connectEagerly().catch((error) => { + console.debug('Failed to connect eagerly to walletconnect', error) + }) + }, []) + + return ( + + ) +} diff --git a/example/connectors/walletConnect.ts b/example/connectors/walletConnect.ts index 3747852..2266402 100644 --- a/example/connectors/walletConnect.ts +++ b/example/connectors/walletConnect.ts @@ -1,15 +1,14 @@ import { initializeConnector } from '@web3-react/core' -import { WalletConnect as WalletConnectV2 } from '@web3-react/walletconnect-v2' +import { WalletConnect } from '@web3-react/walletconnect' -import { MAINNET_CHAINS } from '../chains' +import { URLS } from '../chains' -export const [walletConnectV2, hooks] = initializeConnector( +export const [walletConnect, hooks] = initializeConnector( (actions) => - new WalletConnectV2({ + new WalletConnect({ actions, options: { - projectId: process.env.walletConnectProjectId, - chains: Object.keys(MAINNET_CHAINS).map(Number), + rpc: URLS, }, }) ) diff --git a/example/connectors/walletConnectV2.ts b/example/connectors/walletConnectV2.ts new file mode 100644 index 0000000..3747852 --- /dev/null +++ b/example/connectors/walletConnectV2.ts @@ -0,0 +1,15 @@ +import { initializeConnector } from '@web3-react/core' +import { WalletConnect as WalletConnectV2 } from '@web3-react/walletconnect-v2' + +import { MAINNET_CHAINS } from '../chains' + +export const [walletConnectV2, hooks] = initializeConnector( + (actions) => + new WalletConnectV2({ + actions, + options: { + projectId: process.env.walletConnectProjectId, + chains: Object.keys(MAINNET_CHAINS).map(Number), + }, + }) +) diff --git a/example/package.json b/example/package.json index fb82af9..e812f62 100644 --- a/example/package.json +++ b/example/package.json @@ -20,6 +20,7 @@ "@web3-react/types": "^8.1.0-beta.0", "@web3-react/url": "^8.1.0-beta.0", "@web3-react/walletconnect-v2": "^8.1.0-beta.0", + "@web3-react/walletconnect": "^8.1.0-beta.0", "next": "^12.1.5", "react-dom": "^18.0.0" } diff --git a/example/pages/index.tsx b/example/pages/index.tsx index a1a8b3e..56ca0cb 100644 --- a/example/pages/index.tsx +++ b/example/pages/index.tsx @@ -3,6 +3,7 @@ import GnosisSafeCard from '../components/connectorCards/GnosisSafeCard' import MetaMaskCard from '../components/connectorCards/MetaMaskCard' import NetworkCard from '../components/connectorCards/NetworkCard' import WalletConnectCard from '../components/connectorCards/WalletConnectCard' +import WalletConnectV2Card from '../components/connectorCards/WalletConnectV2Card' import ProviderExample from '../components/ProviderExample' export default function Home() { @@ -11,6 +12,7 @@ export default function Home() {
+ diff --git a/example/utils.ts b/example/utils.ts index e15fe09..68e7946 100644 --- a/example/utils.ts +++ b/example/utils.ts @@ -3,11 +3,13 @@ import { GnosisSafe } from '@web3-react/gnosis-safe' import { MetaMask } from '@web3-react/metamask' import { Network } from '@web3-react/network' import type { Connector } from '@web3-react/types' +import { WalletConnect as WalletConnect } from '@web3-react/walletconnect' import { WalletConnect as WalletConnectV2 } from '@web3-react/walletconnect-v2' export function getName(connector: Connector) { if (connector instanceof MetaMask) return 'MetaMask' if (connector instanceof WalletConnectV2) return 'WalletConnect V2' + if (connector instanceof WalletConnect) return 'WalletConnect' if (connector instanceof CoinbaseWallet) return 'Coinbase Wallet' if (connector instanceof Network) return 'Network' if (connector instanceof GnosisSafe) return 'Gnosis Safe' diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index b9a17ee..6e91edc 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -1,5 +1,3 @@ -import type EventEmitter from 'node:events' - import type { StoreApi } from 'zustand' export interface Web3ReactState { @@ -37,8 +35,10 @@ export interface RequestArguments { } /** per {@link https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1193.md#events EIP-1193} */ -export type Provider = Pick & { +export interface Provider { request(args: RequestArguments): Promise + on(eventName: string | symbol, listener: (...args: any[]) => void): this + removeListener(eventName: string | symbol, listener: (...args: any[]) => void): this } /** per {@link https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1193.md#connect-1 EIP-1193} */ diff --git a/packages/walletconnect-v2/package.json b/packages/walletconnect-v2/package.json index ba64c2f..a023fb7 100644 --- a/packages/walletconnect-v2/package.json +++ b/packages/walletconnect-v2/package.json @@ -26,7 +26,7 @@ "dependencies": { "@web3-react/types": "^8.1.0-beta.0", "eventemitter3": "^4.0.7", - "@walletconnect/ethereum-provider": "^2.4.6" + "@walletconnect/ethereum-provider": "^2.4.7" }, "devDependencies": { "@web3-react/store": "^8.1.0-beta.0" diff --git a/packages/walletconnect/README.md b/packages/walletconnect/README.md new file mode 100644 index 0000000..cce487e --- /dev/null +++ b/packages/walletconnect/README.md @@ -0,0 +1 @@ +# @web3-react/walletconnect diff --git a/packages/walletconnect/package.json b/packages/walletconnect/package.json new file mode 100644 index 0000000..6f61f2f --- /dev/null +++ b/packages/walletconnect/package.json @@ -0,0 +1,35 @@ +{ + "name": "@web3-react/walletconnect", + "keywords": [ + "web3-react", + "walletconnect" + ], + "author": "Noah Zinsmeister ", + "license": "GPL-3.0-or-later", + "repository": "github:Uniswap/web3-react", + "publishConfig": { + "access": "public" + }, + "version": "8.1.0-beta.0", + "files": [ + "dist/*" + ], + "type": "commonjs", + "types": "./dist/index.d.ts", + "main": "./dist/index.js", + "exports": "./dist/index.js", + "scripts": { + "prebuild": "rm -rf dist", + "build": "tsc", + "start": "tsc --watch" + }, + "dependencies": { + "@web3-react/types": "^8.1.0-beta.0", + "eventemitter3": "^4.0.7", + "@walletconnect/ethereum-provider": "^1.7.8" + }, + "devDependencies": { + "@web3-react/store": "^8.1.0-beta.0", + "@walletconnect/types": "^1.7.8" + } +} diff --git a/packages/walletconnect/src/index.spec.ts b/packages/walletconnect/src/index.spec.ts new file mode 100644 index 0000000..1eaa76c --- /dev/null +++ b/packages/walletconnect/src/index.spec.ts @@ -0,0 +1,64 @@ +import { createWeb3ReactStoreAndActions } from '@web3-react/store' +import type { Actions, RequestArguments, Web3ReactStore } from '@web3-react/types' +import EventEmitter from 'node:events' +import { WalletConnect } from '.' +import { MockEIP1193Provider } from '../../eip1193/src/mock' + +// necessary because walletconnect returns chainId as a number +class MockMockWalletConnectProvider extends MockEIP1193Provider { + public connector = new EventEmitter() + + public eth_chainId_number = jest.fn((chainId?: string) => + chainId === undefined ? chainId : Number.parseInt(chainId, 16) + ) + + public request(x: RequestArguments): Promise { + if (x.method === 'eth_chainId') { + return Promise.resolve(this.eth_chainId_number(this.chainId)) + } else { + return super.request(x) + } + } +} + +jest.mock('@walletconnect/ethereum-provider', () => MockMockWalletConnectProvider) + +const chainId = '0x1' +const accounts: string[] = [] + +describe('WalletConnect', () => { + let store: Web3ReactStore + let connector: WalletConnect + let mockProvider: MockMockWalletConnectProvider + + describe('works', () => { + beforeEach(async () => { + let actions: Actions + ;[store, actions] = createWeb3ReactStoreAndActions() + connector = new WalletConnect({ actions, options: { rpc: {} } }) + }) + + test('#activate', async () => { + await connector.connectEagerly().catch(() => {}) + + mockProvider = connector.provider as unknown as MockMockWalletConnectProvider + mockProvider.chainId = chainId + mockProvider.accounts = accounts + + await connector.activate() + + expect(mockProvider.eth_requestAccounts).toHaveBeenCalled() + expect(mockProvider.eth_accounts).not.toHaveBeenCalled() + expect(mockProvider.eth_chainId_number).toHaveBeenCalled() + expect(mockProvider.eth_chainId_number.mock.invocationCallOrder[0]) + .toBeGreaterThan(mockProvider.eth_requestAccounts.mock.invocationCallOrder[0]) + + expect(store.getState()).toEqual({ + chainId: Number.parseInt(chainId, 16), + accounts, + activating: false, + error: undefined, + }) + }) + }) +}) diff --git a/packages/walletconnect/src/index.ts b/packages/walletconnect/src/index.ts new file mode 100644 index 0000000..0991478 --- /dev/null +++ b/packages/walletconnect/src/index.ts @@ -0,0 +1,197 @@ +import type { EventEmitter } from 'node:events' + +import type WalletConnectProvider from '@walletconnect/ethereum-provider' +import type { IWCEthRpcConnectionOptions } from '@walletconnect/types' +import type { Actions, ProviderRpcError } from '@web3-react/types' +import { Connector } from '@web3-react/types' +import EventEmitter3 from 'eventemitter3' + +import { getBestUrl } from './utils' + +export const URI_AVAILABLE = 'URI_AVAILABLE' + +type MockWalletConnectProvider = WalletConnectProvider & EventEmitter + +function parseChainId(chainId: string | number) { + return typeof chainId === 'string' ? Number.parseInt(chainId) : chainId +} + +type WalletConnectOptions = Omit & { + rpc: { [chainId: number]: string | string[] } +} + +/** + * @param options - Options to pass to `@walletconnect/ethereum-provider` + * @param defaultChainId - The chainId to connect to in activate if one is not provided. + * @param timeout - Timeout, in milliseconds, after which to treat network calls to urls as failed when selecting + * online urls. + * @param onError - Handler to report errors thrown from eventListeners. + */ +export interface WalletConnectConstructorArgs { + actions: Actions + options: WalletConnectOptions + defaultChainId?: number + timeout?: number + onError?: (error: Error) => void +} + +/** + * @param desiredChainId - The desired chainId to connect to. + * @param preventUserPrompt - If true, will suppress user-facing interactions and only connect silently. + */ +export interface ActivateOptions { + desiredChainId?: number + onlyIfAlreadyConnected?: boolean +} + +export class WalletConnect extends Connector { + /** {@inheritdoc Connector.provider} */ + public provider?: MockWalletConnectProvider + public readonly events = new EventEmitter3() + + private readonly options: Omit + private readonly rpc: { [chainId: number]: string[] } + private readonly defaultChainId: number + private readonly timeout: number + + private eagerConnection?: Promise + + constructor({ actions, options, defaultChainId, timeout = 5000, onError }: WalletConnectConstructorArgs) { + super(actions, onError) + + const { rpc, ...rest } = options + this.options = rest + this.rpc = Object.keys(rpc).reduce<{ [chainId: number]: string[] }>((accumulator, chainId) => { + const value = rpc[Number(chainId)] + accumulator[Number(chainId)] = Array.isArray(value) ? value : [value] + return accumulator + }, {}) + this.defaultChainId = defaultChainId ?? Number(Object.keys(this.rpc)[0]) + this.timeout = timeout + } + + private disconnectListener = (error?: ProviderRpcError): void => { + this.actions.resetState() + if (error) this.onError?.(error) + } + + private chainChangedListener = (chainId: number | string): void => { + this.actions.update({ chainId: parseChainId(chainId) }) + } + + private accountsChangedListener = (accounts: string[]): void => { + this.actions.update({ accounts }) + } + + private URIListener = (_: Error | null, payload: { params: string[] }): void => { + this.events.emit(URI_AVAILABLE, payload.params[0]) + } + + private async isomorphicInitialize(chainId = this.defaultChainId): Promise { + if (this.eagerConnection) return + + // because we can only use 1 url per chainId, we need to decide between multiple, where necessary + const rpc = Promise.all( + Object.keys(this.rpc).map( + async (chainId): Promise<[number, string]> => [ + Number(chainId), + await getBestUrl(this.rpc[Number(chainId)], this.timeout), + ] + ) + ).then((results) => + results.reduce<{ [chainId: number]: string }>((accumulator, [chainId, url]) => { + accumulator[chainId] = url + return accumulator + }, {}) + ) + + return (this.eagerConnection = import('@walletconnect/ethereum-provider').then(async (m) => { + this.provider = new m.default({ + ...this.options, + chainId, + rpc: await rpc, + }) as unknown as MockWalletConnectProvider + + this.provider.on('disconnect', this.disconnectListener) + this.provider.on('chainChanged', this.chainChangedListener) + this.provider.on('accountsChanged', this.accountsChangedListener) + this.provider.connector.on('display_uri', this.URIListener) + })) + } + + /** {@inheritdoc Connector.connectEagerly} */ + public async connectEagerly(): Promise { + const cancelActivation = this.actions.startActivation() + + try { + await this.isomorphicInitialize() + if (!this.provider?.connected) throw Error('No existing connection') + + // Wallets may resolve eth_chainId and hang on eth_accounts pending user interaction, which may include changing + // chains; they should be requested serially, with accounts first, so that the chainId can settle. + const accounts = await this.provider.request({ method: 'eth_accounts' }) + if (!accounts.length) throw new Error('No accounts returned') + const chainId = await this.provider.request({ method: 'eth_chainId' }) + + this.actions.update({ chainId: parseChainId(chainId), accounts }) + } catch (error) { + cancelActivation() + throw error + } + } + + /** + * @param desiredChainId - The desired chainId to connect to. + */ + public async activate(desiredChainId?: number): Promise { + // this early return clause catches some common cases if activate is called after connection has been established + if (this.provider?.connected) { + if (!desiredChainId || desiredChainId === this.provider.chainId) return + // because the provider is already connected, we can ignore the suppressUserPrompts + return this.provider.request({ + method: 'wallet_switchEthereumChain', + params: [{ chainId: `0x${desiredChainId.toString(16)}` }], + }) + } + + const cancelActivation = this.actions.startActivation() + + // if we're trying to connect to a specific chain that we're not already initialized for, we have to re-initialize + if (desiredChainId && desiredChainId !== this.provider?.chainId) await this.deactivate() + + try { + await this.isomorphicInitialize(desiredChainId) + if (!this.provider) throw new Error('No provider') + + // Wallets may resolve eth_chainId and hang on eth_accounts pending user interaction, which may include changing + // chains; they should be requested serially, with accounts first, so that the chainId can settle. + const accounts = await this.provider + .request({ method: 'eth_requestAccounts' }) + // if a user triggers the walletconnect modal, closes it, and then tries to connect again, + // the modal will not trigger. by deactivating when this happens, we prevent the bug. + .catch(async (error: Error) => { + if (error?.message === 'User closed modal') await this.deactivate() + throw error + }) + const chainId = await this.provider.request({ method: 'eth_chainId' }) + + this.actions.update({ chainId: parseChainId(chainId), accounts }) + } catch (error) { + cancelActivation() + throw error + } + } + + /** {@inheritdoc Connector.deactivate} */ + public async deactivate(): Promise { + this.provider?.off('disconnect', this.disconnectListener) + this.provider?.off('chainChanged', this.chainChangedListener) + this.provider?.off('accountsChanged', this.accountsChangedListener) + // we don't unregister the display_uri handler because the walletconnect types/inheritances are really broken. + // it doesn't matter, anyway, as the connector object is destroyed + await this.provider?.disconnect() + this.provider = undefined + this.eagerConnection = undefined + this.actions.resetState() + } +} diff --git a/packages/walletconnect/src/utils.spec.ts b/packages/walletconnect/src/utils.spec.ts new file mode 100644 index 0000000..ea703b0 --- /dev/null +++ b/packages/walletconnect/src/utils.spec.ts @@ -0,0 +1,75 @@ +import { getBestUrl } from './utils' + +class MockHttpConnection { + public readonly succeed: boolean + public readonly latency: number + + constructor(url: string) { + this.succeed = url.startsWith('succeed') + this.latency = Number.parseInt(url.split('_')[1]) + } +} + +class MockJsonRpcProvider { + private readonly http: MockHttpConnection + + constructor(http: MockHttpConnection) { + this.http = http + } + + public async request() { + return new Promise((resolve, reject) => { + setTimeout(() => { + if (this.http.succeed) { + resolve(1) + } else { + reject() + } + }, this.http.latency) + }) + } +} + +jest.mock('@walletconnect/jsonrpc-http-connection', () => ({ + HttpConnection: MockHttpConnection, +})) +jest.mock('@walletconnect/jsonrpc-provider', () => ({ + JsonRpcProvider: MockJsonRpcProvider, +})) + +describe('getBestUrl', () => { + test('works with 1 url (success)', async () => { + const url = await getBestUrl(['succeed_0'], 100) + expect(url).toBe('succeed_0') + }) + + test('works with 1 url (failure)', async () => { + const url = await getBestUrl(['fail_0'], 100) + expect(url).toBe('fail_0') + }) + + test('works with 2 urls (success/failure)', async () => { + const url = await getBestUrl(['succeed_0', 'fail_0'], 100) + expect(url).toBe('succeed_0') + }) + + test('works with 2 urls (failure/success)', async () => { + const url = await getBestUrl(['fail_0', 'succeed_0'], 100) + expect(url).toBe('succeed_0') + }) + + test('works with 2 successful urls (fast/slow)', async () => { + const url = await getBestUrl(['succeed_0', 'succeed_1'], 100) + expect(url).toBe('succeed_0') + }) + + test('works with 2 successful urls (slow/fast)', async () => { + const url = await getBestUrl(['succeed_1', 'succeed_0'], 100) + expect(url).toBe('succeed_1') + }) + + test('works with 2 successful urls (after timeout/before timeout)', async () => { + const url = await getBestUrl(['succeed_100', 'succeed_0'], 50) + expect(url).toBe('succeed_0') + }) +}) diff --git a/packages/walletconnect/src/utils.ts b/packages/walletconnect/src/utils.ts new file mode 100644 index 0000000..3da9c31 --- /dev/null +++ b/packages/walletconnect/src/utils.ts @@ -0,0 +1,68 @@ +/** + * @param urls - An array of URLs to try to connect to. + * @param timeout - How long to wait before a call is considered failed, in ms. + */ +export async function getBestUrl(urls: string[], timeout: number): Promise { + // if we only have 1 url, it's the best! + if (urls.length === 1) return urls[0] + + const [HttpConnection, JsonRpcProvider] = await Promise.all([ + import('@walletconnect/jsonrpc-http-connection').then(({ HttpConnection }) => HttpConnection), + import('@walletconnect/jsonrpc-provider').then(({ JsonRpcProvider }) => JsonRpcProvider), + ]) + + // the below returns the first url for which there's been a successful call, prioritized by index + return new Promise((resolve) => { + let resolved = false + const successes: { [index: number]: boolean } = {} + + urls.forEach((url, i) => { + const http = new JsonRpcProvider(new HttpConnection(url)) + + // create a promise that resolves on a successful call, and rejects on a failed call or after timeout milliseconds + const promise = new Promise((resolve, reject) => { + http + .request({ method: 'eth_chainId' }) + .then(() => resolve()) + .catch(() => reject()) + + // set a timeout to reject + setTimeout(() => { + reject() + }, timeout) + }) + + void promise + .then(() => true) + .catch(() => false) + .then((success) => { + // if we already resolved, return + if (resolved) return + + // store the result of the call + successes[i] = success + + // if this is the last call and we haven't resolved yet - do so + if (Object.keys(successes).length === urls.length) { + const index = Object.keys(successes).findIndex((j) => successes[Number(j)]) + // no need to set resolved to true, as this is the last promise + return resolve(urls[index === -1 ? 0 : index]) + } + + // otherwise, for each prospective index, check if we can resolve + new Array(urls.length).fill(0).forEach((_, prospectiveIndex) => { + // to resolve, we need to: + // a) have successfully made a call + // b) not be waiting on any other higher-index calls + if ( + successes[prospectiveIndex] && + new Array(prospectiveIndex).fill(0).every((_, j) => successes[j] === false) + ) { + resolved = true + resolve(urls[prospectiveIndex]) + } + }) + }) + }) + }) +} diff --git a/packages/walletconnect/tsconfig.json b/packages/walletconnect/tsconfig.json new file mode 100644 index 0000000..67531bb --- /dev/null +++ b/packages/walletconnect/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.json", + "include": ["./src"], + "compilerOptions": { + "outDir": "./dist" + } +} diff --git a/yarn.lock b/yarn.lock index b5ee196..cd45d1c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2506,10 +2506,31 @@ eslint-plugin-unused-imports "^2.0.0" prettier "^2.8.0" -"@walletconnect/core@2.4.6": - version "2.4.6" - resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-2.4.6.tgz#77072bf3a523b8fa26c93d085af55a5ea88cb48a" - integrity sha512-IPjS3dZvLQ2ZjuVKpel6NHIoW1bkCayh5W8XFC7nhLj5GHou5Gy2FsGgGbRknvCEVWH85AlFKFAvLZCe+TJ2VA== +"@walletconnect/browser-utils@^1.8.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@walletconnect/browser-utils/-/browser-utils-1.8.0.tgz#33c10e777aa6be86c713095b5206d63d32df0951" + integrity sha512-Wcqqx+wjxIo9fv6eBUFHPsW1y/bGWWRboni5dfD8PtOmrihrEpOCmvRJe4rfl7xgJW8Ea9UqKEaq0bIRLHlK4A== + dependencies: + "@walletconnect/safe-json" "1.0.0" + "@walletconnect/types" "^1.8.0" + "@walletconnect/window-getters" "1.0.0" + "@walletconnect/window-metadata" "1.0.0" + detect-browser "5.2.0" + +"@walletconnect/client@^1.8.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@walletconnect/client/-/client-1.8.0.tgz#6f46b5499c7c861c651ff1ebe5da5b66225ca696" + integrity sha512-svyBQ14NHx6Cs2j4TpkQaBI/2AF4+LXz64FojTjMtV4VMMhl81jSO1vNeg+yYhQzvjcGH/GpSwixjyCW0xFBOQ== + dependencies: + "@walletconnect/core" "^1.8.0" + "@walletconnect/iso-crypto" "^1.8.0" + "@walletconnect/types" "^1.8.0" + "@walletconnect/utils" "^1.8.0" + +"@walletconnect/core@2.4.7": + version "2.4.7" + resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-2.4.7.tgz#f1e2935eded3b882128a7fa6b56eff25221e6f2c" + integrity sha512-w92NrtziqrWs070HJICGh80Vp60PaXu06OjNvOnVZEorbTipCWx4xxgcC2NhsT4TCQ8r1FOut6ahLe1PILuRsg== dependencies: "@walletconnect/heartbeat" "1.2.0" "@walletconnect/jsonrpc-provider" "^1.0.6" @@ -2521,12 +2542,42 @@ "@walletconnect/relay-auth" "^1.0.4" "@walletconnect/safe-json" "^1.0.1" "@walletconnect/time" "^1.0.2" - "@walletconnect/types" "2.4.6" - "@walletconnect/utils" "2.4.6" + "@walletconnect/types" "2.4.7" + "@walletconnect/utils" "2.4.7" events "^3.3.0" lodash.isequal "4.5.0" pino "7.11.0" - uint8arrays "3.1.0" + uint8arrays "^3.1.0" + +"@walletconnect/core@^1.8.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.8.0.tgz#6b2748b90c999d9d6a70e52e26a8d5e8bfeaa81e" + integrity sha512-aFTHvEEbXcZ8XdWBw6rpQDte41Rxwnuk3SgTD8/iKGSRTni50gI9S3YEzMj05jozSiOBxQci4pJDMVhIUMtarw== + dependencies: + "@walletconnect/socket-transport" "^1.8.0" + "@walletconnect/types" "^1.8.0" + "@walletconnect/utils" "^1.8.0" + +"@walletconnect/crypto@^1.0.2": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@walletconnect/crypto/-/crypto-1.0.3.tgz#7b8dd4d7e2884fe3543c7c07aea425eef5ef9dd4" + integrity sha512-+2jdORD7XQs76I2Odgr3wwrtyuLUXD/kprNVsjWRhhhdO9Mt6WqVzOPu0/t7OHSmgal8k7SoBQzUc5hu/8zL/g== + dependencies: + "@walletconnect/encoding" "^1.0.2" + "@walletconnect/environment" "^1.0.1" + "@walletconnect/randombytes" "^1.0.3" + aes-js "^3.1.2" + hash.js "^1.1.7" + tslib "1.14.1" + +"@walletconnect/encoding@^1.0.1", "@walletconnect/encoding@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@walletconnect/encoding/-/encoding-1.0.2.tgz#cb3942ad038d6a6bf01158f66773062dd25724da" + integrity sha512-CrwSBrjqJ7rpGQcTL3kU+Ief+Bcuu9PH6JLOb+wM6NITX1GTxR/MfNwnQfhLKK6xpRAyj2/nM04OOH6wS8Imag== + dependencies: + is-typedarray "1.0.0" + tslib "1.14.1" + typedarray-to-buffer "3.1.5" "@walletconnect/environment@^1.0.1": version "1.0.1" @@ -2535,19 +2586,33 @@ dependencies: tslib "1.14.1" -"@walletconnect/ethereum-provider@^2.4.6": - version "2.4.6" - resolved "https://registry.yarnpkg.com/@walletconnect/ethereum-provider/-/ethereum-provider-2.4.6.tgz#f05c76092ec3dda3667a6b7522518375eafc6e38" - integrity sha512-o7UJ7EBzFSTqNAwGcVpqNv5qqaFW6Vi3nOoXPHtcrwYew8TKAcW/OQFHPcm0LeKfE15OvVI+GMHnPBRZ2Ih2RA== +"@walletconnect/ethereum-provider@^1.7.8": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@walletconnect/ethereum-provider/-/ethereum-provider-1.8.0.tgz#ed1dbf9cecc3b818758a060d2f9017c50bde1d32" + integrity sha512-Nq9m+oo5P0F+njsROHw9KMWdoc/8iGHYzQdkjJN/1C7DtsqFRg5k5a3hd9rzCLpbPsOC1q8Z5lRs6JQgDvPm6Q== + dependencies: + "@walletconnect/client" "^1.8.0" + "@walletconnect/jsonrpc-http-connection" "^1.0.2" + "@walletconnect/jsonrpc-provider" "^1.0.5" + "@walletconnect/signer-connection" "^1.8.0" + "@walletconnect/types" "^1.8.0" + "@walletconnect/utils" "^1.8.0" + eip1193-provider "1.0.1" + eventemitter3 "4.0.7" + +"@walletconnect/ethereum-provider@^2.4.7": + version "2.4.7" + resolved "https://registry.yarnpkg.com/@walletconnect/ethereum-provider/-/ethereum-provider-2.4.7.tgz#e863e90dc277b1fbec7de0685eaf28f5fcaeb136" + integrity sha512-YLvVsUMYeRuMbAlLmH8NygpgR17aVH8P9/rvckGXQTMe+MWXOp75SgLTK+HNxl/8YHmmOFyDjWT2gS4+l8ew+Q== dependencies: "@walletconnect/jsonrpc-http-connection" "^1.0.4" "@walletconnect/jsonrpc-provider" "^1.0.6" "@walletconnect/jsonrpc-types" "^1.0.2" "@walletconnect/jsonrpc-utils" "^1.0.4" - "@walletconnect/sign-client" "2.4.6" - "@walletconnect/types" "2.4.6" - "@walletconnect/universal-provider" "2.4.6" - "@walletconnect/utils" "2.4.6" + "@walletconnect/sign-client" "2.4.7" + "@walletconnect/types" "2.4.7" + "@walletconnect/universal-provider" "2.4.7" + "@walletconnect/utils" "2.4.7" "@web3modal/standalone" "2.1.1" events "^3.3.0" @@ -2571,6 +2636,25 @@ ts-node "^10.9.1" tslib "1.14.1" +"@walletconnect/iso-crypto@^1.8.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@walletconnect/iso-crypto/-/iso-crypto-1.8.0.tgz#44ddf337c4f02837c062dbe33fa7ab36789df451" + integrity sha512-pWy19KCyitpfXb70hA73r9FcvklS+FvO9QUIttp3c2mfW8frxgYeRXfxLRCIQTkaYueRKvdqPjbyhPLam508XQ== + dependencies: + "@walletconnect/crypto" "^1.0.2" + "@walletconnect/types" "^1.8.0" + "@walletconnect/utils" "^1.8.0" + +"@walletconnect/jsonrpc-http-connection@^1.0.2": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-http-connection/-/jsonrpc-http-connection-1.0.6.tgz#48c41cf3e5ac9add9425420b345615dc438594cd" + integrity sha512-/3zSqDi7JDN06E4qm0NmVYMitngXfh21UWwy8zeJcBeJc+Jcs094EbLsIxtziIIKTCCbT88lWuTjl1ZujxN7cw== + dependencies: + "@walletconnect/jsonrpc-utils" "^1.0.6" + "@walletconnect/safe-json" "^1.0.1" + cross-fetch "^3.1.4" + tslib "1.14.1" + "@walletconnect/jsonrpc-http-connection@^1.0.4": version "1.0.4" resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-http-connection/-/jsonrpc-http-connection-1.0.4.tgz#aeb0f7eae6565dd031f01d650ee73d358d760ee2" @@ -2581,6 +2665,15 @@ cross-fetch "^3.1.4" tslib "1.14.1" +"@walletconnect/jsonrpc-provider@^1.0.5": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-provider/-/jsonrpc-provider-1.0.8.tgz#d56e5bc95c1ec264748a6911389a3ac80f4bd831" + integrity sha512-M44vzTrF0TeDcxQorm2lJ5klmfqchYOZqmIHb5T9lIPA/rj22643P83j44flZLyzycPqy5UUlIH6foeBPwjxMg== + dependencies: + "@walletconnect/jsonrpc-utils" "^1.0.6" + "@walletconnect/safe-json" "^1.0.1" + tslib "1.14.1" + "@walletconnect/jsonrpc-provider@^1.0.6": version "1.0.6" resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-provider/-/jsonrpc-provider-1.0.6.tgz#e91321ef523f1904e6634e7866a0f3c6f056d2cd" @@ -2590,7 +2683,7 @@ "@walletconnect/safe-json" "^1.0.1" tslib "1.14.1" -"@walletconnect/jsonrpc-types@^1.0.2": +"@walletconnect/jsonrpc-types@^1.0.1", "@walletconnect/jsonrpc-types@^1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-types/-/jsonrpc-types-1.0.2.tgz#b79519f679cd6a5fa4a1bea888f27c1916689a20" integrity sha512-CZe8tjJX73OWdHjrBHy7HtAapJ2tT0Q3TYhPBhRxi3643lwPIQWC9En45ldY14TZwgSewkbZ0FtGBZK0G7Bbyg== @@ -2598,6 +2691,15 @@ keyvaluestorage-interface "^1.0.0" tslib "1.14.1" +"@walletconnect/jsonrpc-utils@^1.0.3", "@walletconnect/jsonrpc-utils@^1.0.6": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-utils/-/jsonrpc-utils-1.0.6.tgz#7fa58e6671247e64e189828103282e6258f5330f" + integrity sha512-snp0tfkjPiDLQp/jrBewI+9SM33GPV4+Gjgldod6XQ7rFyQ5FZjnBxUkY4xWH0+arNxzQSi6v5iDXjCjSaorpg== + dependencies: + "@walletconnect/environment" "^1.0.1" + "@walletconnect/jsonrpc-types" "^1.0.2" + tslib "1.14.1" + "@walletconnect/jsonrpc-utils@^1.0.4": version "1.0.4" resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-utils/-/jsonrpc-utils-1.0.4.tgz#2009ba3907b02516f2caacd2fb871ff0d472b2cb" @@ -2632,6 +2734,33 @@ pino "7.11.0" tslib "1.14.1" +"@walletconnect/mobile-registry@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@walletconnect/mobile-registry/-/mobile-registry-1.4.0.tgz#502cf8ab87330841d794819081e748ebdef7aee5" + integrity sha512-ZtKRio4uCZ1JUF7LIdecmZt7FOLnX72RPSY7aUVu7mj7CSfxDwUn6gBuK6WGtH+NZCldBqDl5DenI5fFSvkKYw== + +"@walletconnect/qrcode-modal@^1.8.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@walletconnect/qrcode-modal/-/qrcode-modal-1.8.0.tgz#ddd6f5c9b7ee52c16adf9aacec2a3eac4994caea" + integrity sha512-BueaFefaAi8mawE45eUtztg3ZFbsAH4DDXh1UNwdUlsvFMjqcYzLUG0xZvDd6z2eOpbgDg2N3bl6gF0KONj1dg== + dependencies: + "@walletconnect/browser-utils" "^1.8.0" + "@walletconnect/mobile-registry" "^1.4.0" + "@walletconnect/types" "^1.8.0" + copy-to-clipboard "^3.3.1" + preact "10.4.1" + qrcode "1.4.4" + +"@walletconnect/randombytes@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@walletconnect/randombytes/-/randombytes-1.0.3.tgz#e795e4918367fd1e6a2215e075e64ab93e23985b" + integrity sha512-35lpzxcHFbTN3ABefC9W+uBpNZl1GC4Wpx0ed30gibfO/y9oLdy1NznbV96HARQKSBV9J9M/rrtIvf6a23jfYw== + dependencies: + "@walletconnect/encoding" "^1.0.2" + "@walletconnect/environment" "^1.0.1" + randombytes "^2.1.0" + tslib "1.14.1" + "@walletconnect/relay-api@^1.0.9": version "1.0.9" resolved "https://registry.yarnpkg.com/@walletconnect/relay-api/-/relay-api-1.0.9.tgz#f8c2c3993dddaa9f33ed42197fc9bfebd790ecaf" @@ -2652,6 +2781,11 @@ tslib "1.14.1" uint8arrays "^3.0.0" +"@walletconnect/safe-json@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@walletconnect/safe-json/-/safe-json-1.0.0.tgz#12eeb11d43795199c045fafde97e3c91646683b2" + integrity sha512-QJzp/S/86sUAgWY6eh5MKYmSfZaRpIlmCJdi5uG4DJlKkZrHEF7ye7gA+VtbVzvTtpM/gRwO2plQuiooIeXjfg== + "@walletconnect/safe-json@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@walletconnect/safe-json/-/safe-json-1.0.1.tgz#9813fa0a7a544b16468730c2d7bed046ed160957" @@ -2659,23 +2793,44 @@ dependencies: tslib "1.14.1" -"@walletconnect/sign-client@2.4.6": - version "2.4.6" - resolved "https://registry.yarnpkg.com/@walletconnect/sign-client/-/sign-client-2.4.6.tgz#6dff6a4683a44d5ac88c3f570c743016d814d878" - integrity sha512-Dt5p4g105/1EFXFCTvdJiqtRGRgyWPzIJ8MSsTlYSoeJiTYwUC+mlBh4Y+Io/cxtc5hUuguaj0MyovIMiL4KkA== +"@walletconnect/sign-client@2.4.7": + version "2.4.7" + resolved "https://registry.yarnpkg.com/@walletconnect/sign-client/-/sign-client-2.4.7.tgz#d01e645f189726d5f919724a4145cdd16e4c4044" + integrity sha512-x5uxnHQkNSn0QNXUdPEfwy4o1Vyi2QIWkDGUh+pfSP4s2vN0+IJAcwqBqkPn+zJ1X7eKYLs+v0ih1eieciYMPA== dependencies: - "@walletconnect/core" "2.4.6" + "@walletconnect/core" "2.4.7" "@walletconnect/events" "^1.0.1" "@walletconnect/heartbeat" "1.2.0" "@walletconnect/jsonrpc-provider" "^1.0.6" "@walletconnect/jsonrpc-utils" "^1.0.4" "@walletconnect/logger" "^2.0.1" "@walletconnect/time" "^1.0.2" - "@walletconnect/types" "2.4.6" - "@walletconnect/utils" "2.4.6" + "@walletconnect/types" "2.4.7" + "@walletconnect/utils" "2.4.7" events "^3.3.0" pino "7.11.0" +"@walletconnect/signer-connection@^1.8.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@walletconnect/signer-connection/-/signer-connection-1.8.0.tgz#6cdf490df770e504cc1a550bdb5bac7696b130bc" + integrity sha512-+YAaTAP52MWZJ2wWnqKClKCPlPHBo6reURFe0cWidLADh9mi/kPWGALZ5AENK22zpem1bbKV466rF5Rzvu0ehA== + dependencies: + "@walletconnect/client" "^1.8.0" + "@walletconnect/jsonrpc-types" "^1.0.1" + "@walletconnect/jsonrpc-utils" "^1.0.3" + "@walletconnect/qrcode-modal" "^1.8.0" + "@walletconnect/types" "^1.8.0" + eventemitter3 "4.0.7" + +"@walletconnect/socket-transport@^1.8.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@walletconnect/socket-transport/-/socket-transport-1.8.0.tgz#9a1128a249628a0be11a0979b522fe82b44afa1b" + integrity sha512-5DyIyWrzHXTcVp0Vd93zJ5XMW61iDM6bcWT4p8DTRfFsOtW46JquruMhxOLeCOieM4D73kcr3U7WtyR4JUsGuQ== + dependencies: + "@walletconnect/types" "^1.8.0" + "@walletconnect/utils" "^1.8.0" + ws "7.5.3" + "@walletconnect/time@^1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@walletconnect/time/-/time-1.0.2.tgz#6c5888b835750ecb4299d28eecc5e72c6d336523" @@ -2683,10 +2838,10 @@ dependencies: tslib "1.14.1" -"@walletconnect/types@2.4.6": - version "2.4.6" - resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.4.6.tgz#45707ba774686f39a542c8cc1e9ca37c4a36691f" - integrity sha512-0ck2VvTRT4pTMQbop2Dku8YuOdNhebyJlXjtHN4naFgu73rXiw7Yml4N4hKjV4cwJoOBepWD2f9Dvl9cDFQ/Wg== +"@walletconnect/types@2.4.7": + version "2.4.7" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.4.7.tgz#9f102b444631149b2cb0d264830860dc5e211dc0" + integrity sha512-1VaPdPJrE+UrEjAhK5bdxq2+MTo3DvUMmQeNUsp3vUGhocQXB9hJQQ1rYBknYYSyDu2rTksGCQ4nv3ZOqfxvHw== dependencies: "@walletconnect/events" "^1.0.1" "@walletconnect/heartbeat" "1.2.0" @@ -2695,27 +2850,32 @@ "@walletconnect/logger" "^2.0.1" events "^3.3.0" -"@walletconnect/universal-provider@2.4.6": - version "2.4.6" - resolved "https://registry.yarnpkg.com/@walletconnect/universal-provider/-/universal-provider-2.4.6.tgz#336ad48e2159f9a32fb2f8e5bb5ed29712ebbcbc" - integrity sha512-FvuCCoQ00kYK3M6wYpaK9goCTa8kK5DQPTrsXYeitfXcJccQHxJahpEzIadLc6sj5+uK06WuLGGSObfpjSG3IA== +"@walletconnect/types@^1.7.8", "@walletconnect/types@^1.8.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.8.0.tgz#3f5e85b2d6b149337f727ab8a71b8471d8d9a195" + integrity sha512-Cn+3I0V0vT9ghMuzh1KzZvCkiAxTq+1TR2eSqw5E5AVWfmCtECFkVZBP6uUJZ8YjwLqXheI+rnjqPy7sVM4Fyg== + +"@walletconnect/universal-provider@2.4.7": + version "2.4.7" + resolved "https://registry.yarnpkg.com/@walletconnect/universal-provider/-/universal-provider-2.4.7.tgz#20b960cc1456a7a1cc77c173c9d38a145ed2ea02" + integrity sha512-xlefq2ahAsH3SpcsofWQQ5JT3Tz9NLAViA8FW07PHhfuf9p7OLp+Mu1wKxQEoBilyvfYRF4R5MTyTPy1wqJiRA== dependencies: "@walletconnect/jsonrpc-http-connection" "^1.0.4" "@walletconnect/jsonrpc-provider" "^1.0.6" "@walletconnect/jsonrpc-types" "^1.0.2" "@walletconnect/jsonrpc-utils" "^1.0.4" "@walletconnect/logger" "^2.0.1" - "@walletconnect/sign-client" "2.4.6" - "@walletconnect/types" "2.4.6" - "@walletconnect/utils" "2.4.6" + "@walletconnect/sign-client" "2.4.7" + "@walletconnect/types" "2.4.7" + "@walletconnect/utils" "2.4.7" eip1193-provider "1.0.1" events "^3.3.0" pino "7.11.0" -"@walletconnect/utils@2.4.6": - version "2.4.6" - resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-2.4.6.tgz#2bd192bfcc019d19929be2881f8e4f54fc9b56a0" - integrity sha512-SowRdiR3TTGeb3ikMP7ucOafgmu58Nh1pCjCff2666gQjVzT9qO1Y9aJ7eS3g3URJtLGzYCEIYohnUYOidvpgA== +"@walletconnect/utils@2.4.7": + version "2.4.7" + resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-2.4.7.tgz#f9589f3181f5dc3fd3d4e2cb4c41a08af42e2aae" + integrity sha512-t3kW0qLClnejTTKg3y/o/MmJb5ZDGfD13YT9Nw56Up3qq/pwVfTtWjt8vJOQWMIm0hZgjgESivcf6/wuu3/Oqw== dependencies: "@stablelib/chacha20poly1305" "1.0.1" "@stablelib/hkdf" "1.0.1" @@ -2726,20 +2886,45 @@ "@walletconnect/relay-api" "^1.0.9" "@walletconnect/safe-json" "^1.0.1" "@walletconnect/time" "^1.0.2" - "@walletconnect/types" "2.4.6" + "@walletconnect/types" "2.4.7" "@walletconnect/window-getters" "^1.0.1" "@walletconnect/window-metadata" "^1.0.1" detect-browser "5.3.0" query-string "7.1.1" - uint8arrays "3.1.0" + uint8arrays "^3.1.0" -"@walletconnect/window-getters@^1.0.1": +"@walletconnect/utils@^1.8.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.8.0.tgz#2591a197c1fa7429941fe428876088fda6632060" + integrity sha512-zExzp8Mj1YiAIBfKNm5u622oNw44WOESzo6hj+Q3apSMIb0Jph9X3GDIdbZmvVZsNPxWDL7uodKgZcCInZv2vA== + dependencies: + "@walletconnect/browser-utils" "^1.8.0" + "@walletconnect/encoding" "^1.0.1" + "@walletconnect/jsonrpc-utils" "^1.0.3" + "@walletconnect/types" "^1.8.0" + bn.js "4.11.8" + js-sha3 "0.8.0" + query-string "6.13.5" + +"@walletconnect/window-getters@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@walletconnect/window-getters/-/window-getters-1.0.0.tgz#1053224f77e725dfd611c83931b5f6c98c32bfc8" + integrity sha512-xB0SQsLaleIYIkSsl43vm8EwETpBzJ2gnzk7e0wMF3ktqiTGS6TFHxcprMl5R44KKh4tCcHCJwolMCaDSwtAaA== + +"@walletconnect/window-getters@^1.0.0", "@walletconnect/window-getters@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@walletconnect/window-getters/-/window-getters-1.0.1.tgz#f36d1c72558a7f6b87ecc4451fc8bd44f63cbbdc" integrity sha512-vHp+HqzGxORPAN8gY03qnbTMnhqIwjeRJNOMOAzePRg4xVEEE2WvYsI9G2NMjOknA8hnuYbU3/hwLcKbjhc8+Q== dependencies: tslib "1.14.1" +"@walletconnect/window-metadata@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@walletconnect/window-metadata/-/window-metadata-1.0.0.tgz#93b1cc685e6b9b202f29c26be550fde97800c4e5" + integrity sha512-9eFvmJxIKCC3YWOL97SgRkKhlyGXkrHwamfechmqszbypFspaSk+t2jQXAEU7YClHF6Qjw5eYOmy1//zFi9/GA== + dependencies: + "@walletconnect/window-getters" "^1.0.0" + "@walletconnect/window-metadata@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@walletconnect/window-metadata/-/window-metadata-1.0.1.tgz#2124f75447b7e989e4e4e1581d55d25bc75f7be5" @@ -2835,6 +3020,11 @@ aes-js@3.0.0: resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" integrity sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0= +aes-js@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.1.2.tgz#db9aabde85d5caabbfc0d4f2a4446960f627146a" + integrity sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ== + agent-base@6, agent-base@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -2886,12 +3076,17 @@ ansi-regex@^2.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= +ansi-regex@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed" + integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== + ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-styles@^3.2.1: +ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== @@ -3220,6 +3415,11 @@ blakejs@^1.1.0: resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.1.1.tgz#bf313053978b2cd4c444a48795710be05c785702" integrity sha512-bLG6PHOCZJKNshTjGRBvET0vTciwQE6zFKOKKXPDJfwFBd4Ac0yBfPZqcGvGJap50l7ktvlpFqc2jGVaUgbJgg== +bn.js@4.11.8: + version "4.11.8" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== + bn.js@^4.11.0, bn.js@^4.11.8, bn.js@^4.11.9: version "4.12.0" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" @@ -3325,7 +3525,25 @@ btoa@^1.2.1: resolved "https://registry.yarnpkg.com/btoa/-/btoa-1.2.1.tgz#01a9909f8b2c93f6bf680ba26131eb30f7fa3d73" integrity sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g== -buffer-from@^1.0.0: +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ== + +buffer-from@^1.0.0, buffer-from@^1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== @@ -3343,6 +3561,14 @@ buffer@6.0.3, buffer@^6.0.3: base64-js "^1.3.1" ieee754 "^1.2.1" +buffer@^5.4.3: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + builtins@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" @@ -3534,6 +3760,15 @@ cli-width@^3.0.0: resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + cliui@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" @@ -3767,6 +4002,13 @@ cookiejar@^2.1.1: resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.3.tgz#fc7a6216e408e74414b90230050842dacda75acc" integrity sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ== +copy-to-clipboard@^3.3.1: + version "3.3.3" + resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz#55ac43a1db8ae639a4bd99511c148cdd1b83a1b0" + integrity sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA== + dependencies: + toggle-selection "^1.0.6" + core-js-compat@^3.20.0: version "3.20.2" resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.20.2.tgz#d1ff6936c7330959b46b2e08b122a8b14e26140b" @@ -3997,6 +4239,11 @@ deprecation@^2.0.0, deprecation@^2.3.1: resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== +detect-browser@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/detect-browser/-/detect-browser-5.2.0.tgz#c9cd5afa96a6a19fda0bbe9e9be48a6b6e1e9c97" + integrity sha512-tr7XntDAu50BVENgQfajMLzacmSe34D+qZc4zjnniz0ZVuw/TZcLcyxHQjYpJTM36sGEkZZlYLnIM1hH7alTMA== + detect-browser@5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/detect-browser/-/detect-browser-5.3.0.tgz#9705ef2bddf46072d0f7265a1fe300e36fe7ceca" @@ -4140,6 +4387,11 @@ emittery@^0.8.1: resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg== +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" @@ -4721,7 +4973,7 @@ ethjs-util@0.1.6, ethjs-util@^0.1.3: is-hex-prefixed "1.0.0" strip-hex-prefix "1.0.0" -eventemitter3@^4.0.4, eventemitter3@^4.0.7: +eventemitter3@4.0.7, eventemitter3@^4.0.4, eventemitter3@^4.0.7: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== @@ -4889,6 +5141,13 @@ find-up@^2.0.0: dependencies: locate-path "^2.0.0" +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" @@ -5439,7 +5698,7 @@ iconv-lite@^0.6.2: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" -ieee754@^1.2.1: +ieee754@^1.1.13, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -5638,6 +5897,11 @@ is-fullwidth-code-point@^1.0.0: dependencies: number-is-nan "^1.0.0" +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w== + is-fullwidth-code-point@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" @@ -5780,7 +6044,7 @@ is-typed-array@^1.1.10, is-typed-array@^1.1.3, is-typed-array@^1.1.9: gopd "^1.0.1" has-tostringtag "^1.0.0" -is-typedarray@^1.0.0, is-typedarray@~1.0.0: +is-typedarray@1.0.0, is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= @@ -5804,6 +6068,11 @@ is-wsl@^2.2.0: dependencies: is-docker "^2.0.0" +isarray@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -6600,6 +6869,14 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + locate-path@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" @@ -7489,7 +7766,7 @@ p-limit@^1.1.0: dependencies: p-try "^1.0.0" -p-limit@^2.2.0: +p-limit@^2.0.0, p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== @@ -7510,6 +7787,13 @@ p-locate@^2.0.0: dependencies: p-limit "^1.1.0" +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + p-locate@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" @@ -7783,6 +8067,11 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" +pngjs@^3.3.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f" + integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w== + pngjs@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-5.0.0.tgz#e79dd2b215767fd9c04561c01236df960bce7fbb" @@ -7797,6 +8086,11 @@ postcss@8.4.14: picocolors "^1.0.0" source-map-js "^1.0.2" +preact@10.4.1: + version "10.4.1" + resolved "https://registry.yarnpkg.com/preact/-/preact-10.4.1.tgz#9b3ba020547673a231c6cf16f0fbaef0e8863431" + integrity sha512-WKrRpCSwL2t3tpOOGhf2WfTpcmbpxaWtDbdJdKdjd0aEiTkvOmS4NBkG6kzlaAHI9AkQ3iVqbFWM3Ei7mZ4o1Q== + preact@^10.5.9: version "10.6.4" resolved "https://registry.yarnpkg.com/preact/-/preact-10.6.4.tgz#ad12c409ff1b4316158486e0a7b8d43636f7ced8" @@ -7910,6 +8204,19 @@ q@^1.5.1: resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= +qrcode@1.4.4: + version "1.4.4" + resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.4.4.tgz#f0c43568a7e7510a55efc3b88d9602f71963ea83" + integrity sha512-oLzEC5+NKFou9P0bMj5+v6Z40evexeE29Z9cummZXZ9QXyMr3lphkURzxjXgPJC5azpxcshoDWV1xE46z+/c3Q== + dependencies: + buffer "^5.4.3" + buffer-alloc "^1.2.0" + buffer-from "^1.1.1" + dijkstrajs "^1.0.1" + isarray "^2.0.1" + pngjs "^3.3.0" + yargs "^13.2.4" + qrcode@1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.5.1.tgz#0103f97317409f7bc91772ef30793a54cd59f0cb" @@ -7932,6 +8239,15 @@ qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== +query-string@6.13.5: + version "6.13.5" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.13.5.tgz#99e95e2fb7021db90a6f373f990c0c814b3812d8" + integrity sha512-svk3xg9qHR39P3JlHuD7g3nRnyay5mHbrPctEBDUxUkHRifPHXJDhBUycdCC0NBjXoDf44Gb+IsOZL1Uwn8M/Q== + dependencies: + decode-uri-component "^0.2.0" + split-on-first "^1.0.0" + strict-uri-encode "^2.0.0" + query-string@7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/query-string/-/query-string-7.1.1.tgz#754620669db978625a90f635f12617c271a088e1" @@ -8720,6 +9036,15 @@ string-width@^1.0.1: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string-width@^3.0.0, string-width@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + string.prototype.matchall@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz#3bf85722021816dcd1bf38bb714915887ca79fd3" @@ -8773,6 +9098,13 @@ strip-ansi@^3.0.0, strip-ansi@^3.0.1: dependencies: ansi-regex "^2.0.0" +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -9012,6 +9344,11 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +toggle-selection@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32" + integrity sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ== + tough-cookie@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" @@ -9176,7 +9513,7 @@ typed-array-length@^1.0.4: for-each "^0.3.3" is-typed-array "^1.1.9" -typedarray-to-buffer@^3.1.5: +typedarray-to-buffer@3.1.5, typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== @@ -9203,14 +9540,7 @@ uid-number@0.0.6: resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" integrity sha1-DqEOgDXo61uOREnwbaHHMGY7qoE= -uint8arrays@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-3.1.0.tgz#8186b8eafce68f28bd29bd29d683a311778901e2" - integrity sha512-ei5rfKtoRO8OyOIor2Rz5fhzjThwIHJZ3uyDPnDHTXbP0aMQ1RN/6AI5B5d9dBxJOU+BvOAk7ZQ1xphsX8Lrog== - dependencies: - multiformats "^9.4.2" - -uint8arrays@^3.0.0: +uint8arrays@^3.0.0, uint8arrays@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-3.1.1.tgz#2d8762acce159ccd9936057572dade9459f65ae0" integrity sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg== @@ -9499,6 +9829,15 @@ workerpool@6.2.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + wrap-ansi@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" @@ -9579,6 +9918,11 @@ ws@7.4.6: resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== +ws@7.5.3: + version "7.5.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.3.tgz#160835b63c7d97bfab418fc1b8a9fced2ac01a74" + integrity sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg== + ws@8.3.0: version "8.3.0" resolved "https://registry.yarnpkg.com/ws/-/ws-8.3.0.tgz#7185e252c8973a60d57170175ff55fdbd116070d" @@ -9646,6 +9990,14 @@ yargs-parser@20.x, yargs-parser@^20.2.2, yargs-parser@^20.2.3: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== +yargs-parser@^13.1.2: + version "13.1.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" + integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + yargs-parser@^18.1.2: version "18.1.3" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" @@ -9677,6 +10029,22 @@ yargs@16.2.0, yargs@^16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" +yargs@^13.2.4: + version "13.3.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" + integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.2" + yargs@^15.3.1: version "15.4.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8"