Commit 43b9e398 authored by Jordan Frankfurt's avatar Jordan Frankfurt Committed by GitHub

fix: allow more session namespace keys (#6802)

* allow more session namespace keys

* pr feedback

* add test case
parent 1247989c
...@@ -24,6 +24,7 @@ import { useIsMobile } from 'nft/hooks' ...@@ -24,6 +24,7 @@ import { useIsMobile } from 'nft/hooks'
import { useCallback, useMemo, useRef, useState } from 'react' import { useCallback, useMemo, useRef, useState } from 'react'
import { AlertTriangle, ChevronDown, ChevronUp } from 'react-feather' import { AlertTriangle, ChevronDown, ChevronUp } from 'react-feather'
import { useTheme } from 'styled-components/macro' import { useTheme } from 'styled-components/macro'
import { getSupportedChainIdsFromWalletConnectSession } from 'utils/getSupportedChainIdsFromWalletConnectSession'
import * as styles from './ChainSelector.css' import * as styles from './ChainSelector.css'
import ChainSelectorRow from './ChainSelectorRow' import ChainSelectorRow from './ChainSelectorRow'
...@@ -35,25 +36,14 @@ interface ChainSelectorProps { ...@@ -35,25 +36,14 @@ interface ChainSelectorProps {
leftAlign?: boolean leftAlign?: boolean
} }
// accounts is an array of strings in the format of "eip155:<chainId>:<address>" function useWalletSupportedChains(): SupportedChainId[] {
function getChainsFromEIP155Accounts(accounts?: string[]): SupportedChainId[] {
if (!accounts) return []
return accounts
.map((account) => {
const splitAccount = account.split(':')
return splitAccount[1] ? parseInt(splitAccount[1]) : undefined
})
.filter((x) => x !== undefined) as SupportedChainId[]
}
function useWalletSupportedChains() {
const { connector } = useWeb3React() const { connector } = useWeb3React()
const connectionType = getConnection(connector).type const connectionType = getConnection(connector).type
switch (connectionType) { switch (connectionType) {
case ConnectionType.WALLET_CONNECT_V2: case ConnectionType.WALLET_CONNECT_V2:
return getChainsFromEIP155Accounts((connector as WalletConnect).provider?.session?.namespaces.eip155.accounts) return getSupportedChainIdsFromWalletConnectSession((connector as WalletConnect).provider?.session)
case ConnectionType.UNISWAP_WALLET: case ConnectionType.UNISWAP_WALLET:
return UniWalletSupportedChains return UniWalletSupportedChains
default: default:
......
import { SessionTypes } from '@walletconnect/types'
import { getSupportedChainIdsFromWalletConnectSession } from './getSupportedChainIdsFromWalletConnectSession'
const testSession: SessionTypes.Struct = {
topic: 'string',
pairingTopic: 'string',
relay: { protocol: '', data: '' },
expiry: 4132684800000,
acknowledged: true,
controller: 'string',
namespaces: {},
requiredNamespaces: {
'eip155:1': {
chains: ['1'],
methods: [],
events: [],
},
},
optionalNamespaces: {
'eip155:137': {
chains: ['137'],
methods: [],
events: [],
},
},
sessionProperties: {},
self: {
publicKey: 'string',
metadata: {
name: 'string',
description: 'string',
url: 'string',
icons: ['string'],
verifyUrl: 'string',
redirect: {
native: 'string',
universal: 'string',
},
},
},
peer: {
publicKey: 'string',
metadata: {
name: 'string',
description: 'string',
url: 'string',
icons: ['string'],
verifyUrl: 'string',
redirect: {
native: 'string',
universal: 'string',
},
},
},
}
describe('getSupportedChainIdsFromWalletConnectSession', () => {
it('supports eip155:<chain> namespaces', () => {
const namespaces = {
'eip155:1': {
chains: ['1'],
accounts: ['eip155:1:0xc0ffee254729296a45a3885639AC7E10F9d54979'],
methods: [],
events: [],
},
'eip155:137': {
chains: ['137'],
accounts: ['eip155:137:0xdeadbeef'],
methods: [],
events: [],
},
}
const session = {
...testSession,
namespaces,
}
const result = getSupportedChainIdsFromWalletConnectSession(session)
expect(result).toEqual([1, 137])
})
it('supports eip155 namespaces without chains field', () => {
const namespaces = {
eip155: {
accounts: ['eip155:1:0xc0ffee254729296a45a3885639AC7E10F9d54979', 'eip155:137:address'],
methods: [],
events: [],
},
}
const session = {
...testSession,
namespaces,
}
const result = getSupportedChainIdsFromWalletConnectSession(session)
expect(result).toEqual([1, 137])
})
it('supports eip155 namespaces with chains field', () => {
const namespaces = {
eip155: {
chains: ['1', '137'],
accounts: ['eip155:1:0xc0ffee254729296a45a3885639AC7E10F9d54979', 'eip155:137:address'],
methods: [],
events: [],
},
}
const session = {
...testSession,
namespaces,
}
const result = getSupportedChainIdsFromWalletConnectSession(session)
expect(result).toEqual([1, 137])
})
it('supports eip155:<chain> namespaces without a chain property', () => {
const namespaces = {
'eip155:1': {
accounts: ['eip155:1:0xc0ffee254729296a45a3885639AC7E10F9d54979'],
methods: [],
events: [],
},
'eip155:137': {
accounts: ['eip155:137:0xdeadbeef'],
methods: [],
events: [],
},
}
const session = {
...testSession,
namespaces,
}
const result = getSupportedChainIdsFromWalletConnectSession(session)
expect(result).toEqual([1, 137])
})
})
import type { SessionTypes } from '@walletconnect/types'
import { SupportedChainId } from 'constants/chains'
// Helper function to extract chainId from string in format 'eip155:{chainId}'
function getChainIdFromFormattedString(item: string): number | null {
const splitItem = item.startsWith('eip155:') ? item.split(':') : []
return splitItem.length > 1 && !isNaN(Number(splitItem[1])) ? Number(splitItem[1]) : null
}
export function getSupportedChainIdsFromWalletConnectSession(session?: SessionTypes.Struct): SupportedChainId[] {
if (!session?.namespaces) return []
const eip155Keys = Object.keys(session.namespaces)
const namespaces = Object.values(session.namespaces)
// Collect all arrays into one for unified processing
const allItems = [
...eip155Keys,
...namespaces.flatMap((namespace) => namespace.chains),
...namespaces.flatMap((namespace) => namespace.accounts),
]
// Process all items to extract chainIds
const allChainIds = allItems
.map((item) => {
if (typeof item === 'string') {
return getChainIdFromFormattedString(item)
}
// Check if the item is a number
return isNaN(Number(item)) ? null : Number(item)
})
.filter((item) => item !== null) // Filter out any null values
return Array.from(new Set(allChainIds)) as SupportedChainId[]
}
...@@ -6458,6 +6458,18 @@ ...@@ -6458,6 +6458,18 @@
resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.8.0.tgz#3f5e85b2d6b149337f727ab8a71b8471d8d9a195" resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.8.0.tgz#3f5e85b2d6b149337f727ab8a71b8471d8d9a195"
integrity sha512-Cn+3I0V0vT9ghMuzh1KzZvCkiAxTq+1TR2eSqw5E5AVWfmCtECFkVZBP6uUJZ8YjwLqXheI+rnjqPy7sVM4Fyg== integrity sha512-Cn+3I0V0vT9ghMuzh1KzZvCkiAxTq+1TR2eSqw5E5AVWfmCtECFkVZBP6uUJZ8YjwLqXheI+rnjqPy7sVM4Fyg==
"@walletconnect/types@^2.8.1":
version "2.8.1"
resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.8.1.tgz#640eb6ad23866886fbe09a9b29832bf3f8647a09"
integrity sha512-MLISp85b+27vVkm3Wkud+eYCwySXCdOrmn0yQCSN6DnRrrunrD05ksz4CXGP7h2oXUvvXPDt/6lXBf1B4AfqrA==
dependencies:
"@walletconnect/events" "^1.0.1"
"@walletconnect/heartbeat" "1.2.1"
"@walletconnect/jsonrpc-types" "1.0.3"
"@walletconnect/keyvaluestorage" "^1.0.2"
"@walletconnect/logger" "^2.0.1"
events "^3.3.0"
"@walletconnect/universal-provider@2.8.0": "@walletconnect/universal-provider@2.8.0":
version "2.8.0" version "2.8.0"
resolved "https://registry.yarnpkg.com/@walletconnect/universal-provider/-/universal-provider-2.8.0.tgz#134f6873742f672c2424969335f9cc75d1532d17" resolved "https://registry.yarnpkg.com/@walletconnect/universal-provider/-/universal-provider-2.8.0.tgz#134f6873742f672c2424969335f9cc75d1532d17"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment