From cb673ad9686a94649fd6de67406fe844279c9d65 Mon Sep 17 00:00:00 2001 From: LuizAsFight Date: Mon, 14 Oct 2024 16:14:54 -0300 Subject: [PATCH 1/7] fix: useWallet and useProvider hooks should be more raw --- examples/react-app/src/hooks/useWallet.ts | 8 ++-- packages/react/src/hooks/index.ts | 1 + packages/react/src/hooks/useProvider.ts | 48 ++++++------------- .../react/src/hooks/useProviderNetwork.ts | 21 ++++++++ packages/react/src/hooks/useWallet.ts | 35 +++++++++----- packages/react/src/utils/queryKeys.ts | 5 +- 6 files changed, 65 insertions(+), 53 deletions(-) create mode 100644 packages/react/src/hooks/useProviderNetwork.ts diff --git a/examples/react-app/src/hooks/useWallet.ts b/examples/react-app/src/hooks/useWallet.ts index e9ccbcb0..dc0907d8 100644 --- a/examples/react-app/src/hooks/useWallet.ts +++ b/examples/react-app/src/hooks/useWallet.ts @@ -34,10 +34,10 @@ export const useWallet = () => { refetch: refetchBalance, } = useBalance({ account, - query: { - refetchInterval: 5000, - refetchOnWindowFocus: true, - }, + // query: { + // refetchInterval: 5000, + // refetchOnWindowFocus: true, + // }, }); const { wallet } = useFuelWallet({ account }); const isLoading = [isLoadingAccount, isLoadingBalance].some(Boolean); diff --git a/packages/react/src/hooks/index.ts b/packages/react/src/hooks/index.ts index b3da396b..655031d1 100644 --- a/packages/react/src/hooks/index.ts +++ b/packages/react/src/hooks/index.ts @@ -14,6 +14,7 @@ export * from './useNetwork'; export * from './useNetworks'; export * from './useNodeInfo'; export * from './useProvider'; +export * from './useProviderNetwork'; export * from './useSelectNetwork'; export * from './useSendTransaction'; export * from './useTransaction'; diff --git a/packages/react/src/hooks/useProvider.ts b/packages/react/src/hooks/useProvider.ts index dcc4a6bd..74cf9cc5 100644 --- a/packages/react/src/hooks/useProvider.ts +++ b/packages/react/src/hooks/useProvider.ts @@ -1,7 +1,7 @@ -import { Provider } from 'fuels'; -import { type UseNamedQueryParams, useNamedQuery } from '../core'; -import { useFuel } from '../providers'; -import { QUERY_KEYS } from '../utils'; +import type { Provider } from 'fuels'; +import { useMemo } from 'react'; +import type { UseNamedQueryParams } from '../core'; +import { useWallet } from './useWallet'; type UseProviderParams = { /** @@ -16,6 +16,9 @@ type UseProviderParams = { }; // @TODO: Add a link to fuel connector's documentation. +/** + * @deprecated This hook is deprecated and will be removed in a future version. + */ /** * A hook to retrieve the current provider in the connected app. * @@ -29,33 +32,12 @@ type UseProviderParams = { * const { provider } = useProvider(); * ``` */ -export const useProvider = (params?: UseProviderParams) => { - const { fuel, networks } = useFuel(); - return useNamedQuery('provider', { - queryKey: QUERY_KEYS.provider(), - queryFn: async () => { - const currentNetwork = await fuel.currentNetwork(); - const network = networks.find( - (n) => n.chainId === currentNetwork.chainId, - ); - if (!network?.url) { - const provider = await fuel.getProvider(); - console.warn( - 'Please provide a networks with a RPC url configuration to your FuelProvider getProvider will be removed.', - ); - return provider || null; - } - const provider = await Provider.create(network.url); - if (provider.getChainId() !== currentNetwork.chainId) { - throw new Error( - `The provider's chainId (${provider.getChainId()}) does not match the current network's chainId (${ - currentNetwork.chainId - })`, - ); - } - return provider; - }, - placeholderData: null, - ...params?.query, - }); +export const useProvider = (_params?: UseProviderParams) => { + const { wallet } = useWallet(); + + const provider = useMemo(() => { + return wallet?.provider; + }, [wallet?.provider, wallet?.provider.url]); + + return { provider }; }; diff --git a/packages/react/src/hooks/useProviderNetwork.ts b/packages/react/src/hooks/useProviderNetwork.ts new file mode 100644 index 00000000..ba4307eb --- /dev/null +++ b/packages/react/src/hooks/useProviderNetwork.ts @@ -0,0 +1,21 @@ +import { Provider } from 'fuels'; +import { useEffect, useState } from 'react'; +import { useNetwork } from './useNetwork'; + +export const useProviderNetwork = () => { + const { network } = useNetwork(); + const [provider, setProvider] = useState(null); + + useEffect(() => { + async function createProvider() { + if (network?.url) { + const fuelProvider = await Provider.create(network?.url); + setProvider(fuelProvider); + } + } + + createProvider(); + }, [network?.url]); + + return { provider }; +}; diff --git a/packages/react/src/hooks/useWallet.ts b/packages/react/src/hooks/useWallet.ts index 46b39728..aa36e24b 100644 --- a/packages/react/src/hooks/useWallet.ts +++ b/packages/react/src/hooks/useWallet.ts @@ -7,7 +7,8 @@ import { } from '../core'; import { useFuel } from '../providers'; import { QUERY_KEYS } from '../utils'; -import { useProvider } from './useProvider'; +import { useAccount } from './useAccount'; +import { useNetwork } from './useNetwork'; type UseWalletParamsDeprecated = string | null; @@ -56,29 +57,37 @@ export function useWallet( export function useWallet( params?: UseWalletParamsDeprecated | UseWalletParams, -): DefinedNamedUseQueryResult<'wallet', Account | null, Error> { +) { const { fuel } = useFuel(); - const { provider } = useProvider(); + const { network } = useNetwork(); + const { account } = useAccount(); + const _params: UseWalletParams = typeof params === 'string' ? { account: params } : params ?? {}; - return useNamedQuery('wallet', { - queryKey: QUERY_KEYS.wallet(_params.account, provider), + // console.log(`asd account`, account); + // console.log(`asd network?.url`, network?.url); + + const queried = useNamedQuery('wallet', { + queryKey: QUERY_KEYS.wallet(account, network?.url), queryFn: async () => { try { - if (!provider) return null; - const accountAddress = - _params.account || (await fuel.currentAccount()) || ''; - // Check if the address is valid - await Address.fromString(accountAddress); - const wallet = await fuel.getWallet(accountAddress); - wallet.connect(provider); - return wallet || null; + console.log('asd start querying useWallet', account, network?.url); + if (!account || !network?.url) return null; + await Address.fromString(account); + const wallet = await fuel.getWallet(account); + console.log('asd completed querying useWallet', wallet); + return wallet; } catch (_error: unknown) { return null; } }, + enabled: !!account && !!network?.url, placeholderData: null, ..._params.query, }); + + // console.log(`asd queried.wallet`, queried.wallet); + + return queried; } diff --git a/packages/react/src/utils/queryKeys.ts b/packages/react/src/utils/queryKeys.ts index 8b86d1cb..aa9f8f02 100644 --- a/packages/react/src/utils/queryKeys.ts +++ b/packages/react/src/utils/queryKeys.ts @@ -47,11 +47,10 @@ export const QUERY_KEYS = { queryKey.push(provider.getChainId()); return queryKey; }, - wallet: (address?: string | null, provider?: Provider | null): QueryKey => { + wallet: (address?: string | null, providerUrl?: string | null): QueryKey => { const queryKey = QUERY_KEYS.base.concat('wallet'); if (address) queryKey.push(address); - if (provider?.getChainId?.() !== undefined) - queryKey.push(provider.getChainId()); + if (providerUrl) queryKey.push(providerUrl); return queryKey; }, transaction: (id?: string): QueryKey => { From 1bf430da6c4a98d3a3c3616c0234bc96bc869840 Mon Sep 17 00:00:00 2001 From: LuizAsFight Date: Tue, 15 Oct 2024 03:07:40 -0300 Subject: [PATCH 2/7] chore: make provider use configured network if available --- packages/react/src/hooks/useProvider.ts | 3 --- packages/react/src/hooks/useWallet.ts | 27 ++++++++++++++++--------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/packages/react/src/hooks/useProvider.ts b/packages/react/src/hooks/useProvider.ts index 74cf9cc5..fd2e4cd5 100644 --- a/packages/react/src/hooks/useProvider.ts +++ b/packages/react/src/hooks/useProvider.ts @@ -16,9 +16,6 @@ type UseProviderParams = { }; // @TODO: Add a link to fuel connector's documentation. -/** - * @deprecated This hook is deprecated and will be removed in a future version. - */ /** * A hook to retrieve the current provider in the connected app. * diff --git a/packages/react/src/hooks/useWallet.ts b/packages/react/src/hooks/useWallet.ts index aa36e24b..2794ddc4 100644 --- a/packages/react/src/hooks/useWallet.ts +++ b/packages/react/src/hooks/useWallet.ts @@ -1,4 +1,4 @@ -import { type Account, Address } from 'fuels'; +import { type Account, Address, Provider } from 'fuels'; import { type DefinedNamedUseQueryResult, @@ -58,25 +58,34 @@ export function useWallet( export function useWallet( params?: UseWalletParamsDeprecated | UseWalletParams, ) { - const { fuel } = useFuel(); + const { fuel, networks } = useFuel(); const { network } = useNetwork(); const { account } = useAccount(); const _params: UseWalletParams = - typeof params === 'string' ? { account: params } : params ?? {}; - - // console.log(`asd account`, account); - // console.log(`asd network?.url`, network?.url); + typeof params === 'string' ? { account: params } : (params ?? {}); const queried = useNamedQuery('wallet', { queryKey: QUERY_KEYS.wallet(account, network?.url), queryFn: async () => { try { - console.log('asd start querying useWallet', account, network?.url); + console.log('asd useWallet querying start', account, network?.url); if (!account || !network?.url) return null; await Address.fromString(account); const wallet = await fuel.getWallet(account); - console.log('asd completed querying useWallet', wallet); + + console.log('asd useWallet querying completed', wallet); + + const configuredNetwork = networks.find( + (n) => n.chainId === network.chainId, + ); + + if (configuredNetwork?.url && configuredNetwork.url !== network.url) { + // if the user configured a different network for the same chainId, we connect to the configured network instead + const provider = await Provider.create(configuredNetwork.url); + wallet.connect(provider); + } + return wallet; } catch (_error: unknown) { return null; @@ -87,7 +96,5 @@ export function useWallet( ..._params.query, }); - // console.log(`asd queried.wallet`, queried.wallet); - return queried; } From 0ca940106e6d62761542f32340fe8a680736ddbc Mon Sep 17 00:00:00 2001 From: LuizAsFight Date: Tue, 15 Oct 2024 03:15:45 -0300 Subject: [PATCH 3/7] chore --- examples/react-app/src/hooks/useWallet.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/react-app/src/hooks/useWallet.ts b/examples/react-app/src/hooks/useWallet.ts index dc0907d8..e9ccbcb0 100644 --- a/examples/react-app/src/hooks/useWallet.ts +++ b/examples/react-app/src/hooks/useWallet.ts @@ -34,10 +34,10 @@ export const useWallet = () => { refetch: refetchBalance, } = useBalance({ account, - // query: { - // refetchInterval: 5000, - // refetchOnWindowFocus: true, - // }, + query: { + refetchInterval: 5000, + refetchOnWindowFocus: true, + }, }); const { wallet } = useFuelWallet({ account }); const isLoading = [isLoadingAccount, isLoadingBalance].some(Boolean); From 39e2c62c4e9b97c9bc6719f2749924147aabb930 Mon Sep 17 00:00:00 2001 From: LuizAsFight Date: Tue, 15 Oct 2024 03:17:13 -0300 Subject: [PATCH 4/7] chore --- packages/react/src/hooks/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/react/src/hooks/index.ts b/packages/react/src/hooks/index.ts index 655031d1..b3da396b 100644 --- a/packages/react/src/hooks/index.ts +++ b/packages/react/src/hooks/index.ts @@ -14,7 +14,6 @@ export * from './useNetwork'; export * from './useNetworks'; export * from './useNodeInfo'; export * from './useProvider'; -export * from './useProviderNetwork'; export * from './useSelectNetwork'; export * from './useSendTransaction'; export * from './useTransaction'; From fe7bd2fd76a5fd472e0e46afb8fb6519a78f3b84 Mon Sep 17 00:00:00 2001 From: LuizAsFight Date: Tue, 15 Oct 2024 03:38:26 -0300 Subject: [PATCH 5/7] feat: add skip auto reconnect --- packages/connectors/src/defaultConnectors.ts | 3 +++ .../walletconnect-connector/src/WalletConnectConnector.ts | 7 ++++--- packages/walletconnect-connector/src/types.ts | 2 ++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/connectors/src/defaultConnectors.ts b/packages/connectors/src/defaultConnectors.ts index 7abbcb4f..6322aa10 100644 --- a/packages/connectors/src/defaultConnectors.ts +++ b/packages/connectors/src/defaultConnectors.ts @@ -18,6 +18,7 @@ type DefaultConnectors = { wcProjectId?: string; burnerWalletConfig?: BurnerWalletConfig; ethWagmiConfig?: Config; + ethSkipAutoReconnect?: boolean; solanaConfig?: ProviderType; chainId?: number; fuelProvider?: FuelProvider | Promise; @@ -28,6 +29,7 @@ export function defaultConnectors({ wcProjectId, burnerWalletConfig, ethWagmiConfig, + ethSkipAutoReconnect, solanaConfig: _solanaConfig, chainId, fuelProvider, @@ -41,6 +43,7 @@ export function defaultConnectors({ wagmiConfig: ethWagmiConfig, chainId, fuelProvider, + skipAutoReconnect: ethSkipAutoReconnect, }), new SolanaConnector({ projectId: wcProjectId, diff --git a/packages/walletconnect-connector/src/WalletConnectConnector.ts b/packages/walletconnect-connector/src/WalletConnectConnector.ts index 5955c57d..2e3733dd 100644 --- a/packages/walletconnect-connector/src/WalletConnectConnector.ts +++ b/packages/walletconnect-connector/src/WalletConnectConnector.ts @@ -202,10 +202,11 @@ export class WalletConnectConnector extends PredicateConnector { protected async requireConnection() { const wagmiConfig = this.getWagmiConfig(); if (!this.web3Modal) this.createModal(); - if (!wagmiConfig) return; - const { state } = wagmiConfig; - if (state.status === 'disconnected' && state.connections.size > 0) { + if (this.config.skipAutoReconnect || !wagmiConfig) return; + + const { status, connections } = wagmiConfig.state; + if (status === 'disconnected' && connections.size > 0) { await reconnect(wagmiConfig); } } diff --git a/packages/walletconnect-connector/src/types.ts b/packages/walletconnect-connector/src/types.ts index dcd19752..2277abfa 100644 --- a/packages/walletconnect-connector/src/types.ts +++ b/packages/walletconnect-connector/src/types.ts @@ -9,4 +9,6 @@ export type WalletConnectConfig = { predicateConfig?: PredicateConfig; storage?: StorageAbstract; chainId?: number; + // if the dapp already has wagmi from eth connectors, it's better to skip auto reconnection as it can lead to session loss when refreshing the page + skipAutoReconnect?: boolean; }; From 331f28770babd3f879441bb1506850f255ab2e74 Mon Sep 17 00:00:00 2001 From: LuizAsFight Date: Tue, 15 Oct 2024 03:38:26 -0300 Subject: [PATCH 6/7] feat: add skip auto reconnect --- packages/connectors/src/defaultConnectors.ts | 3 +++ .../walletconnect-connector/src/WalletConnectConnector.ts | 7 ++++--- packages/walletconnect-connector/src/types.ts | 2 ++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/connectors/src/defaultConnectors.ts b/packages/connectors/src/defaultConnectors.ts index 7abbcb4f..6322aa10 100644 --- a/packages/connectors/src/defaultConnectors.ts +++ b/packages/connectors/src/defaultConnectors.ts @@ -18,6 +18,7 @@ type DefaultConnectors = { wcProjectId?: string; burnerWalletConfig?: BurnerWalletConfig; ethWagmiConfig?: Config; + ethSkipAutoReconnect?: boolean; solanaConfig?: ProviderType; chainId?: number; fuelProvider?: FuelProvider | Promise; @@ -28,6 +29,7 @@ export function defaultConnectors({ wcProjectId, burnerWalletConfig, ethWagmiConfig, + ethSkipAutoReconnect, solanaConfig: _solanaConfig, chainId, fuelProvider, @@ -41,6 +43,7 @@ export function defaultConnectors({ wagmiConfig: ethWagmiConfig, chainId, fuelProvider, + skipAutoReconnect: ethSkipAutoReconnect, }), new SolanaConnector({ projectId: wcProjectId, diff --git a/packages/walletconnect-connector/src/WalletConnectConnector.ts b/packages/walletconnect-connector/src/WalletConnectConnector.ts index 5955c57d..2e3733dd 100644 --- a/packages/walletconnect-connector/src/WalletConnectConnector.ts +++ b/packages/walletconnect-connector/src/WalletConnectConnector.ts @@ -202,10 +202,11 @@ export class WalletConnectConnector extends PredicateConnector { protected async requireConnection() { const wagmiConfig = this.getWagmiConfig(); if (!this.web3Modal) this.createModal(); - if (!wagmiConfig) return; - const { state } = wagmiConfig; - if (state.status === 'disconnected' && state.connections.size > 0) { + if (this.config.skipAutoReconnect || !wagmiConfig) return; + + const { status, connections } = wagmiConfig.state; + if (status === 'disconnected' && connections.size > 0) { await reconnect(wagmiConfig); } } diff --git a/packages/walletconnect-connector/src/types.ts b/packages/walletconnect-connector/src/types.ts index dcd19752..2277abfa 100644 --- a/packages/walletconnect-connector/src/types.ts +++ b/packages/walletconnect-connector/src/types.ts @@ -9,4 +9,6 @@ export type WalletConnectConfig = { predicateConfig?: PredicateConfig; storage?: StorageAbstract; chainId?: number; + // if the dapp already has wagmi from eth connectors, it's better to skip auto reconnection as it can lead to session loss when refreshing the page + skipAutoReconnect?: boolean; }; From 17936bd28b9694272bb9ba7f846b124f4a04feef Mon Sep 17 00:00:00 2001 From: LuizAsFight Date: Tue, 15 Oct 2024 03:49:07 -0300 Subject: [PATCH 7/7] chore --- .changeset/strong-bugs-remain.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/strong-bugs-remain.md diff --git a/.changeset/strong-bugs-remain.md b/.changeset/strong-bugs-remain.md new file mode 100644 index 00000000..cffd372f --- /dev/null +++ b/.changeset/strong-bugs-remain.md @@ -0,0 +1,6 @@ +--- +"@fuel-connectors/walletconnect-connector": minor +"@fuels/connectors": minor +--- + +feat: added `skipAutoReconnect` to avoid WalletConnectConnector reconnecting automatically over the Wagmi already reconnected