diff --git a/.changeset/fix-wcnamespace-caip-network-id.md b/.changeset/fix-wcnamespace-caip-network-id.md new file mode 100644 index 0000000000..2fa205f67b --- /dev/null +++ b/.changeset/fix-wcnamespace-caip-network-id.md @@ -0,0 +1,6 @@ +--- +"@reown/appkit-controllers": patch +"@reown/appkit-utils": patch +--- + +Fix `createNamespaces` using `id` to reconstruct CAIP network ID instead of the existing `caipNetworkId` property. For standard chains these are equivalent, but for custom chains (e.g. Neo3, Stellar) where the chain `id` differs from the CAIP-2 chain reference, the wrong namespace was sent to wallets over WalletConnect. Also fixes `rpcMap` keys to use the full `caipNetworkId`. diff --git a/packages/appkit-utils/src/WCNamespaceUtil.ts b/packages/appkit-utils/src/WCNamespaceUtil.ts index 1ba1e43795..947eb72188 100644 --- a/packages/appkit-utils/src/WCNamespaceUtil.ts +++ b/packages/appkit-utils/src/WCNamespaceUtil.ts @@ -65,15 +65,13 @@ export function createDefaultNamespace(chainNamespace: string): Namespace { export function createNamespaces(caipNetworks: CaipNetwork[]): NamespaceConfig { return caipNetworks.reduce((acc, chain) => { - const { id, chainNamespace, rpcUrls } = chain + const { caipNetworkId, chainNamespace, rpcUrls } = chain const rpcUrl = rpcUrls.default.http[0] if (!acc[chainNamespace]) { acc[chainNamespace] = createDefaultNamespace(chainNamespace) } - const caipNetworkId = `${chainNamespace}:${id}` - // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style const namespace = acc[chainNamespace] @@ -91,7 +89,7 @@ export function createNamespaces(caipNetworks: CaipNetwork[]): NamespaceConfig { } if (namespace?.rpcMap && rpcUrl) { - namespace.rpcMap[id] = rpcUrl + namespace.rpcMap[caipNetworkId] = rpcUrl } return acc diff --git a/packages/controllers/src/utils/WalletConnectUtil.ts b/packages/controllers/src/utils/WalletConnectUtil.ts index 465519faf6..8bbd647b44 100644 --- a/packages/controllers/src/utils/WalletConnectUtil.ts +++ b/packages/controllers/src/utils/WalletConnectUtil.ts @@ -203,15 +203,13 @@ export const WcHelpersUtil = { configOverride?: OptionsControllerState['universalProviderConfigOverride'] ): NamespaceConfig { const defaultNamespaces = caipNetworks.reduce((acc, chain) => { - const { id, chainNamespace, rpcUrls } = chain + const { caipNetworkId, chainNamespace, rpcUrls } = chain const rpcUrl = rpcUrls.default.http[0] if (!acc[chainNamespace]) { acc[chainNamespace] = this.createDefaultNamespace(chainNamespace) } - const caipNetworkId = `${chainNamespace}:${id}` - // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style const namespace = acc[chainNamespace] @@ -229,7 +227,7 @@ export const WcHelpersUtil = { } if (namespace?.rpcMap && rpcUrl) { - namespace.rpcMap[id] = rpcUrl + namespace.rpcMap[caipNetworkId] = rpcUrl } return acc diff --git a/packages/controllers/tests/utils/WalletConnectUtil.test.ts b/packages/controllers/tests/utils/WalletConnectUtil.test.ts index 92a866a104..e71e9fce01 100644 --- a/packages/controllers/tests/utils/WalletConnectUtil.test.ts +++ b/packages/controllers/tests/utils/WalletConnectUtil.test.ts @@ -158,8 +158,8 @@ describe('WcHelpersUtil', () => { events: ['accountsChanged', 'chainChanged'], chains: ['eip155:1', 'eip155:137'], rpcMap: { - '1': 'https://mainnet.infura.io/v3/YOUR-PROJECT-ID', - '137': 'https://polygon.rpc.com' + 'eip155:1': 'https://mainnet.infura.io/v3/YOUR-PROJECT-ID', + 'eip155:137': 'https://polygon.rpc.com' } }, solana: { @@ -179,8 +179,8 @@ describe('WcHelpersUtil', () => { 'solana:8E9rvCKLFQia2Y35HXjjpWzj8weVo44K' ], rpcMap: { - '5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp': 'https://api.mainnet-beta.solana.com', - EtWTRABZaYq6iMfeYKouRu166VU2xqa1: 'https://api.mainnet-beta.solana.com' + 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp': 'https://api.mainnet-beta.solana.com', + 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1': 'https://api.mainnet-beta.solana.com' } } }) @@ -190,6 +190,25 @@ describe('WcHelpersUtil', () => { const namespaces = WcHelpersUtil.createNamespaces([]) expect(namespaces).toEqual({}) }) + + test('uses caipNetworkId directly when id differs from caip chain reference (custom chains)', () => { + const customNetwork: CaipNetwork = { + id: 1, + chainNamespace: 'neo3', + caipNetworkId: 'neo3:MainNet', + name: 'Neo3 MainNet', + nativeCurrency: { name: 'GAS', symbol: 'GAS', decimals: 8 }, + rpcUrls: { default: { http: ['https://mainnet1.neo.coz.io'] } } + } as unknown as CaipNetwork + + const namespaces = WcHelpersUtil.createNamespaces([customNetwork]) + + expect(namespaces['neo3']?.chains).toContain('neo3:MainNet') + expect(namespaces['neo3']?.chains).not.toContain('neo3:1') + expect(namespaces['neo3']?.rpcMap).toEqual({ + 'neo3:MainNet': 'https://mainnet1.neo.coz.io' + }) + }) }) describe('getChainsFromNamespaces', () => {