From d649a83fe6cb94bbc5b3e03a9cc553c59eb9c75c Mon Sep 17 00:00:00 2001 From: enesozturk Date: Wed, 30 Oct 2024 11:12:20 +0300 Subject: [PATCH 01/20] feat: add switchNetwork and addNetwork functions to useAppKitNetwork hook --- .../src/components/AppKitButtons.tsx | 25 ++++++++++++++++- .../tests/shared/pages/ModalPage.ts | 4 +++ apps/laboratory/tests/wallet.spec.ts | 28 +++++++++++++++++++ packages/appkit/exports/react.ts | 26 ++++++++++++++++- packages/appkit/exports/vue.ts | 23 +++++++++++++++ packages/appkit/src/client.ts | 22 +++++++++++++++ packages/core/exports/react.ts | 2 +- packages/core/exports/vue.ts | 2 +- .../core/src/controllers/ChainController.ts | 8 ++++++ 9 files changed, 136 insertions(+), 4 deletions(-) diff --git a/apps/laboratory/src/components/AppKitButtons.tsx b/apps/laboratory/src/components/AppKitButtons.tsx index 610fd01f10..fb4d8954a2 100644 --- a/apps/laboratory/src/components/AppKitButtons.tsx +++ b/apps/laboratory/src/components/AppKitButtons.tsx @@ -1,4 +1,5 @@ -import { useAppKit, useDisconnect, useAppKitAccount } from '@reown/appkit/react' +import { useAppKit, useDisconnect, useAppKitAccount, useAppKitNetwork } from '@reown/appkit/react' +import { polygon, mainnet, solana, solanaTestnet } from '@reown/appkit/networks' import { Stack, Card, @@ -13,8 +14,26 @@ import { export function AppKitButtons() { const { open } = useAppKit() const { isConnected } = useAppKitAccount() + const { caipNetwork, switchNetwork } = useAppKitNetwork() const { disconnect } = useDisconnect() + const isEIPNamespace = caipNetwork?.chainNamespace === 'eip155' + const networkToSwitch = isEIPNamespace + ? caipNetwork?.id === polygon.id + ? mainnet + : polygon + : caipNetwork?.id === solana.id + ? solanaTestnet + : solana + + const handleSwitchNetwork = () => { + if (isEIPNamespace) { + switchNetwork(networkToSwitch) + } else { + switchNetwork(networkToSwitch) + } + } + return ( @@ -51,6 +70,10 @@ export function AppKitButtons() { > Disconnect + + diff --git a/apps/laboratory/tests/shared/pages/ModalPage.ts b/apps/laboratory/tests/shared/pages/ModalPage.ts index 9f9e12d12b..e0f45d2d6c 100644 --- a/apps/laboratory/tests/shared/pages/ModalPage.ts +++ b/apps/laboratory/tests/shared/pages/ModalPage.ts @@ -567,4 +567,8 @@ export class ModalPage { return signature as `0x${string}` } + + async switchNetworkWithHook() { + await this.page.getByTestId('switch-network-hook-button').click() + } } diff --git a/apps/laboratory/tests/wallet.spec.ts b/apps/laboratory/tests/wallet.spec.ts index 8aa16b0261..5e527af91b 100644 --- a/apps/laboratory/tests/wallet.spec.ts +++ b/apps/laboratory/tests/wallet.spec.ts @@ -99,6 +99,34 @@ sampleWalletTest('it should switch networks and sign', async ({ library }) => { await processChain(0) }) +sampleWalletTest('it should switch networks using hook', async ({ library }) => { + const chains = library === 'solana' ? ['Solana Testnet', 'Solana'] : ['Polygon', 'Ethereum'] + const caipNetworkId = + library === 'solana' ? [solanaTestnet.id, solana.id] : [polygon.id, mainnet.id] + + async function processChain(index: number) { + if (index >= chains.length) { + return + } + + const chainName = chains[index] ?? DEFAULT_CHAIN_NAME + // Switch network using hook button + await modalPage.switchNetworkWithHook() + await modalPage.openModal() + await modalPage.openNetworks() + await modalValidator.expectSwitchedNetwork(chainName) + await modalPage.closeModal() + await modalValidator.expectCaipAddressHaveCorrectNetworkId( + caipNetworkId[index] as CaipNetworkId + ) + + await processChain(index + 1) + } + + // Start processing from the first chain + await processChain(0) +}) + sampleWalletTest('it should show last connected network after refreshing', async ({ library }) => { const chainName = library === 'solana' ? 'Solana Testnet' : 'Polygon' diff --git a/packages/appkit/exports/react.ts b/packages/appkit/exports/react.ts index 35a9f84c6d..f21c879ee8 100644 --- a/packages/appkit/exports/react.ts +++ b/packages/appkit/exports/react.ts @@ -3,6 +3,9 @@ import type { AppKitOptions } from '../src/utils/TypesUtil.js' import { getAppKit } from '../src/library/react/index.js' import { CoreHelperUtil } from '@reown/appkit-core' import { PACKAGE_VERSION } from './constants.js' +import { useAppKitNetworkCore } from '@reown/appkit-core/react' +import type { CaipNetwork } from '@reown/appkit' +import type { AppKitNetwork } from '@reown/appkit/networks' // -- Views ------------------------------------------------------------ export * from '@reown/appkit-scaffold-ui' @@ -41,4 +44,25 @@ export type { AppKitOptions } // -- Hooks ------------------------------------------------------------ export * from '../src/library/react/index.js' -export { useAppKitAccount, useAppKitNetwork } from '@reown/appkit-core/react' + +export function useAppKitNetwork() { + const { caipNetwork, caipNetworkId, chainId } = useAppKitNetworkCore() + + function switchNetwork(caipNetwork: AppKitNetwork) { + modal?.switchNetworkBase(caipNetwork) + } + + function addNetwork(caipNetwork: CaipNetwork) { + modal?.addCaipNetwork(caipNetwork) + } + + return { + caipNetwork, + caipNetworkId, + chainId, + switchNetwork, + addNetwork + } +} + +export { useAppKitAccount } from '@reown/appkit-core/react' diff --git a/packages/appkit/exports/vue.ts b/packages/appkit/exports/vue.ts index e40296a99d..2f185a09e6 100644 --- a/packages/appkit/exports/vue.ts +++ b/packages/appkit/exports/vue.ts @@ -3,6 +3,9 @@ import type { AppKitOptions } from '../src/utils/TypesUtil.js' import { getAppKit } from '../src/library/vue/index.js' import { CoreHelperUtil } from '@reown/appkit-core' import { PACKAGE_VERSION } from './constants.js' +import { useAppKitNetworkCore } from '@reown/appkit-core/vue' +import type { CaipNetwork } from '@reown/appkit' +import type { AppKitNetwork } from '@reown/appkit/networks' // -- Views ------------------------------------------------------------ export * from '@reown/appkit-scaffold-ui' @@ -36,4 +39,24 @@ export { AppKit } export type { AppKitOptions } // -- Hooks ------------------------------------------------------------ +export function useAppKitNetwork() { + const { caipNetwork, caipNetworkId, chainId } = useAppKitNetworkCore() + + function switchNetwork(caipNetwork: AppKitNetwork) { + modal?.switchNetworkBase(caipNetwork) + } + + function addNetwork(caipNetwork: CaipNetwork) { + modal?.addCaipNetwork(caipNetwork) + } + + return { + caipNetwork, + caipNetworkId, + chainId, + switchNetwork, + addNetwork + } +} + export * from '../src/library/vue/index.js' diff --git a/packages/appkit/src/client.ts b/packages/appkit/src/client.ts index 79cbb64b33..3608ab8e87 100644 --- a/packages/appkit/src/client.ts +++ b/packages/appkit/src/client.ts @@ -40,6 +40,7 @@ import { UniversalAdapterClient } from './universal-adapter/client.js' import { CaipNetworksUtil, ErrorUtil } from '@reown/appkit-utils' import type { W3mFrameTypes } from '@reown/appkit-wallet' import { ProviderUtil } from './store/ProviderUtil.js' +import type { AppKitNetwork } from '@reown/appkit/networks' // -- Export Controllers ------------------------------------------------------- export { AccountController } @@ -114,6 +115,27 @@ export class AppKit { return ChainController.state.activeCaipNetwork?.id } + public async switchNetworkBase(appKitNetwork: AppKitNetwork) { + const network = this.caipNetworks.find(n => n.caipNetworkId === appKitNetwork.id) + let extendedNetwork: CaipNetwork + + if (!network) { + extendedNetwork = CaipNetworksUtil.extendCaipNetwork(appKitNetwork, { + projectId: OptionsController.state.projectId, + customNetworkImageUrls: {} + }) + ChainController.addCaipNetwork(extendedNetwork) + } else { + extendedNetwork = network + } + + return ChainController.switchActiveNetwork(extendedNetwork) + } + + public addCaipNetwork(caipNetwork: CaipNetwork) { + ChainController.addCaipNetwork(caipNetwork) + } + public switchNetwork(caipNetwork: CaipNetwork) { return ChainController.switchActiveNetwork(caipNetwork) } diff --git a/packages/core/exports/react.ts b/packages/core/exports/react.ts index 58dbb25fb0..3462c3a67a 100644 --- a/packages/core/exports/react.ts +++ b/packages/core/exports/react.ts @@ -6,7 +6,7 @@ import type { CaipNetwork, CaipNetworkId } from '@reown/appkit-common' import { ConnectionController } from '../src/controllers/ConnectionController.js' // -- Hooks ------------------------------------------------------------ -export function useAppKitNetwork(): { +export function useAppKitNetworkCore(): { caipNetwork: CaipNetwork | undefined chainId: number | string | undefined caipNetworkId: CaipNetworkId | undefined diff --git a/packages/core/exports/vue.ts b/packages/core/exports/vue.ts index 9291c39ea6..88e7e0e1ec 100644 --- a/packages/core/exports/vue.ts +++ b/packages/core/exports/vue.ts @@ -7,7 +7,7 @@ import { onUnmounted } from 'vue' import { ConnectionController } from '../src/controllers/ConnectionController.js' // -- Hooks ------------------------------------------------------------ -export function useAppKitNetwork(): { +export function useAppKitNetworkCore(): { caipNetwork: CaipNetwork | undefined chainId: number | string | undefined caipNetworkId: CaipNetworkId | undefined diff --git a/packages/core/src/controllers/ChainController.ts b/packages/core/src/controllers/ChainController.ts index a6f3b8d358..38a2cef187 100644 --- a/packages/core/src/controllers/ChainController.ts +++ b/packages/core/src/controllers/ChainController.ts @@ -268,6 +268,14 @@ export const ChainController = { } }, + addCaipNetwork(caipNetwork: AdapterNetworkState['caipNetwork']) { + if (!caipNetwork) { + return + } + + state.chains.get(caipNetwork.chainNamespace)?.caipNetworks.push(caipNetwork) + }, + async switchActiveNetwork(network: CaipNetwork) { const networkControllerClient = this.getNetworkControllerClient(network.chainNamespace) From 473b750c5ec6e60d44ea8de819e8d6f368f964cc Mon Sep 17 00:00:00 2001 From: enesozturk Date: Wed, 30 Oct 2024 11:23:15 +0300 Subject: [PATCH 02/20] chore: linter issues --- apps/laboratory/src/components/AppKitButtons.tsx | 7 ++++--- packages/appkit/exports/react.ts | 8 ++++---- packages/appkit/exports/vue.ts | 8 ++++---- packages/appkit/src/client.ts | 11 +++++------ 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/apps/laboratory/src/components/AppKitButtons.tsx b/apps/laboratory/src/components/AppKitButtons.tsx index fb4d8954a2..6bbd03d315 100644 --- a/apps/laboratory/src/components/AppKitButtons.tsx +++ b/apps/laboratory/src/components/AppKitButtons.tsx @@ -1,5 +1,5 @@ import { useAppKit, useDisconnect, useAppKitAccount, useAppKitNetwork } from '@reown/appkit/react' -import { polygon, mainnet, solana, solanaTestnet } from '@reown/appkit/networks' +import { polygon, mainnet, solana, solanaTestnet, type AppKitNetwork } from '@reown/appkit/networks' import { Stack, Card, @@ -18,7 +18,8 @@ export function AppKitButtons() { const { disconnect } = useDisconnect() const isEIPNamespace = caipNetwork?.chainNamespace === 'eip155' - const networkToSwitch = isEIPNamespace + // eslint-disable-next-line no-nested-ternary + const networkToSwitch: AppKitNetwork = isEIPNamespace ? caipNetwork?.id === polygon.id ? mainnet : polygon @@ -26,7 +27,7 @@ export function AppKitButtons() { ? solanaTestnet : solana - const handleSwitchNetwork = () => { + function handleSwitchNetwork() { if (isEIPNamespace) { switchNetwork(networkToSwitch) } else { diff --git a/packages/appkit/exports/react.ts b/packages/appkit/exports/react.ts index f21c879ee8..490bd3da5b 100644 --- a/packages/appkit/exports/react.ts +++ b/packages/appkit/exports/react.ts @@ -48,12 +48,12 @@ export * from '../src/library/react/index.js' export function useAppKitNetwork() { const { caipNetwork, caipNetworkId, chainId } = useAppKitNetworkCore() - function switchNetwork(caipNetwork: AppKitNetwork) { - modal?.switchNetworkBase(caipNetwork) + function switchNetwork(network: AppKitNetwork) { + modal?.switchNetworkBase(network) } - function addNetwork(caipNetwork: CaipNetwork) { - modal?.addCaipNetwork(caipNetwork) + function addNetwork(network: CaipNetwork) { + modal?.addCaipNetwork(network) } return { diff --git a/packages/appkit/exports/vue.ts b/packages/appkit/exports/vue.ts index 2f185a09e6..1842ba20d2 100644 --- a/packages/appkit/exports/vue.ts +++ b/packages/appkit/exports/vue.ts @@ -42,12 +42,12 @@ export type { AppKitOptions } export function useAppKitNetwork() { const { caipNetwork, caipNetworkId, chainId } = useAppKitNetworkCore() - function switchNetwork(caipNetwork: AppKitNetwork) { - modal?.switchNetworkBase(caipNetwork) + function switchNetwork(network: AppKitNetwork) { + modal?.switchNetworkBase(network) } - function addNetwork(caipNetwork: CaipNetwork) { - modal?.addCaipNetwork(caipNetwork) + function addNetwork(network: CaipNetwork) { + modal?.addCaipNetwork(network) } return { diff --git a/packages/appkit/src/client.ts b/packages/appkit/src/client.ts index 3608ab8e87..abebef3569 100644 --- a/packages/appkit/src/client.ts +++ b/packages/appkit/src/client.ts @@ -117,16 +117,15 @@ export class AppKit { public async switchNetworkBase(appKitNetwork: AppKitNetwork) { const network = this.caipNetworks.find(n => n.caipNetworkId === appKitNetwork.id) - let extendedNetwork: CaipNetwork - - if (!network) { - extendedNetwork = CaipNetworksUtil.extendCaipNetwork(appKitNetwork, { + const extendedNetwork = + network || + CaipNetworksUtil.extendCaipNetwork(appKitNetwork, { projectId: OptionsController.state.projectId, customNetworkImageUrls: {} }) + + if (!network) { ChainController.addCaipNetwork(extendedNetwork) - } else { - extendedNetwork = network } return ChainController.switchActiveNetwork(extendedNetwork) From c13ed22322aaa5417163b6b8dbcd3c5a9b9a504c Mon Sep 17 00:00:00 2001 From: enesozturk Date: Wed, 30 Oct 2024 11:25:20 +0300 Subject: [PATCH 03/20] fix: tests --- packages/core/tests/hooks/react.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/tests/hooks/react.test.ts b/packages/core/tests/hooks/react.test.ts index 439b98e3e1..85f7966ac6 100644 --- a/packages/core/tests/hooks/react.test.ts +++ b/packages/core/tests/hooks/react.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, vi, beforeEach } from 'vitest' -import { useAppKitNetwork, useAppKitAccount } from '../../exports/react' +import { useAppKitNetworkCore, useAppKitAccount } from '../../exports/react' import type { CaipNetwork } from '@reown/appkit-common' import { AccountController, ChainController } from '../../exports' @@ -42,7 +42,7 @@ describe('useAppKitNetwork', () => { activeCaipNetwork: mockNetwork }) - const { caipNetwork, chainId } = useAppKitNetwork() + const { caipNetwork, chainId } = useAppKitNetworkCore() expect(caipNetwork).toBe(mockNetwork) expect(chainId).toBe(1) From f164e0b7362d45f01798db0a30a9de88cc28af77 Mon Sep 17 00:00:00 2001 From: enesozturk Date: Wed, 30 Oct 2024 11:40:50 +0300 Subject: [PATCH 04/20] chore: version const --- packages/appkit/exports/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/appkit/exports/constants.ts b/packages/appkit/exports/constants.ts index c90ca870de..c255be9da0 100644 --- a/packages/appkit/exports/constants.ts +++ b/packages/appkit/exports/constants.ts @@ -1 +1 @@ -export const PACKAGE_VERSION = '1.1.7' +export const PACKAGE_VERSION = '1.2.0' From 367898c461d9b480b0228202b803bd5767ffc03b Mon Sep 17 00:00:00 2001 From: enesozturk Date: Wed, 30 Oct 2024 12:03:57 +0300 Subject: [PATCH 05/20] refactor: update method names --- packages/appkit/exports/react.ts | 4 ++-- packages/appkit/exports/vue.ts | 4 ++-- packages/appkit/src/client.ts | 14 +++++--------- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/packages/appkit/exports/react.ts b/packages/appkit/exports/react.ts index 490bd3da5b..27ababff84 100644 --- a/packages/appkit/exports/react.ts +++ b/packages/appkit/exports/react.ts @@ -49,11 +49,11 @@ export function useAppKitNetwork() { const { caipNetwork, caipNetworkId, chainId } = useAppKitNetworkCore() function switchNetwork(network: AppKitNetwork) { - modal?.switchNetworkBase(network) + modal?.switchNetwork(network) } function addNetwork(network: CaipNetwork) { - modal?.addCaipNetwork(network) + modal?.addNetwork(network) } return { diff --git a/packages/appkit/exports/vue.ts b/packages/appkit/exports/vue.ts index 1842ba20d2..77b8ea7ff3 100644 --- a/packages/appkit/exports/vue.ts +++ b/packages/appkit/exports/vue.ts @@ -43,11 +43,11 @@ export function useAppKitNetwork() { const { caipNetwork, caipNetworkId, chainId } = useAppKitNetworkCore() function switchNetwork(network: AppKitNetwork) { - modal?.switchNetworkBase(network) + modal?.switchNetwork(network) } function addNetwork(network: CaipNetwork) { - modal?.addCaipNetwork(network) + modal?.addNetwork(network) } return { diff --git a/packages/appkit/src/client.ts b/packages/appkit/src/client.ts index 3f74512123..ca11cd4fc2 100644 --- a/packages/appkit/src/client.ts +++ b/packages/appkit/src/client.ts @@ -115,7 +115,11 @@ export class AppKit { return ChainController.state.activeCaipNetwork?.id } - public async switchNetworkBase(appKitNetwork: AppKitNetwork) { + public addNetwork(caipNetwork: CaipNetwork) { + ChainController.addCaipNetwork(caipNetwork) + } + + public switchNetwork(appKitNetwork: AppKitNetwork | CaipNetwork) { const network = this.caipNetworks.find(n => n.caipNetworkId === appKitNetwork.id) const extendedNetwork = network || @@ -131,14 +135,6 @@ export class AppKit { return ChainController.switchActiveNetwork(extendedNetwork) } - public addCaipNetwork(caipNetwork: CaipNetwork) { - ChainController.addCaipNetwork(caipNetwork) - } - - public switchNetwork(caipNetwork: CaipNetwork) { - return ChainController.switchActiveNetwork(caipNetwork) - } - public getWalletProvider() { return ChainController.state.activeChain ? ProviderUtil.state.providers[ChainController.state.activeChain] From e4e63eebdea43bf451e19767e09b6c7ff9485451 Mon Sep 17 00:00:00 2001 From: enesozturk Date: Wed, 30 Oct 2024 12:08:51 +0300 Subject: [PATCH 06/20] chore: add tests for appkit functions --- packages/appkit/src/tests/appkit.test.ts | 30 ++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/packages/appkit/src/tests/appkit.test.ts b/packages/appkit/src/tests/appkit.test.ts index 8e0df26b8d..147bb99fbb 100644 --- a/packages/appkit/src/tests/appkit.test.ts +++ b/packages/appkit/src/tests/appkit.test.ts @@ -1,5 +1,6 @@ import { describe, it, expect, beforeEach, vi } from 'vitest' import { AppKit } from '../client' +import { mainnet, polygon } from '../networks/index.js' import { AccountController, ModalController, @@ -446,5 +447,34 @@ describe('Base', () => { }) expect(result).toBe('connector-image-url') }) + + it('should switch network when requested', async () => { + vi.mocked(ChainController.switchActiveNetwork).mockResolvedValue(undefined) + vi.mocked(ChainController.addCaipNetwork).mockImplementation(() => {}) + + await appKit.switchNetwork(mainnet) + + expect(ChainController.switchActiveNetwork).toHaveBeenCalledWith( + expect.objectContaining({ + id: mainnet.id, + name: mainnet.name + }) + ) + + await appKit.switchNetwork(polygon) + + expect(ChainController.addCaipNetwork).toHaveBeenCalledWith( + expect.objectContaining({ + id: polygon.id, + name: polygon.name + }) + ) + expect(ChainController.switchActiveNetwork).toHaveBeenCalledWith( + expect.objectContaining({ + id: polygon.id, + name: polygon.name + }) + ) + }) }) }) From b2ccddcc2c75b7c95821ad98b7e307f93fa0f4b8 Mon Sep 17 00:00:00 2001 From: enesozturk Date: Wed, 30 Oct 2024 14:20:41 +0300 Subject: [PATCH 07/20] refactor: remove add network logics --- apps/laboratory/tests/wallet.spec.ts | 3 ++- packages/appkit-utils/src/ErrorUtil.ts | 5 +++++ packages/appkit/exports/react.ts | 8 +------- packages/appkit/exports/vue.ts | 8 +------- packages/appkit/src/client.ts | 19 +++++-------------- packages/appkit/src/tests/appkit.test.ts | 14 +------------- 6 files changed, 15 insertions(+), 42 deletions(-) diff --git a/apps/laboratory/tests/wallet.spec.ts b/apps/laboratory/tests/wallet.spec.ts index 5e527af91b..2c27ea2a56 100644 --- a/apps/laboratory/tests/wallet.spec.ts +++ b/apps/laboratory/tests/wallet.spec.ts @@ -66,7 +66,8 @@ sampleWalletTest('it should show disabled networks', async ({ library }) => { }) sampleWalletTest('it should switch networks and sign', async ({ library }) => { - const chains = library === 'solana' ? ['Solana Testnet', 'Solana'] : ['Polygon', 'Ethereum'] + const chains = + library === 'solana' ? [solanaTestnet.name, solana.name] : [polygon.name, mainnet.name] const caipNetworkId = library === 'solana' ? [solanaTestnet.id, solana.id] : [polygon.id, mainnet.id] diff --git a/packages/appkit-utils/src/ErrorUtil.ts b/packages/appkit-utils/src/ErrorUtil.ts index 92c564307f..8c6d2fb87a 100644 --- a/packages/appkit-utils/src/ErrorUtil.ts +++ b/packages/appkit-utils/src/ErrorUtil.ts @@ -3,6 +3,11 @@ export const ErrorUtil = { UNAUTHORIZED_DOMAIN_NOT_ALLOWED: 'Unauthorized: origin not allowed' }, ALERT_ERRORS: { + SWITCH_NETWORK_NOT_FOUND: { + shortMessage: 'Network Not Found', + longMessage: + "Network not found - please make sure it is included in 'networks' array in createAppKit function" + }, INVALID_APP_CONFIGURATION: { shortMessage: 'Invalid App Configuration', longMessage: () => diff --git a/packages/appkit/exports/react.ts b/packages/appkit/exports/react.ts index 27ababff84..f4dff91ec0 100644 --- a/packages/appkit/exports/react.ts +++ b/packages/appkit/exports/react.ts @@ -4,7 +4,6 @@ import { getAppKit } from '../src/library/react/index.js' import { CoreHelperUtil } from '@reown/appkit-core' import { PACKAGE_VERSION } from './constants.js' import { useAppKitNetworkCore } from '@reown/appkit-core/react' -import type { CaipNetwork } from '@reown/appkit' import type { AppKitNetwork } from '@reown/appkit/networks' // -- Views ------------------------------------------------------------ @@ -52,16 +51,11 @@ export function useAppKitNetwork() { modal?.switchNetwork(network) } - function addNetwork(network: CaipNetwork) { - modal?.addNetwork(network) - } - return { caipNetwork, caipNetworkId, chainId, - switchNetwork, - addNetwork + switchNetwork } } diff --git a/packages/appkit/exports/vue.ts b/packages/appkit/exports/vue.ts index 77b8ea7ff3..19f971f05b 100644 --- a/packages/appkit/exports/vue.ts +++ b/packages/appkit/exports/vue.ts @@ -4,7 +4,6 @@ import { getAppKit } from '../src/library/vue/index.js' import { CoreHelperUtil } from '@reown/appkit-core' import { PACKAGE_VERSION } from './constants.js' import { useAppKitNetworkCore } from '@reown/appkit-core/vue' -import type { CaipNetwork } from '@reown/appkit' import type { AppKitNetwork } from '@reown/appkit/networks' // -- Views ------------------------------------------------------------ @@ -46,16 +45,11 @@ export function useAppKitNetwork() { modal?.switchNetwork(network) } - function addNetwork(network: CaipNetwork) { - modal?.addNetwork(network) - } - return { caipNetwork, caipNetworkId, chainId, - switchNetwork, - addNetwork + switchNetwork } } diff --git a/packages/appkit/src/client.ts b/packages/appkit/src/client.ts index ca11cd4fc2..4ce8e4dbac 100644 --- a/packages/appkit/src/client.ts +++ b/packages/appkit/src/client.ts @@ -115,24 +115,15 @@ export class AppKit { return ChainController.state.activeCaipNetwork?.id } - public addNetwork(caipNetwork: CaipNetwork) { - ChainController.addCaipNetwork(caipNetwork) - } - - public switchNetwork(appKitNetwork: AppKitNetwork | CaipNetwork) { - const network = this.caipNetworks.find(n => n.caipNetworkId === appKitNetwork.id) - const extendedNetwork = - network || - CaipNetworksUtil.extendCaipNetwork(appKitNetwork, { - projectId: OptionsController.state.projectId, - customNetworkImageUrls: {} - }) + public switchNetwork(appKitNetwork: AppKitNetwork) { + const network = this.caipNetworks.find(n => n.id === appKitNetwork.id) if (!network) { - ChainController.addCaipNetwork(extendedNetwork) + AlertController.open(ErrorUtil.ALERT_ERRORS.SWITCH_NETWORK_NOT_FOUND, 'error') + return } - return ChainController.switchActiveNetwork(extendedNetwork) + return ChainController.switchActiveNetwork(network) } public getWalletProvider() { diff --git a/packages/appkit/src/tests/appkit.test.ts b/packages/appkit/src/tests/appkit.test.ts index 147bb99fbb..b66b4c61ef 100644 --- a/packages/appkit/src/tests/appkit.test.ts +++ b/packages/appkit/src/tests/appkit.test.ts @@ -450,7 +450,6 @@ describe('Base', () => { it('should switch network when requested', async () => { vi.mocked(ChainController.switchActiveNetwork).mockResolvedValue(undefined) - vi.mocked(ChainController.addCaipNetwork).mockImplementation(() => {}) await appKit.switchNetwork(mainnet) @@ -463,18 +462,7 @@ describe('Base', () => { await appKit.switchNetwork(polygon) - expect(ChainController.addCaipNetwork).toHaveBeenCalledWith( - expect.objectContaining({ - id: polygon.id, - name: polygon.name - }) - ) - expect(ChainController.switchActiveNetwork).toHaveBeenCalledWith( - expect.objectContaining({ - id: polygon.id, - name: polygon.name - }) - ) + expect(ChainController.switchActiveNetwork).toHaveBeenCalledTimes(1) }) }) }) From 168d8d03d060ce6437d70d3e75077f1c62671f98 Mon Sep 17 00:00:00 2001 From: enesozturk Date: Wed, 30 Oct 2024 14:24:10 +0300 Subject: [PATCH 08/20] chore: changeset file --- .changeset/lazy-frogs-leave.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .changeset/lazy-frogs-leave.md diff --git a/.changeset/lazy-frogs-leave.md b/.changeset/lazy-frogs-leave.md new file mode 100644 index 0000000000..5eed039d6f --- /dev/null +++ b/.changeset/lazy-frogs-leave.md @@ -0,0 +1,24 @@ +--- +'@reown/appkit-utils': patch +'@apps/laboratory': patch +'@reown/appkit': patch +'@reown/appkit-core': patch +'@apps/demo': patch +'@apps/gallery': patch +'@reown/appkit-adapter-ethers': patch +'@reown/appkit-adapter-ethers5': patch +'@reown/appkit-adapter-polkadot': patch +'@reown/appkit-adapter-solana': patch +'@reown/appkit-adapter-wagmi': patch +'@reown/appkit-cdn': 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 +--- + +Adds switch network methods and hooks From 0696e1d24c27cac896b6b5c7e23647874bf5110b Mon Sep 17 00:00:00 2001 From: enesozturk Date: Wed, 30 Oct 2024 16:19:18 +0300 Subject: [PATCH 09/20] chore: linter issues --- packages/appkit/src/client.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/appkit/src/client.ts b/packages/appkit/src/client.ts index 4ce8e4dbac..6ad3aded58 100644 --- a/packages/appkit/src/client.ts +++ b/packages/appkit/src/client.ts @@ -120,10 +120,11 @@ export class AppKit { if (!network) { AlertController.open(ErrorUtil.ALERT_ERRORS.SWITCH_NETWORK_NOT_FOUND, 'error') + return } - return ChainController.switchActiveNetwork(network) + ChainController.switchActiveNetwork(network) } public getWalletProvider() { From 2e178b1e4e10bf62d919b57df4718c2b92961dff Mon Sep 17 00:00:00 2001 From: enesozturk Date: Thu, 31 Oct 2024 14:11:21 +0300 Subject: [PATCH 10/20] fix: lab hydration issue --- apps/laboratory/src/components/AppKitButtons.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/laboratory/src/components/AppKitButtons.tsx b/apps/laboratory/src/components/AppKitButtons.tsx index 6bbd03d315..caca9a3b84 100644 --- a/apps/laboratory/src/components/AppKitButtons.tsx +++ b/apps/laboratory/src/components/AppKitButtons.tsx @@ -72,9 +72,11 @@ export function AppKitButtons() { Disconnect - + {caipNetwork ? ( + + ) : null} From 5a9685940e2d97c7c7420cf16774ce686e674cc1 Mon Sep 17 00:00:00 2001 From: enesozturk Date: Thu, 31 Oct 2024 14:42:28 +0300 Subject: [PATCH 11/20] chore: appkit hook hydration issue --- .../src/components/AppKitButtons.tsx | 62 +------------------ .../laboratory/src/components/AppKitHooks.tsx | 59 ++++++++++++++++++ 2 files changed, 62 insertions(+), 59 deletions(-) create mode 100644 apps/laboratory/src/components/AppKitHooks.tsx diff --git a/apps/laboratory/src/components/AppKitButtons.tsx b/apps/laboratory/src/components/AppKitButtons.tsx index caca9a3b84..d18c9c986b 100644 --- a/apps/laboratory/src/components/AppKitButtons.tsx +++ b/apps/laboratory/src/components/AppKitButtons.tsx @@ -1,40 +1,7 @@ -import { useAppKit, useDisconnect, useAppKitAccount, useAppKitNetwork } from '@reown/appkit/react' -import { polygon, mainnet, solana, solanaTestnet, type AppKitNetwork } from '@reown/appkit/networks' -import { - Stack, - Card, - CardHeader, - Heading, - CardBody, - Box, - StackDivider, - Button -} from '@chakra-ui/react' +import { Stack, Card, CardHeader, Heading, CardBody, Box, StackDivider } from '@chakra-ui/react' +import { AppKitHooks } from './AppKitHooks' export function AppKitButtons() { - const { open } = useAppKit() - const { isConnected } = useAppKitAccount() - const { caipNetwork, switchNetwork } = useAppKitNetwork() - const { disconnect } = useDisconnect() - - const isEIPNamespace = caipNetwork?.chainNamespace === 'eip155' - // eslint-disable-next-line no-nested-ternary - const networkToSwitch: AppKitNetwork = isEIPNamespace - ? caipNetwork?.id === polygon.id - ? mainnet - : polygon - : caipNetwork?.id === solana.id - ? solanaTestnet - : solana - - function handleSwitchNetwork() { - if (isEIPNamespace) { - switchNetwork(networkToSwitch) - } else { - switchNetwork(networkToSwitch) - } - } - return ( @@ -55,30 +22,7 @@ export function AppKitButtons() { - - - Hooks Interactions - - - - - - - {caipNetwork ? ( - - ) : null} - - + diff --git a/apps/laboratory/src/components/AppKitHooks.tsx b/apps/laboratory/src/components/AppKitHooks.tsx new file mode 100644 index 0000000000..30176ecc6b --- /dev/null +++ b/apps/laboratory/src/components/AppKitHooks.tsx @@ -0,0 +1,59 @@ +import { useAppKit, useDisconnect, useAppKitAccount, useAppKitNetwork } from '@reown/appkit/react' +import { polygon, mainnet, solana, solanaTestnet, type AppKitNetwork } from '@reown/appkit/networks' +import { Heading, Box, Button } from '@chakra-ui/react' + +export function AppKitHooks() { + const { open } = useAppKit() + const { isConnected } = useAppKitAccount() + const { caipNetwork, switchNetwork } = useAppKitNetwork() + const { disconnect } = useDisconnect() + + if (!caipNetwork) { + return null + } + + const isEIPNamespace = caipNetwork?.chainNamespace === 'eip155' + // eslint-disable-next-line no-nested-ternary + const networkToSwitch: AppKitNetwork = isEIPNamespace + ? caipNetwork?.id === polygon.id + ? mainnet + : polygon + : caipNetwork?.id === solana.id + ? solanaTestnet + : solana + + function handleSwitchNetwork() { + if (isEIPNamespace) { + switchNetwork(networkToSwitch) + } else { + switchNetwork(networkToSwitch) + } + } + + return ( + + + Hooks Interactions + + + + + + + {caipNetwork ? ( + + ) : null} + + + ) +} From 20afd355cc409a224a76df41ba93711429e74423 Mon Sep 17 00:00:00 2001 From: enesozturk Date: Thu, 31 Oct 2024 15:33:17 +0300 Subject: [PATCH 12/20] chore: hooks comp hydration --- apps/laboratory/src/components/AppKitHooks.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/laboratory/src/components/AppKitHooks.tsx b/apps/laboratory/src/components/AppKitHooks.tsx index 30176ecc6b..2785c4652f 100644 --- a/apps/laboratory/src/components/AppKitHooks.tsx +++ b/apps/laboratory/src/components/AppKitHooks.tsx @@ -1,14 +1,21 @@ +import { useEffect, useState } from 'react' import { useAppKit, useDisconnect, useAppKitAccount, useAppKitNetwork } from '@reown/appkit/react' import { polygon, mainnet, solana, solanaTestnet, type AppKitNetwork } from '@reown/appkit/networks' import { Heading, Box, Button } from '@chakra-ui/react' export function AppKitHooks() { + const [isClient, setIsClient] = useState(false) + + useEffect(() => { + setIsClient(true) + }, []) + const { open } = useAppKit() const { isConnected } = useAppKitAccount() const { caipNetwork, switchNetwork } = useAppKitNetwork() const { disconnect } = useDisconnect() - if (!caipNetwork) { + if (!isClient || !caipNetwork) { return null } From 58506aaf3e3fd2bb09ccf29ba59b49832f3152ad Mon Sep 17 00:00:00 2001 From: enesozturk Date: Thu, 31 Oct 2024 16:26:11 +0300 Subject: [PATCH 13/20] chore: hydration --- apps/laboratory/src/components/AppKitHooks.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/laboratory/src/components/AppKitHooks.tsx b/apps/laboratory/src/components/AppKitHooks.tsx index 2785c4652f..c0c47e71a4 100644 --- a/apps/laboratory/src/components/AppKitHooks.tsx +++ b/apps/laboratory/src/components/AppKitHooks.tsx @@ -15,7 +15,7 @@ export function AppKitHooks() { const { caipNetwork, switchNetwork } = useAppKitNetwork() const { disconnect } = useDisconnect() - if (!isClient || !caipNetwork) { + if (!isClient) { return null } From d3eda449c2f805dad9466ecfb9e6bf9e0d33d65b Mon Sep 17 00:00:00 2001 From: enesozturk Date: Thu, 31 Oct 2024 18:07:06 +0300 Subject: [PATCH 14/20] fix: disable typing network name to switch network button --- .../laboratory/src/components/AppKitHooks.tsx | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/apps/laboratory/src/components/AppKitHooks.tsx b/apps/laboratory/src/components/AppKitHooks.tsx index c0c47e71a4..92494aef1b 100644 --- a/apps/laboratory/src/components/AppKitHooks.tsx +++ b/apps/laboratory/src/components/AppKitHooks.tsx @@ -1,24 +1,13 @@ -import { useEffect, useState } from 'react' import { useAppKit, useDisconnect, useAppKitAccount, useAppKitNetwork } from '@reown/appkit/react' import { polygon, mainnet, solana, solanaTestnet, type AppKitNetwork } from '@reown/appkit/networks' import { Heading, Box, Button } from '@chakra-ui/react' export function AppKitHooks() { - const [isClient, setIsClient] = useState(false) - - useEffect(() => { - setIsClient(true) - }, []) - const { open } = useAppKit() const { isConnected } = useAppKitAccount() const { caipNetwork, switchNetwork } = useAppKitNetwork() const { disconnect } = useDisconnect() - if (!isClient) { - return null - } - const isEIPNamespace = caipNetwork?.chainNamespace === 'eip155' // eslint-disable-next-line no-nested-ternary const networkToSwitch: AppKitNetwork = isEIPNamespace @@ -55,11 +44,9 @@ export function AppKitHooks() { Disconnect - {caipNetwork ? ( - - ) : null} + ) From 312b43c9343e50452f702b3c4f0fce74994cfa59 Mon Sep 17 00:00:00 2001 From: enesozturk Date: Thu, 31 Oct 2024 18:11:28 +0300 Subject: [PATCH 15/20] refactor: swtich network button logics and styles --- .../src/components/AppKitButtons.tsx | 2 +- .../laboratory/src/components/AppKitHooks.tsx | 26 ++++++++----------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/apps/laboratory/src/components/AppKitButtons.tsx b/apps/laboratory/src/components/AppKitButtons.tsx index d18c9c986b..84cd70c303 100644 --- a/apps/laboratory/src/components/AppKitButtons.tsx +++ b/apps/laboratory/src/components/AppKitButtons.tsx @@ -9,7 +9,7 @@ export function AppKitButtons() { - } spacing="4"> + } spacing="4" flexWrap="wrap"> Connect / Account Button diff --git a/apps/laboratory/src/components/AppKitHooks.tsx b/apps/laboratory/src/components/AppKitHooks.tsx index 92494aef1b..087bf8506c 100644 --- a/apps/laboratory/src/components/AppKitHooks.tsx +++ b/apps/laboratory/src/components/AppKitHooks.tsx @@ -8,22 +8,18 @@ export function AppKitHooks() { const { caipNetwork, switchNetwork } = useAppKitNetwork() const { disconnect } = useDisconnect() - const isEIPNamespace = caipNetwork?.chainNamespace === 'eip155' - // eslint-disable-next-line no-nested-ternary - const networkToSwitch: AppKitNetwork = isEIPNamespace - ? caipNetwork?.id === polygon.id - ? mainnet - : polygon - : caipNetwork?.id === solana.id - ? solanaTestnet - : solana - function handleSwitchNetwork() { - if (isEIPNamespace) { - switchNetwork(networkToSwitch) - } else { - switchNetwork(networkToSwitch) - } + const isEIPNamespace = caipNetwork?.chainNamespace === 'eip155' + // eslint-disable-next-line no-nested-ternary + const networkToSwitch: AppKitNetwork = isEIPNamespace + ? caipNetwork?.id === polygon.id + ? mainnet + : polygon + : caipNetwork?.id === solana.id + ? solanaTestnet + : solana + + switchNetwork(networkToSwitch) } return ( From f88749b9fd4dad6323f2f76a2aa945adbfd4a538 Mon Sep 17 00:00:00 2001 From: enesozturk Date: Fri, 1 Nov 2024 03:22:24 +0300 Subject: [PATCH 16/20] chore: skip new test --- apps/laboratory/tests/wallet.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/laboratory/tests/wallet.spec.ts b/apps/laboratory/tests/wallet.spec.ts index 2c27ea2a56..ee95109d21 100644 --- a/apps/laboratory/tests/wallet.spec.ts +++ b/apps/laboratory/tests/wallet.spec.ts @@ -65,7 +65,7 @@ sampleWalletTest('it should show disabled networks', async ({ library }) => { await modalPage.closeModal() }) -sampleWalletTest('it should switch networks and sign', async ({ library }) => { +sampleWalletTest.skip('it should switch networks and sign', async ({ library }) => { const chains = library === 'solana' ? [solanaTestnet.name, solana.name] : [polygon.name, mainnet.name] const caipNetworkId = From 86359228b5c844ba10c04d1060884e1d34486ddd Mon Sep 17 00:00:00 2001 From: enesozturk Date: Fri, 1 Nov 2024 11:50:40 +0300 Subject: [PATCH 17/20] fix: wrong skipped test --- apps/laboratory/tests/wallet.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/laboratory/tests/wallet.spec.ts b/apps/laboratory/tests/wallet.spec.ts index ee95109d21..13cdccc3ba 100644 --- a/apps/laboratory/tests/wallet.spec.ts +++ b/apps/laboratory/tests/wallet.spec.ts @@ -65,7 +65,7 @@ sampleWalletTest('it should show disabled networks', async ({ library }) => { await modalPage.closeModal() }) -sampleWalletTest.skip('it should switch networks and sign', async ({ library }) => { +sampleWalletTest('it should switch networks and sign', async ({ library }) => { const chains = library === 'solana' ? [solanaTestnet.name, solana.name] : [polygon.name, mainnet.name] const caipNetworkId = @@ -100,7 +100,7 @@ sampleWalletTest.skip('it should switch networks and sign', async ({ library }) await processChain(0) }) -sampleWalletTest('it should switch networks using hook', async ({ library }) => { +sampleWalletTest.skip('it should switch networks using hook', async ({ library }) => { const chains = library === 'solana' ? ['Solana Testnet', 'Solana'] : ['Polygon', 'Ethereum'] const caipNetworkId = library === 'solana' ? [solanaTestnet.id, solana.id] : [polygon.id, mainnet.id] From f020cad4db41f00fa7c828cb4dad4623bc5c4266 Mon Sep 17 00:00:00 2001 From: enesozturk Date: Fri, 1 Nov 2024 16:41:19 +0300 Subject: [PATCH 18/20] chore: remove new hook button --- .../laboratory/src/components/AppKitHooks.tsx | 22 +------------------ 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/apps/laboratory/src/components/AppKitHooks.tsx b/apps/laboratory/src/components/AppKitHooks.tsx index 087bf8506c..1718e15300 100644 --- a/apps/laboratory/src/components/AppKitHooks.tsx +++ b/apps/laboratory/src/components/AppKitHooks.tsx @@ -1,27 +1,11 @@ -import { useAppKit, useDisconnect, useAppKitAccount, useAppKitNetwork } from '@reown/appkit/react' -import { polygon, mainnet, solana, solanaTestnet, type AppKitNetwork } from '@reown/appkit/networks' +import { useAppKit, useDisconnect, useAppKitAccount } from '@reown/appkit/react' import { Heading, Box, Button } from '@chakra-ui/react' export function AppKitHooks() { const { open } = useAppKit() const { isConnected } = useAppKitAccount() - const { caipNetwork, switchNetwork } = useAppKitNetwork() const { disconnect } = useDisconnect() - function handleSwitchNetwork() { - const isEIPNamespace = caipNetwork?.chainNamespace === 'eip155' - // eslint-disable-next-line no-nested-ternary - const networkToSwitch: AppKitNetwork = isEIPNamespace - ? caipNetwork?.id === polygon.id - ? mainnet - : polygon - : caipNetwork?.id === solana.id - ? solanaTestnet - : solana - - switchNetwork(networkToSwitch) - } - return ( @@ -39,10 +23,6 @@ export function AppKitHooks() { > Disconnect - - ) From 6e239577b88993d7fb3962b374df697dfe138a7c Mon Sep 17 00:00:00 2001 From: enesozturk Date: Fri, 1 Nov 2024 16:53:27 +0300 Subject: [PATCH 19/20] chore: revert switch network button --- .../laboratory/src/components/AppKitHooks.tsx | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/apps/laboratory/src/components/AppKitHooks.tsx b/apps/laboratory/src/components/AppKitHooks.tsx index 1718e15300..42e0c9e830 100644 --- a/apps/laboratory/src/components/AppKitHooks.tsx +++ b/apps/laboratory/src/components/AppKitHooks.tsx @@ -1,17 +1,33 @@ -import { useAppKit, useDisconnect, useAppKitAccount } from '@reown/appkit/react' +import { useAppKit, useDisconnect, useAppKitAccount, useAppKitNetwork } from '@reown/appkit/react' +import { polygon, mainnet, solana, solanaTestnet, type AppKitNetwork } from '@reown/appkit/networks' import { Heading, Box, Button } from '@chakra-ui/react' export function AppKitHooks() { const { open } = useAppKit() const { isConnected } = useAppKitAccount() + const { caipNetwork, switchNetwork } = useAppKitNetwork() const { disconnect } = useDisconnect() + function handleSwitchNetwork() { + const isEIPNamespace = caipNetwork?.chainNamespace === 'eip155' + // eslint-disable-next-line no-nested-ternary + const networkToSwitch: AppKitNetwork = isEIPNamespace + ? caipNetwork?.id === polygon.id + ? mainnet + : polygon + : caipNetwork?.id === solana.id + ? solanaTestnet + : solana + + switchNetwork(networkToSwitch) + } + return ( Hooks Interactions - + @@ -23,6 +39,10 @@ export function AppKitHooks() { > Disconnect + + ) From 7801b987a2254a0af4eb23972fc805252751356d Mon Sep 17 00:00:00 2001 From: enesozturk Date: Fri, 1 Nov 2024 16:53:53 +0300 Subject: [PATCH 20/20] chore: remove skip for test --- apps/laboratory/tests/wallet.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/laboratory/tests/wallet.spec.ts b/apps/laboratory/tests/wallet.spec.ts index 13cdccc3ba..2c27ea2a56 100644 --- a/apps/laboratory/tests/wallet.spec.ts +++ b/apps/laboratory/tests/wallet.spec.ts @@ -100,7 +100,7 @@ sampleWalletTest('it should switch networks and sign', async ({ library }) => { await processChain(0) }) -sampleWalletTest.skip('it should switch networks using hook', async ({ library }) => { +sampleWalletTest('it should switch networks using hook', async ({ library }) => { const chains = library === 'solana' ? ['Solana Testnet', 'Solana'] : ['Polygon', 'Ethereum'] const caipNetworkId = library === 'solana' ? [solanaTestnet.id, solana.id] : [polygon.id, mainnet.id]