Skip to content

Commit

Permalink
fix: add check for missing address or chainId when getting siwe sessi…
Browse files Browse the repository at this point in the history
…on (#3332)

Co-authored-by: tomiir <rocchitomas@gmail.com>
  • Loading branch information
zoruka and tomiir authored Nov 27, 2024
1 parent f270e13 commit 60c6b2c
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 14 deletions.
23 changes: 23 additions & 0 deletions .changeset/curly-cameras-call.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
'@reown/appkit-siwe': 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': patch
'@reown/appkit-utils': patch
'@reown/appkit-cdn': patch
'@reown/appkit-common': patch
'@reown/appkit-core': patch
'@reown/appkit-experimental': patch
'@reown/appkit-polyfills': patch
'@reown/appkit-scaffold-ui': patch
'@reown/appkit-siwx': patch
'@reown/appkit-ui': patch
'@reown/appkit-wallet': patch
---

Adds check for missing address or chainId when getting siwe session for guarantee of backwards compatibility.
5 changes: 1 addition & 4 deletions packages/adapters/wagmi/src/connectors/UniversalConnector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -345,11 +345,8 @@ export function walletConnect(

config.emitter.emit('change', { chainId })
},
async onConnect(connectInfo) {
const chainId = Number(connectInfo.chainId)
const accounts = await this.getAccounts()
onConnect(_connectInfo) {
this.setRequestedChainsIds(caipNetworks.map(x => Number(x.id)))
config.emitter.emit('connect', { accounts, chainId })
},
async onDisconnect(_error) {
this.setRequestedChainsIds([])
Expand Down
7 changes: 6 additions & 1 deletion packages/core/src/controllers/ChainController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,12 @@ export const ChainController = {
const newAdapter = state.chains.get(caipNetwork.chainNamespace)
state.activeChain = caipNetwork.chainNamespace
state.activeCaipNetwork = caipNetwork
state.activeCaipAddress = newAdapter?.accountState?.caipAddress

if (newAdapter?.accountState?.address) {
state.activeCaipAddress = `${caipNetwork.chainNamespace}:${caipNetwork.id}:${newAdapter?.accountState?.address}`
} else {
state.activeCaipAddress = undefined
}

if (newAdapter) {
AccountController.replaceState(newAdapter.accountState)
Expand Down
13 changes: 9 additions & 4 deletions packages/core/src/utils/SIWXUtil.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { CaipNetworkId } from '@reown/appkit-common'
import type { CaipNetworkId, ChainNamespace } from '@reown/appkit-common'
import { OptionsController } from '../controllers/OptionsController.js'
import { CoreHelperUtil } from './CoreHelperUtil.js'
import { ChainController } from '../controllers/ChainController.js'
Expand All @@ -23,10 +23,14 @@ export const SIWXUtil = {
if (!(siwx && caipAddress)) {
return
}
const [network, chainId, address] = caipAddress.split(':') as [string, string, string]
const [namespace, chainId, address] = caipAddress.split(':') as [ChainNamespace, string, string]

if (!ChainController.checkIfSupportedNetwork(namespace)) {
return
}

try {
const sessions = await siwx.getSessions(`${network}:${chainId}` as CaipNetworkId, address)
const sessions = await siwx.getSessions(`${namespace}:${chainId}`, address)

if (sessions.length) {
return
Expand Down Expand Up @@ -187,7 +191,7 @@ export const SIWXUtil = {

// Ignores chainId and account address to get other message data
const siwxMessage = await siwx.createMessage({
chainId: '' as CaipNetworkId,
chainId: ChainController.getActiveCaipNetwork()?.caipNetworkId || ('' as CaipNetworkId),
accountAddress: ''
})

Expand All @@ -202,6 +206,7 @@ export const SIWXUtil = {
version: siwxMessage.version,
resources: siwxMessage.resources,
statement: siwxMessage.statement,
chainId: siwxMessage.chainId,

methods,
chains
Expand Down
30 changes: 25 additions & 5 deletions packages/siwe/src/mapToSIWX.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,21 @@ const subscriptions: (() => void)[] = []
export function mapToSIWX(siwe: AppKitSIWEClient): SIWXConfig {
async function getSession() {
try {
return await siwe.methods.getSession()
const response = await siwe.methods.getSession()

if (!response) {
return undefined
}

if (!response?.address) {
throw new Error('SIWE session is missing address')
}

if (!response?.chainId) {
throw new Error('SIWE session is missing chainId')
}

return response
} catch (error) {
console.warn('AppKit:SIWE:getSession - error:', error)

Expand Down Expand Up @@ -55,7 +69,7 @@ export function mapToSIWX(siwe: AppKitSIWEClient): SIWXConfig {
if (siwe.options.signOutOnAccountChange) {
const session = await getSession()

const lowercaseSessionAddress = session?.address.toLowerCase()
const lowercaseSessionAddress = session?.address?.toLowerCase()
const lowercaseCaipAddress =
CoreHelperUtil?.getPlainAddress(activeCaipAddress)?.toLowerCase()

Expand Down Expand Up @@ -141,8 +155,14 @@ export function mapToSIWX(siwe: AppKitSIWEClient): SIWXConfig {
console.warn('AppKit:SIWE:setSessions - signOut error', error)
}
} else {
const addingSessions = sessions.map(session => this.addSession(session))
await Promise.all(addingSessions)
/*
* The default SIWE implementation would only support one session
* So we only add the first session to keep backwards compatibility
*/
const session = (sessions.find(
s => s.data.chainId === ChainController.getActiveCaipNetwork()?.caipNetworkId
) || sessions[0]) as SIWXSession
await this.addSession(session)
}
},

Expand All @@ -164,7 +184,7 @@ export function mapToSIWX(siwe: AppKitSIWEClient): SIWXConfig {

const siweSession = await getSession()
const siweCaipNetworkId = `eip155:${siweSession?.chainId}`
const lowercaseSessionAddress = siweSession?.address.toLowerCase()
const lowercaseSessionAddress = siweSession?.address?.toLowerCase()
const lowercaseCaipAddress = address?.toLowerCase()

if (
Expand Down
39 changes: 39 additions & 0 deletions packages/siwe/tests/mapToSIWX.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,27 @@ describe('SIWE: mapToSIWX', () => {
expect(addSessionSpy).not.toBeCalled()
expect(signOutSpy).toBeCalled()
})

it('should only use the active network session', async () => {
const siwx = mapToSIWX(siweConfig)

const addSessionSpy = vi.spyOn(siwx, 'addSession')

const firstSessionMock = { ...sessionMock }
const secondSessionMock = {
...sessionMock,
data: { ...sessionMock.data, chainId: 'eip155:2' as const }
}

vi.spyOn(ChainController, 'getActiveCaipNetwork').mockReturnValue({
caipNetworkId: 'eip155:2'
} as any)

await expect(siwx.setSessions([firstSessionMock, secondSessionMock])).resolves.not.toThrow()

expect(addSessionSpy).not.toBeCalledWith(firstSessionMock)
expect(addSessionSpy).toBeCalledWith(secondSessionMock)
})
})

describe('getSessions', () => {
Expand Down Expand Up @@ -243,6 +264,24 @@ describe('SIWE: mapToSIWX', () => {

await expect(siwx.getSessions('eip155:1', 'mock-address')).resolves.toMatchObject([])
})

it('should accept undefined address or chain', async () => {
const siwx = mapToSIWX(siweConfig)

vi.spyOn(siweConfig.methods, 'getSession').mockResolvedValueOnce({
address: undefined as any,
chainId: 1
})

await expect(siwx.getSessions('eip155:1', 'mock-address')).resolves.toMatchObject([])

vi.spyOn(siweConfig.methods, 'getSession').mockResolvedValueOnce({
address: 'mock-address',
chainId: undefined as any
})

await expect(siwx.getSessions('eip155:1', 'mock-address')).resolves.toMatchObject([])
})
})

describe('siwe.options.signOutOnNetworkChange', () => {
Expand Down

0 comments on commit 60c6b2c

Please sign in to comment.