diff --git a/apps/laboratory/tests/shared/pages/WalletPage.ts b/apps/laboratory/tests/shared/pages/WalletPage.ts index 7027c09159..27123d84e6 100644 --- a/apps/laboratory/tests/shared/pages/WalletPage.ts +++ b/apps/laboratory/tests/shared/pages/WalletPage.ts @@ -9,6 +9,8 @@ export class WalletPage { private gotoHome: Locator private vercelPreview: Locator + public connectToSingleAccount = false + constructor(public page: Page) { this.gotoHome = this.page.getByTestId('wc-connect') this.vercelPreview = this.page.locator('css=vercel-live-feedback') @@ -33,7 +35,15 @@ export class WalletPage { if (isVercelPreview) { await this.vercelPreview.evaluate((iframe: HTMLIFrameElement) => iframe.remove()) } - await this.gotoHome.click() + /* + * If connecting to a single account manually navigate. + * Otherwise click the home button. + */ + if (this.connectToSingleAccount) { + await this.page.goto(`${this.baseURL}/walletconnect?addressesToApprove=1`) + } else { + await this.gotoHome.click() + } const input = this.page.getByTestId('uri-input') await input.waitFor({ state: 'visible', @@ -113,4 +123,12 @@ export class WalletPage { const disconnectButton = this.page.getByText('Delete') await disconnectButton.click() } + + /** + * Sets a flag to indicate whether to connect to a single account + * @param connectToSingleAccount boolean flag to set + */ + setConnectToSingleAccount(connectToSingleAccount: boolean) { + this.connectToSingleAccount = connectToSingleAccount + } } diff --git a/apps/laboratory/tests/shared/validators/ModalValidator.ts b/apps/laboratory/tests/shared/validators/ModalValidator.ts index 34a128a249..49e2a9b88d 100644 --- a/apps/laboratory/tests/shared/validators/ModalValidator.ts +++ b/apps/laboratory/tests/shared/validators/ModalValidator.ts @@ -61,6 +61,15 @@ export class ModalValidator { }) } + async expectSingleAccount() { + await expect( + this.page.getByTestId('single-account-avatar'), + 'Single account widget should be present' + ).toBeVisible({ + timeout: MAX_WAIT + }) + } + async expectConnectScreen() { await expect(this.page.getByText('Connect Wallet')).toBeVisible({ timeout: MAX_WAIT diff --git a/apps/laboratory/tests/wallet.spec.ts b/apps/laboratory/tests/wallet.spec.ts index 7148ad5c05..dd98cb135a 100644 --- a/apps/laboratory/tests/wallet.spec.ts +++ b/apps/laboratory/tests/wallet.spec.ts @@ -135,6 +135,21 @@ sampleWalletTest('it should show multiple accounts', async ({ library }) => { await modalPage.closeModal() }) +sampleWalletTest('it should disconnect and connect to a single account', async ({ library }) => { + if (library === 'solana') { + return + } + + await walletPage.disconnectConnection() + await modalValidator.expectDisconnected() + walletPage.setConnectToSingleAccount(true) + await modalPage.qrCodeFlow(modalPage, walletPage) + await modalPage.openAccount() + await modalValidator.expectSingleAccount() + walletPage.setConnectToSingleAccount(false) + await modalPage.closeModal() +}) + sampleWalletTest( 'it should show switch network modal if network is not supported', async ({ library }) => { @@ -142,6 +157,9 @@ sampleWalletTest( return } + await walletPage.disconnectConnection() + await modalValidator.expectDisconnected() + await modalPage.qrCodeFlow(modalPage, walletPage) await walletPage.enableTestnets() await walletPage.switchNetwork('eip155:5') await modalValidator.expectNetworkNotSupportedVisible() diff --git a/packages/scaffold-ui/src/partials/w3m-account-default-widget/index.ts b/packages/scaffold-ui/src/partials/w3m-account-default-widget/index.ts index c5144f506c..b17f8e02a0 100644 --- a/packages/scaffold-ui/src/partials/w3m-account-default-widget/index.ts +++ b/packages/scaffold-ui/src/partials/w3m-account-default-widget/index.ts @@ -10,7 +10,8 @@ import { SnackController, ConstantsUtil as CommonConstantsUtil, OptionsController, - ChainController + ChainController, + type AccountType } from '@reown/appkit-core' import { customElement, UiHelperUtil } from '@reown/appkit-ui' import { LitElement, html } from 'lit' @@ -33,6 +34,8 @@ export class W3mAccountDefaultWidget extends LitElement { @state() public address = CoreHelperUtil.getPlainAddress(AccountController.state.caipAddress) + @state() public allAccounts: AccountType[] = AccountController.state.allAccounts + @state() private profileImage = AccountController.state.profileImage @state() private profileName = AccountController.state.profileName @@ -57,7 +60,10 @@ export class W3mAccountDefaultWidget extends LitElement { AccountController.subscribeKey('balanceSymbol', val => (this.balanceSymbol = val)), AccountController.subscribeKey('profileName', val => (this.profileName = val)), AccountController.subscribeKey('profileImage', val => (this.profileImage = val)), - OptionsController.subscribeKey('features', val => (this.features = val)) + OptionsController.subscribeKey('features', val => (this.features = val)), + AccountController.subscribeKey('allAccounts', allAccounts => { + this.allAccounts = allAccounts + }) ] ) } @@ -72,15 +78,16 @@ export class W3mAccountDefaultWidget extends LitElement { throw new Error('w3m-account-view: No account provided') } + const shouldShowMultiAccount = + ChainController.state.activeChain === ConstantsUtil.CHAIN.EVM && this.allAccounts.length > 1 + return html` - ${ChainController.state.activeChain === ConstantsUtil.CHAIN.EVM - ? this.multiAccountTemplate() - : this.singleAccountTemplate()} + ${shouldShowMultiAccount ? this.multiAccountTemplate() : this.singleAccountTemplate()} ${CoreHelperUtil.formatBalance(this.balance, this.balanceSymbol)} @@ -216,6 +223,7 @@ export class W3mAccountDefaultWidget extends LitElement { alt=${ifDefined(this.caipAddress)} address=${ifDefined(CoreHelperUtil.getPlainAddress(this.caipAddress))} imageSrc=${ifDefined(this.profileImage === null ? undefined : this.profileImage)} + data-testid="single-account-avatar" > @@ -249,7 +257,7 @@ export class W3mAccountDefaultWidget extends LitElement { throw new Error('w3m-account-view: No account provided') } - const account = AccountController.state.allAccounts?.find(acc => acc.address === this.address) + const account = this.allAccounts.find(acc => acc.address === this.address) const label = AccountController.state.addressLabels.get(this.address) return html`