diff --git a/apps/laboratory/tests/multichain/multichain-wagmi-solana.spec.ts b/apps/laboratory/tests/multichain/multichain-wagmi-solana.spec.ts index 696430d028..3aa394866d 100644 --- a/apps/laboratory/tests/multichain/multichain-wagmi-solana.spec.ts +++ b/apps/laboratory/tests/multichain/multichain-wagmi-solana.spec.ts @@ -48,7 +48,7 @@ test.skip('it should show disabled networks', async () => { await modalPage.closeModal() }) -test.only('it should switch networks and sign', async () => { +test('it should switch networks and sign', async () => { const chains = ['Polygon', 'Solana'] async function processChain(index: number) { diff --git a/packages/adapters/ethers/src/client.ts b/packages/adapters/ethers/src/client.ts index 7dccf29f2a..8ecd54ca2c 100644 --- a/packages/adapters/ethers/src/client.ts +++ b/packages/adapters/ethers/src/client.ts @@ -1047,13 +1047,11 @@ export class EthersAdapter { if (this.authProvider) { try { this.appKit?.setLoading(true) - const { chainId } = await this.authProvider.switchNetwork( - caipNetwork.chainId as number - ) + await this.authProvider.switchNetwork(caipNetwork.id) const { address, preferredAccountType } = await this.authProvider.connect({ - chainId: caipNetwork.chainId as number | undefined + chainId: caipNetwork.id }) - const caipAddress = `${this.chainNamespace}:${chainId}:${address}` + const caipAddress = `${caipNetwork.id}:${address}` this.appKit?.setCaipNetwork(caipNetwork) this.appKit?.setCaipAddress(caipAddress as CaipAddress, this.chainNamespace) diff --git a/packages/adapters/ethers5/src/client.ts b/packages/adapters/ethers5/src/client.ts index 2c69e9b2f0..480b6dc7d8 100644 --- a/packages/adapters/ethers5/src/client.ts +++ b/packages/adapters/ethers5/src/client.ts @@ -1060,13 +1060,11 @@ export class Ethers5Adapter { if (this.authProvider) { try { this.appKit?.setLoading(true) - const { chainId } = await this.authProvider.switchNetwork( - caipNetwork.chainId as number - ) + await this.authProvider.switchNetwork(caipNetwork.id) const { address, preferredAccountType } = await this.authProvider.connect({ - chainId: caipNetwork.chainId as number | undefined + chainId: caipNetwork.id }) - const caipAddress = `${this.chainNamespace}:${chainId}:${address}` + const caipAddress = `${caipNetwork.id}:${address}` this.appKit?.setCaipNetwork(caipNetwork) this.appKit?.setCaipAddress(caipAddress as CaipAddress, this.chainNamespace) diff --git a/packages/adapters/solana/src/client.ts b/packages/adapters/solana/src/client.ts index dca682af4c..a1036238fe 100644 --- a/packages/adapters/solana/src/client.ts +++ b/packages/adapters/solana/src/client.ts @@ -376,7 +376,7 @@ export class SolanaAdapter implements ChainAdapter { } if (!this.appKit?.getCaipNetwork()) { - throw new Error('CaipNetwork is not set') + this.appKit?.setCaipNetwork(this.defaultCaipNetwork) } const balance = @@ -416,13 +416,16 @@ export class SolanaAdapter implements ChainAdapter { const user = await this.w3mFrameProvider?.getUser({ chainId: caipNetwork?.id }) - this.authSession = user + if (caipNetwork.chainNamespace === 'solana') { + this.authSession = user + } if (user) { - const caipAddress = `solana:${caipNetwork.chainId}:${user.address}` as CaipAddress - ProviderUtil.setProvider(this.chainNamespace, this.authProvider) - ProviderUtil.setProviderId(this.chainNamespace, 'walletConnect') - this.appKit?.setCaipAddress(caipAddress, this.chainNamespace) - this.syncAccount(user.address) + const caipAddress = `${caipNetwork.id}:${user.address}` + this.appKit?.setCaipNetwork(caipNetwork) + this.appKit?.setCaipAddress(caipAddress as CaipAddress, this.chainNamespace) + if (caipNetwork.chainNamespace === 'solana') { + this.syncAccount(user.address) + } } } else { this.appKit?.setCaipNetwork(caipNetwork) diff --git a/packages/adapters/solana/src/providers/AuthProvider.ts b/packages/adapters/solana/src/providers/AuthProvider.ts index a0c780cf22..60846a4dcb 100644 --- a/packages/adapters/solana/src/providers/AuthProvider.ts +++ b/packages/adapters/solana/src/providers/AuthProvider.ts @@ -15,6 +15,7 @@ import { withSolanaNamespace } from '../utils/withSolanaNamespace.js' import base58 from 'bs58' import { isVersionedTransaction } from '@solana/wallet-adapter-base' import type { CaipNetwork, ChainNamespace } from '@reown/appkit-common' +import { ProviderUtil } from '@reown/appkit/store' export type AuthProviderConfig = { getProvider: () => W3mFrameProvider @@ -201,8 +202,7 @@ export class AuthProvider extends ProviderEventEmitter implements Provider, Prov required?: Required ): Required extends true ? PublicKey : PublicKey | undefined { const session = this.getSession() - const namespace = this.getActiveNamespace() - if (!session || namespace !== 'solana') { + if (!session) { if (required) { throw new Error('Account is required') } @@ -231,10 +231,12 @@ export class AuthProvider extends ProviderEventEmitter implements Provider, Prov }) this.getProvider().onConnect(response => { - this.setSession(response) - const activeNamespace = this.getActiveNamespace() + const chainId = response.chainId - if (activeNamespace === 'solana') { + if (String(chainId)?.startsWith('solana')) { + ProviderUtil.setProvider('solana', this) + ProviderUtil.setProviderId('solana', 'w3mAuth') + this.setSession(response) this.emit('connect', this.getPublicKey(true)) } }) diff --git a/packages/adapters/wagmi/src/client.ts b/packages/adapters/wagmi/src/client.ts index 36f2d8c598..bd193352d5 100644 --- a/packages/adapters/wagmi/src/client.ts +++ b/packages/adapters/wagmi/src/client.ts @@ -64,7 +64,7 @@ import { requireCaipAddress } from './utils/helpers.js' import { W3mFrameHelpers, W3mFrameRpcConstants } from '@reown/appkit-wallet' -import type { W3mFrameProvider, W3mFrameTypes } from '@reown/appkit-wallet' +import { W3mFrameProvider, type W3mFrameTypes } from '@reown/appkit-wallet' import { NetworkUtil } from '@reown/appkit-common' import { normalize } from 'viem/ens' import type { AppKitOptions } from '@reown/appkit' @@ -234,10 +234,17 @@ export class WagmiAdapter implements ChainAdapter { this.networkControllerClient = { switchCaipNetwork: async caipNetwork => { - const chainId = Number(NetworkUtil.caipNetworkIdToNumber(caipNetwork?.id)) - - if (chainId && this.wagmiConfig) { - await switchChain(this.wagmiConfig, { chainId }) + if (caipNetwork?.id && this.wagmiConfig) { + const connections = getConnections(this.wagmiConfig) + const connector = connections[0]?.connector + const provider = await connector?.getProvider() + if (provider instanceof W3mFrameProvider) { + await provider.switchNetwork(caipNetwork.id) + } else { + await switchChain(this.wagmiConfig, { + chainId: Number(NetworkUtil.caipNetworkIdToNumber(caipNetwork?.id)) + }) + } } }, getApprovedCaipNetworksData: async () => { @@ -601,7 +608,6 @@ export class WagmiAdapter implements ChainAdapter { > >) { const isConnected = ChainController.state.activeCaipAddress - if (status === 'disconnected' && !isConnected) { this.appKit?.resetAccount(this.chainNamespace) this.appKit?.resetWcConnection() @@ -635,7 +641,7 @@ export class WagmiAdapter implements ChainAdapter { this.appKit?.setCaipAddress(caipAddress, chainNamespace) }) if (this.appKit?.getCaipNetwork()?.chainNamespace !== 'solana') { - this.syncNetwork(address, currentChainId, true) + await this.syncNetwork(address, currentChainId, true) await Promise.all([ this.syncProfile(address, currentChainId), this.syncBalance(address, currentChainId), @@ -645,8 +651,8 @@ export class WagmiAdapter implements ChainAdapter { } } else if (status === 'connected' && address && chainId) { const caipAddress = `eip155:${chainId}:${address}` as CaipAddress - this.syncNetwork(address, chainId, true) this.appKit?.setCaipAddress(caipAddress, this.chainNamespace) + await this.syncNetwork(address, chainId, true) await Promise.all([ this.syncProfile(address, chainId), this.syncBalance(address, chainId), @@ -683,7 +689,6 @@ export class WagmiAdapter implements ChainAdapter { private async syncNetwork(address?: Hex, chainId?: number, isConnected?: boolean) { const chain = this.caipNetworks.find((c: CaipNetwork) => c.chainId === chainId) - if (chain && chainId) { this.appKit?.setCaipNetwork({ chainId: chain.chainId, diff --git a/packages/adapters/wagmi/src/tests/client.test.ts b/packages/adapters/wagmi/src/tests/client.test.ts index 7d111b6980..7bf0a95a53 100644 --- a/packages/adapters/wagmi/src/tests/client.test.ts +++ b/packages/adapters/wagmi/src/tests/client.test.ts @@ -92,18 +92,12 @@ describe('Wagmi Client', () => { expect(mockAppKit.getIsConnectedState()).toBe(false) expect(mockAppKit.getCaipAddress()).toBeUndefined() - const setApprovedCaipNetworksData = vi - .spyOn(mockAppKit, 'setApprovedCaipNetworksData') - .mockResolvedValue() - expect(mockWagmiClient.wagmiConfig).toBeDefined() await connect(mockWagmiClient.wagmiConfig, { connector: mockWagmiClient.wagmiConfig.connectors[0]! }) - expect(setApprovedCaipNetworksData).toHaveBeenCalledOnce() - expect(mockAppKit.getCaipAddress()).toBe( `${ConstantsUtil.EIP155}:${mainnet.chainId}:${mockAccount.address}` ) diff --git a/packages/appkit/src/client.ts b/packages/appkit/src/client.ts index cc5c525ed2..788a7d1e3e 100644 --- a/packages/appkit/src/client.ts +++ b/packages/appkit/src/client.ts @@ -257,11 +257,9 @@ export class AppKit { } public getAddress = (chainNamespace?: ChainNamespace) => { - if (ChainController.state.activeChain === chainNamespace || !chainNamespace) { - return AccountController.state.address - } + const caipAddress = this.getCaipAddress(chainNamespace) - return ChainController.getAccountProp('address', chainNamespace) + return caipAddress?.split(':')[2] } public getProvider = () => AccountController.state.provider @@ -293,7 +291,7 @@ export class AppKit { AccountController.resetAccount(chain) } - public setCaipNetwork: (typeof NetworkController)['setCaipNetwork'] = caipNetwork => { + public setCaipNetwork: (typeof ChainController)['setActiveCaipNetwork'] = caipNetwork => { ChainController.setActiveCaipNetwork(caipNetwork) } diff --git a/packages/core/src/controllers/ChainController.ts b/packages/core/src/controllers/ChainController.ts index ad115e2dea..421e059bb3 100644 --- a/packages/core/src/controllers/ChainController.ts +++ b/packages/core/src/controllers/ChainController.ts @@ -274,29 +274,6 @@ export const ChainController = { this.setActiveNamespace(caipNetwork.chainNamespace, caipNetwork) } }, - - /** - * The setCaipNetwork function is being called for different purposes and it needs to be controlled if it should replace the NetworkController state or not. - * While we initializing the adapters, we need to set the caipNetwork without replacing the state. - * But when we switch the network, we need to replace the state. - * @param chain - * @param caipNetwork - * @param shouldReplace - if true, it will replace the NetworkController state - */ - setCaipNetwork( - chain: ChainNamespace | undefined, - caipNetwork: NetworkControllerState['caipNetwork'], - shouldReplace = false - ) { - state.activeChain = caipNetwork?.chainNamespace - state.activeCaipNetwork = caipNetwork - PublicStateController.set({ - activeChain: state.activeChain, - selectedNetworkId: state.activeCaipNetwork?.id - }) - this.setChainNetworkData(chain, { caipNetwork }, shouldReplace) - }, - setActiveConnector(connector: ChainControllerState['activeConnector']) { if (connector) { state.activeConnector = ref(connector) diff --git a/packages/core/src/controllers/ConnectionController.ts b/packages/core/src/controllers/ConnectionController.ts index 520bfa5c0f..3d99491e29 100644 --- a/packages/core/src/controllers/ConnectionController.ts +++ b/packages/core/src/controllers/ConnectionController.ts @@ -16,7 +16,6 @@ import { ModalController } from './ModalController.js' import { ConnectorController } from './ConnectorController.js' import { EventsController } from './EventsController.js' import type { ChainNamespace } from '@reown/appkit-common' -import { RouterController } from './RouterController.js' // -- Types --------------------------------------------- // export interface ConnectExternalOptions { @@ -98,7 +97,6 @@ export const ConnectionController = { async connectExternal(options: ConnectExternalOptions, chain: ChainNamespace, setChain = true) { await this._getClient(chain).connectExternal?.(options) if (setChain) { - ChainController.setActiveNamespace(chain) StorageUtil.setConnectedConnector(options.type) } }, @@ -167,10 +165,6 @@ export const ConnectionController = { state.recentWallet = undefined TransactionsController.resetTransactions() StorageUtil.deleteWalletConnectDeepLink() - if (ModalController.state.open) { - ModalController.close() - RouterController.reset('Connect') - } }, setWcLinking(wcLinking: ConnectionControllerState['wcLinking']) { diff --git a/packages/core/src/controllers/NetworkController.ts b/packages/core/src/controllers/NetworkController.ts index 8a222ab8e5..75f7d624d8 100644 --- a/packages/core/src/controllers/NetworkController.ts +++ b/packages/core/src/controllers/NetworkController.ts @@ -84,18 +84,6 @@ export const NetworkController = { } }, - setCaipNetwork(caipNetwork: NetworkControllerState['caipNetwork']) { - if (!caipNetwork) { - return - } - - if (!caipNetwork?.chainNamespace) { - throw new Error('chain is required to set active network') - } - - ChainController.setCaipNetwork(caipNetwork?.chainNamespace, caipNetwork) - }, - setRequestedCaipNetworks( requestedNetworks: NetworkControllerState['requestedCaipNetworks'], chain: ChainNamespace | undefined diff --git a/packages/core/tests/controllers/SwapController.test.ts b/packages/core/tests/controllers/SwapController.test.ts index f34fdb8988..2930b78148 100644 --- a/packages/core/tests/controllers/SwapController.test.ts +++ b/packages/core/tests/controllers/SwapController.test.ts @@ -5,7 +5,6 @@ import { BlockchainApiController, ChainController, ConnectionController, - NetworkController, SwapController, type NetworkControllerClient } from '../../exports/index.js' @@ -56,7 +55,7 @@ beforeAll(async () => { } ]) - NetworkController.setCaipNetwork(caipNetwork) + ChainController.setActiveCaipNetwork(caipNetwork) AccountController.setCaipAddress(caipAddress, chain) vi.spyOn(BlockchainApiController, 'fetchSwapTokens').mockResolvedValue(tokensResponse)