Skip to content

Commit 43ee901

Browse files
authored
Merge branch 'main' into fix/ethers-swaps
2 parents fbfea16 + dc8544d commit 43ee901

File tree

17 files changed

+985
-915
lines changed

17 files changed

+985
-915
lines changed

.changeset/selfish-cows-shave.md

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
'@reown/appkit-scaffold-ui': patch
3+
'@reown/appkit': patch
4+
'@reown/appkit-core': patch
5+
'@reown/appkit-adapter-bitcoin': patch
6+
'@reown/appkit-adapter-ethers': patch
7+
'@reown/appkit-adapter-ethers5': patch
8+
'@reown/appkit-adapter-solana': patch
9+
'@reown/appkit-adapter-wagmi': patch
10+
'@reown/appkit-utils': patch
11+
'@reown/appkit-cdn': patch
12+
'@reown/appkit-cli': patch
13+
'@reown/appkit-common': patch
14+
'@reown/appkit-experimental': patch
15+
'@reown/appkit-polyfills': patch
16+
'@reown/appkit-siwe': patch
17+
'@reown/appkit-siwx': patch
18+
'@reown/appkit-ui': patch
19+
'@reown/appkit-wallet': patch
20+
'@reown/appkit-wallet-button': patch
21+
---
22+
23+
Adds `enableNetworkSwitcher` prop to allow disabling of network switching in the modal

apps/laboratory/tests/email.spec.ts

+10-4
Original file line numberDiff line numberDiff line change
@@ -121,21 +121,24 @@ emailTest('it should show names feature only for EVM networks', async ({ library
121121

122122
emailTest('it should show loading on page refresh', async () => {
123123
await page.page.reload()
124-
await validator.expectConnectButtonLoading()
124+
// Await validator.expectConnectButtonLoading()
125125
await validator.expectAccountButtonReady()
126126
})
127127

128128
emailTest('it should show snackbar error if failed to fetch token balance', async () => {
129129
// Clear cache and set offline to simulate token balance fetch failure
130130
await page.page.evaluate(() => window.localStorage.removeItem('@appkit/portfolio_cache'))
131-
await context.setOffline(true)
131+
await context.route('**/*', route => {
132+
route.abort()
133+
})
132134
await page.openAccount()
133135
await validator.expectSnackbar('Token Balance Unavailable')
136+
await context.unroute('**/*')
134137
await page.closeModal()
135138
})
136139

137140
emailTest('it should disconnect correctly', async ({ library }) => {
138-
await context.setOffline(false)
141+
await page.page.reload()
139142
if (library === 'solana') {
140143
await page.openAccount()
141144
await page.openProfileView()
@@ -147,8 +150,11 @@ emailTest('it should disconnect correctly', async ({ library }) => {
147150
})
148151

149152
emailTest('it should abort request if it takes more than 30 seconds', async () => {
150-
await context.setOffline(true)
153+
await context.route('**/*', route => {
154+
route.abort()
155+
})
151156
await page.loginWithEmail(tempEmail, false)
152157
await page.page.waitForTimeout(30_000)
153158
await validator.expectSnackbar('Something went wrong')
159+
await context.unroute('**/*')
154160
})

apps/laboratory/tests/smart-account.spec.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,16 @@ smartAccountTest(
8686
await page.switchNetwork(targetChain)
8787
await validator.expectSwitchedNetwork(targetChain)
8888
await page.closeModal()
89-
9089
await page.openAccount()
9190
await page.openProfileView()
9291
await validator.expectTogglePreferredTypeVisible(false)
9392
await page.closeModal()
9493

94+
//Requesting a sign immediately after login or after switch network causes a 'user rejected' error from embedded wallet so a small delay is needed
95+
await new Promise<void>(resolve => {
96+
setTimeout(resolve, 1000)
97+
})
98+
9599
await page.sign(namespace)
96100
await page.approveSign()
97101
await validator.expectAcceptedSign()
@@ -112,6 +116,10 @@ smartAccountTest('it should switch to smart account and sign', async ({ library
112116
await page.closeModal()
113117
await validator.expectAccountButtonReady()
114118

119+
// Requesting a sign immediately after login or after switch network causes a 'user rejected' error from embedded wallet so a small delay is needed
120+
await new Promise<void>(resolve => {
121+
setTimeout(resolve, 1000)
122+
})
115123
await page.sign(namespace)
116124
await page.approveSign()
117125
await validator.expectAcceptedSign()

packages/adapters/wagmi/src/client.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,8 @@ export class WagmiAdapter extends AdapterBlueprint {
331331
gasPrice: params.gasPrice as bigint,
332332
data: params.data as Hex,
333333
chainId,
334-
type: 'legacy' as const
334+
type: 'legacy' as const,
335+
parameters: ['nonce'] as const
335336
}
336337

337338
await prepareTransactionRequest(this.wagmiConfig, txParams)

packages/appkit/src/client/appkit-base-client.ts

+3
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,8 @@ export abstract class AppKitBaseClient {
198198
OptionsController.setEnableWalletGuide(options.enableWalletGuide !== false)
199199
OptionsController.setEnableWallets(options.enableWallets !== false)
200200
OptionsController.setEIP6963Enabled(options.enableEIP6963 !== false)
201+
OptionsController.setEnableNetworkSwitch(options.enableNetworkSwitch !== false)
202+
201203
OptionsController.setEnableAuthLogger(options.enableAuthLogger !== false)
202204
OptionsController.setCustomRpcUrls(options.customRpcUrls)
203205
OptionsController.setSdkVersion(options.sdkVersion)
@@ -970,6 +972,7 @@ export abstract class AppKitBaseClient {
970972
if (network?.chainNamespace === ChainController.state.activeChain) {
971973
// If the network is unsupported and the user doesn't allow unsupported chains, we show the unsupported chain UI
972974
if (
975+
OptionsController.state.enableNetworkSwitch &&
973976
!OptionsController.state.allowUnsupportedChain &&
974977
ChainController.state.activeCaipNetwork?.name === ConstantsUtil.UNSUPPORTED_NETWORK_NAME
975978
) {

packages/appkit/tests/client/public-methods.test.ts

+67-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import type UniversalProvider from '@walletconnect/universal-provider'
22
import { beforeEach, describe, expect, it, vi } from 'vitest'
33

4-
import type { AuthConnector, Connector, SocialProvider } from '@reown/appkit'
4+
import type { AdapterNetworkState, AuthConnector, Connector, SocialProvider } from '@reown/appkit'
55
import {
66
type Balance,
77
type CaipNetwork,
8+
ConstantsUtil,
89
SafeLocalStorage,
910
SafeLocalStorageKeys,
1011
getSafeConnectorIdKey
@@ -1048,4 +1049,69 @@ describe('Base Public methods', () => {
10481049
}
10491050
})
10501051
})
1052+
1053+
it('should handle network switcher UI when enableNetworkSwitch is true', async () => {
1054+
vi.spyOn(ChainController, 'getNetworkData').mockReturnValue(
1055+
mainnet as unknown as AdapterNetworkState
1056+
)
1057+
vi.spyOn(ChainController, 'getCaipNetworkByNamespace').mockReturnValue(mainnet)
1058+
vi.spyOn(ChainController, 'getNetworkProp').mockReturnValue(true)
1059+
vi.spyOn(ChainController, 'state', 'get').mockReturnValue({
1060+
...ChainController.state,
1061+
activeCaipNetwork: {
1062+
...mainnet,
1063+
name: ConstantsUtil.UNSUPPORTED_NETWORK_NAME
1064+
},
1065+
activeChain: 'eip155'
1066+
})
1067+
vi.spyOn(OptionsController, 'state', 'get').mockReturnValue({
1068+
...OptionsController.state,
1069+
allowUnsupportedChain: false,
1070+
enableNetworkSwitch: true
1071+
})
1072+
1073+
const showUnsupportedChainUI = vi.spyOn(ChainController, 'showUnsupportedChainUI')
1074+
const setActiveCaipNetwork = vi.spyOn(ChainController, 'setActiveCaipNetwork')
1075+
1076+
const appKit = new AppKit(mockOptions)
1077+
await appKit['syncAccount']({
1078+
address: '0x123',
1079+
chainId: mainnet.id,
1080+
chainNamespace: mainnet.chainNamespace
1081+
})
1082+
1083+
expect(showUnsupportedChainUI).toHaveBeenCalled()
1084+
expect(setActiveCaipNetwork).toHaveBeenCalledWith(mainnet)
1085+
})
1086+
1087+
it('should handle network switcher UI when enableNetworkSwitch is false', async () => {
1088+
vi.spyOn(ChainController, 'getNetworkData').mockReturnValue(
1089+
mainnet as unknown as AdapterNetworkState
1090+
)
1091+
vi.spyOn(ChainController, 'getCaipNetworkByNamespace').mockReturnValue(mainnet)
1092+
vi.spyOn(ChainController, 'getNetworkProp').mockReturnValue(true)
1093+
vi.spyOn(ChainController, 'state', 'get').mockReturnValue({
1094+
...ChainController.state,
1095+
activeCaipNetwork: mainnet,
1096+
activeChain: 'eip155'
1097+
})
1098+
vi.spyOn(OptionsController, 'state', 'get').mockReturnValue({
1099+
...OptionsController.state,
1100+
allowUnsupportedChain: false,
1101+
enableNetworkSwitch: false
1102+
})
1103+
1104+
const showUnsupportedChainUI = vi.spyOn(ChainController, 'showUnsupportedChainUI')
1105+
const setActiveCaipNetwork = vi.spyOn(ChainController, 'setActiveCaipNetwork')
1106+
1107+
const appKit = new AppKit(mockOptions)
1108+
await appKit['syncAccount']({
1109+
address: '0x123',
1110+
chainId: mainnet.id,
1111+
chainNamespace: mainnet.chainNamespace
1112+
})
1113+
1114+
expect(showUnsupportedChainUI).not.toHaveBeenCalled()
1115+
expect(setActiveCaipNetwork).toHaveBeenCalledWith(mainnet)
1116+
})
10511117
})

packages/controllers/src/controllers/AccountController.ts

-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import type { W3mFrameTypes } from '@reown/appkit-wallet'
66

77
import { ConstantsUtil } from '../utils/ConstantsUtil.js'
88
import { CoreHelperUtil } from '../utils/CoreHelperUtil.js'
9-
import { SwapApiUtil } from '../utils/SwapApiUtil.js'
109
import type {
1110
AccountType,
1211
AccountTypeMap,
@@ -17,7 +16,6 @@ import type {
1716
import { BlockchainApiController } from './BlockchainApiController.js'
1817
import { ChainController } from './ChainController.js'
1918
import { SnackController } from './SnackController.js'
20-
import { SwapController } from './SwapController.js'
2119

2220
// -- Types --------------------------------------------- //
2321
export interface AccountControllerState {
@@ -255,7 +253,6 @@ export const AccountController = {
255253
)
256254

257255
this.setTokenBalance(filteredBalances, chain)
258-
SwapController.setBalances(SwapApiUtil.mapBalancesToSwapTokens(response.balances))
259256
state.lastRetry = undefined
260257
state.balanceLoading = false
261258

packages/controllers/src/controllers/BlockchainApiController.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,8 @@ export const BlockchainApiController = {
357357
amount,
358358
from,
359359
to,
360-
userAddress
360+
userAddress,
361+
disableEstimate
361362
}: BlockchainApiGenerateSwapCalldataRequest) {
362363
const isSupported = await BlockchainApiController.isNetworkSupported(
363364
ChainController.state.activeCaipNetwork?.caipNetworkId
@@ -379,7 +380,8 @@ export const BlockchainApiController = {
379380
projectId: OptionsController.state.projectId,
380381
from,
381382
to,
382-
userAddress
383+
userAddress,
384+
disableEstimate
383385
}
384386
})
385387
},

packages/controllers/src/controllers/ChainController.ts

+1
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,7 @@ export const ChainController = {
354354

355355
if (
356356
!isSupported &&
357+
OptionsController.state.enableNetworkSwitch &&
357358
!OptionsController.state.allowUnsupportedChain &&
358359
!ConnectionController.state.wcBasic
359360
) {

packages/controllers/src/controllers/OptionsController.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,11 @@ export interface OptionsControllerStatePublic {
178178
rpcMap?: Record<string, string>
179179
defaultChain?: string
180180
}
181+
/**
182+
* Enable or disable the network switching functionality in the modal.
183+
* @default true
184+
*/
185+
enableNetworkSwitch?: boolean
181186
}
182187

183188
export interface OptionsControllerStateInternal {
@@ -197,7 +202,8 @@ const state = proxy<OptionsControllerState & OptionsControllerStateInternal>({
197202
projectId: '',
198203
sdkType: 'appkit',
199204
sdkVersion: 'html-wagmi-undefined',
200-
defaultAccountTypes: ConstantsUtil.DEFAULT_ACCOUNT_TYPES
205+
defaultAccountTypes: ConstantsUtil.DEFAULT_ACCOUNT_TYPES,
206+
enableNetworkSwitch: true
201207
})
202208

203209
// -- Controller ---------------------------------------- //
@@ -361,6 +367,10 @@ export const OptionsController = {
361367
state.manualWCControl = manualWCControl
362368
},
363369

370+
setEnableNetworkSwitch(enableNetworkSwitch: OptionsControllerState['enableNetworkSwitch']) {
371+
state.enableNetworkSwitch = enableNetworkSwitch
372+
},
373+
364374
setDefaultAccountTypes(
365375
defaultAccountType: Partial<OptionsControllerState['defaultAccountTypes']> = {}
366376
) {

packages/controllers/src/controllers/SwapController.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { W3mFrameRpcConstants } from '@reown/appkit-wallet/utils'
77

88
import { ConstantsUtil } from '../utils/ConstantsUtil.js'
99
import { CoreHelperUtil } from '../utils/CoreHelperUtil.js'
10+
import { SendApiUtil } from '../utils/SendApiUtil.js'
1011
import { SwapApiUtil } from '../utils/SwapApiUtil.js'
1112
import { SwapCalculationUtil } from '../utils/SwapCalculationUtil.js'
1213
import type { SwapTokenWithBalance } from '../utils/TypeUtil.js'
@@ -416,14 +417,14 @@ export const SwapController = {
416417
},
417418

418419
async getMyTokensWithBalance(forceUpdate?: string) {
419-
const balances = await SwapApiUtil.getMyTokensWithBalance(forceUpdate)
420-
421-
if (!balances) {
420+
const balances = await SendApiUtil.getMyTokensWithBalance(forceUpdate)
421+
const swapBalances = SendApiUtil.mapBalancesToSwapTokens(balances)
422+
if (!swapBalances) {
422423
return
423424
}
424425

425426
await this.getInitialGasPrice()
426-
this.setBalances(balances)
427+
this.setBalances(swapBalances)
427428
},
428429

429430
setBalances(balances: SwapTokenWithBalance[]) {
@@ -675,7 +676,8 @@ export const SwapController = {
675676
userAddress: fromCaipAddress,
676677
from: sourceToken.address,
677678
to: toToken.address,
678-
amount: amount as string
679+
amount: amount as string,
680+
disableEstimate: true
679681
})
680682

681683
const isSourceTokenIsNetworkToken = sourceToken.address === networkAddress

packages/controllers/src/utils/TypeUtil.ts

+1
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@ export interface BlockchainApiGenerateSwapCalldataRequest {
303303
slippage: string
304304
permit?: string
305305
}
306+
disableEstimate?: boolean
306307
}
307308

308309
export interface BlockchainApiGenerateSwapCalldataResponse {

packages/controllers/tests/controllers/AccountController.test.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,6 @@ describe('AccountController', () => {
216216

217217
const setTokenBalanceSpy = vi.spyOn(AccountController, 'setTokenBalance')
218218
const setBalancesSpy = vi.spyOn(SwapController, 'setBalances')
219-
220219
const result = await AccountController.fetchTokenBalance()
221220

222221
expect(result).toEqual([
@@ -230,7 +229,7 @@ describe('AccountController', () => {
230229
]),
231230
'eip155'
232231
)
233-
expect(setBalancesSpy).toHaveBeenCalled()
232+
expect(setBalancesSpy).not.toHaveBeenCalled()
234233
expect(AccountController.state.lastRetry).toBeUndefined()
235234
expect(AccountController.state.balanceLoading).toBe(false)
236235
})

packages/controllers/tests/controllers/OptionsController.test.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ describe('OptionsController', () => {
1616
eip155: 'smartAccount',
1717
polkadot: 'eoa',
1818
solana: 'eoa'
19-
}
19+
},
20+
enableNetworkSwitch: true
2021
})
2122
})
2223

packages/scaffold-ui/src/partials/w3m-header/index.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -231,11 +231,12 @@ export class W3mHeader extends LitElement {
231231
const isApproveTransaction = view === 'ApproveTransaction'
232232
const isConnectingSIWEView = view === 'ConnectingSiwe'
233233
const isAccountView = view === 'Account'
234+
const enableNetworkSwitch = OptionsController.state.enableNetworkSwitch
234235

235236
const shouldHideBack =
236237
isApproveTransaction || isConnectingSIWEView || (isConnectHelp && isEmbeddedEnable)
237238

238-
if (isAccountView) {
239+
if (isAccountView && enableNetworkSwitch) {
239240
return html`<wui-select
240241
id="dynamic"
241242
data-testid="w3m-account-select-network"

0 commit comments

Comments
 (0)