Skip to content

Commit

Permalink
fix: Wagmi Switch To (#2679)
Browse files Browse the repository at this point in the history
Co-authored-by: Enes <enesozturk.d@gmail.com>
  • Loading branch information
tomiir and enesozturk authored Aug 9, 2024
1 parent cb83cd8 commit a6e707e
Show file tree
Hide file tree
Showing 9 changed files with 1,610 additions and 1,088 deletions.
27 changes: 27 additions & 0 deletions apps/laboratory/tests/shared/pages/ModalPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -394,4 +394,31 @@ export class ModalPage {
await networkToSwitchButton.click()
await networkToSwitchButton.waitFor({ state: 'hidden' })
}

async switchAccount() {
const switchAccountButton1 = this.page.getByTestId('w3m-switch-address-button-1')
await expect(switchAccountButton1).toBeVisible()
await switchAccountButton1.click()
}

async getAddress(): Promise<`0x${string}`> {
const address = await this.page.getByTestId('w3m-address').textContent()
expect(address, 'Address should be present').toBeTruthy()

return address as `0x${string}`
}

async getChainId(): Promise<number> {
const chainId = await this.page.getByTestId('w3m-chain-id').textContent()
expect(chainId, 'Chain ID should be present').toBeTruthy()

return Number(chainId)
}

async getSignature(): Promise<`0x${string}`> {
const signature = await this.page.getByTestId('w3m-signature').textContent()
expect(signature, 'Signature should be present').toBeTruthy()

return signature as `0x${string}`
}
}
21 changes: 0 additions & 21 deletions apps/laboratory/tests/shared/pages/ModalWalletPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,25 +47,4 @@ export class ModalWalletPage extends ModalPage {
await disconnectBtn.click()
await this.page.getByTestId('connect-button').waitFor({ state: 'visible', timeout: 5000 })
}

async getAddress(): Promise<`0x${string}`> {
const address = await this.page.getByTestId('w3m-address').textContent()
expect(address, 'Address should be present').toBeTruthy()

return address as `0x${string}`
}

async getChainId(): Promise<number> {
const chainId = await this.page.getByTestId('w3m-chain-id').textContent()
expect(chainId, 'Chain ID should be present').toBeTruthy()

return Number(chainId)
}

async getSignature(): Promise<`0x${string}`> {
const signature = await this.page.getByTestId('w3m-signature').textContent()
expect(signature, 'Signature should be present').toBeTruthy()

return signature as `0x${string}`
}
}
5 changes: 5 additions & 0 deletions apps/laboratory/tests/shared/validators/ModalValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,4 +176,9 @@ export class ModalValidator {
const connectButton = this.page.getByTestId('connect-button')
await expect(connectButton).toContainText('Connecting...')
}

async expectAccountSwitched(oldAddress: string) {
const address = this.page.getByTestId('w3m-address')
await expect(address).not.toHaveText(oldAddress)
}
}
32 changes: 21 additions & 11 deletions apps/laboratory/tests/wallet.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,16 @@ sampleWalletTest.afterAll(async () => {
})

// -- Tests --------------------------------------------------------------------
sampleWalletTest.only(
'it should show testnet and devnet disabled on solana',
async ({ library }) => {
if (library !== 'solana') {
return
}

await modalPage.openModal()
await modalPage.openNetworks()
await modalValidator.expectNetworksDisabled('Solana Testnet')
sampleWalletTest('it should show testnet and devnet disabled on solana', async ({ library }) => {
if (library !== 'solana') {
return
}
)

await modalPage.openModal()
await modalPage.openNetworks()
await modalValidator.expectNetworksDisabled('Solana Testnet')
await modalPage.closeModal()
})

sampleWalletTest('it should switch networks and sign', async ({ library }) => {
if (library === 'solana') {
Expand Down Expand Up @@ -104,6 +102,18 @@ sampleWalletTest('it should show multiple accounts', async ({ library }) => {
await modalPage.closeModal()
})

sampleWalletTest('it should switch between multiple accounts', async ({ library }) => {
// Multi address not available in Solana wallet and wagmi does not allow programatic account switching
if (library === 'solana' || library === 'wagmi') {
return
}
const originalAddress = await modalPage.getAddress()
await modalPage.openAccount()
await modalPage.openProfileView()
await modalPage.switchAccount()
await modalValidator.expectAccountSwitched(originalAddress)
})

sampleWalletTest(
'it should show Switch Network modal if network is not supported',
async ({ library }) => {
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@
"typescript": "5.3.3",
"vite": "5.2.11",
"vitest": "2.0.3",
"vite-plugin-node-polyfills": "0.22.0"
"vite-plugin-node-polyfills": "0.22.0",
"pino": "7.11.0"
},
"packageManager": "pnpm@9.5.0",
"pnpm": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@ export class W3mSwitchAddressView extends LitElement {
></wui-banner-img>
</wui-flex>
<wui-flex flexDirection="column" gap="xxl" .padding=${['l', 'xl', 'xl', 'xl'] as const}>
${this.allAccounts.map(account => this.getAddressTemplate(account))}
${this.allAccounts.map((account, index) => this.getAddressTemplate(account, index))}
</wui-flex>
`
}

// -- Private ------------------------------------------- //

private getAddressTemplate(account: AccountType) {
private getAddressTemplate(account: AccountType, index: number) {
const label = this.labels?.get(account.address)

return html`
Expand Down Expand Up @@ -125,6 +125,7 @@ export class W3mSwitchAddressView extends LitElement {
? ''
: html`
<wui-button
data-testid=${`w3m-switch-address-button-${index}`}
textVariant="small-600"
size="md"
variant="accent"
Expand Down
13 changes: 11 additions & 2 deletions packages/wagmi/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ import type { Chain as AvailableChain } from '@web3modal/common'
import {
getCaipDefaultChain,
getEmailCaipNetworks,
getWalletConnectCaipNetworks
getWalletConnectCaipNetworks,
requireCaipAddress
} from './utils/helpers.js'
import { W3mFrameHelpers, W3mFrameRpcConstants } from '@web3modal/wallet'
import type { W3mFrameProvider, W3mFrameTypes } from '@web3modal/wallet'
Expand Down Expand Up @@ -266,7 +267,12 @@ export class Web3Modal extends Web3ModalScaffold {
}
},

signMessage: async message => signMessage(this.wagmiConfig, { message }),
signMessage: async message => {
const caipAddress = this.getCaipAddress() || ''
const account = requireCaipAddress(caipAddress)

return signMessage(this.wagmiConfig, { message, account })
},

estimateGas: async args => {
try {
Expand Down Expand Up @@ -304,11 +310,14 @@ export class Web3Modal extends Web3ModalScaffold {
},

writeContract: async (data: WriteContractArgs) => {
const caipAddress = this.getCaipAddress() || ''
const account = requireCaipAddress(caipAddress)
const chainId = NetworkUtil.caipNetworkIdToNumber(this.getCaipNetwork()?.id)

const tx = await wagmiWriteContract(wagmiConfig, {
chainId,
address: data.tokenAddress,
account,
abi: data.abi,
functionName: data.method,
args: [data.receiverAddress, data.tokenAmount]
Expand Down
14 changes: 13 additions & 1 deletion packages/wagmi/src/utils/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { CoreHelperUtil } from '@web3modal/scaffold'
import { ConstantsUtil, PresetsUtil } from '@web3modal/scaffold-utils'
import { EthereumProvider } from '@walletconnect/ethereum-provider'
import { getChainsFromAccounts } from '@walletconnect/utils'
import { fallback, http } from 'viem'
import { fallback, http, type Hex } from 'viem'

import type { CaipNetwork, CaipNetworkId } from '@web3modal/scaffold'
import type { Chain } from '@wagmi/core/chains'
Expand Down Expand Up @@ -71,3 +71,15 @@ export function getTransport({ chain, projectId }: { chain: Chain; projectId: st
http(chainDefaultUrl)
])
}

export function requireCaipAddress(caipAddress: string) {
if (!caipAddress) {
throw new Error('No CAIP address provided')
}
const account = caipAddress.split(':')[2] as Hex
if (!account) {
throw new Error('Invalid CAIP address')
}

return account
}
Loading

0 comments on commit a6e707e

Please sign in to comment.