0xtrails 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/dist/address.d.ts.map +1 -1
  2. package/dist/analytics.d.ts +86 -1
  3. package/dist/analytics.d.ts.map +1 -1
  4. package/dist/apiClient.d.ts +1 -1
  5. package/dist/apiClient.d.ts.map +1 -1
  6. package/dist/{ccip-BmFTEOaB.js → ccip-dLSEJjCf.js} +55 -55
  7. package/dist/cctpqueue.d.ts +1 -1
  8. package/dist/cctpqueue.d.ts.map +1 -1
  9. package/dist/chains.d.ts +9 -3
  10. package/dist/chains.d.ts.map +1 -1
  11. package/dist/constants.d.ts +1 -0
  12. package/dist/constants.d.ts.map +1 -1
  13. package/dist/decoders.d.ts +58 -0
  14. package/dist/decoders.d.ts.map +1 -0
  15. package/dist/ens.d.ts +13 -0
  16. package/dist/ens.d.ts.map +1 -0
  17. package/dist/error.d.ts +9 -0
  18. package/dist/error.d.ts.map +1 -1
  19. package/dist/{index-BPsVj7zK.js → index-BXbaLmtt.js} +28779 -25738
  20. package/dist/index.js +2 -2
  21. package/dist/intents.d.ts +4 -4
  22. package/dist/intents.d.ts.map +1 -1
  23. package/dist/lifi.d.ts +4 -0
  24. package/dist/lifi.d.ts.map +1 -0
  25. package/dist/metaTxns.d.ts +1 -1
  26. package/dist/metaTxns.d.ts.map +1 -1
  27. package/dist/mode.d.ts +1 -1
  28. package/dist/mode.d.ts.map +1 -1
  29. package/dist/preconditions.d.ts +1 -1
  30. package/dist/preconditions.d.ts.map +1 -1
  31. package/dist/prepareSend.d.ts +32 -24
  32. package/dist/prepareSend.d.ts.map +1 -1
  33. package/dist/prices.d.ts +3 -1
  34. package/dist/prices.d.ts.map +1 -1
  35. package/dist/proxyCaller.d.ts +0 -1
  36. package/dist/proxyCaller.d.ts.map +1 -1
  37. package/dist/relaySdk.d.ts.map +1 -1
  38. package/dist/relayer.d.ts.map +1 -1
  39. package/dist/tokenBalances.d.ts +1 -1
  40. package/dist/tokenBalances.d.ts.map +1 -1
  41. package/dist/tokens.d.ts +2 -1
  42. package/dist/tokens.d.ts.map +1 -1
  43. package/dist/trails.d.ts +4 -4
  44. package/dist/trails.d.ts.map +1 -1
  45. package/dist/transactions.d.ts +4 -0
  46. package/dist/transactions.d.ts.map +1 -1
  47. package/dist/utils.d.ts +6 -0
  48. package/dist/utils.d.ts.map +1 -1
  49. package/dist/wallets.d.ts +247 -5
  50. package/dist/wallets.d.ts.map +1 -1
  51. package/dist/widget/components/ChainFilterDropdown.d.ts +2 -0
  52. package/dist/widget/components/ChainFilterDropdown.d.ts.map +1 -1
  53. package/dist/widget/components/ConnectWallet.d.ts +1 -0
  54. package/dist/widget/components/ConnectWallet.d.ts.map +1 -1
  55. package/dist/widget/components/DebugScreensDropdown.d.ts.map +1 -1
  56. package/dist/widget/components/ErrorDisplay.d.ts +9 -0
  57. package/dist/widget/components/ErrorDisplay.d.ts.map +1 -0
  58. package/dist/widget/components/FundSendForm.d.ts +2 -2
  59. package/dist/widget/components/FundSendForm.d.ts.map +1 -1
  60. package/dist/widget/components/OriginTransferInformation.d.ts +10 -0
  61. package/dist/widget/components/OriginTransferInformation.d.ts.map +1 -0
  62. package/dist/widget/components/PaySendForm.d.ts +2 -2
  63. package/dist/widget/components/PaySendForm.d.ts.map +1 -1
  64. package/dist/widget/components/QrCode.d.ts +1 -1
  65. package/dist/widget/components/QrCode.d.ts.map +1 -1
  66. package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
  67. package/dist/widget/components/Receipt.d.ts.map +1 -1
  68. package/dist/widget/components/Receive.d.ts +12 -0
  69. package/dist/widget/components/Receive.d.ts.map +1 -0
  70. package/dist/widget/components/RefundAddressInput.d.ts +13 -0
  71. package/dist/widget/components/RefundAddressInput.d.ts.map +1 -0
  72. package/dist/widget/components/Swap.d.ts +47 -0
  73. package/dist/widget/components/Swap.d.ts.map +1 -0
  74. package/dist/widget/components/SwapDisplay.d.ts +9 -0
  75. package/dist/widget/components/SwapDisplay.d.ts.map +1 -0
  76. package/dist/widget/components/TokenList.d.ts +0 -2
  77. package/dist/widget/components/TokenList.d.ts.map +1 -1
  78. package/dist/widget/components/TokenSelector.d.ts +26 -0
  79. package/dist/widget/components/TokenSelector.d.ts.map +1 -0
  80. package/dist/widget/components/TransferPendingVertical.d.ts +2 -0
  81. package/dist/widget/components/TransferPendingVertical.d.ts.map +1 -1
  82. package/dist/widget/components/WalletConnect.d.ts.map +1 -1
  83. package/dist/widget/components/WalletConnectionPending.d.ts +12 -0
  84. package/dist/widget/components/WalletConnectionPending.d.ts.map +1 -0
  85. package/dist/widget/components/WalletList.d.ts.map +1 -1
  86. package/dist/widget/components/YellowWarningAnimation.d.ts +2 -0
  87. package/dist/widget/components/YellowWarningAnimation.d.ts.map +1 -0
  88. package/dist/widget/hooks/useAmountUsd.d.ts +1 -3
  89. package/dist/widget/hooks/useAmountUsd.d.ts.map +1 -1
  90. package/dist/widget/hooks/useCheckout.d.ts.map +1 -1
  91. package/dist/widget/hooks/useDebugScreens.d.ts +22 -0
  92. package/dist/widget/hooks/useDebugScreens.d.ts.map +1 -0
  93. package/dist/widget/hooks/useSendForm.d.ts +12 -6
  94. package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
  95. package/dist/widget/hooks/useTokenList.d.ts +2 -3
  96. package/dist/widget/hooks/useTokenList.d.ts.map +1 -1
  97. package/dist/widget/index.js +1 -1
  98. package/dist/widget/widget.d.ts.map +1 -1
  99. package/package.json +19 -15
  100. package/src/aave.ts +13 -13
  101. package/src/address.ts +3 -0
  102. package/src/analytics.ts +192 -8
  103. package/src/apiClient.ts +1 -1
  104. package/src/cctpqueue.ts +1 -1
  105. package/src/chains.ts +45 -7
  106. package/src/constants.ts +7 -4
  107. package/src/decoders.ts +310 -0
  108. package/src/ens.ts +32 -0
  109. package/src/error.ts +101 -1
  110. package/src/intents.ts +10 -2
  111. package/src/lifi.ts +58 -0
  112. package/src/metaTxns.ts +1 -1
  113. package/src/mode.ts +1 -1
  114. package/src/morpho.ts +3 -3
  115. package/src/pools.ts +18 -18
  116. package/src/preconditions.ts +1 -1
  117. package/src/prepareSend.ts +463 -113
  118. package/src/prices.ts +26 -1
  119. package/src/proxyCaller.ts +2 -14
  120. package/src/relaySdk.ts +1 -0
  121. package/src/relayer.ts +8 -0
  122. package/src/tokenBalances.ts +24 -17
  123. package/src/tokens.ts +147 -22
  124. package/src/trails.ts +4 -4
  125. package/src/transactions.ts +35 -17
  126. package/src/utils.ts +28 -0
  127. package/src/wallets.ts +275 -35
  128. package/src/widget/compiled.css +2 -2
  129. package/src/widget/components/ChainFilterDropdown.tsx +42 -33
  130. package/src/widget/components/ChainImage.tsx +1 -1
  131. package/src/widget/components/ConnectWallet.tsx +92 -128
  132. package/src/widget/components/DebugScreensDropdown.tsx +6 -0
  133. package/src/widget/components/ErrorDisplay.tsx +150 -0
  134. package/src/widget/components/FundSendForm.tsx +78 -11
  135. package/src/widget/components/OriginTransferInformation.tsx +59 -0
  136. package/src/widget/components/PaySendForm.tsx +80 -13
  137. package/src/widget/components/QRCodeDeposit.tsx +6 -6
  138. package/src/widget/components/QrCode.tsx +278 -17
  139. package/src/widget/components/QuoteDetails.tsx +93 -25
  140. package/src/widget/components/Receipt.tsx +296 -103
  141. package/src/widget/components/Receive.tsx +146 -0
  142. package/src/widget/components/RecentTokens.tsx +1 -1
  143. package/src/widget/components/RefundAddressInput.tsx +149 -0
  144. package/src/widget/components/Swap.tsx +769 -0
  145. package/src/widget/components/SwapDisplay.tsx +68 -0
  146. package/src/widget/components/TokenList.tsx +27 -363
  147. package/src/widget/components/TokenSelector.tsx +405 -0
  148. package/src/widget/components/TransferPendingVertical.tsx +162 -112
  149. package/src/widget/components/WalletConnect.tsx +9 -7
  150. package/src/widget/components/WalletConnectionPending.tsx +157 -0
  151. package/src/widget/components/WalletList.tsx +6 -5
  152. package/src/widget/components/YellowWarningAnimation.tsx +146 -0
  153. package/src/widget/hooks/useAmountUsd.ts +3 -8
  154. package/src/widget/hooks/useCheckout.ts +3 -2
  155. package/src/widget/hooks/useDebugScreens.ts +583 -0
  156. package/src/widget/hooks/useSendForm.ts +111 -35
  157. package/src/widget/hooks/useTokenList.ts +155 -122
  158. package/src/widget/widget.tsx +503 -523
@@ -15,7 +15,7 @@ import React, {
15
15
  } from "react"
16
16
  import { createPortal } from "react-dom"
17
17
  import type { Chain, WalletClient } from "viem"
18
- import { createWalletClient, custom, http, parseUnits } from "viem"
18
+ import { createWalletClient, custom, http, isAddress } from "viem"
19
19
  import * as viemChains from "viem/chains"
20
20
  import type { Connector } from "wagmi"
21
21
  import {
@@ -26,10 +26,7 @@ import {
26
26
  WagmiContext,
27
27
  WagmiProvider,
28
28
  } from "wagmi"
29
- import { injected, walletConnect, safe, baseAccount } from "wagmi/connectors"
30
- import { useAPIClient } from "../apiClient.js"
31
- import { getChainInfo } from "../chains.js"
32
- import { useIndexerGatewayClient } from "../indexerClient.js"
29
+ import { getChainInfo, getRpcUrl } from "../chains.js"
33
30
  import type { TransactionState } from "../transactions.js"
34
31
  import type { RelayerEnv, MetaTxnReceipt } from "../relayer.js"
35
32
  import type { Theme } from "../theme.js"
@@ -45,22 +42,25 @@ import TransferPending from "./components/TransferPendingVertical.js"
45
42
  import WalletConfirmation from "./components/WalletConfirmation.js"
46
43
  import QRCodeDeposit from "./components/QRCodeDeposit.js"
47
44
  import { ThemeProvider } from "./components/ThemeProvider.js"
48
- import {
49
- getWalletConnectProjectId,
50
- setWalletConnectProjectId,
51
- } from "../config.js"
45
+ import { setWalletConnectProjectId } from "../config.js"
52
46
  import { useAmountUsd } from "./hooks/useAmountUsd.js"
53
47
  import { useRecentTokens } from "./hooks/useRecentTokens.js"
54
48
  import { getWethAddress } from "../tokens.js"
55
49
  import css from "./compiled.css?inline"
56
- import { trackWalletConnected, trackWidgetScreen } from "../analytics.js"
50
+ import {
51
+ getSessionId,
52
+ trackWalletConnected,
53
+ trackWidgetScreen,
54
+ } from "../analytics.js"
57
55
  import type { PrepareSendQuote } from "../prepareSend.js"
58
- import { getNormalizedQuoteObject } from "../prepareSend.js"
59
56
  import type { SupportedToken } from "../tokens.js"
60
57
  import {
61
- getErrorString,
62
58
  getIsWalletRejectedError,
63
59
  getIsBalanceTooLowError,
60
+ getFullErrorMessage,
61
+ getIsApiError,
62
+ getIsRateLimitedError,
63
+ getPrettifiedErrorMessage,
64
64
  } from "../error.js"
65
65
  import {
66
66
  setSequenceIndexerUrl,
@@ -73,11 +73,14 @@ import {
73
73
  setSlippageTolerance,
74
74
  } from "../config.js"
75
75
  import { FundSendForm } from "./components/FundSendForm.js"
76
+ import { Swap } from "./components/Swap.js"
77
+ import { Receive } from "./components/Receive.js"
76
78
  import type { MeshConnectProps } from "./components/MeshConnectIframe.js"
77
79
  import { MeshConnectFlow } from "./components/MeshConnectFlow.js"
78
80
  import WalletConnectScreen from "./components/WalletConnect.js"
79
81
  import FundMethods from "./components/FundMethods.js"
80
82
  import EarnPools from "./components/EarnPools.js"
83
+ import WalletConnectionPending from "./components/WalletConnectionPending.js"
81
84
  import type { Mode } from "../mode.js"
82
85
  import type { OnCompleteProps } from "./hooks/useSendForm.js"
83
86
  import type { Pool } from "../pools.js"
@@ -86,10 +89,26 @@ import { AaveProvider, AaveClient } from "@aave/react"
86
89
  import { encodeFunctionData } from "viem"
87
90
  import { cssObjectToString } from "../cssUtils.js"
88
91
  import { useCheckout } from "./hooks/useCheckout.js"
89
- import { WALLET_CONFIGS, walletConnectConnector } from "../wallets.js"
92
+ import { useWallets, walletConnectConnector, connectors } from "../wallets.js"
93
+ import { isValidNumeric, isValidInteger } from "../prices.js"
94
+ import { ErrorDisplay } from "./components/ErrorDisplay.js"
95
+ import { useDebugScreens } from "./hooks/useDebugScreens.js"
90
96
 
91
97
  export const aaveClient = AaveClient.create()
92
98
 
99
+ // Validate toToken - must be "ETH", "USDC", or a valid hex address
100
+ const isValidToToToken = (toToken: string | null | undefined) => {
101
+ if (toToken === null || toToken === undefined || toToken === "") {
102
+ return true // Empty values are considered valid
103
+ }
104
+ const token = String(toToken).trim()
105
+ if (token?.length > 0 && token?.length <= 5) {
106
+ return true
107
+ }
108
+
109
+ return isAddress(token)
110
+ }
111
+
93
112
  type Screen =
94
113
  | "connect"
95
114
  | "tokens"
@@ -97,6 +116,8 @@ type Screen =
97
116
  | "fund-form"
98
117
  | "fund-methods"
99
118
  | "earn-pools"
119
+ | "swap"
120
+ | "receive"
100
121
  | "wallet-confirmation"
101
122
  | "qr-code-deposit"
102
123
  | "pending"
@@ -104,6 +125,7 @@ type Screen =
104
125
  | "mesh-connect"
105
126
  | "wallet-connect"
106
127
  | "wallet-list"
128
+ | "wallet-connection-pending"
107
129
 
108
130
  export const defaultWalletOptions = ["injected", "walletconnect"]
109
131
 
@@ -183,7 +205,7 @@ const useWalletManager = (
183
205
  const [walletClient, setWalletClient] = useState<WalletClient | null>(null)
184
206
 
185
207
  useEffect(() => {
186
- const connect = async () => {
208
+ const connectWallet = async () => {
187
209
  try {
188
210
  if (!connector) {
189
211
  return
@@ -208,7 +230,7 @@ const useWalletManager = (
208
230
  console.error("[trails-sdk] Failed to connect wallet", error)
209
231
  }
210
232
  }
211
- connect().catch(console.error)
233
+ connectWallet().catch(console.error)
212
234
  }, [address, chainId, connector])
213
235
 
214
236
  return walletClient
@@ -243,7 +265,7 @@ const useTransactionState = (
243
265
  onOriginConfirmation({
244
266
  txHash: originTxHash,
245
267
  chainId: originChainId,
246
- sessionId: Date.now().toString(),
268
+ sessionId: getSessionId(),
247
269
  })
248
270
  }
249
271
  }, [originTxHash, onOriginConfirmation, originChainId])
@@ -253,7 +275,7 @@ const useTransactionState = (
253
275
  onDestinationConfirmation({
254
276
  txHash: destinationTxHash,
255
277
  chainId: destinationChainId,
256
- sessionId: Date.now().toString(),
278
+ sessionId: getSessionId(),
257
279
  })
258
280
  }
259
281
  }, [destinationTxHash, onDestinationConfirmation, destinationChainId])
@@ -269,16 +291,6 @@ const useTransactionState = (
269
291
  (tx: TransactionState) => tx.state === "failed",
270
292
  )
271
293
 
272
- console.log(
273
- "[trails-sdk] Transaction state monitoring:",
274
- "allConfirmed:",
275
- allConfirmed,
276
- "hasFailures:",
277
- hasFailures,
278
- "states:",
279
- transactionStates.map((tx) => tx.state),
280
- )
281
-
282
294
  if (allConfirmed && !hasFailures && onComplete) {
283
295
  console.log(
284
296
  "[trails-sdk] All transactions confirmed, triggering completion",
@@ -308,9 +320,6 @@ const useTransactionState = (
308
320
  const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
309
321
  (
310
322
  {
311
- appId: sequenceProjectAccessKey,
312
- sequenceIndexerUrl,
313
- sequenceApiUrl,
314
323
  toAddress,
315
324
  toAmount,
316
325
  toChainId,
@@ -335,20 +344,46 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
335
344
  ref,
336
345
  ) => {
337
346
  const { address, isConnected, chainId, connector } = useAccount()
338
- const { disconnect } = useDisconnect()
347
+ const { disconnectAsync } = useDisconnect()
339
348
  const { recentTokens, addRecentToken } = useRecentTokens(address)
349
+ const { wallets: allWallets } = useWallets()
340
350
  const [isModalOpen, setIsModalOpen] = useState(false)
351
+ const [currentMode, setCurrentMode] = useState<Mode>(mode)
341
352
  const [currentScreen, setCurrentScreen] = useState<Screen>(
342
- isConnected ? "tokens" : "connect",
353
+ isConnected
354
+ ? currentMode === "swap"
355
+ ? "swap"
356
+ : currentMode === "receive"
357
+ ? "receive"
358
+ : "tokens"
359
+ : currentMode === "receive"
360
+ ? "receive"
361
+ : "connect",
343
362
  )
344
363
  const [selectedToken, setSelectedToken] = useState<Token | null>(null)
345
- const [selectedFundMethod, setSelectedFundMethod] = useState<string | null>(
346
- null,
347
- )
364
+ const [selectedFundMethod, setSelectedFundMethod] =
365
+ useState<string>("wallet")
348
366
  const [selectedPool, setSelectedPool] = useState<Pool | null>(null)
349
367
  const [selectedWalletId, setSelectedWalletId] = useState<string | null>(
350
- null,
368
+ () => {
369
+ // Initialize from localStorage if available
370
+ if (typeof window !== "undefined") {
371
+ try {
372
+ return localStorage.getItem("trails-last-wallet") || null
373
+ } catch (error) {
374
+ console.error(
375
+ "[trails-sdk] Failed to read from localStorage:",
376
+ error,
377
+ )
378
+ return null
379
+ }
380
+ }
381
+ return null
382
+ },
351
383
  )
384
+ const [isConnecting, setIsConnecting] = useState(false)
385
+ const [showWalletConnectionRetry, setShowWalletConnectionRetry] =
386
+ useState(false)
352
387
  const [generatedCalldata, setGeneratedCalldata] = useState<
353
388
  string | undefined
354
389
  >(undefined)
@@ -364,12 +399,108 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
364
399
  const [totalCompletionSeconds, setTotalCompletionSeconds] = useState<
365
400
  number | null
366
401
  >(null)
367
- const { connect } = useConnect()
402
+ const { connectAsync } = useConnect()
403
+
404
+ // Validate widget props
405
+ useEffect(() => {
406
+ const isValidToAmount = isValidNumeric(toAmount)
407
+ const isValidToChainId = isValidInteger(toChainId)
408
+ const isValidToToken = isValidToToToken(toToken)
409
+ const isValidToAddress = toAddress ? isAddress(toAddress) : true
410
+
411
+ if (
412
+ isValidToAmount &&
413
+ isValidToChainId &&
414
+ isValidToToken &&
415
+ isValidToAddress
416
+ ) {
417
+ setError(null)
418
+ return
419
+ }
420
+
421
+ // Validate toAmount - must be numeric if provided
422
+ if (!isValidToAmount) {
423
+ console.error(
424
+ "[trails-sdk] Invalid toAmount prop: must be numeric. Received:",
425
+ toAmount,
426
+ )
427
+ setError("Invalid toAmount: must be a numeric value")
428
+ return
429
+ }
430
+
431
+ // Validate toChainId - must be numeric if provided
432
+ if (!isValidToChainId) {
433
+ console.error(
434
+ "[trails-sdk] Invalid toChainId prop: must be numeric. Received:",
435
+ toChainId,
436
+ )
437
+ setError("Invalid toChainId: must be a numeric value")
438
+ return
439
+ }
440
+
441
+ // Validate toToken - must be "ETH", "USDC", or a valid hex address
442
+ if (!isValidToToken) {
443
+ console.error(
444
+ "[trails-sdk] Invalid toToken prop: must be a valid token symbol or a valid hex address. Received:",
445
+ toToken,
446
+ )
447
+ setError(
448
+ "Invalid toToken: must be a valid token symbol or a valid hex address",
449
+ )
450
+ return
451
+ }
452
+
453
+ if (!isValidToAddress) {
454
+ console.error(
455
+ "[trails-sdk] Invalid toAddress prop: must be a valid hex address. Received:",
456
+ toAddress,
457
+ )
458
+ setError("Invalid toAddress: must be a valid hex address")
459
+ }
460
+
461
+ if (currentMode === "fund") {
462
+ if (toAmount) {
463
+ setError("toAmount is not allowed in fund mode")
464
+ return
465
+ }
466
+ }
467
+
468
+ if (currentMode === "swap") {
469
+ if (toAmount) {
470
+ setError("toAmount is not allowed in swap mode")
471
+ return
472
+ }
473
+ if (toChainId) {
474
+ setError("toChainId is not allowed in swap mode")
475
+ return
476
+ }
477
+ if (toToken) {
478
+ setError("toToken is not allowed in swap mode")
479
+ }
480
+ if (toAddress) {
481
+ setError("toAddress is not allowed in swap mode")
482
+ return
483
+ }
484
+ }
485
+ }, [toAmount, toChainId, toToken, currentMode, toAddress])
368
486
 
369
487
  const walletClient = useWalletManager(address, chainId, connector)
370
488
 
489
+ // Function to save wallet ID to localStorage
490
+ const saveLastClickedWallet = (walletId: string) => {
491
+ setSelectedWalletId(walletId)
492
+ if (typeof window !== "undefined") {
493
+ try {
494
+ localStorage.setItem("trails-last-wallet", walletId)
495
+ } catch (error) {
496
+ console.error("[trails-sdk] Failed to save to localStorage:", error)
497
+ }
498
+ }
499
+ }
500
+
371
501
  const [meshConnectProps, setMeshConnectProps] =
372
502
  useState<Partial<MeshConnectProps> | null>(null)
503
+ const [isNavigatingBack, setIsNavigatingBack] = useState(false)
373
504
 
374
505
  // Hook to auto-select pool when mode is "earn" and toAddress is specified
375
506
  const useAutoSelectPool = (
@@ -434,7 +565,7 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
434
565
 
435
566
  if (matchingPool) {
436
567
  console.log(
437
- "[trails-sdk] Auto-selected pool for toAddress:",
568
+ `[trails-sdk] Auto-selected pool for ${mode} mode toAddress:`,
438
569
  toAddress,
439
570
  "toChainId:",
440
571
  targetChainId,
@@ -445,7 +576,7 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
445
576
  setSelectedPool(matchingPool)
446
577
  } else {
447
578
  console.log(
448
- "[trails-sdk] No matching pool found for toAddress:",
579
+ `[trails-sdk] No matching pool found for ${mode} mode toAddress:`,
449
580
  toAddress,
450
581
  "toChainId:",
451
582
  targetChainId,
@@ -459,7 +590,7 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
459
590
  return { poolsLoading }
460
591
  }
461
592
 
462
- useAutoSelectPool(mode, toAddress, toChainId, toToken)
593
+ useAutoSelectPool(currentMode, toAddress, toChainId, toToken)
463
594
 
464
595
  const {
465
596
  setOriginTxHash,
@@ -482,31 +613,78 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
482
613
  onCheckoutStatusUpdate,
483
614
  })
484
615
 
616
+ // Use the debug screens hook
617
+ const { handleDebugScreenSelect } = useDebugScreens({
618
+ setCurrentScreen,
619
+ setSelectedToken,
620
+ setTransactionStates,
621
+ setPrepareSendQuote,
622
+ setShowWalletConfirmRetry,
623
+ setCurrentMode,
624
+ setSelectedWalletId,
625
+ setShowWalletConnectionRetry,
626
+ setError,
627
+ setIsConnecting,
628
+ setMeshConnectProps,
629
+ isConnected,
630
+ })
631
+
485
632
  // redirect to tokens screen only once after initial connection
486
633
  const [alreadyRedirectedToTokens, setAlreadyRedirectedToTokens] =
487
634
  useState(false)
488
635
 
489
636
  // Update screen based on connection state and mode
490
637
  useEffect(() => {
638
+ if (isNavigatingBack) {
639
+ return
640
+ }
491
641
  if (isConnected) {
492
- if (currentScreen === "connect" || currentScreen === "wallet-list") {
642
+ if (
643
+ currentScreen === "connect" ||
644
+ currentScreen === "wallet-list" ||
645
+ currentScreen === "wallet-connection-pending"
646
+ ) {
493
647
  if (!alreadyRedirectedToTokens) {
494
648
  setAlreadyRedirectedToTokens(true)
495
- setCurrentScreen("tokens")
649
+ // Route to appropriate screen based on mode
650
+ if (currentMode === "swap") {
651
+ setCurrentScreen("swap")
652
+ } else if (currentMode === "receive") {
653
+ setCurrentScreen("receive")
654
+ } else {
655
+ setCurrentScreen("tokens")
656
+ }
496
657
  }
497
658
  }
498
659
  } else {
499
660
  if (
500
661
  currentScreen !== "connect" &&
501
662
  currentScreen !== "wallet-connect" &&
502
- currentScreen !== "wallet-list"
663
+ currentScreen !== "wallet-list" &&
664
+ currentScreen !== "wallet-connection-pending" &&
665
+ currentScreen !== "receive"
503
666
  ) {
504
667
  setTimeout(() => {
505
668
  setCurrentScreen("connect")
506
669
  }, 0)
507
670
  }
508
671
  }
509
- }, [isConnected, currentScreen, alreadyRedirectedToTokens])
672
+ }, [
673
+ isConnected,
674
+ currentScreen,
675
+ alreadyRedirectedToTokens,
676
+ currentMode,
677
+ isNavigatingBack,
678
+ ])
679
+
680
+ useEffect(() => {
681
+ if (
682
+ currentScreen === "wallet-connection-pending" &&
683
+ alreadyRedirectedToTokens
684
+ ) {
685
+ setAlreadyRedirectedToTokens(false)
686
+ }
687
+ }, [currentScreen, alreadyRedirectedToTokens])
510
688
 
511
689
  // Auto-detect mode changes and switch screens accordingly
512
690
  useEffect(() => {
@@ -514,12 +692,12 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
514
692
  selectedToken &&
515
693
  (currentScreen === "send-form" || currentScreen === "fund-form")
516
694
  ) {
517
- const targetScreen = mode === "fund" ? "fund-form" : "send-form"
695
+ const targetScreen = currentMode === "fund" ? "fund-form" : "send-form"
518
696
  if (currentScreen !== targetScreen) {
519
697
  setCurrentScreen(targetScreen)
520
698
  }
521
699
  }
522
- }, [mode, currentScreen, selectedToken])
700
+ }, [currentMode, currentScreen, selectedToken])
523
701
 
524
702
  useEffect(() => {
525
703
  trackWidgetScreen({
@@ -532,6 +710,7 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
532
710
  if (!address || !chainId || !connector?.name) {
533
711
  return
534
712
  }
713
+
535
714
  trackWalletConnected({
536
715
  walletType: connector?.name || "",
537
716
  address,
@@ -541,43 +720,43 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
541
720
 
542
721
  // Update generated calldata when amount changes in earn mode
543
722
  useEffect(() => {
544
- if (selectedPool && mode === "earn" && generatedCalldata) {
723
+ if (selectedPool && currentMode === "earn" && generatedCalldata) {
545
724
  // The calldata will be updated via the onAmountUpdate callback
546
725
  // This effect ensures we have the initial calldata set up
547
726
  console.log(
548
727
  "Earn mode: Pool selected, calldata ready for amount updates",
549
728
  )
550
729
  }
551
- }, [selectedPool, mode, generatedCalldata])
552
-
553
- const indexerGatewayClient = useIndexerGatewayClient({
554
- indexerGatewayUrl: sequenceIndexerUrl || undefined,
555
- projectAccessKey: sequenceProjectAccessKey,
556
- })
557
-
558
- const apiClient = useAPIClient({
559
- apiUrl: sequenceApiUrl || undefined,
560
- projectAccessKey: sequenceProjectAccessKey,
561
- })
730
+ }, [selectedPool, currentMode, generatedCalldata])
562
731
 
563
732
  const handleWalletConnect = async (walletId: string) => {
564
733
  try {
565
734
  setError(null)
735
+ setIsConnecting(true)
566
736
 
567
737
  // Handle special case for wallet-list screen
568
738
  if (walletId === "wallet-list") {
569
739
  setCurrentScreen("wallet-list")
740
+ setIsConnecting(false)
570
741
  return
571
742
  }
572
743
 
573
- const config = WALLET_CONFIGS[walletId as keyof typeof WALLET_CONFIGS]
744
+ const config = allWallets.find((w) => w.id === walletId)
574
745
  if (!config) {
575
746
  setError(`No configuration found for wallet: ${walletId}`)
747
+ setIsConnecting(false)
576
748
  return
577
749
  }
578
- console.log("[trails-sdk] Connecting to wallet", walletId)
750
+ console.log("[trails-sdk] Initiating connection to wallet", walletId)
579
751
  if (config.connector !== walletConnectConnector) {
580
- await connect({ connector: config.connector() })
752
+ console.log(
753
+ "[trails-sdk] Initiating connection to walletId",
754
+ walletId,
755
+ )
756
+ await connectAsync({ connector: config.connector })
757
+ console.log(`[trails-sdk] Successfully connected to ${config.name}`)
758
+ // Set the last clicked wallet after successful connection
759
+ saveLastClickedWallet(walletId)
581
760
  } else if (config.connector === walletConnectConnector) {
582
761
  // Store the current connector as previous before switching to WalletConnect
583
762
  if (connector && connector.name !== "WalletConnect") {
@@ -585,14 +764,16 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
585
764
  }
586
765
  // Route to dedicated WalletConnect screen where we show our own QR
587
766
  setCurrentScreen("wallet-connect")
767
+ setIsConnecting(false)
588
768
  return
589
769
  }
590
- console.log(`[trails-sdk] Connected to ${config.name}`)
770
+ setIsConnecting(false)
591
771
  } catch (error) {
592
772
  console.error("[trails-sdk] Failed to connect:", error)
593
773
  setError(
594
774
  error instanceof Error ? error.message : "Failed to connect wallet",
595
775
  )
776
+ setIsConnecting(false)
596
777
  }
597
778
  }
598
779
 
@@ -600,25 +781,35 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
600
781
  setError(null)
601
782
 
602
783
  try {
603
- await disconnect()
784
+ await disconnectAsync()
604
785
  setAlreadyRedirectedToTokens(false)
605
786
  } catch (error) {
606
787
  console.error("[trails-sdk] Failed to disconnect:", error)
607
788
  }
608
789
 
609
- setCurrentScreen("connect")
790
+ if (currentMode === "receive") {
791
+ setCurrentScreen("receive")
792
+ } else {
793
+ setCurrentScreen("connect")
794
+ }
610
795
  }
611
796
 
612
797
  const handleContinue = () => {
613
- setCurrentScreen("tokens")
798
+ if (currentMode === "swap") {
799
+ setCurrentScreen("swap")
800
+ } else if (currentMode === "receive") {
801
+ setCurrentScreen("receive")
802
+ } else {
803
+ setCurrentScreen("tokens")
804
+ }
614
805
  }
615
806
 
616
807
  const getAvailableWallets = (): WalletOption[] => {
617
808
  const requestedWallets = walletOptions || defaultWalletOptions
618
809
  const availableWallets = requestedWallets
619
- .filter((id) => WALLET_CONFIGS[id as keyof typeof WALLET_CONFIGS])
810
+ .filter((id) => allWallets.find((w) => w.id === id))
620
811
  .map((id) => {
621
- const config = WALLET_CONFIGS[id as keyof typeof WALLET_CONFIGS]
812
+ const config = allWallets.find((w) => w.id === id)
622
813
  if (!config) return null
623
814
  return {
624
815
  id: config.id,
@@ -636,7 +827,7 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
636
827
  setSelectedToken(token)
637
828
 
638
829
  // For earn mode, check if we have toAddress and toChainId specified
639
- if (mode === "earn") {
830
+ if (currentMode === "earn") {
640
831
  if (toAddress && toChainId) {
641
832
  // Skip earn-pools and go directly to send-form when toAddress and toChainId are specified
642
833
  setCurrentScreen("send-form")
@@ -647,23 +838,15 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
647
838
  // Go to earn-pools for pool selection when no specific destination is set
648
839
  setCurrentScreen("earn-pools")
649
840
  }
841
+ } else if (currentMode === "swap") {
842
+ setCurrentScreen("swap")
843
+ } else if (currentMode === "receive") {
844
+ setCurrentScreen("send-form")
650
845
  } else {
651
- setCurrentScreen(mode === "fund" ? "fund-form" : "send-form")
846
+ setCurrentScreen(currentMode === "fund" ? "fund-form" : "send-form")
652
847
  }
653
848
 
654
- // Track the token in recent tokens
655
- const chainInfo = getChainInfo(token.chainId)
656
- const supportedToken: SupportedToken = {
657
- id: `${token.symbol}-${chainInfo?.name || token.chainId}`,
658
- symbol: token.symbol,
659
- name: token.name,
660
- contractAddress: token.contractAddress,
661
- decimals: token.contractInfo?.decimals || 18,
662
- chainId: token.chainId,
663
- chainName: chainInfo?.name || `Chain ${token.chainId}`,
664
- imageUrl: token.imageUrl,
665
- }
666
- addRecentToken(supportedToken)
849
+ handleTrackToken(token)
667
850
  } catch (err) {
668
851
  setError(
669
852
  err instanceof Error ? err.message : "An unknown error occurred",
@@ -691,20 +874,46 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
691
874
  handleTokenSelect(token)
692
875
  }
693
876
 
877
+ const handleTrackToken = (token: Token) => {
878
+ // Track the token in recent tokens
879
+ const chainInfo = getChainInfo(token.chainId)
880
+ const supportedToken: SupportedToken = {
881
+ id: `${token.symbol}-${chainInfo?.name || token.chainId}`,
882
+ symbol: token.symbol,
883
+ name: token.name,
884
+ contractAddress: token.contractAddress,
885
+ decimals: token.contractInfo?.decimals || (token as any).decimals || 18,
886
+ chainId: token.chainId,
887
+ chainName: chainInfo?.name || `Chain ${token.chainId}`,
888
+ imageUrl: token.imageUrl,
889
+ }
890
+ addRecentToken(supportedToken)
891
+ }
892
+
694
893
  const handleOnSend = async (amount: string, recipient: string) => {
695
894
  console.log("[trails-sdk] handleOnSend", amount, recipient)
696
895
  }
697
896
 
698
897
  const handleSendAnother = () => {
699
- setCurrentScreen("tokens")
898
+ if (currentMode === "swap") {
899
+ setCurrentScreen("swap")
900
+ } else if (currentMode === "receive") {
901
+ setCurrentScreen("receive")
902
+ } else {
903
+ setCurrentScreen("tokens")
904
+ }
700
905
  resetState()
701
906
  }
702
907
 
703
908
  const resetState = useCallback(() => {
704
- setSelectedFundMethod(null)
705
- setCurrentScreen("connect")
909
+ setSelectedFundMethod("wallet")
910
+ // Reset to appropriate screen based on mode
911
+ setCurrentScreen(currentMode === "receive" ? "receive" : "connect")
706
912
  setSelectedToken(null)
707
913
  setSelectedPool(null)
914
+ setSelectedWalletId(null)
915
+ setIsConnecting(false)
916
+ setShowWalletConnectionRetry(false)
708
917
  setGeneratedCalldata(undefined)
709
918
  setOriginTxHash("")
710
919
  setOriginChainId(null)
@@ -713,12 +922,14 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
713
922
  setTransactionStates([])
714
923
  setPrepareSendQuote(null)
715
924
  setTotalCompletionSeconds(null)
925
+ setAlreadyRedirectedToTokens(false)
716
926
  }, [
717
927
  setDestinationTxHash,
718
928
  setDestinationChainId,
719
929
  setTransactionStates,
720
930
  setOriginTxHash,
721
931
  setOriginChainId,
932
+ currentMode,
722
933
  ])
723
934
 
724
935
  // Expose modal control methods via ref
@@ -744,6 +955,13 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
744
955
 
745
956
  const handleBack = () => {
746
957
  setError(null)
958
+ console.log("[trails-sdk] handleBack", currentScreen)
959
+
960
+ // Set flag to prevent auto-selection when navigating back
961
+ if (setIsNavigatingBack) {
962
+ setIsNavigatingBack(true)
963
+ }
964
+
747
965
  switch (currentScreen) {
748
966
  case "fund-methods":
749
967
  setCurrentScreen("connect")
@@ -755,8 +973,15 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
755
973
  setCurrentScreen("tokens")
756
974
  setSelectedToken(null)
757
975
  break
976
+ case "swap":
977
+ setCurrentScreen("connect")
978
+ setSelectedToken(null)
979
+ break
980
+ case "receive":
981
+ setCurrentScreen("connect")
982
+ break
758
983
  case "send-form":
759
- if (mode === "earn" && !toAddress && !toChainId) {
984
+ if (currentMode === "earn" && !toAddress && !toChainId) {
760
985
  setCurrentScreen("earn-pools")
761
986
  } else {
762
987
  setCurrentScreen("tokens")
@@ -768,11 +993,39 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
768
993
  setSelectedToken(null)
769
994
  break
770
995
  case "wallet-confirmation":
771
- setCurrentScreen(mode === "fund" ? "fund-form" : "send-form")
996
+ setCurrentScreen(
997
+ currentMode === "fund"
998
+ ? "fund-form"
999
+ : currentMode === "swap"
1000
+ ? "swap"
1001
+ : currentMode === "receive"
1002
+ ? "receive"
1003
+ : currentMode === "earn"
1004
+ ? "earn-pools"
1005
+ : "send-form",
1006
+ )
1007
+ break
1008
+ case "qr-code-deposit":
1009
+ setCurrentScreen(
1010
+ currentMode === "fund"
1011
+ ? "fund-form"
1012
+ : currentMode === "swap"
1013
+ ? "swap"
1014
+ : currentMode === "receive"
1015
+ ? "receive"
1016
+ : currentMode === "earn"
1017
+ ? "earn-pools"
1018
+ : "send-form",
1019
+ )
772
1020
  break
773
1021
  case "receipt":
774
- setCurrentScreen("tokens")
775
- setSelectedToken(null)
1022
+ // In receive mode, going back should go to receive screen
1023
+ if (currentMode === "receive") {
1024
+ setCurrentScreen("receive")
1025
+ } else {
1026
+ setCurrentScreen("tokens")
1027
+ setSelectedToken(null)
1028
+ }
776
1029
  setDestinationTxHash("")
777
1030
  setDestinationChainId(null)
778
1031
  setOriginTxHash("")
@@ -783,13 +1036,28 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
783
1036
  break
784
1037
  case "wallet-connect":
785
1038
  setCurrentScreen("wallet-list")
1039
+ setSelectedWalletId(null)
786
1040
  break
787
1041
  case "wallet-list":
788
1042
  setCurrentScreen("connect")
789
1043
  break
1044
+ case "wallet-connection-pending":
1045
+ setCurrentScreen("wallet-list")
1046
+ setSelectedWalletId(null)
1047
+ setError(null)
1048
+ setIsConnecting(false)
1049
+ setShowWalletConnectionRetry(false)
1050
+ break
790
1051
  default:
791
1052
  break
792
1053
  }
1054
+
1055
+ // Reset the flag after a short delay to allow the screen change to complete
1056
+ if (setIsNavigatingBack) {
1057
+ setTimeout(() => {
1058
+ setIsNavigatingBack(false)
1059
+ }, 100)
1060
+ }
793
1061
  }
794
1062
 
795
1063
  function handleWalletConfirmComplete() {
@@ -849,406 +1117,6 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
849
1117
  setTransactionStates([..._transactionStates])
850
1118
  }
851
1119
 
852
- const handleDebugScreenSelect = async (screen: string) => {
853
- // Reset necessary state based on the target screen
854
- setError(null)
855
-
856
- const dummySelectedToken = {
857
- id: 1,
858
- name: "USD Coin",
859
- symbol: "USDC",
860
- balance: parseUnits("1.99", 6)?.toString(),
861
- imageUrl:
862
- "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/logo.png",
863
- chainId: 1,
864
- contractAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
865
- contractInfo: {
866
- decimals: 6,
867
- symbol: "USDC",
868
- name: "USD Coin",
869
- },
870
- }
871
-
872
- const dummyQuote = await getNormalizedQuoteObject({
873
- originAddress: "0x5A0fb747531bC369367CB031472b89ea4D5c6Df7",
874
- originAmount: parseUnits("1", 6)?.toString(),
875
- originTokenAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
876
- originChainId: 1,
877
- originTokenPriceUsd: "1",
878
- destinationChainId: 137,
879
- destinationTokenAddress: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
880
- destinationAmount: parseUnits("0.97", 6)?.toString(),
881
- destinationTokenPriceUsd: "1",
882
- })
883
-
884
- switch (screen) {
885
- case "connect":
886
- setSelectedToken(null)
887
- setTransactionStates([])
888
- setCurrentScreen("connect")
889
- break
890
- case "tokens":
891
- if (isConnected) {
892
- setSelectedToken(null)
893
- setTransactionStates([])
894
- setCurrentScreen("tokens")
895
- }
896
- break
897
- case "send-form":
898
- // Set dummy USDC token for debug mode
899
- setSelectedToken(dummySelectedToken)
900
- setTransactionStates([])
901
- setCurrentScreen("send-form")
902
- break
903
- case "fund-form":
904
- // Set dummy USDC token for debug mode
905
- setSelectedToken(dummySelectedToken)
906
- setTransactionStates([])
907
- setCurrentScreen("fund-form")
908
- break
909
- case "wallet-confirmation":
910
- // Set dummy USDC token for debug mode
911
- setSelectedToken(dummySelectedToken)
912
- setPrepareSendQuote(dummyQuote)
913
- setTransactionStates([])
914
- setShowWalletConfirmRetry(false)
915
- setCurrentScreen("wallet-confirmation")
916
- break
917
- case "wallet-confirmation-retry":
918
- // Set dummy USDC token for debug mode
919
- setSelectedToken(dummySelectedToken)
920
- setPrepareSendQuote(dummyQuote)
921
- setTransactionStates([])
922
- setShowWalletConfirmRetry(true)
923
- setCurrentScreen("wallet-confirmation")
924
- break
925
- case "pending-1-item-0-confirmed":
926
- // Set dummy transaction states for debug mode - showing all steps
927
- setTransactionStates([
928
- {
929
- transactionHash:
930
- "0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
931
- explorerUrl:
932
- "https://polygonscan.com/tx/0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
933
- chainId: 137,
934
- state: "pending",
935
- label: "Swap",
936
- },
937
- ])
938
- setPrepareSendQuote(dummyQuote)
939
- setCurrentScreen("pending")
940
- break
941
- case "pending-1-item-1-confirmed":
942
- // Set dummy transaction states for debug mode - showing all steps
943
- setTransactionStates([
944
- {
945
- transactionHash:
946
- "0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
947
- explorerUrl:
948
- "https://polygonscan.com/tx/0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
949
- chainId: 137,
950
- state: "confirmed",
951
- label: "Swap",
952
- },
953
- ])
954
- setPrepareSendQuote(dummyQuote)
955
- setCurrentScreen("pending")
956
- break
957
- case "pending-2-item-0-confirmed":
958
- // Set dummy transaction states for debug mode - showing all steps
959
- setTransactionStates([
960
- {
961
- transactionHash:
962
- "0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
963
- explorerUrl:
964
- "https://polygonscan.com/tx/0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
965
- chainId: 137,
966
- state: "pending",
967
- label: "Transfer",
968
- },
969
- {
970
- transactionHash:
971
- "0x6ff30196ca0d4998cc6928bca2ec282766eb3c3997535e0a61e0d69c9c9b16b8",
972
- explorerUrl:
973
- "https://polygonscan.com/tx/0x6ff30196ca0d4998cc6928bca2ec282766eb3c3997535e0a61e0d69c9c9b16b8",
974
- chainId: 137,
975
- state: "pending",
976
- label: "Swap",
977
- },
978
- ])
979
- setPrepareSendQuote(dummyQuote)
980
- setCurrentScreen("pending")
981
- break
982
- case "pending-2-item-1-confirmed":
983
- // Set dummy transaction states for debug mode - showing all steps
984
- setTransactionStates([
985
- {
986
- transactionHash:
987
- "0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
988
- explorerUrl:
989
- "https://polygonscan.com/tx/0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
990
- chainId: 137,
991
- state: "confirmed",
992
- label: "Transfer",
993
- },
994
- {
995
- transactionHash:
996
- "0x6ff30196ca0d4998cc6928bca2ec282766eb3c3997535e0a61e0d69c9c9b16b8",
997
- explorerUrl:
998
- "https://polygonscan.com/tx/0x6ff30196ca0d4998cc6928bca2ec282766eb3c3997535e0a61e0d69c9c9b16b8",
999
- chainId: 137,
1000
- state: "pending",
1001
- label: "Swap",
1002
- },
1003
- ])
1004
- setPrepareSendQuote(dummyQuote)
1005
- setCurrentScreen("pending")
1006
- break
1007
- case "pending-2-item-2-confirmed":
1008
- // Set dummy transaction states for debug mode - showing all steps
1009
- setTransactionStates([
1010
- {
1011
- transactionHash:
1012
- "0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
1013
- explorerUrl:
1014
- "https://polygonscan.com/tx/0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
1015
- chainId: 137,
1016
- state: "confirmed",
1017
- label: "Transfer",
1018
- },
1019
- {
1020
- transactionHash:
1021
- "0x6ff30196ca0d4998cc6928bca2ec282766eb3c3997535e0a61e0d69c9c9b16b8",
1022
- explorerUrl:
1023
- "https://polygonscan.com/tx/0x6ff30196ca0d4998cc6928bca2ec282766eb3c3997535e0a61e0d69c9c9b16b8",
1024
- chainId: 137,
1025
- state: "confirmed",
1026
- label: "Swap",
1027
- },
1028
- ])
1029
- setPrepareSendQuote(dummyQuote)
1030
- setCurrentScreen("pending")
1031
- break
1032
- case "pending-3-item-0-confirmed":
1033
- // Set dummy transaction states for debug mode - showing all steps
1034
- setTransactionStates([
1035
- {
1036
- transactionHash:
1037
- "0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
1038
- explorerUrl:
1039
- "https://polygonscan.com/tx/0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
1040
- chainId: 137,
1041
- state: "pending",
1042
- label: "Transfer",
1043
- },
1044
- {
1045
- transactionHash:
1046
- "0x6ff30196ca0d4998cc6928bca2ec282766eb3c3997535e0a61e0d69c9c9b16b8",
1047
- explorerUrl:
1048
- "https://polygonscan.com/tx/0x6ff30196ca0d4998cc6928bca2ec282766eb3c3997535e0a61e0d69c9c9b16b8",
1049
- chainId: 137,
1050
- state: "pending",
1051
- label: "Swap & Bridge",
1052
- },
1053
- {
1054
- transactionHash:
1055
- "0xf3b172111d2e64e9d4940d91097f04a0bbd0acc816e2cf49eec664c6f8fcaf76",
1056
- explorerUrl:
1057
- "https://arbiscan.io/tx/0xf3b172111d2e64e9d4940d91097f04a0bbd0acc816e2cf49eec664c6f8fcaf76",
1058
- chainId: 42161,
1059
- state: "pending",
1060
- label: "Execute",
1061
- },
1062
- ])
1063
- setPrepareSendQuote(dummyQuote)
1064
- setCurrentScreen("pending")
1065
- break
1066
- case "pending-3-item-1-confirmed":
1067
- // Set dummy transaction states for debug mode - showing all steps
1068
- setTransactionStates([
1069
- {
1070
- transactionHash:
1071
- "0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
1072
- explorerUrl:
1073
- "https://polygonscan.com/tx/0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
1074
- chainId: 137,
1075
- state: "confirmed",
1076
- label: "Transfer",
1077
- },
1078
- {
1079
- transactionHash:
1080
- "0x6ff30196ca0d4998cc6928bca2ec282766eb3c3997535e0a61e0d69c9c9b16b8",
1081
- explorerUrl:
1082
- "https://polygonscan.com/tx/0x6ff30196ca0d4998cc6928bca2ec282766eb3c3997535e0a61e0d69c9c9b16b8",
1083
- chainId: 137,
1084
- state: "pending",
1085
- label: "Swap & Bridge",
1086
- },
1087
- {
1088
- transactionHash:
1089
- "0xf3b172111d2e64e9d4940d91097f04a0bbd0acc816e2cf49eec664c6f8fcaf76",
1090
- explorerUrl:
1091
- "https://arbiscan.io/tx/0xf3b172111d2e64e9d4940d91097f04a0bbd0acc816e2cf49eec664c6f8fcaf76",
1092
- chainId: 42161,
1093
- state: "pending",
1094
- label: "Execute",
1095
- },
1096
- ])
1097
- setPrepareSendQuote(dummyQuote)
1098
- setCurrentScreen("pending")
1099
- break
1100
- case "pending-3-item-2-confirmed":
1101
- // Set dummy transaction states for debug mode - showing all steps
1102
- setTransactionStates([
1103
- {
1104
- transactionHash:
1105
- "0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
1106
- explorerUrl:
1107
- "https://polygonscan.com/tx/0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
1108
- chainId: 137,
1109
- state: "confirmed",
1110
- label: "Transfer",
1111
- },
1112
- {
1113
- transactionHash:
1114
- "0x6ff30196ca0d4998cc6928bca2ec282766eb3c3997535e0a61e0d69c9c9b16b8",
1115
- explorerUrl:
1116
- "https://polygonscan.com/tx/0x6ff30196ca0d4998cc6928bca2ec282766eb3c3997535e0a61e0d69c9c9b16b8",
1117
- chainId: 137,
1118
- state: "confirmed",
1119
- label: "Swap & Bridge",
1120
- },
1121
- {
1122
- transactionHash:
1123
- "0xf3b172111d2e64e9d4940d91097f04a0bbd0acc816e2cf49eec664c6f8fcaf76",
1124
- explorerUrl:
1125
- "https://arbiscan.io/tx/0xf3b172111d2e64e9d4940d91097f04a0bbd0acc816e2cf49eec664c6f8fcaf76",
1126
- chainId: 42161,
1127
- state: "pending",
1128
- label: "Execute",
1129
- },
1130
- ])
1131
- setPrepareSendQuote(dummyQuote)
1132
- setCurrentScreen("pending")
1133
- break
1134
- case "pending-3-item-3-confirmed":
1135
- // Set dummy transaction states for debug mode - showing all steps
1136
- setTransactionStates([
1137
- {
1138
- transactionHash:
1139
- "0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
1140
- explorerUrl:
1141
- "https://polygonscan.com/tx/0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
1142
- chainId: 137,
1143
- state: "confirmed",
1144
- label: "Transfer",
1145
- },
1146
- {
1147
- transactionHash:
1148
- "0x6ff30196ca0d4998cc6928bca2ec282766eb3c3997535e0a61e0d69c9c9b16b8",
1149
- explorerUrl:
1150
- "https://polygonscan.com/tx/0x6ff30196ca0d4998cc6928bca2ec282766eb3c3997535e0a61e0d69c9c9b16b8",
1151
- chainId: 137,
1152
- state: "confirmed",
1153
- label: "Swap & Bridge",
1154
- },
1155
- {
1156
- transactionHash:
1157
- "0xf3b172111d2e64e9d4940d91097f04a0bbd0acc816e2cf49eec664c6f8fcaf76",
1158
- explorerUrl:
1159
- "https://arbiscan.io/tx/0xf3b172111d2e64e9d4940d91097f04a0bbd0acc816e2cf49eec664c6f8fcaf76",
1160
- chainId: 42161,
1161
- state: "confirmed",
1162
- label: "Execute",
1163
- },
1164
- ])
1165
- setPrepareSendQuote(dummyQuote)
1166
- setCurrentScreen("pending")
1167
- break
1168
- case "receipt":
1169
- // Set dummy transaction states data for debug mode
1170
- setTransactionStates([
1171
- {
1172
- transactionHash:
1173
- "0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
1174
- explorerUrl:
1175
- "https://polygonscan.com/tx/0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
1176
- chainId: 137,
1177
- state: "confirmed",
1178
- label: "Transfer",
1179
- },
1180
- {
1181
- transactionHash:
1182
- "0x6ff30196ca0d4998cc6928bca2ec282766eb3c3997535e0a61e0d69c9c9b16b8",
1183
- explorerUrl:
1184
- "https://polygonscan.com/tx/0x6ff30196ca0d4998cc6928bca2ec282766eb3c3997535e0a61e0d69c9c9b16b8",
1185
- chainId: 137,
1186
- state: "confirmed",
1187
- label: "Swap & Bridge",
1188
- },
1189
- {
1190
- transactionHash:
1191
- "0xf3b172111d2e64e9d4940d91097f04a0bbd0acc816e2cf49eec664c6f8fcaf76",
1192
- explorerUrl:
1193
- "https://arbiscan.io/tx/0xf3b172111d2e64e9d4940d91097f04a0bbd0acc816e2cf49eec664c6f8fcaf76",
1194
- chainId: 42161,
1195
- state: "confirmed",
1196
- label: "Execute",
1197
- },
1198
- ])
1199
-
1200
- setCurrentScreen("receipt")
1201
- break
1202
- case "receipt-failed":
1203
- // Set dummy transaction states data for debug mode
1204
- setTransactionStates([
1205
- {
1206
- transactionHash:
1207
- "0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
1208
- explorerUrl:
1209
- "https://polygonscan.com/tx/0x45bb2259631e73f32841a6058b0a4008c75bca296942bec6326d188978d5353d",
1210
- chainId: 137,
1211
- state: "confirmed",
1212
- label: "Transfer",
1213
- },
1214
- {
1215
- transactionHash:
1216
- "0x6ff30196ca0d4998cc6928bca2ec282766eb3c3997535e0a61e0d69c9c9b16b8",
1217
- explorerUrl:
1218
- "https://polygonscan.com/tx/0x6ff30196ca0d4998cc6928bca2ec282766eb3c3997535e0a61e0d69c9c9b16b8",
1219
- chainId: 137,
1220
- state: "confirmed",
1221
- label: "Swap & Bridge",
1222
- },
1223
- {
1224
- transactionHash: "",
1225
- explorerUrl: "",
1226
- chainId: 42161,
1227
- state: "failed",
1228
- label: "Execute",
1229
- },
1230
- ])
1231
-
1232
- setCurrentScreen("receipt")
1233
- break
1234
- case "mesh-connect":
1235
- setCurrentScreen("mesh-connect")
1236
- break
1237
- case "wallet-connect":
1238
- setCurrentScreen("wallet-connect")
1239
- break
1240
- case "wallet-list":
1241
- setCurrentScreen("wallet-list")
1242
- break
1243
- case "fund-methods":
1244
- setCurrentScreen("fund-methods")
1245
- break
1246
- case "earn-pools":
1247
- setCurrentScreen("earn-pools")
1248
- break
1249
- }
1250
- }
1251
-
1252
1120
  const handleSelectWalletConnect = () => {
1253
1121
  // Store the current connector as previous before switching to WalletConnect
1254
1122
  if (connector && connector.name !== "WalletConnect") {
@@ -1266,7 +1134,7 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
1266
1134
  )
1267
1135
 
1268
1136
  try {
1269
- await connect({ connector: previousConnector })
1137
+ await connectAsync({ connector: previousConnector })
1270
1138
  } catch (error) {
1271
1139
  console.error(
1272
1140
  "[trails-sdk] Failed to reconnect to previous wallet:",
@@ -1430,12 +1298,17 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
1430
1298
  if (error) {
1431
1299
  console.error("[trails-sdk] Error sending transaction", error)
1432
1300
  }
1433
- const errorMessage = getErrorString(error)
1301
+ const errorMessage = getFullErrorMessage(error)
1434
1302
  const isRejected = getIsWalletRejectedError(error)
1435
1303
  const isBalanceTooLow = getIsBalanceTooLowError(error)
1436
- if (isRejected) {
1304
+ const isApiError = getIsApiError(error)
1305
+ const isRateLimited = getIsRateLimitedError(error)
1306
+
1307
+ if (isRateLimited) {
1308
+ // no-op
1309
+ } else if (isRejected) {
1437
1310
  setShowWalletConfirmRetry(true)
1438
- } else if (isBalanceTooLow) {
1311
+ } else if (isBalanceTooLow || isApiError) {
1439
1312
  setShowWalletConfirmRetry(true)
1440
1313
  setError(errorMessage)
1441
1314
  } else {
@@ -1489,7 +1362,6 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
1489
1362
  amount: toAmount,
1490
1363
  token: toToken,
1491
1364
  chainId: Number(toChainId),
1492
- apiClient: apiClient,
1493
1365
  })
1494
1366
 
1495
1367
  const renderScreenContent = () => {
@@ -1497,11 +1369,27 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
1497
1369
  case "connect":
1498
1370
  return (
1499
1371
  <ConnectWallet
1500
- onConnect={handleWalletConnect}
1372
+ onConnect={(walletId) => {
1373
+ if (
1374
+ allWallets.find((w) => w.id === walletId)?.connector ===
1375
+ walletConnectConnector
1376
+ ) {
1377
+ saveLastClickedWallet(walletId)
1378
+ setCurrentScreen("wallet-connect")
1379
+ } else {
1380
+ saveLastClickedWallet(walletId)
1381
+ setCurrentScreen("wallet-connection-pending")
1382
+ // Auto-trigger connection
1383
+ setTimeout(() => {
1384
+ handleWalletConnect(walletId)
1385
+ }, 100)
1386
+ }
1387
+ }}
1501
1388
  onDisconnect={handleWalletDisconnect}
1502
1389
  onContinue={handleContinue}
1503
1390
  walletOptions={getAvailableWallets()}
1504
1391
  onError={handleConnectError}
1392
+ lastClickedWallet={selectedWalletId}
1505
1393
  />
1506
1394
  )
1507
1395
  case "fund-methods":
@@ -1525,7 +1413,6 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
1525
1413
  <TokenList
1526
1414
  onContinue={handleTokenSelect}
1527
1415
  onBack={handleBack}
1528
- indexerGatewayClient={indexerGatewayClient}
1529
1416
  targetAmountUsd={targetAmountUsd}
1530
1417
  targetAmountUsdFormatted={targetAmountUsdFormatted}
1531
1418
  onError={handleTokenListError}
@@ -1578,7 +1465,7 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
1578
1465
  onAmountUpdate={(amount: string) => {
1579
1466
  if (
1580
1467
  selectedPool &&
1581
- mode === "earn" &&
1468
+ currentMode === "earn" &&
1582
1469
  amount &&
1583
1470
  amount !== ""
1584
1471
  ) {
@@ -1597,7 +1484,7 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
1597
1484
  setGeneratedCalldata(undefined)
1598
1485
  }
1599
1486
  }}
1600
- mode={mode}
1487
+ mode={currentMode}
1601
1488
  selectedPool={selectedPool}
1602
1489
  checkoutOnHandlers={checkoutOnHandlers}
1603
1490
  />
@@ -1655,6 +1542,8 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
1655
1542
  onElapsedTime={handleElapsedTime}
1656
1543
  transactionStates={transactionStates}
1657
1544
  quote={prepareSendQuote}
1545
+ mode={currentMode}
1546
+ onContinue={() => setCurrentScreen("receipt")}
1658
1547
  />
1659
1548
  )
1660
1549
  case "receipt":
@@ -1694,15 +1583,26 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
1694
1583
  onBack={handleBack}
1695
1584
  onWalletSelect={(walletId) => {
1696
1585
  if (
1697
- WALLET_CONFIGS[walletId]?.connector === walletConnectConnector
1586
+ allWallets.find((w) => w.id === walletId)?.connector ===
1587
+ walletConnectConnector
1698
1588
  ) {
1699
- setSelectedWalletId(walletId)
1589
+ saveLastClickedWallet(walletId)
1700
1590
  setCurrentScreen("wallet-connect")
1701
1591
  } else {
1702
- handleWalletConnect(walletId)
1592
+ saveLastClickedWallet(walletId)
1593
+ setCurrentScreen("wallet-connection-pending")
1594
+ // Auto-trigger connection
1595
+ setTimeout(() => {
1596
+ handleWalletConnect(walletId)
1597
+ }, 100)
1703
1598
  }
1704
1599
  }}
1705
- walletOptions={Object.values(WALLET_CONFIGS)}
1600
+ walletOptions={allWallets.map((wallet) => ({
1601
+ id: wallet.id,
1602
+ name: wallet.name,
1603
+ icon: wallet.icon,
1604
+ connector: wallet.connector,
1605
+ }))}
1706
1606
  />
1707
1607
  )
1708
1608
  case "earn-pools":
@@ -1716,6 +1616,69 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
1716
1616
  }}
1717
1617
  />
1718
1618
  )
1619
+ case "swap":
1620
+ return walletClient?.account ? (
1621
+ <Swap
1622
+ onSend={handleOnSend}
1623
+ onBack={handleBack}
1624
+ onWaitingForWalletConfirm={handleWaitingForWalletConfirm}
1625
+ onConfirm={() => setCurrentScreen("pending")}
1626
+ onComplete={handleTransferComplete}
1627
+ selectedToken={selectedToken}
1628
+ account={walletClient.account}
1629
+ toRecipient={toAddress || undefined}
1630
+ toAmount={toAmount || undefined}
1631
+ toChainId={toChainId ? Number(toChainId) : undefined}
1632
+ toToken={toToken || undefined}
1633
+ toCalldata={toCalldata || undefined}
1634
+ walletClient={walletClient}
1635
+ onTransactionStateChange={handleTransactionStateChange}
1636
+ onError={handleSendError}
1637
+ paymasterUrls={paymasterUrls}
1638
+ gasless={gasless}
1639
+ setWalletConfirmRetryHandler={setWalletConfirmRetryHandler}
1640
+ quoteProvider={quoteProvider}
1641
+ fundMethod={selectedFundMethod}
1642
+ onNavigateToMeshConnect={handleNavigateToMeshConnect}
1643
+ onAmountUpdate={undefined}
1644
+ mode={currentMode}
1645
+ checkoutOnHandlers={checkoutOnHandlers}
1646
+ recentTokens={recentTokens}
1647
+ onRecentTokenSelect={handleRecentTokenSelect}
1648
+ onTrackToken={handleTrackToken}
1649
+ />
1650
+ ) : (
1651
+ <div className="text-center p-4 rounded-lg text-gray-600 bg-gray-50 dark:text-gray-300 dark:bg-gray-800">
1652
+ Please connect wallet
1653
+ </div>
1654
+ )
1655
+ case "receive":
1656
+ return (
1657
+ <Receive
1658
+ accountAddress={toAddress || ""}
1659
+ onBack={handleBack}
1660
+ isConnected={isConnected}
1661
+ onConnectWallet={() => setCurrentScreen("connect")}
1662
+ onPay={() => setCurrentScreen("tokens")}
1663
+ toChainId={toChainId ? Number(toChainId) : undefined}
1664
+ />
1665
+ )
1666
+ case "wallet-connection-pending":
1667
+ return (
1668
+ <WalletConnectionPending
1669
+ onBack={handleBack}
1670
+ onRetry={() => {
1671
+ if (selectedWalletId) {
1672
+ setShowWalletConnectionRetry(false)
1673
+ handleWalletConnect(selectedWalletId)
1674
+ }
1675
+ }}
1676
+ selectedWalletId={selectedWalletId || ""}
1677
+ isConnecting={isConnecting}
1678
+ error={error}
1679
+ showRetry={showWalletConnectionRetry}
1680
+ />
1681
+ )
1719
1682
  default:
1720
1683
  return null
1721
1684
  }
@@ -1754,11 +1717,17 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
1754
1717
  layout
1755
1718
  >
1756
1719
  {renderScreenContent()}
1720
+ {/* Error Display */}
1757
1721
  {error && (
1758
- <div className="border rounded-lg p-4 mt-4 bg-red-50 border-red-200 dark:bg-red-900/20 dark:border-red-800">
1759
- <p className="text-sm break-words text-red-600 dark:text-red-200">
1760
- {error}
1761
- </p>
1722
+ <div className="mt-2">
1723
+ <ErrorDisplay
1724
+ errorPrettified={getPrettifiedErrorMessage(
1725
+ error,
1726
+ "An error occured",
1727
+ )}
1728
+ error={error}
1729
+ severity="error"
1730
+ />
1762
1731
  </div>
1763
1732
  )}
1764
1733
  </motion.div>
@@ -1772,6 +1741,25 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
1772
1741
  return renderScreen()
1773
1742
  }
1774
1743
 
1744
+ const defaultButtonText = useMemo(() => {
1745
+ if (currentMode === "fund") {
1746
+ return "Fund"
1747
+ }
1748
+ if (currentMode === "swap") {
1749
+ return "Swap"
1750
+ }
1751
+ if (currentMode === "earn") {
1752
+ return "Earn"
1753
+ }
1754
+ if (currentMode === "receive") {
1755
+ return "Receive"
1756
+ }
1757
+ if (currentMode === "pay") {
1758
+ return "Pay"
1759
+ }
1760
+ return "Pay"
1761
+ }, [currentMode])
1762
+
1775
1763
  return (
1776
1764
  <div className="flex flex-col items-center justify-center space-y-8 py-12">
1777
1765
  {!children ? (
@@ -1781,7 +1769,7 @@ const WidgetInner = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
1781
1769
  onClick={() => setIsModalOpen(true)}
1782
1770
  className="trails-modal-button cursor-pointer font-semibold py-3 px-6 trails-font"
1783
1771
  >
1784
- {buttonText || (mode === "fund" ? "Fund" : "Pay")}
1772
+ {buttonText || defaultButtonText}
1785
1773
  </motion.button>
1786
1774
  ) : (
1787
1775
  <motion.div
@@ -1847,28 +1835,20 @@ export const TrailsWidget = forwardRef<TrailsWidgetRef, TrailsWidgetProps>(
1847
1835
  const chains = [...Object.values(viemChains)] as any
1848
1836
  const baseConfig = {
1849
1837
  chains,
1850
- transports: (chains as Array<Chain>).reduce(
1851
- (acc, chain) => ({
1838
+ transports: (chains as Array<Chain>).reduce((acc, chain) => {
1839
+ const sequenceRpcUrl = getRpcUrl(chain.id, props.appId)
1840
+ return {
1852
1841
  ...acc,
1853
- [chain.id]: http(),
1854
- }),
1855
- {},
1856
- ) as Record<number, ReturnType<typeof http>>,
1842
+ [chain.id]: sequenceRpcUrl ? http(sequenceRpcUrl) : http(),
1843
+ }
1844
+ }, {}) as Record<number, ReturnType<typeof http>>,
1857
1845
  }
1858
1846
 
1859
1847
  return createConfig({
1860
1848
  ...baseConfig,
1861
- connectors: [
1862
- injected(),
1863
- walletConnect({
1864
- projectId: getWalletConnectProjectId(),
1865
- showQrModal: false,
1866
- }),
1867
- safe(),
1868
- baseAccount(),
1869
- ],
1849
+ connectors: connectors,
1870
1850
  })
1871
- }, [])
1851
+ }, [props.appId])
1872
1852
 
1873
1853
  // Create content with only the providers that don't exist in parent
1874
1854
  const content = (() => {