0xtrails 0.12.0 → 0.12.2

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 (205) hide show
  1. package/dist/analytics.d.ts +65 -50
  2. package/dist/analytics.d.ts.map +1 -1
  3. package/dist/{ccip-DtfgR432.js → ccip-62W6LwH2.js} +28 -28
  4. package/dist/chains.d.ts.map +1 -1
  5. package/dist/error.d.ts +2 -0
  6. package/dist/error.d.ts.map +1 -1
  7. package/dist/estimate.d.ts.map +1 -1
  8. package/dist/fees.d.ts.map +1 -1
  9. package/dist/{index-CHiCSmCD.js → index-C0QTNYIA.js} +43750 -41806
  10. package/dist/index.d.ts +5 -0
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +199 -171
  13. package/dist/localeUtils.d.ts.map +1 -1
  14. package/dist/meld/components/MeldCountriesList.d.ts +0 -2
  15. package/dist/meld/components/MeldCountriesList.d.ts.map +1 -1
  16. package/dist/meld/components/MeldFundMethods.d.ts.map +1 -1
  17. package/dist/meld/components/MeldTokensList.d.ts.map +1 -1
  18. package/dist/meld/utils/meld.d.ts +2 -52
  19. package/dist/meld/utils/meld.d.ts.map +1 -1
  20. package/dist/poolUtils.d.ts.map +1 -1
  21. package/dist/prepareSend.d.ts.map +1 -1
  22. package/dist/prices.d.ts +1 -2
  23. package/dist/prices.d.ts.map +1 -1
  24. package/dist/query/balance.fetchers.d.ts +2 -2
  25. package/dist/query/balance.fetchers.d.ts.map +1 -1
  26. package/dist/query/fiat.fetchers.d.ts +11 -0
  27. package/dist/query/fiat.fetchers.d.ts.map +1 -0
  28. package/dist/query/fiat.hooks.d.ts +18 -0
  29. package/dist/query/fiat.hooks.d.ts.map +1 -0
  30. package/dist/query/fiat.queries.d.ts +24 -0
  31. package/dist/query/fiat.queries.d.ts.map +1 -0
  32. package/dist/query/meld.fetchers.d.ts +19 -0
  33. package/dist/query/meld.fetchers.d.ts.map +1 -0
  34. package/dist/query/meld.hooks.d.ts +4 -0
  35. package/dist/query/meld.hooks.d.ts.map +1 -0
  36. package/dist/query/meld.queries.d.ts +61 -0
  37. package/dist/query/meld.queries.d.ts.map +1 -0
  38. package/dist/recover.d.ts.map +1 -1
  39. package/dist/tokens.d.ts.map +1 -1
  40. package/dist/transactionIntent/deposits/depositOrchestrator.d.ts.map +1 -1
  41. package/dist/transactionIntent/deposits/gaslessDeposit.d.ts.map +1 -1
  42. package/dist/transactionIntent/deposits/standardDeposit.d.ts +7 -1
  43. package/dist/transactionIntent/deposits/standardDeposit.d.ts.map +1 -1
  44. package/dist/transactionIntent/handlers/intentHandler.d.ts +2 -0
  45. package/dist/transactionIntent/handlers/intentHandler.d.ts.map +1 -1
  46. package/dist/transactionIntent/quote/normalizeQuote.d.ts +2 -2
  47. package/dist/transactionIntent/quote/normalizeQuote.d.ts.map +1 -1
  48. package/dist/transactionIntent/quote/quoteHelpers.d.ts +1 -1
  49. package/dist/transactionIntent/quote/quoteHelpers.d.ts.map +1 -1
  50. package/dist/transactionIntent/types.d.ts +2 -0
  51. package/dist/transactionIntent/types.d.ts.map +1 -1
  52. package/dist/transactionIntent/utils/balanceChecker.d.ts +3 -1
  53. package/dist/transactionIntent/utils/balanceChecker.d.ts.map +1 -1
  54. package/dist/transactions.d.ts +2 -9
  55. package/dist/transactions.d.ts.map +1 -1
  56. package/dist/umd/trails.min.js +206 -152
  57. package/dist/utils/fiat.d.ts +8 -0
  58. package/dist/utils/fiat.d.ts.map +1 -0
  59. package/dist/utils/format.d.ts.map +1 -1
  60. package/dist/utils/passthrough.d.ts +5 -2
  61. package/dist/utils/passthrough.d.ts.map +1 -1
  62. package/dist/utils/validation.d.ts +33 -0
  63. package/dist/utils/validation.d.ts.map +1 -1
  64. package/dist/utils.d.ts.map +1 -1
  65. package/dist/walletUtils.d.ts +1 -1
  66. package/dist/walletUtils.d.ts.map +1 -1
  67. package/dist/widget/components/ClassicSwap.d.ts.map +1 -1
  68. package/dist/widget/components/DepositTracker.d.ts.map +1 -1
  69. package/dist/widget/components/Earn.d.ts +2 -0
  70. package/dist/widget/components/Earn.d.ts.map +1 -1
  71. package/dist/widget/components/FeeOption.d.ts.map +1 -1
  72. package/dist/widget/components/Fund.d.ts.map +1 -1
  73. package/dist/widget/components/FundMethods.d.ts.map +1 -1
  74. package/dist/widget/components/HookModalContent.d.ts.map +1 -1
  75. package/dist/widget/components/MeldForm.d.ts.map +1 -1
  76. package/dist/widget/components/MeldHistory.d.ts.map +1 -1
  77. package/dist/widget/components/MeldStepsFlow.d.ts.map +1 -1
  78. package/dist/widget/components/OFTProgressBar.d.ts +2 -0
  79. package/dist/widget/components/OFTProgressBar.d.ts.map +1 -1
  80. package/dist/widget/components/OnRampProviderSelector.d.ts.map +1 -1
  81. package/dist/widget/components/OnrampHistoryRow.d.ts.map +1 -1
  82. package/dist/widget/components/Pay.d.ts.map +1 -1
  83. package/dist/widget/components/PercentageMaxButtons.d.ts.map +1 -1
  84. package/dist/widget/components/PoolDeposit.d.ts +2 -0
  85. package/dist/widget/components/PoolDeposit.d.ts.map +1 -1
  86. package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
  87. package/dist/widget/components/Receipt.d.ts.map +1 -1
  88. package/dist/widget/components/SlippageToleranceSettings.d.ts.map +1 -1
  89. package/dist/widget/components/Swap.d.ts +2 -0
  90. package/dist/widget/components/Swap.d.ts.map +1 -1
  91. package/dist/widget/components/TransferPendingVertical.d.ts.map +1 -1
  92. package/dist/widget/components/Withdraw.d.ts.map +1 -1
  93. package/dist/widget/hooks/useAmountUsd.d.ts.map +1 -1
  94. package/dist/widget/hooks/useCustomTokenSearch.d.ts.map +1 -1
  95. package/dist/widget/hooks/useDisplayCurrencyPreference.d.ts.map +1 -1
  96. package/dist/widget/hooks/useFiatOnRampCurrencies.d.ts +3 -21
  97. package/dist/widget/hooks/useFiatOnRampCurrencies.d.ts.map +1 -1
  98. package/dist/widget/hooks/useMeldTransactionHistory.d.ts.map +1 -1
  99. package/dist/widget/hooks/useOnRampCountryDefaults.d.ts +0 -18
  100. package/dist/widget/hooks/useOnRampCountryDefaults.d.ts.map +1 -1
  101. package/dist/widget/hooks/useOnRampPaymentMethods.d.ts +2 -18
  102. package/dist/widget/hooks/useOnRampPaymentMethods.d.ts.map +1 -1
  103. package/dist/widget/hooks/useOnRampQuote.d.ts.map +1 -1
  104. package/dist/widget/hooks/useQuote.d.ts +5 -1
  105. package/dist/widget/hooks/useQuote.d.ts.map +1 -1
  106. package/dist/widget/hooks/useSendForm.d.ts +3 -1
  107. package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
  108. package/dist/widget/hooks/useTokenList.d.ts.map +1 -1
  109. package/dist/widget/hooks/useTokenWithFreshBalance.d.ts +3 -2
  110. package/dist/widget/hooks/useTokenWithFreshBalance.d.ts.map +1 -1
  111. package/dist/widget/index.js +1 -1
  112. package/dist/widget/types/commonProps.d.ts +2 -0
  113. package/dist/widget/types/commonProps.d.ts.map +1 -1
  114. package/dist/widget/utils/transactionFailure.d.ts +20 -0
  115. package/dist/widget/utils/transactionFailure.d.ts.map +1 -0
  116. package/dist/widget/widget.d.ts +44 -3
  117. package/dist/widget/widget.d.ts.map +1 -1
  118. package/dist/widget/workers/intentExecutionWorker.d.ts.map +1 -1
  119. package/package.json +22 -22
  120. package/src/analytics.ts +115 -79
  121. package/src/chains.ts +0 -1
  122. package/src/error.ts +11 -0
  123. package/src/estimate.ts +12 -7
  124. package/src/fees.ts +0 -1
  125. package/src/index.ts +11 -0
  126. package/src/localeUtils.ts +3 -1
  127. package/src/meld/components/MeldCountriesList.tsx +30 -15
  128. package/src/meld/components/MeldFundMethods.tsx +8 -4
  129. package/src/meld/components/MeldTokensList.tsx +90 -2
  130. package/src/meld/utils/meld.ts +3 -400
  131. package/src/poolUtils.ts +5 -19
  132. package/src/prepareSend.ts +32 -5
  133. package/src/prices.ts +7 -33
  134. package/src/query/balance.fetchers.ts +128 -168
  135. package/src/query/fiat.fetchers.ts +33 -0
  136. package/src/query/fiat.hooks.ts +71 -0
  137. package/src/query/fiat.queries.ts +67 -0
  138. package/src/query/meld.fetchers.ts +97 -0
  139. package/src/query/meld.hooks.ts +18 -0
  140. package/src/query/meld.queries.ts +184 -0
  141. package/src/recover.ts +6 -1
  142. package/src/tokens.ts +31 -6
  143. package/src/transactionIntent/deposits/depositOrchestrator.ts +2 -0
  144. package/src/transactionIntent/deposits/gaslessDeposit.ts +9 -2
  145. package/src/transactionIntent/deposits/standardDeposit.ts +35 -14
  146. package/src/transactionIntent/handlers/intentHandler.ts +134 -138
  147. package/src/transactionIntent/quote/normalizeQuote.ts +31 -22
  148. package/src/transactionIntent/quote/quoteHelpers.ts +24 -7
  149. package/src/transactionIntent/types.ts +2 -0
  150. package/src/transactionIntent/utils/balanceChecker.ts +10 -4
  151. package/src/transactions.ts +22 -13
  152. package/src/umd.tsx +1 -1
  153. package/src/utils/fiat.ts +32 -0
  154. package/src/utils/format.ts +1 -3
  155. package/src/utils/passthrough.ts +19 -3
  156. package/src/utils/validation.ts +88 -0
  157. package/src/utils.ts +2 -1
  158. package/src/walletUtils.ts +2 -2
  159. package/src/widget/components/AccountIntentTransactionHistory.tsx +2 -2
  160. package/src/widget/components/ClassicSwap.tsx +10 -4
  161. package/src/widget/components/DepositTracker.tsx +2 -5
  162. package/src/widget/components/Earn.tsx +6 -0
  163. package/src/widget/components/FeeOption.tsx +15 -8
  164. package/src/widget/components/Fund.tsx +16 -11
  165. package/src/widget/components/FundMethods.tsx +255 -192
  166. package/src/widget/components/HookModalContent.tsx +4 -0
  167. package/src/widget/components/MeldForm.tsx +44 -42
  168. package/src/widget/components/MeldHistory.tsx +4 -3
  169. package/src/widget/components/MeldStepsFlow.tsx +33 -71
  170. package/src/widget/components/OFTProgressBar.tsx +32 -12
  171. package/src/widget/components/OnRampProviderSelector.tsx +2 -1
  172. package/src/widget/components/OnrampHistoryRow.tsx +2 -1
  173. package/src/widget/components/Pay.tsx +8 -2
  174. package/src/widget/components/PercentageMaxButtons.tsx +5 -3
  175. package/src/widget/components/PoolDeposit.tsx +6 -0
  176. package/src/widget/components/PoolWithdraw.tsx +1 -1
  177. package/src/widget/components/QuoteDetails.tsx +5 -4
  178. package/src/widget/components/Receipt.tsx +4 -3
  179. package/src/widget/components/SlippageToleranceSettings.tsx +3 -2
  180. package/src/widget/components/Swap.tsx +2 -0
  181. package/src/widget/components/TransferPendingVertical.tsx +21 -28
  182. package/src/widget/components/UserPreferences.tsx +1 -1
  183. package/src/widget/components/Withdraw.tsx +20 -14
  184. package/src/widget/hooks/useAmountUsd.ts +3 -15
  185. package/src/widget/hooks/useCustomTokenSearch.tsx +2 -6
  186. package/src/widget/hooks/useDisplayCurrencyPreference.tsx +1 -2
  187. package/src/widget/hooks/useFiatOnRampCurrencies.ts +11 -76
  188. package/src/widget/hooks/useMeldTransactionHistory.ts +24 -89
  189. package/src/widget/hooks/useOnRampCountryDefaults.ts +3 -49
  190. package/src/widget/hooks/useOnRampPaymentMethods.ts +21 -100
  191. package/src/widget/hooks/useOnRampQuote.ts +2 -5
  192. package/src/widget/hooks/useQuote.ts +10 -12
  193. package/src/widget/hooks/useSendForm.ts +6 -0
  194. package/src/widget/hooks/useTokenList.ts +3 -6
  195. package/src/widget/hooks/useTokenWithFreshBalance.ts +141 -11
  196. package/src/widget/types/commonProps.ts +2 -0
  197. package/src/widget/utils/transactionFailure.ts +52 -0
  198. package/src/widget/widget.tsx +137 -59
  199. package/src/widget/workers/intentExecutionWorker.ts +3 -1
  200. package/dist/widget/hooks/useExchangeRate.d.ts +0 -31
  201. package/dist/widget/hooks/useExchangeRate.d.ts.map +0 -1
  202. package/dist/widget/hooks/useFiatCurrencyList.d.ts +0 -3
  203. package/dist/widget/hooks/useFiatCurrencyList.d.ts.map +0 -1
  204. package/src/widget/hooks/useExchangeRate.ts +0 -257
  205. package/src/widget/hooks/useFiatCurrencyList.ts +0 -66
@@ -17,7 +17,7 @@ import {
17
17
  } from "./providers/WidgetProviderTree.js"
18
18
  import { createWagmiConfig } from "./utils/createWagmiConfig.js"
19
19
  import { ShadowPortal } from "./components/ShadowPortal.js"
20
- import type { Chain, WalletClient } from "viem"
20
+ import type { Chain, WalletClient, EIP1193Provider } from "viem"
21
21
  import {
22
22
  createWalletClient,
23
23
  custom,
@@ -35,6 +35,22 @@ interface EIP6963Connector extends Connector {
35
35
  icon?: string
36
36
  }
37
37
  }
38
+ /** Transfer result data returned by an onramp provider on completion.
39
+ * Shape based on @meshconnect/web-link-sdk TransferFinishedPayload. */
40
+ interface OnrampTransferResult {
41
+ status: string
42
+ txId: string
43
+ fromAddress: string
44
+ toAddress: string
45
+ symbol: string
46
+ amount: number
47
+ networkId: string
48
+ amountInFiat?: number
49
+ totalAmountInFiat?: number
50
+ networkName?: string
51
+ txHash?: string
52
+ transferId?: string
53
+ }
38
54
  import {
39
55
  createStorage,
40
56
  useAccount,
@@ -57,16 +73,19 @@ import {
57
73
  getIsUserRejectionError,
58
74
  getPrettifiedErrorMessage,
59
75
  } from "../error.js"
76
+ import { removeStoredIntent } from "../intentStorage.js"
60
77
  import { logger } from "../logger.js"
61
78
  import type { Mode } from "../mode.js"
62
79
  import type { Pool } from "../pools.js"
63
80
  import { usePools } from "../pools.js"
64
- import type { PrepareSendQuote } from "../prepareSend.js"
65
- import { isValidInteger, isValidNumeric } from "../prices.js"
81
+ // TODO: temporary ignore this Biome warning for now; do not refactor code in this pass.
82
+ // biome-ignore lint/style/useImportType: Keep current import shape for now per requested temporary ignores.
83
+ import { type PrepareSendQuote } from "../prepareSend.js"
84
+ import { isValidInteger, isValidNumeric } from "../utils/validation.js"
66
85
  import type { Theme } from "../theme.js"
67
86
  import type { Token } from "../tokens.js"
68
87
  import { getWethAddress } from "../tokens.js"
69
- import type { IntentTransaction, FeeOption } from "@0xtrails/api"
88
+ import type { IntentTransaction } from "@0xtrails/api"
70
89
  import type { TransactionState } from "../transactions.js"
71
90
  import {
72
91
  useQRCodeWallets,
@@ -118,7 +137,7 @@ import { FundWalletSelection } from "./components/FundWalletSelection.js"
118
137
  import { WalletList } from "./components/WalletList.js"
119
138
  import { useBack } from "./hooks/useBack.js"
120
139
  import { useCheckout } from "./hooks/useCheckout.js"
121
- import { useCurrentScreen } from "./hooks/useCurrentScreen.js"
140
+ import { useCurrentScreen, type Screen } from "./hooks/useCurrentScreen.js"
122
141
  import { useDebugScreens } from "./hooks/useDebugScreens.js"
123
142
  import { useEarnPool } from "./hooks/useEarnPool.js"
124
143
  import { useInitialRedirect } from "./hooks/useInitialRedirect.js"
@@ -150,6 +169,14 @@ import {
150
169
  isNativeToken,
151
170
  normalizeAddress,
152
171
  } from "../utils/address.js"
172
+ import type { SendOptions, SwapReturn } from "./hooks/useQuote.js"
173
+ import { hasFailedOrAbortedTransaction } from "./utils/transactionFailure.js"
174
+
175
+ export type FundMethodListOption =
176
+ | "connected-wallet"
177
+ | "crypto-transfer"
178
+ | "cc-onramp"
179
+ | "exchange-onramp"
153
180
 
154
181
  // Validate toToken - must be "ETH", "USDC", or a valid hex address
155
182
  const isValidToToToken = (toToken: string | null | undefined) => {
@@ -203,7 +230,10 @@ export type TrailsWidgetProps = {
203
230
  sessionId: string
204
231
  }) => void
205
232
  onCheckoutStart?: (data: { sessionId: string }) => void
206
- onCheckoutQuote?: (data: { sessionId: string; quote: any }) => void
233
+ onCheckoutQuote?: (data: {
234
+ sessionId: string
235
+ quote: PrepareSendQuote
236
+ }) => void
207
237
  onCheckoutSignatureRequest?: (data: { sessionId: string }) => void
208
238
  onCheckoutSignatureConfirmed?: (data: { sessionId: string }) => void
209
239
  onCheckoutSignatureRejected?: (data: {
@@ -235,6 +265,8 @@ export type TrailsWidgetProps = {
235
265
  disableCss?: boolean
236
266
  swapProvider?: string
237
267
  bridgeProvider?: string
268
+ swapProviderFallback?: boolean
269
+ bridgeProviderFallback?: boolean
238
270
  slippageTolerance?: number | string
239
271
  priceImpactWarningThresholdBps?: number
240
272
  priceImpactWarningMessage?: string
@@ -250,6 +282,26 @@ export type TrailsWidgetProps = {
250
282
  hideSwap?: boolean
251
283
  /** Array of wallet addresses to hide from the funding wallet selection. */
252
284
  hideWallets?: string[]
285
+ /**
286
+ * Ordered list of funding methods to display.
287
+ *
288
+ * Supported readable values (mapped internally):
289
+ * - "connected-wallet"
290
+ * - "crypto-transfer"
291
+ * - "cc-onramp"
292
+ * - "exchange-onramp"
293
+ *
294
+ * @example ["connected-wallet", "crypto-transfer"]
295
+ */
296
+ fundMethodsList?: FundMethodListOption[]
297
+ /**
298
+ * If true, methods not in fundMethodsList are hidden.
299
+ *
300
+ * If false (default), unlisted methods are shown but disabled.
301
+ *
302
+ * Default: false.
303
+ */
304
+ hideUnlistedFundMethods?: boolean
253
305
  }
254
306
  toast?: boolean
255
307
  appName?: string
@@ -269,8 +321,8 @@ export type TrailsWidgetProps = {
269
321
  * ```
270
322
  */
271
323
  onramp?: (handlers: {
272
- setCurrentScreen: (screen: string) => void
273
- onComplete?: (transferData: any) => void
324
+ setCurrentScreen: (screen: Screen) => void
325
+ onComplete?: (transferData: OnrampTransferResult) => void
274
326
  onError?: (error: unknown) => void
275
327
  onBack?: () => void
276
328
  toTokenSymbol?: string
@@ -306,17 +358,14 @@ const useWalletManager = (
306
358
  return
307
359
  }
308
360
 
309
- const activeProvider = await connector.getProvider()
361
+ const activeProvider =
362
+ (await connector.getProvider()) as EIP1193Provider
310
363
 
311
364
  if (activeProvider && address && chainId) {
312
365
  // Validate that the provider's accounts include the expected address
313
366
  // This helps detect EIP-6963 multi-wallet mismatches where the wrong provider is used
314
367
  try {
315
- const providerAccounts = await (
316
- activeProvider as {
317
- request: (args: { method: string }) => Promise<string[]>
318
- }
319
- ).request({
368
+ const providerAccounts = await activeProvider.request({
320
369
  method: "eth_accounts",
321
370
  })
322
371
  const normalizedAddress = normalizeAddress(address)
@@ -378,7 +427,7 @@ const useWalletManager = (
378
427
  const client = createWalletClient({
379
428
  account: address as `0x${string}`,
380
429
  chain,
381
- transport: custom(activeProvider as any),
430
+ transport: custom(activeProvider),
382
431
  })
383
432
 
384
433
  setWalletClient(client)
@@ -562,6 +611,8 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
562
611
  buttonText,
563
612
  swapProvider,
564
613
  bridgeProvider,
614
+ swapProviderFallback,
615
+ bridgeProviderFallback,
565
616
  priceImpactWarningThresholdBps,
566
617
  priceImpactWarningMessage,
567
618
  priceImpactFallbackBridgeUrl,
@@ -637,13 +688,20 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
637
688
  },
638
689
  })
639
690
 
640
- // Handle fromAccount preselection
691
+ // Handle fromAccount preselection (one-time only)
692
+ // We use a ref to ensure this only runs once on mount.
693
+ // Without this guard, the effect re-fires on every render cycle
694
+ // and overrides the user's wallet selection (e.g. switching back
695
+ // from MetaMask to Privy embedded wallet).
696
+ const hasInitializedFromAccount = useRef(false)
641
697
  useEffect(() => {
698
+ if (hasInitializedFromAccount.current) return
642
699
  if (!fromAccount) return
643
700
  if (!connections.length) return
644
701
 
645
702
  // Check if fromAccount is already the active account
646
703
  if (address && addressEqual(address, fromAccount)) {
704
+ hasInitializedFromAccount.current = true
647
705
  return
648
706
  }
649
707
 
@@ -664,6 +722,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
664
722
  switchAccount({
665
723
  connector: targetConnection.connector,
666
724
  })
725
+ hasInitializedFromAccount.current = true
667
726
  } else {
668
727
  logger.console.log(
669
728
  "[trails-sdk] [TrailsWidget] fromAccount not found in connected wallets:",
@@ -730,15 +789,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
730
789
  const [onrampProviderQuote, setOnrampProviderQuote] =
731
790
  useState<OnrampQuote | null>(null)
732
791
  const [prepareSendFn, setPrepareSendFn] = useState<
733
- | ((options?: {
734
- selectedFeeOption?: FeeOption | null
735
- onOriginSend?: () => void
736
- depositTransactionHash?: string
737
- skipCommit?: boolean
738
- commitOnly?: boolean
739
- skipIntentMonitoring?: boolean
740
- }) => Promise<any>)
741
- | null
792
+ ((options?: SendOptions) => Promise<SwapReturn | null>) | null
742
793
  >(null)
743
794
 
744
795
  // Store widget creation parameters for retry functionality
@@ -796,11 +847,12 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
796
847
  }
797
848
  }, [])
798
849
 
799
- // biome-ignore lint/correctness/useExhaustiveDependencies: intentionally reacts to configuredMode prop changes
850
+ const prevConfiguredModeRef = useRef(configuredMode)
800
851
  useEffect(() => {
801
- if (isConnected) {
802
- setCurrentScreen("home")
803
- }
852
+ if (!isConnected) return
853
+ if (configuredMode === prevConfiguredModeRef.current) return
854
+ prevConfiguredModeRef.current = configuredMode
855
+ setCurrentScreen("home")
804
856
  }, [configuredMode, isConnected, setCurrentScreen])
805
857
 
806
858
  const goHome = useCallback(() => {
@@ -821,10 +873,8 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
821
873
  getInitialScreenForMode,
822
874
  )
823
875
 
824
- // Global wallet connection check, redirect to connect screen when disconnected
825
- // This ensures a wallet must be connected to use any part of the widget
876
+ // Keep screen and wallet-connection state in sync without bouncing between screens
826
877
  useEffect(() => {
827
- // Screens that are exempt from the connection requirement (connection-related screens)
828
878
  const connectionExemptScreens = [
829
879
  "connect",
830
880
  "wallet-connect",
@@ -832,11 +882,21 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
832
882
  "wallet-list",
833
883
  ]
834
884
 
835
- // If not connected and not on a connection-related screen, redirect to connect
836
885
  if (!isConnected && !connectionExemptScreens.includes(currentScreen)) {
837
886
  setCurrentScreen("connect")
887
+ return
838
888
  }
839
- }, [isConnected, currentScreen, setCurrentScreen])
889
+
890
+ if (isConnected && connectionExemptScreens.includes(currentScreen)) {
891
+ setCurrentScreen(getInitialScreenForMode(currentMode))
892
+ }
893
+ }, [
894
+ isConnected,
895
+ currentScreen,
896
+ currentMode,
897
+ setCurrentScreen,
898
+ getInitialScreenForMode,
899
+ ])
840
900
 
841
901
  const modeToButtonText: Record<string, string> = {
842
902
  fund: "Fund",
@@ -1094,7 +1154,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1094
1154
  if (!transactionStates || transactionStates.length === 0) return
1095
1155
 
1096
1156
  const firstTx = transactionStates[0]
1097
- if (firstTx?.state === "failed" || firstTx?.state === "aborted") {
1157
+ if (firstTx && hasFailedOrAbortedTransaction(firstTx)) {
1098
1158
  logger.console.log(
1099
1159
  `[trails-sdk] First transaction state is ${firstTx.state}, navigating to receipt`,
1100
1160
  )
@@ -1287,7 +1347,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1287
1347
 
1288
1348
  const handleConnectWallet = async (
1289
1349
  walletId: string,
1290
- providedConnector?: any,
1350
+ providedConnector?: Connector,
1291
1351
  ) => {
1292
1352
  try {
1293
1353
  setError(null)
@@ -1299,9 +1359,9 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1299
1359
 
1300
1360
  if (!walletConnector) {
1301
1361
  // First, try to find an EIP-6963 connector that matches this wallet ID
1302
- const eip6963Connector = connectors.find((c: any) => {
1362
+ const eip6963Connector = connectors.find((c) => {
1303
1363
  if (c.type !== "injected") return false
1304
- const rdns = c.info?.rdns
1364
+ const rdns = (c as EIP6963Connector).info?.rdns
1305
1365
  if (rdns && WALLET_RDNS_MAP[rdns] === walletId) {
1306
1366
  logger.console.log(
1307
1367
  `[trails-sdk] Found EIP-6963 connector for ${walletId} with rdns ${rdns}`,
@@ -1335,6 +1395,12 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1335
1395
  }
1336
1396
  }
1337
1397
 
1398
+ if (!walletConnector) {
1399
+ setError(`No connector available for wallet: ${walletId}`)
1400
+ setIsConnecting(false)
1401
+ return
1402
+ }
1403
+
1338
1404
  logger.console.log(
1339
1405
  "[trails-sdk] Initiating connection to wallet",
1340
1406
  walletId,
@@ -1705,6 +1771,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1705
1771
  }
1706
1772
 
1707
1773
  const handleSendAnother = () => {
1774
+ invalidateTokenBalancesCache()
1708
1775
  const initialScreen = getInitialScreenForMode(currentMode)
1709
1776
  setCurrentScreen(initialScreen)
1710
1777
  resetState()
@@ -1780,7 +1847,18 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1780
1847
  onOpen?.()
1781
1848
  }, [openTrailsModal, onOpen])
1782
1849
 
1850
+ const screensWithCommittedIntent: Screen[] = [
1851
+ "wallet-confirmation",
1852
+ "onramp-confirmation",
1853
+ ]
1854
+
1783
1855
  const handleCloseModal = useCallback(() => {
1856
+ if (
1857
+ prepareSendQuote?.intentId &&
1858
+ screensWithCommittedIntent.includes(currentScreen)
1859
+ ) {
1860
+ removeStoredIntent(prepareSendQuote.intentId)
1861
+ }
1784
1862
  if (pendingSelection) {
1785
1863
  logger.console.log(
1786
1864
  "[trails-sdk] handleCloseModal called, rejecting pending selection",
@@ -1804,6 +1882,8 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1804
1882
  onClose,
1805
1883
  pendingSelection,
1806
1884
  setPendingSelection,
1885
+ prepareSendQuote,
1886
+ currentScreen,
1807
1887
  ])
1808
1888
 
1809
1889
  // Register handleCloseModal with TrailsModalProvider so ScreenHeader can use it
@@ -1863,10 +1943,14 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
1863
1943
  setDestinationChainId(lastTransactionState?.chainId)
1864
1944
  }
1865
1945
 
1946
+ // clear the stored intent from local storage
1947
+ if (prepareSendQuote?.intentId) {
1948
+ removeStoredIntent(prepareSendQuote.intentId)
1949
+ }
1866
1950
  setCurrentScreen("receipt")
1867
1951
  }
1868
1952
 
1869
- async function handleOnrampComplete(transferData: any) {
1953
+ async function handleOnrampComplete(transferData: OnrampTransferResult) {
1870
1954
  logger.console.log("[trails-sdk] Onramp transfer completed:", transferData)
1871
1955
  logger.console.log(
1872
1956
  "[trails-sdk] Using real transaction states from prepareSendQuote",
@@ -2150,16 +2234,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
2150
2234
 
2151
2235
  const handleWaitingForWalletConfirm = (
2152
2236
  quote: PrepareSendQuote,
2153
- sendFn?:
2154
- | ((options?: {
2155
- selectedFeeOption?: FeeOption | null
2156
- onOriginSend?: () => void
2157
- depositTransactionHash?: string
2158
- skipCommit?: boolean
2159
- commitOnly?: boolean
2160
- skipIntentMonitoring?: boolean
2161
- }) => Promise<any>)
2162
- | null,
2237
+ sendFn?: ((options?: SendOptions) => Promise<SwapReturn | null>) | null,
2163
2238
  ) => {
2164
2239
  setShowWalletConfirmRetry(false)
2165
2240
  setPrepareSendQuote(quote ?? null)
@@ -2204,14 +2279,7 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
2204
2279
  paymentMethodType?: string
2205
2280
  },
2206
2281
  sessionId?: string,
2207
- sendFn?:
2208
- | ((options?: {
2209
- selectedFeeOption?: FeeOption | null
2210
- onOriginSend?: () => void
2211
- depositTransactionHash?: string
2212
- skipCommit?: boolean
2213
- }) => Promise<any>)
2214
- | null,
2282
+ sendFn?: ((options?: SendOptions) => Promise<SwapReturn | null>) | null,
2215
2283
  popupWindowRef?: Window | null,
2216
2284
  ) => {
2217
2285
  logger.console.log(
@@ -2477,6 +2545,8 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
2477
2545
  setWalletConfirmRetryHandler={setWalletConfirmRetryHandler}
2478
2546
  swapProvider={swapProvider}
2479
2547
  bridgeProvider={bridgeProvider}
2548
+ swapProviderFallback={swapProviderFallback}
2549
+ bridgeProviderFallback={bridgeProviderFallback}
2480
2550
  fundMethod={selectedFundMethod}
2481
2551
  onAmountUpdate={(amount: string) => {
2482
2552
  if (
@@ -2535,6 +2605,8 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
2535
2605
  setWalletConfirmRetryHandler={setWalletConfirmRetryHandler}
2536
2606
  swapProvider={swapProvider}
2537
2607
  bridgeProvider={bridgeProvider}
2608
+ swapProviderFallback={swapProviderFallback}
2609
+ bridgeProviderFallback={bridgeProviderFallback}
2538
2610
  fundMethod={selectedFundMethod}
2539
2611
  checkoutOnHandlers={checkoutOnHandlers}
2540
2612
  recentTokens={recentTokens}
@@ -2716,8 +2788,8 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
2716
2788
  return (
2717
2789
  <div className="flex flex-col h-full">
2718
2790
  {onrampFactory({
2719
- setCurrentScreen: (screen: string) => {
2720
- setCurrentScreen(screen as any)
2791
+ setCurrentScreen: (screen) => {
2792
+ setCurrentScreen(screen)
2721
2793
  },
2722
2794
  onComplete: handleOnrampComplete,
2723
2795
  onError: (error) => {
@@ -2837,6 +2909,8 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
2837
2909
  setWalletConfirmRetryHandler={setWalletConfirmRetryHandler}
2838
2910
  swapProvider={swapProvider}
2839
2911
  bridgeProvider={bridgeProvider}
2912
+ swapProviderFallback={swapProviderFallback}
2913
+ bridgeProviderFallback={bridgeProviderFallback}
2840
2914
  fundMethod={selectedFundMethod}
2841
2915
  checkoutOnHandlers={checkoutOnHandlers}
2842
2916
  recentTokens={recentTokens}
@@ -2878,6 +2952,8 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
2878
2952
  setWalletConfirmRetryHandler={setWalletConfirmRetryHandler}
2879
2953
  swapProvider={swapProvider}
2880
2954
  bridgeProvider={bridgeProvider}
2955
+ swapProviderFallback={swapProviderFallback}
2956
+ bridgeProviderFallback={bridgeProviderFallback}
2881
2957
  fundMethod={selectedFundMethod}
2882
2958
  onAmountUpdate={undefined}
2883
2959
  checkoutOnHandlers={checkoutOnHandlers}
@@ -2910,6 +2986,8 @@ const WidgetContent = forwardRef<TrailsWidgetRef>((_, ref) => {
2910
2986
  setWalletConfirmRetryHandler={setWalletConfirmRetryHandler}
2911
2987
  swapProvider={swapProvider}
2912
2988
  bridgeProvider={bridgeProvider}
2989
+ swapProviderFallback={swapProviderFallback}
2990
+ bridgeProviderFallback={bridgeProviderFallback}
2913
2991
  checkoutOnHandlers={checkoutOnHandlers}
2914
2992
  recentTokens={recentTokens}
2915
2993
  onTrackToken={handleTrackToken}
@@ -253,7 +253,9 @@ export class IntentExecutionWorker {
253
253
  status === IntentStatus.SUCCEEDED ||
254
254
  status === IntentStatus.FAILED ||
255
255
  status === IntentStatus.REFUNDED ||
256
- status === IntentStatus.ABORTED
256
+ status === IntentStatus.ABORTED ||
257
+ status === IntentStatus.INVALID ||
258
+ status === IntentStatus.EXECUTING
257
259
  ) {
258
260
  logger.console.log(
259
261
  `[trails-sdk][intent-worker] Removing intent ${storedIntent.intentId} with final status: ${status}`,
@@ -1,31 +0,0 @@
1
- interface UseExchangeRateOptions {
2
- fromCurrency?: string;
3
- toCurrency?: string;
4
- disabled?: boolean;
5
- }
6
- interface UseExchangeRateResult {
7
- exchangeRate: number | undefined;
8
- isLoading: boolean;
9
- error: Error | null;
10
- }
11
- /**
12
- * Wrapper hook for exchange rate fetching that abstracts the underlying implementation
13
- * This allows us to easily swap out the exchange rate provider in the future
14
- */
15
- export declare function useExchangeRate(options?: UseExchangeRateOptions): UseExchangeRateResult;
16
- /**
17
- * Hook to get exchange rate from USD to user's preferred display currency
18
- */
19
- export declare function useUsdToDisplayCurrencyRate(): UseExchangeRateResult;
20
- /**
21
- * Hook to convert USD amount to user's preferred display currency
22
- */
23
- export declare function useConvertUsdToDisplayCurrency(): {
24
- convert: (usdAmount: number) => number;
25
- formatAmount: (usdAmount: number) => string;
26
- displayCurrency: string;
27
- exchangeRate: number | undefined;
28
- isLoading: boolean;
29
- };
30
- export {};
31
- //# sourceMappingURL=useExchangeRate.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useExchangeRate.d.ts","sourceRoot":"","sources":["../../../src/widget/hooks/useExchangeRate.ts"],"names":[],"mappings":"AAMA,UAAU,sBAAsB;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,UAAU,qBAAqB;IAC7B,YAAY,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,SAAS,EAAE,OAAO,CAAA;IAClB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;CACpB;AAgED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,OAAO,GAAE,sBAA2B,GACnC,qBAAqB,CA6EvB;AAED;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,qBAAqB,CASnE;AAED;;GAEG;AACH,wBAAgB,8BAA8B,IAAI;IAChD,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAA;IACtC,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAA;IAC3C,eAAe,EAAE,MAAM,CAAA;IACvB,YAAY,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,SAAS,EAAE,OAAO,CAAA;CACnB,CAiCA"}
@@ -1,3 +0,0 @@
1
- import { FiatCurrency } from '@0xtrails/api';
2
- export declare function useFiatCurrencyList(): import('@tanstack/react-query').UseQueryResult<FiatCurrency[], Error>;
3
- //# sourceMappingURL=useFiatCurrencyList.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useFiatCurrencyList.d.ts","sourceRoot":"","sources":["../../../src/widget/hooks/useFiatCurrencyList.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAyCjD,wBAAgB,mBAAmB,0EAoBlC"}