From d9e0e67d5eb5fc473b3c53f5ae6860e8ecccefc0 Mon Sep 17 00:00:00 2001 From: Felipe Mendes Date: Wed, 15 Jan 2025 15:28:42 -0300 Subject: [PATCH 1/2] refactor: remove onUri callbacks in favor of adding single callback listener --- .../bitcoin/tests/BitcoinAdapter.test.ts | 9 ++---- packages/adapters/solana/src/client.ts | 7 ++--- .../providers/SolanaWalletConnectProvider.ts | 11 +------- .../solana/src/tests/GenericProvider.test.ts | 13 ++++----- .../src/tests/WalletConnectProvider.test.ts | 1 - .../adapters/solana/src/tests/client.test.ts | 4 +-- packages/adapters/wagmi/src/client.ts | 28 ++++++------------- .../src/adapters/ChainAdapterBlueprint.ts | 4 +-- packages/appkit/src/client.ts | 9 ++++-- .../src/connectors/WalletConnectConnector.ts | 12 ++------ .../appkit/src/universal-adapter/client.ts | 20 +------------ packages/appkit/tests/appkit.test.ts | 11 ++++++++ .../connectors/WalletConnectConnector.test.ts | 4 +-- .../appkit/tests/universal-adapter.test.ts | 12 ++------ .../src/controllers/ConnectionController.ts | 11 ++------ .../controllers/ConnectionController.test.ts | 24 ++++++++-------- 16 files changed, 64 insertions(+), 116 deletions(-) diff --git a/packages/adapters/bitcoin/tests/BitcoinAdapter.test.ts b/packages/adapters/bitcoin/tests/BitcoinAdapter.test.ts index 7b76af4a06..76fbab75ed 100644 --- a/packages/adapters/bitcoin/tests/BitcoinAdapter.test.ts +++ b/packages/adapters/bitcoin/tests/BitcoinAdapter.test.ts @@ -53,19 +53,14 @@ describe('BitcoinAdapter', () => { }) it('should call connect from WALLET_CONNECT connector', async () => { - const onUri = vi.fn() - await adapter.connectWalletConnect(onUri) - ;( - mockWalletConnect.provider.on as MockedFunction - ).mock.calls.find(([name]) => name === 'display_uri')![1]('mock_uri') + await adapter.connectWalletConnect() - expect(onUri).toHaveBeenCalled() expect(mockWalletConnect.provider.connect).toHaveBeenCalled() }) it('should throw if caipNetworks is not defined', async () => { adapter = new BitcoinAdapter({ api }) - await expect(adapter.connectWalletConnect(vi.fn())).rejects.toThrow() + await expect(adapter.connectWalletConnect()).rejects.toThrow() }) it('should set BitcoinWalletConnectConnector', async () => { diff --git a/packages/adapters/solana/src/client.ts b/packages/adapters/solana/src/client.ts index 9c6e76dbd7..43258a8416 100644 --- a/packages/adapters/solana/src/client.ts +++ b/packages/adapters/solana/src/client.ts @@ -331,11 +331,8 @@ export class SolanaAdapter extends AdapterBlueprint { ) } - public override async connectWalletConnect( - onUri: (uri: string) => void, - chainId?: string | number - ) { - const result = await super.connectWalletConnect(onUri, chainId) + public override async connectWalletConnect(chainId?: string | number) { + const result = await super.connectWalletConnect(chainId) const rpcUrl = this.caipNetworks?.find(n => n.id === chainId)?.rpcUrls.default.http[0] as string const connection = new Connection(rpcUrl, this.connectionSettings) diff --git a/packages/adapters/solana/src/providers/SolanaWalletConnectProvider.ts b/packages/adapters/solana/src/providers/SolanaWalletConnectProvider.ts index 684fc9d581..2c16d0c279 100644 --- a/packages/adapters/solana/src/providers/SolanaWalletConnectProvider.ts +++ b/packages/adapters/solana/src/providers/SolanaWalletConnectProvider.ts @@ -45,9 +45,6 @@ export class SolanaWalletConnectProvider this.getActiveChain = getActiveChain } - // -- Universal Provider Events ------------------------ // - public onUri?: (uri: string) => void - // -- Public ------------------------------------------- // public get session(): SessionTypes.Struct | undefined { return this.provider.session @@ -80,13 +77,7 @@ export class SolanaWalletConnectProvider } public async connect() { - if (!this.onUri) { - throw new Error('onUri callback is required to connect WalletConnectProvider') - } - - await super.connectWalletConnect({ - onUri: this.onUri - }) + await super.connectWalletConnect() const account = this.getAccount(true) diff --git a/packages/adapters/solana/src/tests/GenericProvider.test.ts b/packages/adapters/solana/src/tests/GenericProvider.test.ts index 5328ec095f..791e5de054 100644 --- a/packages/adapters/solana/src/tests/GenericProvider.test.ts +++ b/packages/adapters/solana/src/tests/GenericProvider.test.ts @@ -20,14 +20,11 @@ const getActiveChain = vi.fn(() => TestConstants.chains[0]) const providers: { name: string; provider: Provider }[] = [ { name: 'WalletConnectProvider', - provider: Object.assign( - new SolanaWalletConnectProvider({ - provider: mockUniversalProvider(), - chains: TestConstants.chains, - getActiveChain - }), - { onUri: vi.fn() } - ) + provider: new SolanaWalletConnectProvider({ + provider: mockUniversalProvider(), + chains: TestConstants.chains, + getActiveChain + }) }, { name: 'WalletStandardProvider', diff --git a/packages/adapters/solana/src/tests/WalletConnectProvider.test.ts b/packages/adapters/solana/src/tests/WalletConnectProvider.test.ts index d35febaaaf..bf1fa9eccd 100644 --- a/packages/adapters/solana/src/tests/WalletConnectProvider.test.ts +++ b/packages/adapters/solana/src/tests/WalletConnectProvider.test.ts @@ -25,7 +25,6 @@ describe('WalletConnectProvider specific tests', () => { chains: TestConstants.chains, getActiveChain }) - walletConnectProvider.onUri = vi.fn() }) it('should call connect', async () => { diff --git a/packages/adapters/solana/src/tests/client.test.ts b/packages/adapters/solana/src/tests/client.test.ts index 9f5ca495bf..87a954bbc5 100644 --- a/packages/adapters/solana/src/tests/client.test.ts +++ b/packages/adapters/solana/src/tests/client.test.ts @@ -230,12 +230,10 @@ describe('SolanaAdapter', () => { describe('SolanaAdapter - connectWalletConnect', () => { it('should connect WalletConnect provider', async () => { - const onUri = vi.fn() vi.mocked(adapter['connectors']).push(mockWalletConnectConnector) - await adapter.connectWalletConnect(onUri) + await adapter.connectWalletConnect() expect(mockWalletConnectConnector.provider.connect).toHaveBeenCalled() - expect(mockWalletConnectConnector.provider.on).toHaveBeenCalledWith('display_uri', onUri) expect(SolStoreUtil.setConnection).toHaveBeenCalled() }) }) diff --git a/packages/adapters/wagmi/src/client.ts b/packages/adapters/wagmi/src/client.ts index b5855dc6d1..32354a0ef7 100644 --- a/packages/adapters/wagmi/src/client.ts +++ b/packages/adapters/wagmi/src/client.ts @@ -473,38 +473,28 @@ export class WagmiAdapter extends AdapterBlueprint { } } - public override async connectWalletConnect( - onUri: (uri: string) => void, - chainId?: number | string - ) { + public override async connectWalletConnect(chainId?: number | string) { // Attempt one click auth first const walletConnectConnector = this.getWalletConnectConnector() - const isAuthenticated = await walletConnectConnector.authenticate({ onUri }) + const isAuthenticated = await walletConnectConnector.authenticate() if (isAuthenticated) { return { clientId: await walletConnectConnector.provider.client.core.crypto.getClientId() } } // Attempt to connect using wagmi connector - const connector = this.getWagmiConnector('walletConnect') + const wagmiConnector = this.getWagmiConnector('walletConnect') - if (!connector) { + if (!wagmiConnector) { throw new Error('UniversalAdapter:connectWalletConnect - connector not found') } - const provider = (await connector.getProvider()) as UniversalProvider - - if (!this.caipNetworks || !provider) { - throw new Error( - 'UniversalAdapter:connectWalletConnect - caipNetworks or provider is undefined' - ) - } - - provider.on('display_uri', onUri) - - await connect(this.wagmiConfig, { connector, chainId: chainId ? Number(chainId) : undefined }) + await connect(this.wagmiConfig, { + connector: wagmiConnector, + chainId: chainId ? Number(chainId) : undefined + }) - return { clientId: await provider.client.core.crypto.getClientId() } + return { clientId: await walletConnectConnector.provider.client.core.crypto.getClientId() } } public async connect( diff --git a/packages/appkit/src/adapters/ChainAdapterBlueprint.ts b/packages/appkit/src/adapters/ChainAdapterBlueprint.ts index 8effb863b1..6025af47fe 100644 --- a/packages/appkit/src/adapters/ChainAdapterBlueprint.ts +++ b/packages/appkit/src/adapters/ChainAdapterBlueprint.ts @@ -187,16 +187,14 @@ export abstract class AdapterBlueprint< /** * Connects to WalletConnect. - * @param {(uri: string) => void} onUri - Callback function to handle the WalletConnect URI * @param {number | string} [_chainId] - Optional chain ID to connect to */ public async connectWalletConnect( - onUri: (uri: string) => void, _chainId?: number | string ): Promise { const connector = this.getWalletConnectConnector() - const result = await connector.connectWalletConnect({ onUri }) + const result = await connector.connectWalletConnect() return { clientId: result.clientId } } diff --git a/packages/appkit/src/client.ts b/packages/appkit/src/client.ts index 53390e674f..6d8eb75939 100644 --- a/packages/appkit/src/client.ts +++ b/packages/appkit/src/client.ts @@ -829,14 +829,14 @@ export class AppKit { private createClients() { this.connectionControllerClient = { - connectWalletConnect: async (onUri: (uri: string) => void) => { + connectWalletConnect: async () => { const adapter = this.getAdapter(ChainController.state.activeChain) if (!adapter) { throw new Error('Adapter not found') } - const result = await adapter.connectWalletConnect(onUri, this.getCaipNetwork()?.id) + const result = await adapter.connectWalletConnect(this.getCaipNetwork()?.id) this.close() this.setClientId(result?.clientId || null) @@ -1289,6 +1289,11 @@ export class AppKit { private listenWalletConnect() { if (this.universalProvider) { + this.universalProvider.on( + 'display_uri', + ConnectionController.setUri.bind(ConnectionController) + ) + this.universalProvider.on('disconnect', () => { this.chainNamespaces.forEach(namespace => { this.resetAccount(namespace) diff --git a/packages/appkit/src/connectors/WalletConnectConnector.ts b/packages/appkit/src/connectors/WalletConnectConnector.ts index 412ac8dd53..c2e89db7e2 100644 --- a/packages/appkit/src/connectors/WalletConnectConnector.ts +++ b/packages/appkit/src/connectors/WalletConnectConnector.ts @@ -33,8 +33,8 @@ export class WalletConnectConnector { - this.provider.on('display_uri', params.onUri) - + async authenticate(): Promise { const chains = this.chains.map(network => network.caipNetworkId) return SIWXUtil.universalProviderAuthenticate({ @@ -72,10 +70,6 @@ export namespace WalletConnectConnector { namespace: Namespace } - export type ConnectParams = { - onUri: (uri: string) => void - } - export type ConnectResult = { clientId: string | null session: SessionTypes.Struct diff --git a/packages/appkit/src/universal-adapter/client.ts b/packages/appkit/src/universal-adapter/client.ts index 14049a2383..6ada4a53c2 100644 --- a/packages/appkit/src/universal-adapter/client.ts +++ b/packages/appkit/src/universal-adapter/client.ts @@ -2,12 +2,7 @@ import type UniversalProvider from '@walletconnect/universal-provider' import bs58 from 'bs58' import { type ChainNamespace, ConstantsUtil } from '@reown/appkit-common' -import { - ChainController, - ConnectionController, - CoreHelperUtil, - OptionsController -} from '@reown/appkit-core' +import { ChainController, CoreHelperUtil } from '@reown/appkit-core' import { AdapterBlueprint } from '../adapters/ChainAdapterBlueprint.js' import { WalletConnectConnector } from '../connectors/WalletConnectConnector.js' @@ -23,19 +18,6 @@ export class UniversalAdapter extends AdapterBlueprint { ) } - public override async connectWalletConnect( - onUri: (uri: string) => void, - _chainId?: string | number | undefined - ): Promise<{ clientId: string } | undefined> { - if (OptionsController.state.useInjectedUniversalProvider && ConnectionController.state.wcUri) { - onUri(ConnectionController.state.wcUri) - - return undefined - } - - return super.connectWalletConnect(onUri, _chainId) - } - public async connect( params: AdapterBlueprint.ConnectParams ): Promise { diff --git a/packages/appkit/tests/appkit.test.ts b/packages/appkit/tests/appkit.test.ts index 4de41d8d0c..0239e15c78 100644 --- a/packages/appkit/tests/appkit.test.ts +++ b/packages/appkit/tests/appkit.test.ts @@ -1832,6 +1832,7 @@ describe('WalletConnect Events', () => { let universalProvider: Mocked> let chainChangedCallback: (chainId: string | number) => void + let displayUriCallback: (uri: string) => void beforeEach(async () => { appkit = new AppKit({ @@ -1850,6 +1851,9 @@ describe('WalletConnect Events', () => { chainChangedCallback = universalProvider.on.mock.calls.find( ([event]) => event === 'chainChanged' )?.[1] + displayUriCallback = universalProvider.on.mock.calls.find( + ([event]) => event === 'display_uri' + )?.[1] }) describe('chainChanged', () => { @@ -1875,4 +1879,11 @@ describe('WalletConnect Events', () => { expect(setCaipNetworkSpy).toHaveBeenNthCalledWith(2, newChain) }) }) + + describe('display_uri', () => { + it('should call openUri', () => { + displayUriCallback('mock_uri') + expect(ConnectionController.setUri).toHaveBeenCalledWith('mock_uri') + }) + }) }) diff --git a/packages/appkit/tests/connectors/WalletConnectConnector.test.ts b/packages/appkit/tests/connectors/WalletConnectConnector.test.ts index adf124dc52..02e1c7dca7 100644 --- a/packages/appkit/tests/connectors/WalletConnectConnector.test.ts +++ b/packages/appkit/tests/connectors/WalletConnectConnector.test.ts @@ -51,7 +51,7 @@ describe('WalletConnectConnector', () => { .spyOn(SIWXUtil, 'universalProviderAuthenticate') .mockResolvedValueOnce(false) - await connector.connectWalletConnect({ onUri: vi.fn() }) + await connector.connectWalletConnect() expect(authenticateSpy).toHaveBeenCalledWith( expect.objectContaining({ @@ -68,7 +68,7 @@ describe('WalletConnectConnector', () => { Promise.resolve(true) ) - await connector.connectWalletConnect({ onUri: vi.fn() }) + await connector.connectWalletConnect() expect(provider.connect).not.toHaveBeenCalled() }) diff --git a/packages/appkit/tests/universal-adapter.test.ts b/packages/appkit/tests/universal-adapter.test.ts index ea147e9cf1..589afd6877 100644 --- a/packages/appkit/tests/universal-adapter.test.ts +++ b/packages/appkit/tests/universal-adapter.test.ts @@ -63,11 +63,8 @@ describe('UniversalAdapter', () => { describe('connectWalletConnect', () => { it('should connect successfully', async () => { - const onUri = vi.fn() + await adapter.connectWalletConnect() - await adapter.connectWalletConnect(onUri) - - expect(mockProvider.on).toHaveBeenCalledWith('display_uri', expect.any(Function)) expect(mockProvider.connect).toHaveBeenCalledWith({ optionalNamespaces: expect.any(Object) }) @@ -79,13 +76,12 @@ describe('UniversalAdapter', () => { writable: true }) - await expect(adapter.connectWalletConnect(() => {})).rejects.toThrow( + await expect(adapter.connectWalletConnect()).rejects.toThrow( 'WalletConnectConnector not found' ) }) it('should call onUri when display_uri event is emitted', async () => { - const onUri = vi.fn() const testUri = 'wc:test-uri' // Call the callback directly when 'on' is called @@ -96,9 +92,7 @@ describe('UniversalAdapter', () => { return mockProvider }) - await adapter.connectWalletConnect(onUri) - - expect(onUri).toHaveBeenCalledWith(testUri) + await adapter.connectWalletConnect() }) }) diff --git a/packages/core/src/controllers/ConnectionController.ts b/packages/core/src/controllers/ConnectionController.ts index a708209c09..7132bb1445 100644 --- a/packages/core/src/controllers/ConnectionController.ts +++ b/packages/core/src/controllers/ConnectionController.ts @@ -32,7 +32,7 @@ export interface ConnectExternalOptions { } export interface ConnectionControllerClient { - connectWalletConnect?: (onUri: (uri: string) => void) => Promise + connectWalletConnect?: () => Promise disconnect: () => Promise signMessage: (message: string) => Promise sendTransaction: (args: SendTransactionArgs) => Promise @@ -125,12 +125,7 @@ export const ConnectionController = { return } wcConnectionPromise = new Promise(async (resolve, reject) => { - await this._getClient() - ?.connectWalletConnect?.(uri => { - state.wcUri = uri - state.wcPairingExpiry = CoreHelperUtil.getPairingExpiry() - }) - .catch(reject) + await this._getClient()?.connectWalletConnect?.().catch(reject) resolve() }) this.state.status = 'connecting' @@ -139,7 +134,7 @@ export const ConnectionController = { state.wcPairingExpiry = undefined this.state.status = 'connected' } else { - await this._getClient()?.connectWalletConnect?.(uri => this.setUri(uri)) + await this._getClient()?.connectWalletConnect?.() } }, diff --git a/packages/core/tests/controllers/ConnectionController.test.ts b/packages/core/tests/controllers/ConnectionController.test.ts index 01f35d4e25..463329444f 100644 --- a/packages/core/tests/controllers/ConnectionController.test.ts +++ b/packages/core/tests/controllers/ConnectionController.test.ts @@ -29,10 +29,7 @@ const caipNetworks = [ ] const client: ConnectionControllerClient = { - connectWalletConnect: async onUri => { - onUri(walletConnectUri) - await Promise.resolve(walletConnectUri) - }, + connectWalletConnect: async () => {}, disconnect: async () => Promise.resolve(), signMessage: async (message: string) => Promise.resolve(message), estimateGas: async () => Promise.resolve(BigInt(0)), @@ -116,15 +113,8 @@ describe('ConnectionController', () => { }) it('should update state correctly and set wcPromisae on connectWalletConnect()', async () => { - // Setup timers for pairing expiry - const fakeDate = new Date(0) - vi.useFakeTimers() - vi.setSystemTime(fakeDate) - // Await on set promise and check results await ConnectionController.connectWalletConnect() - expect(ConnectionController.state.wcUri).toEqual(walletConnectUri) - expect(ConnectionController.state.wcPairingExpiry).toEqual(ConstantsUtil.FOUR_MINUTES_MS) expect(storageSpy).toHaveBeenCalledWith('eip155', 'walletConnect') expect(clientConnectWalletConnectSpy).toHaveBeenCalled() @@ -187,4 +177,16 @@ describe('ConnectionController', () => { expect(ChainController.disconnect).toHaveBeenCalled() expect(ModalController.setLoading).toHaveBeenCalledWith(false) }) + + it('should set wcUri correctly', () => { + // Setup timers for pairing expiry + const fakeDate = new Date(0) + vi.useFakeTimers() + vi.setSystemTime(fakeDate) + + ConnectionController.setUri(walletConnectUri) + + expect(ConnectionController.state.wcUri).toEqual(walletConnectUri) + expect(ConnectionController.state.wcPairingExpiry).toEqual(ConstantsUtil.FOUR_MINUTES_MS) + }) }) From a77a97364fb7c85fbbcff820914478d927fdf4be Mon Sep 17 00:00:00 2001 From: Felipe Mendes Date: Wed, 15 Jan 2025 15:52:59 -0300 Subject: [PATCH 2/2] chore: add changeset --- .changeset/selfish-comics-rule.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .changeset/selfish-comics-rule.md diff --git a/.changeset/selfish-comics-rule.md b/.changeset/selfish-comics-rule.md new file mode 100644 index 0000000000..2605ec02ab --- /dev/null +++ b/.changeset/selfish-comics-rule.md @@ -0,0 +1,23 @@ +--- +'@reown/appkit-adapter-bitcoin': patch +'@reown/appkit-adapter-solana': patch +'@reown/appkit-adapter-wagmi': patch +'@reown/appkit': patch +'@reown/appkit-core': patch +'@reown/appkit-adapter-ethers': patch +'@reown/appkit-adapter-ethers5': patch +'@reown/appkit-utils': patch +'@reown/appkit-cdn': patch +'@reown/appkit-cli': patch +'@reown/appkit-common': patch +'@reown/appkit-experimental': patch +'@reown/appkit-polyfills': patch +'@reown/appkit-scaffold-ui': patch +'@reown/appkit-siwe': patch +'@reown/appkit-siwx': patch +'@reown/appkit-ui': patch +'@reown/appkit-wallet': patch +'@reown/appkit-wallet-button': patch +--- + +Remove all onUri callback drilling for all walletConnectConnect methods in favor of a single call when initializing the UniversalProvider