Skip to content

Commit

Permalink
fix: Show unsupported network UI on reconnect when chainId in wallet …
Browse files Browse the repository at this point in the history
…is not supported (#3266)
  • Loading branch information
svenvoskamp authored Nov 19, 2024
1 parent e6f7742 commit 6557a06
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 9 deletions.
24 changes: 24 additions & 0 deletions .changeset/orange-crabs-learn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
'@reown/appkit-adapter-ethers5': patch
'@reown/appkit-adapter-ethers': patch
'@reown/appkit-adapter-wagmi': patch
'@reown/appkit': patch
'@apps/demo': patch
'@apps/gallery': patch
'@apps/laboratory': patch
'@reown/appkit-adapter-polkadot': patch
'@reown/appkit-adapter-solana': 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-siwe': patch
'@reown/appkit-siwx': patch
'@reown/appkit-ui': patch
'@reown/appkit-wallet': patch
---

Show unsupported network UI on reconnect when chainId in wallet is not supported
14 changes: 12 additions & 2 deletions packages/adapters/ethers/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,10 @@ export class EthersAdapter extends AdapterBlueprint {
method: 'eth_requestAccounts'
})

const requestChainId = await selectedProvider.request({
method: 'eth_chainId'
})

this.listenProviderEvents(selectedProvider)

if (!accounts[0]) {
Expand All @@ -238,7 +242,7 @@ export class EthersAdapter extends AdapterBlueprint {

return {
address: accounts[0],
chainId: Number(chainId),
chainId: Number(requestChainId) || Number(chainId),
provider: selectedProvider,
type: connector.type,
id
Expand Down Expand Up @@ -346,6 +350,8 @@ export class EthersAdapter extends AdapterBlueprint {

let accounts: string[] = []

let requestChainId: string | undefined = undefined

if (type === 'AUTH') {
const { address } = await (selectedProvider as unknown as W3mFrameProvider).connect({
chainId
Expand All @@ -357,12 +363,16 @@ export class EthersAdapter extends AdapterBlueprint {
method: 'eth_requestAccounts'
})

requestChainId = await selectedProvider.request({
method: 'eth_chainId'
})

this.listenProviderEvents(selectedProvider)
}

return {
address: accounts[0] as `0x${string}`,
chainId: Number(chainId),
chainId: Number(requestChainId) || Number(chainId),
provider: selectedProvider,
type: type as ConnectorType,
id
Expand Down
6 changes: 5 additions & 1 deletion packages/adapters/ethers/src/tests/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,11 @@ describe('EthersAdapter', () => {

describe('EthersAdapter -connect', () => {
it('should connect with external provider', async () => {
vi.mocked(mockProvider.request).mockResolvedValue(['0x123'])
vi.mocked(mockProvider.request).mockImplementation(request => {
if (request.method === 'eth_requestAccounts') return Promise.resolve(['0x123'])
if (request.method === 'eth_chainId') return Promise.resolve('0x1')
return Promise.resolve(null)
})
const connectors = [
{
id: 'test',
Expand Down
14 changes: 12 additions & 2 deletions packages/adapters/ethers5/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,10 @@ export class Ethers5Adapter extends AdapterBlueprint {
method: 'eth_requestAccounts'
})

const requestChainId = await selectedProvider.request({
method: 'eth_chainId'
})

this.listenProviderEvents(selectedProvider)

if (!accounts[0]) {
Expand All @@ -239,7 +243,7 @@ export class Ethers5Adapter extends AdapterBlueprint {

return {
address: accounts[0],
chainId: Number(chainId),
chainId: Number(requestChainId) || Number(chainId),
provider: selectedProvider,
type: connector.type,
id
Expand Down Expand Up @@ -347,6 +351,8 @@ export class Ethers5Adapter extends AdapterBlueprint {

let accounts: string[] = []

let requestChainId: string | undefined = undefined

if (type === 'AUTH') {
const { address } = await (selectedProvider as unknown as W3mFrameProvider).connect({
chainId
Expand All @@ -358,12 +364,16 @@ export class Ethers5Adapter extends AdapterBlueprint {
method: 'eth_requestAccounts'
})

requestChainId = await selectedProvider.request({
method: 'eth_chainId'
})

this.listenProviderEvents(selectedProvider)
}

return {
address: accounts[0] as `0x${string}`,
chainId: Number(chainId),
chainId: Number(requestChainId) || Number(chainId),
provider: selectedProvider,
type: type as ConnectorType,
id
Expand Down
6 changes: 5 additions & 1 deletion packages/adapters/ethers5/src/tests/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,11 @@ describe('Ethers5Adapter', () => {

describe('Ethers5Adapter -connect', () => {
it('should connect with external provider', async () => {
vi.mocked(mockProvider.request).mockResolvedValue(['0x123'])
vi.mocked(mockProvider.request).mockImplementation(request => {
if (request.method === 'eth_requestAccounts') return Promise.resolve(['0x123'])
if (request.method === 'eth_chainId') return Promise.resolve('0x1')
return Promise.resolve(null)
})
const connectors = [
{
id: 'test',
Expand Down
4 changes: 2 additions & 2 deletions packages/adapters/wagmi/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -350,14 +350,14 @@ export class WagmiAdapter extends AdapterBlueprint {
public async syncConnection(
params: AdapterBlueprint.SyncConnectionParams
): Promise<AdapterBlueprint.ConnectResult> {
const { id, chainId } = params
const { id } = params
const connections = getConnections(this.wagmiConfig)
const connection = connections.find(c => c.connector.id === id)
const connector = this.wagmiConfig.connectors.find(c => c.id === id)
const provider = (await connector?.getProvider()) as Provider

return {
chainId: Number(chainId),
chainId: Number(connection?.chainId),
address: connection?.accounts[0] as string,
provider,
type: connection?.connector.type as ConnectorType,
Expand Down
8 changes: 8 additions & 0 deletions packages/appkit/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -770,6 +770,10 @@ export class AppKit {
chainNamespace: chain || (ChainController.state.activeChain as ChainNamespace)
})
}

if (!this.caipNetworks?.some(network => network.id === res?.chainId)) {
ChainController.showUnsupportedChainUI()
}
},
reconnectExternal: async ({ id, info, type, provider }) => {
const adapter = this.getAdapter(ChainController.state.activeChain as ChainNamespace)
Expand Down Expand Up @@ -1527,6 +1531,10 @@ export class AppKit {
this.syncProvider({ ...res, chainNamespace: connectedNamespace as ChainNamespace })
await this.syncAccount({ ...res, chainNamespace: connectedNamespace as ChainNamespace })
}

if (!this.caipNetworks?.some(network => network.id === res?.chainId)) {
ChainController.showUnsupportedChainUI()
}
}
}

Expand Down
44 changes: 43 additions & 1 deletion packages/appkit/src/tests/appkit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import {
AssetUtil,
ConnectorController,
ChainController,
type Connector
type Connector,
StorageUtil
} from '@reown/appkit-core'
import {
SafeLocalStorage,
Expand Down Expand Up @@ -524,6 +525,47 @@ describe('Base', () => {

expect(AccountController.setStatus).toHaveBeenCalledWith('disconnected', 'eip155')
})

it('should show unsupported chain UI when synced chainId is not supported', async () => {
vi.mocked(ChainController).state = {
chains: new Map([['eip155', { namespace: 'eip155' }]]),
activeChain: 'eip155'
} as any
;(appKit as any).caipNetworks = [{ id: 'eip155:1', chainNamespace: 'eip155' }]

const mockAdapter = {
syncConnection: vi.fn().mockResolvedValue({
chainId: 'eip155:999', // Unsupported chain
address: '0x123'
}),
getBalance: vi.fn().mockResolvedValue({ balance: '0', symbol: 'ETH' }),
getProfile: vi.fn().mockResolvedValue({}),
on: vi.fn(),
off: vi.fn(),
emit: vi.fn()
}

vi.spyOn(appKit as any, 'getAdapter').mockReturnValue(mockAdapter)

vi.spyOn(StorageUtil, 'setConnectedConnector').mockImplementation(vi.fn())
vi.spyOn(StorageUtil, 'setConnectedNamespace').mockImplementation(vi.fn())

vi.spyOn(SafeLocalStorage, 'getItem').mockImplementation((key: string) => {
if (key === SafeLocalStorageKeys.CONNECTED_CONNECTOR) {
return 'test-wallet'
}
if (key === SafeLocalStorageKeys.CONNECTED_NAMESPACE) {
return 'eip155'
}
return undefined
})

vi.mocked(ChainController.showUnsupportedChainUI).mockImplementation(vi.fn())

await (appKit as any).syncExistingConnection()

expect(ChainController.showUnsupportedChainUI).toHaveBeenCalled()
})
})
describe('Base Initialization', () => {
let appKit: AppKit
Expand Down

0 comments on commit 6557a06

Please sign in to comment.