Skip to content

Commit

Permalink
fix: sync accounts in wagmi and subscribe to account change (#2544)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomiir authored Jul 17, 2024
1 parent 6f6eff1 commit f7f565c
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 12 deletions.
3 changes: 3 additions & 0 deletions apps/laboratory/tests/shared/pages/ModalPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,4 +317,7 @@ export class ModalPage {

await this.enterOTP(otp, headerTitle)
}
async openProfileView() {
await this.page.getByTestId('wui-profile-button').click()
}
}
3 changes: 0 additions & 3 deletions apps/laboratory/tests/shared/pages/ModalWalletPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ export class ModalWalletPage extends ModalPage {
super(page, library, flavor)
}

async openProfileView() {
await this.page.getByTestId('wui-profile-button').click()
}
async openSettings() {
await this.page.getByTestId('account-settings-button').click()
}
Expand Down
9 changes: 9 additions & 0 deletions apps/laboratory/tests/shared/validators/ModalValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,13 @@ export class ModalValidator {
const externalConnector = this.page.getByTestId(/^wallet-selector-external/u)
await expect(externalConnector).toBeVisible()
}

async expectMultipleAccounts() {
await expect(this.page.getByText('Switch Address')).toBeVisible({
timeout: MAX_WAIT
})
const accounts = await this.page.getByTestId('switch-address-item').all()

expect(accounts.length).toBeGreaterThan(1)
}
}
11 changes: 11 additions & 0 deletions apps/laboratory/tests/wallet.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,14 @@ testConnectedMW(
await processChain(0)
}
)

testConnectedMW('it should show multiple accounts', async ({ modalPage, modalValidator }) => {
// Multi address not available in solana wallet
if (modalPage.library === 'solana') {
return
}
await modalPage.openAccount()
await modalPage.openProfileView()
await modalValidator.expectMultipleAccounts()
await modalPage.closeModal()
})
2 changes: 1 addition & 1 deletion packages/scaffold-ui/src/views/w3m-profile-view/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export class W3mProfileView extends LitElement {
@click=${() => this.onSwitchAccount(account)}
>Switch</wui-button
>`}
</wui-list-account> `
</wui-list-account>`
}

private onCopyAddress() {
Expand Down
11 changes: 8 additions & 3 deletions packages/scaffold-ui/src/views/w3m-switch-address-view/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { UiHelperUtil, customElement } from '@web3modal/ui'
import { LitElement, html } from 'lit'
import { state } from 'lit/decorators.js'
import styles from './styles.js'
import { ifDefined } from 'lit/directives/if-defined.js'

@customElement('w3m-switch-address-view')
export class W3mSwitchAddressView extends LitElement {
Expand Down Expand Up @@ -67,8 +68,8 @@ export class W3mSwitchAddressView extends LitElement {
return html`
<wui-flex justifyContent="center" .padding=${['xl', '0', 'xl', '0'] as const}>
<wui-banner-img
imageSrc="${this.metadata?.icons[0]}"
text="${this.metadata?.url}"
imageSrc=${ifDefined(this.metadata?.icons[0])}
text=${ifDefined(this.metadata?.url)}
size="sm"
></wui-banner-img>
</wui-flex>
Expand All @@ -84,7 +85,11 @@ export class W3mSwitchAddressView extends LitElement {
const label = this.labels?.get(account.address)

return html`
<wui-flex flexDirection="row" justifyContent="space-between">
<wui-flex
flexDirection="row"
justifyContent="space-between"
data-testid="switch-address-item"
>
<wui-flex alignItems="center">
<wui-avatar address=${account.address}></wui-avatar>
${this.shouldShowIcon
Expand Down
51 changes: 46 additions & 5 deletions packages/wagmi/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ import {
writeContract as wagmiWriteContract,
getAccount,
getEnsAddress as wagmiGetEnsAddress,
reconnect
reconnect,
getConnections,
switchAccount
} from '@wagmi/core'
import { mainnet } from 'viem/chains'
import { prepareTransactionRequest, sendTransaction as wagmiSendTransaction } from '@wagmi/core'
Expand Down Expand Up @@ -377,6 +379,26 @@ export class Web3Modal extends Web3ModalScaffold {
})

this.setEIP6963Enabled(w3mOptions.enableEIP6963 !== false)

this.subscribeShouldUpdateToAddress((newAddress?: string) => {
if (newAddress) {
const connections = getConnections(this.wagmiConfig)
const connector = connections[0]?.connector
if (connector) {
switchAccount(this.wagmiConfig, {
connector
}).then(response =>
this.syncAccount({
address: newAddress as Hex,
isConnected: true,
addresses: response.accounts,
connector,
chainId: response.chainId
})
)
}
}
})
}

// -- Public ------------------------------------------------------------------
Expand Down Expand Up @@ -419,22 +441,33 @@ export class Web3Modal extends Web3ModalScaffold {
address,
isConnected,
chainId,
connector
}: Pick<GetAccountReturnType, 'address' | 'isConnected' | 'chainId' | 'connector'>) {
connector,
addresses
}: Partial<
Pick<GetAccountReturnType, 'address' | 'isConnected' | 'chainId' | 'connector' | 'addresses'>
>) {
this.resetAccount()
this.syncNetwork(address, chainId, isConnected)
const isAuthConnecor = connector?.id === ConstantsUtil.AUTH_CONNECTOR_ID
if (isConnected && address && chainId) {
const caipAddress: CaipAddress = `${ConstantsUtil.EIP155}:${chainId}:${address}`
this.setIsConnected(isConnected)
this.setCaipAddress(caipAddress)
await Promise.all([
this.syncProfile(address, chainId),
this.syncBalance(address, chainId),
this.syncConnectedWalletInfo(connector),
this.setApprovedCaipNetworksData()
])
if (connector) {
this.syncConnectedWalletInfo(connector)
}

// Set by authConnector.onIsConnectedHandler as we need the account type
if (!isAuthConnecor && addresses?.length) {
this.setAllAccounts(addresses.map(addr => ({ address: addr, type: 'eoa' })))
}

this.hasSyncedConnectedAccount = true
this.setAllAccounts([{ address, type: 'eoa' }])
} else if (!isConnected && this.hasSyncedConnectedAccount) {
this.resetWcConnection()
this.resetNetwork()
Expand Down Expand Up @@ -722,6 +755,14 @@ export class Web3Modal extends Web3ModalScaffold {
this.chain
)
super.setLoading(false)
this.setAllAccounts(
req.accounts || [
{
address: req.address,
type: (req.preferredAccountType || 'eoa') as W3mFrameTypes.AccountType
}
]
)
})

provider.onGetSmartAccountEnabledNetworks(networks => {
Expand Down

0 comments on commit f7f565c

Please sign in to comment.