Skip to content
Merged
7 changes: 7 additions & 0 deletions .changeset/eager-carpets-obey.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@reown/appkit-controllers': patch
'@reown/appkit-scaffold-ui': patch
'@reown/appkit': patch
---

Fixes issue causing infinite loading after switching from solana to evm using embedded wallet SIWX default
2 changes: 2 additions & 0 deletions apps/laboratory/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"playwright:install-deps": "pnpm playwright install-deps",
"synpress": "synpress ./tests/wallet-setup",
"playwright:test": "HEADLESS=true playwright test",
"playwright:test:siwx-email": "playwright test --grep 'siwx-email.spec.ts'",
"playwright:test:mobile-wallet-features": "playwright test --grep 'mobile-wallet-features.spec.ts'",
"playwright:test:basic": "playwright test --grep 'basic-tests.spec.ts'",
"playwright:test:flag-enable-reconnect": "HEADLESS=true playwright test --grep 'flag-enable-reconnect.spec.ts'",
Expand Down Expand Up @@ -61,6 +62,7 @@
"playwright:test:core": "playwright test --grep core.spec.ts",
"playwright:debug:core": "pnpm playwright:test:core --debug",
"playwright:test:core-universal-provider": "playwright test --grep universal-provider.spec.ts",
"playwright:debug:siwx-email": "pnpm playwright:test:siwx-email --debug",
"playwright:debug:core-universal-provider": "pnpm playwright:test:core-universal-provider --debug",
"playwright:debug": "pnpm playwright:test --debug",
"playwright:debug:mobile-wallet-features": "pnpm playwright:test:mobile-wallet-features --debug",
Expand Down
6 changes: 4 additions & 2 deletions apps/laboratory/tests/shared/pages/ModalWalletPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import { setupNetworkListener } from '@/src/utils/NetworkUtil'

import { ModalPage } from './ModalPage'

type ModalWalletFlavor = 'default' | 'all' | 'siwe' | 'siwx'

export class ModalWalletPage extends ModalPage {
public override readonly page: Page
public override readonly library: string
public override readonly flavor: 'default' | 'all' | 'siwe'
public override readonly flavor: ModalWalletFlavor

constructor(page: Page, library: string, flavor: 'default' | 'all' | 'siwe') {
constructor(page: Page, library: string, flavor: ModalWalletFlavor) {
super(page, library, flavor)
setupNetworkListener(page)
this.page = page
Expand Down
99 changes: 99 additions & 0 deletions apps/laboratory/tests/siwx-email.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { timingFixture } from './shared/fixtures/timing-fixture'
import { ModalWalletPage } from './shared/pages/ModalWalletPage'
import { Email } from './shared/utils/email'
import { getTestnet2ByLibrary, getTestnetByLibrary } from './shared/utils/namespace'
import { ModalValidator } from './shared/validators/ModalValidator'

/* eslint-disable init-declarations */
let modalPage: ModalWalletPage
let modalValidator: ModalValidator

const targetLibraries = ['ethers', 'solana']

// -- Setup --------------------------------------------------------------------
const siwxEmailTest = timingFixture.extend<{ library: string }>({
library: ['ethers', { option: true }]
})

siwxEmailTest.describe.configure({ mode: 'serial' })

siwxEmailTest.beforeAll(async ({ library, browser }) => {
if (!targetLibraries.includes(library)) {
return
}
const context = await browser.newContext()
const browserPage = await context.newPage()

modalPage = new ModalWalletPage(browserPage, library, 'siwx')
modalValidator = new ModalValidator(browserPage)

await modalPage.load()

siwxEmailTest.setTimeout(300000)

const mailsacApiKey = process.env['MAILSAC_API_KEY']
if (!mailsacApiKey) {
throw new Error('MAILSAC_API_KEY is not set')
}
const email = new Email(mailsacApiKey)

const emailAddress = await email.getEmailAddressToUse()
await modalPage.emailFlow({
emailAddress,
context,
mailsacApiKey
})

// Should do 1CA, so no need to approve prompt siwe
await modalValidator.expectConnected()
})

siwxEmailTest(
'it should require request signature when switching networks',
async ({ library }) => {
if (!targetLibraries.includes(library)) {
return
}
const network = getTestnetByLibrary(library)

await modalPage.switchNetwork(network)
await modalPage.promptSiwe()
await modalPage.approveSign()
await modalValidator.expectConnected()
}
)

siwxEmailTest(
'it should fallback to the last session when cancel siwe from AppKit',
async ({ library }) => {
if (!targetLibraries.includes(library)) {
return
}
const newNetwork = getTestnet2ByLibrary(library)
const prevNetwork = getTestnetByLibrary(library)

await modalPage.switchNetwork(newNetwork)
await modalPage.cancelSiwe()
await modalValidator.expectNetworkButton(prevNetwork)
await modalValidator.expectConnected()
}
)

siwxEmailTest(
'it should be connected after connecting and refreshing the page',
async ({ library }) => {
if (!targetLibraries.includes(library)) {
return
}
await modalPage.page.reload()
await modalValidator.expectConnected()
}
)

siwxEmailTest('it should disconnect', async ({ library }) => {
if (!targetLibraries.includes(library)) {
return
}
await modalPage.disconnectWithHook()
await modalValidator.expectDisconnected()
})
2 changes: 1 addition & 1 deletion packages/appkit/exports/constants.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const PACKAGE_VERSION = '1.7.13'
export const PACKAGE_VERSION = '1.7.15'
6 changes: 3 additions & 3 deletions packages/controllers/src/controllers/ChainController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -600,15 +600,15 @@ const controller = {
})
},

checkIfSupportedNetwork(namespace: ChainNamespace, caipNetwork?: CaipNetwork) {
const activeCaipNetwork = caipNetwork || state.activeCaipNetwork
checkIfSupportedNetwork(namespace: ChainNamespace, caipNetworkId?: CaipNetworkId) {
const activeCaipNetworkId = caipNetworkId || state.activeCaipNetwork?.caipNetworkId
const requestedCaipNetworks = ChainController.getRequestedCaipNetworks(namespace)

if (!requestedCaipNetworks.length) {
return true
}

return requestedCaipNetworks?.some(network => network.id === activeCaipNetwork?.id)
return requestedCaipNetworks?.some(network => network.caipNetworkId === activeCaipNetworkId)
},

checkIfSupportedChainId(chainId: number | string) {
Expand Down
9 changes: 5 additions & 4 deletions packages/controllers/src/utils/SIWXUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,15 @@ export const SIWXUtil = {
return OptionsController.state.siwx
},

async initializeIfEnabled() {
async initializeIfEnabled(caipAddress = ChainController.getActiveCaipAddress()) {
const siwx = OptionsController.state.siwx
const caipAddress = ChainController.getActiveCaipAddress()

if (!(siwx && caipAddress)) {
return
}
const [namespace, chainId, address] = caipAddress.split(':') as [ChainNamespace, string, string]

if (!ChainController.checkIfSupportedNetwork(namespace)) {
if (!ChainController.checkIfSupportedNetwork(namespace, `${namespace}:${chainId}`)) {
return
}

Expand Down Expand Up @@ -260,8 +259,10 @@ export const SIWXUtil = {
}
}

const caipNetwork = `${chainNamespace}:${chainId}` as CaipNetworkId

const siwxMessage = await siwx.createMessage({
chainId: ChainController.getActiveCaipNetwork()?.caipNetworkId || ('' as CaipNetworkId),
chainId: caipNetwork,
accountAddress: '<<AccountAddress>>'
})

Expand Down
5 changes: 4 additions & 1 deletion packages/scaffold-ui/src/modal/w3m-account-button/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,10 @@ class W3mAccountButtonBase extends LitElement {
'networkState',
val => {
this.setNetworkData(val)
this.isSupported = ChainController.checkIfSupportedNetwork(namespace, val?.caipNetwork)
this.isSupported = ChainController.checkIfSupportedNetwork(
namespace,
val?.caipNetwork?.caipNetworkId
)
},
namespace
)
Expand Down
2 changes: 1 addition & 1 deletion packages/scaffold-ui/src/modal/w3m-modal/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ export class W3mModalBase extends LitElement {
ModalController.close()
}

await SIWXUtil.initializeIfEnabled()
await SIWXUtil.initializeIfEnabled(caipAddress)
this.caipAddress = caipAddress
ChainController.setIsSwitchingNamespace(false)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,14 @@ export class W3mNetworkSwitchView extends LitElement {
}
}

private onSwitchNetwork() {
private async onSwitchNetwork() {
try {
this.error = false
if (ChainController.state.activeChain !== this.network?.chainNamespace) {
ChainController.setIsSwitchingNamespace(true)
}
if (this.network) {
ChainController.switchActiveNetwork(this.network)
await ChainController.switchActiveNetwork(this.network)
}
} catch (error) {
this.error = true
Expand Down
Loading