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
@@ -24,6 +24,7 @@ import { ChainImage } from "./ChainImage.js"
24
24
  import { PriceImpactWarning } from "./PriceImpactWarning.js"
25
25
  import { TokenImage } from "./TokenImage.js"
26
26
  import { Tooltip } from "./Tooltip.js"
27
+ import { hasFailedOrAbortedTransaction } from "../utils/transactionFailure.js"
27
28
 
28
29
  interface QuoteDetailsProps {
29
30
  quote?: PrepareSendQuote | null
@@ -1113,10 +1114,10 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
1113
1114
  {hasLiveStates && liveTxState.state && (
1114
1115
  <span
1115
1116
  className={`px-2 py-0.5 rounded-full text-xs ${
1116
- liveTxState.state === "confirmed"
1117
- ? "bg-green-100 text-green-700 dark:bg-green-900/50 dark:text-green-400"
1118
- : liveTxState.state === "aborted"
1119
- ? "bg-red-100 text-red-700 dark:bg-red-900/50 dark:text-red-400"
1117
+ hasFailedOrAbortedTransaction(liveTxState)
1118
+ ? "bg-red-100 text-red-700 dark:bg-red-900/50 dark:text-red-400"
1119
+ : liveTxState.state === "confirmed"
1120
+ ? "bg-green-100 text-green-700 dark:bg-green-900/50 dark:text-green-400"
1120
1121
  : "bg-yellow-100 text-yellow-700 dark:bg-yellow-900/50 dark:text-yellow-400"
1121
1122
  }`}
1122
1123
  >
@@ -12,6 +12,7 @@ import { formatDuration } from "../../utils/time.js"
12
12
  import { hasMetaTxError } from "../../utils/passthrough.js"
13
13
  import type { OnrampQuote } from "../hooks/useOnRampQuote.js"
14
14
  import { useTrails } from "../providers/TrailsProvider.js"
15
+ import { hasAnyFailedOrAbortedTransactions } from "../utils/transactionFailure.js"
15
16
  import { ChainImage } from "./ChainImage.js"
16
17
  import { GreenCheckAnimation } from "./GreenCheckAnimation.js"
17
18
  import { QuoteDetails } from "./QuoteDetails.js"
@@ -172,8 +173,8 @@ export const Receipt: React.FC<ReceiptProps> = ({
172
173
  return transactionStates.some((tx) => tx.state === "aborted")
173
174
  }, [transactionStates])
174
175
 
175
- const hasFailed = useMemo(() => {
176
- return transactionStates.some((tx) => tx.state === "failed")
176
+ const hasFailedOrAborted = useMemo(() => {
177
+ return hasAnyFailedOrAbortedTransactions(transactionStates)
177
178
  }, [transactionStates])
178
179
 
179
180
  const shouldShowRefundInfo = showRefundInfo || hasRefunded
@@ -271,7 +272,7 @@ export const Receipt: React.FC<ReceiptProps> = ({
271
272
 
272
273
  if (
273
274
  (!finalExplorerUrl && !shouldShowRefundInfo && !hasAnyTransactionHash) ||
274
- ((hasAborted || hasFailed) && !hasRefunded)
275
+ (hasFailedOrAborted && !hasRefunded)
275
276
  ) {
276
277
  return (
277
278
  <div className="flex flex-col justify-center min-h-full space-y-6">
@@ -2,6 +2,7 @@ import { HelpCircle } from "lucide-react"
2
2
  import type React from "react"
3
3
  import { useEffect, useState } from "react"
4
4
  import { SLIPPAGE_AUTO } from "../../constants.js"
5
+ import { isValidNumber, isNonNegativeNumber } from "../../utils/validation.js"
5
6
 
6
7
  // Convert decimal format to percentage for display
7
8
  // Format: "0.05" (5%) -> "5"
@@ -87,7 +88,7 @@ export const SlippageToleranceSettings: React.FC<
87
88
  if (value === "" || /^\d*\.?\d*$/.test(value)) {
88
89
  // Check if the value would exceed 20% and prevent it
89
90
  const numValue = parseFloat(value)
90
- if (!Number.isNaN(numValue) && numValue > 20) {
91
+ if (isValidNumber(numValue) && numValue > 20) {
91
92
  return // Don't update if it would exceed 20%
92
93
  }
93
94
  setDisplayValue(value)
@@ -109,7 +110,7 @@ export const SlippageToleranceSettings: React.FC<
109
110
  const percentage = parseFloat(displayValue)
110
111
 
111
112
  // Validate range (0% to 20%)
112
- if (Number.isNaN(percentage) || percentage < 0 || percentage > 20) {
113
+ if (!isNonNegativeNumber(percentage) || percentage > 20) {
113
114
  // Reset to stored value or AUTO default
114
115
  try {
115
116
  const stored = localStorage.getItem(SLIPPAGE_STORAGE_KEY)
@@ -53,6 +53,8 @@ interface SwapProps {
53
53
  setWalletConfirmRetryHandler: (handler: () => Promise<void>) => void
54
54
  swapProvider?: string
55
55
  bridgeProvider?: string
56
+ swapProviderFallback?: boolean
57
+ bridgeProviderFallback?: boolean
56
58
  fundMethod?: FundMethod
57
59
  onAmountUpdate?: (amount: string) => void
58
60
  checkoutOnHandlers?: CheckoutOnHandlers
@@ -8,6 +8,10 @@ import { formatDuration, MINUTE_MS } from "../../utils/time.js"
8
8
  import { hasMetaTxError } from "../../utils/passthrough.js"
9
9
  import { useMode } from "../hooks/useMode.js"
10
10
  import type { OnrampQuote } from "../hooks/useOnRampQuote.js"
11
+ import {
12
+ hasAnyFailedOrAbortedTransactions,
13
+ hasFailedOrAbortedTransaction,
14
+ } from "../utils/transactionFailure.js"
11
15
  import { OFTProgressBar } from "./OFTProgressBar.js"
12
16
  import { OriginTransferInformation } from "./OriginTransferInformation.js"
13
17
  import { QuoteDetails } from "./QuoteDetails.js"
@@ -125,15 +129,7 @@ export const TransferPending: React.FC<TransferPendingProps> = ({
125
129
  const isOFT = isOFTRoute(quote?.routeProviders)
126
130
 
127
131
  const showContinueButton =
128
- (transactionStates?.some(
129
- (tx) => tx.state === "failed" || tx.state === "aborted",
130
- ) ||
131
- transactionStates?.some((tx) =>
132
- tx?.decodedGuestModuleEvents?.some(
133
- (event) => event.type === "CallFailed",
134
- ),
135
- )) &&
136
- onContinue
132
+ hasAnyFailedOrAbortedTransactions(transactionStates) && onContinue
137
133
 
138
134
  // Timeout warning: OFT routes can take significantly longer than standard routes.
139
135
  useEffect(() => {
@@ -246,10 +242,10 @@ export const TransferPending: React.FC<TransferPendingProps> = ({
246
242
 
247
243
  useEffect(() => {
248
244
  const interval = setInterval(() => {
249
- setElapsedSeconds(elapsedSeconds + 1)
245
+ setElapsedSeconds((prev) => prev + 1)
250
246
  }, 1000)
251
247
  return () => clearInterval(interval)
252
- }, [elapsedSeconds])
248
+ }, [])
253
249
 
254
250
  // Timer for active pending transaction
255
251
  useEffect(() => {
@@ -283,7 +279,7 @@ export const TransferPending: React.FC<TransferPendingProps> = ({
283
279
  const renderStep = (tx: TransactionState, index: number) => {
284
280
  const isActivePending = index === activePendingIndex
285
281
  const isCompleted = tx.state === "confirmed"
286
- const isFailed = tx.state === "failed" || tx.state === "aborted"
282
+ const isFailed = hasFailedOrAbortedTransaction(tx)
287
283
 
288
284
  // Check if this transaction has meta tx errors
289
285
  const txHasMetaError = hasMetaTxError(tx)
@@ -291,7 +287,7 @@ export const TransferPending: React.FC<TransferPendingProps> = ({
291
287
  // Check if any previous transaction has failed (to disable spinners after failure)
292
288
  const hasPreviousFailure = transactionStates
293
289
  .slice(0, index)
294
- .some((prevTx) => hasMetaTxError(prevTx))
290
+ .some((prevTx) => hasFailedOrAbortedTransaction(prevTx))
295
291
 
296
292
  // Determine step state
297
293
  let stepState: "completed" | "active" | "pending" | "failed"
@@ -440,16 +436,10 @@ export const TransferPending: React.FC<TransferPendingProps> = ({
440
436
  if (
441
437
  tx &&
442
438
  tx.state === "confirmed" &&
443
- !tx?.decodedGuestModuleEvents?.some(
444
- (event) => event.type === "CallFailed",
445
- )
439
+ !hasFailedOrAbortedTransaction(tx)
446
440
  ) {
447
441
  lastGoodStepIndex = i
448
- } else if (
449
- tx?.decodedGuestModuleEvents?.some(
450
- (event) => event.type === "CallFailed",
451
- )
452
- ) {
442
+ } else if (hasFailedOrAbortedTransaction(tx)) {
453
443
  // Stop at first failure
454
444
  break
455
445
  }
@@ -482,13 +472,16 @@ export const TransferPending: React.FC<TransferPendingProps> = ({
482
472
  </div>
483
473
  </div>
484
474
 
485
- {/* OFT Progress Bar - Shows 20-minute countdown after deposit confirmed */}
486
- {isOFT && depositConfirmedAt && (
487
- <OFTProgressBar
488
- depositConfirmedAt={depositConfirmedAt}
489
- showContent={showContent}
490
- />
491
- )}
475
+ {/* OFT Progress Bar - uses quote-provided estimate when available */}
476
+ {isOFT &&
477
+ depositConfirmedAt &&
478
+ quote?.completionEstimateSeconds != null && (
479
+ <OFTProgressBar
480
+ depositConfirmedAt={depositConfirmedAt}
481
+ estimatedDurationSeconds={quote.completionEstimateSeconds}
482
+ showContent={showContent}
483
+ />
484
+ )}
492
485
 
493
486
  {/* Continue Button - Show only when there are failures */}
494
487
  {showContinueButton && (
@@ -5,7 +5,7 @@ import { logger } from "../../logger.js"
5
5
  import { useBalanceVisible } from "../hooks/useBalanceVisible.js"
6
6
  import { useClickTracking } from "../hooks/useClickTracking.js"
7
7
  import { useDisplayCurrencyPreference } from "../hooks/useDisplayCurrencyPreference.js"
8
- import { useFiatCurrencyList } from "../hooks/useFiatCurrencyList.js"
8
+ import { useFiatCurrencyList } from "../../query/fiat.hooks.js"
9
9
  import {
10
10
  SUPPORTED_LOCALES,
11
11
  useLocalePreference,
@@ -2,6 +2,7 @@ import type React from "react"
2
2
  import { useCallback, useEffect, useRef, useState } from "react"
3
3
  import { getChainInfo } from "../../chains.js"
4
4
  import { FIAT_CURRENCY_SYMBOLS } from "../../constants.js"
5
+ import { isPositiveNumber, toSafeNumber } from "../../utils/validation.js"
5
6
  import { logger } from "../../logger.js"
6
7
  import { TradeType } from "../../prepareSend.js"
7
8
  import {
@@ -65,6 +66,8 @@ const Withdraw: React.FC<WithdrawProps> = ({
65
66
  setWalletConfirmRetryHandler,
66
67
  swapProvider,
67
68
  bridgeProvider,
69
+ swapProviderFallback,
70
+ bridgeProviderFallback,
68
71
  onAmountUpdate,
69
72
  checkoutOnHandlers,
70
73
  recentTokens,
@@ -219,11 +222,13 @@ const Withdraw: React.FC<WithdrawProps> = ({
219
222
  onSend,
220
223
  onConfirm,
221
224
  onComplete,
222
- selectedToken: originToken as any,
225
+ selectedToken: originToken ?? undefined,
223
226
  setWalletConfirmRetryHandler,
224
227
  tradeType: tradeType,
225
228
  swapProvider,
226
229
  bridgeProvider,
230
+ swapProviderFallback,
231
+ bridgeProviderFallback,
227
232
  fundMethod: "wallet",
228
233
  mode,
229
234
  checkoutOnHandlers,
@@ -310,7 +315,7 @@ const Withdraw: React.FC<WithdrawProps> = ({
310
315
  "[trails-sdk] Auto-selecting origin token:",
311
316
  defaultOriginToken,
312
317
  )
313
- setOriginToken(defaultOriginToken as any)
318
+ setOriginToken(defaultOriginToken)
314
319
  setOriginChainId(defaultOriginToken.chainId)
315
320
  }
316
321
  }, [
@@ -350,8 +355,8 @@ const Withdraw: React.FC<WithdrawProps> = ({
350
355
  "[trails-sdk] Auto-selecting destination token:",
351
356
  defaultDestinationToken,
352
357
  )
353
- setDestinationToken(defaultDestinationToken as any)
354
- setSelectedDestToken(defaultDestinationToken as any)
358
+ setDestinationToken(defaultDestinationToken)
359
+ setSelectedDestToken(defaultDestinationToken)
355
360
 
356
361
  const chainInfo = getChainInfo(defaultDestinationToken.chainId)
357
362
  if (chainInfo) {
@@ -443,10 +448,11 @@ const Withdraw: React.FC<WithdrawProps> = ({
443
448
  ])
444
449
 
445
450
  useEffect(() => {
446
- if (selectedDestToken) {
447
- setSelectedDestinationChain(
448
- getChainInfo((selectedDestToken as any)?.chainId as any) as any,
449
- )
451
+ if (selectedDestToken?.chainId) {
452
+ const chainInfo = getChainInfo(selectedDestToken.chainId)
453
+ if (chainInfo) {
454
+ setSelectedDestinationChain(chainInfo)
455
+ }
450
456
  }
451
457
  }, [selectedDestToken, setSelectedDestinationChain])
452
458
 
@@ -457,7 +463,7 @@ const Withdraw: React.FC<WithdrawProps> = ({
457
463
  "[trails-sdk] Syncing destination token to useSendForm:",
458
464
  destinationToken,
459
465
  )
460
- setSelectedDestToken(destinationToken as any)
466
+ setSelectedDestToken(destinationToken)
461
467
  }
462
468
  }, [destinationToken, setSelectedDestToken])
463
469
 
@@ -565,7 +571,7 @@ const Withdraw: React.FC<WithdrawProps> = ({
565
571
 
566
572
  // Handle recent token selection
567
573
  const handleRecentTokenSelect = useCallback(
568
- (token: any) => {
574
+ (token: Token) => {
569
575
  if (showSourceTokenSelector) {
570
576
  handleSourceTokenSelectorSelect(token)
571
577
  } else if (showDestinationTokenSelector) {
@@ -717,7 +723,7 @@ const Withdraw: React.FC<WithdrawProps> = ({
717
723
 
718
724
  if (isEnteringFiat && tokenPriceUsd > 0) {
719
725
  // User is entering fiat, convert to token amount for backend
720
- const inputAmount = parseFloat(value) || 0
726
+ const inputAmount = toSafeNumber(value)
721
727
  const rateData = forexRateStore.getRate()
722
728
  const usdAmount =
723
729
  rateData && rateData.currency !== "USD"
@@ -778,7 +784,7 @@ const Withdraw: React.FC<WithdrawProps> = ({
778
784
  if (inputDisplayValue && tokenPriceUsd > 0) {
779
785
  const currentValue = parseFloat(inputDisplayValue)
780
786
 
781
- if (!Number.isNaN(currentValue) && currentValue > 0) {
787
+ if (isPositiveNumber(currentValue)) {
782
788
  const rateData = forexRateStore.getRate()
783
789
 
784
790
  if (newMode) {
@@ -837,7 +843,7 @@ const Withdraw: React.FC<WithdrawProps> = ({
837
843
  />
838
844
  </svg>
839
845
  {(() => {
840
- const inputValue = Number(inputDisplayValue) || 0
846
+ const inputValue = toSafeNumber(inputDisplayValue)
841
847
 
842
848
  if (isEnteringFiat) {
843
849
  // Currently entering in fiat, show the token amount
@@ -965,7 +971,7 @@ const Withdraw: React.FC<WithdrawProps> = ({
965
971
  <div className="min-w-[138px] flex">
966
972
  <TokenSelectorButton
967
973
  token={selectedDestToken}
968
- chainId={(selectedDestToken as any)?.chainId}
974
+ chainId={selectedDestToken?.chainId}
969
975
  onSelect={() => setShowDestinationTokenSelector(true)}
970
976
  unselectable={!!toToken}
971
977
  fullWidth={true}
@@ -1,4 +1,3 @@
1
- import { useQuery } from "@tanstack/react-query"
2
1
  import { useTokenPrice } from "../../prices.js"
3
2
  import {
4
3
  formatUsdAmountDisplay,
@@ -34,22 +33,11 @@ export function useAmountUsd({ amount, token, chainId }: UseAmountUsdProps): {
34
33
  : null,
35
34
  )
36
35
 
37
- const { data: amountUsd } = useQuery({
38
- queryKey: ["amountUsd", amount, tokenPrice?.priceUsd],
39
- queryFn: () => {
40
- if (!amount || !tokenPrice?.priceUsd) {
41
- return null
42
- }
43
-
44
- const tokenPriceValue = tokenPrice.priceUsd
45
- const value = Number(amount) * tokenPriceValue
46
- return value
47
- },
48
- enabled: !!amount && !!tokenPrice?.priceUsd,
49
- })
36
+ const amountUsd =
37
+ amount && tokenPrice?.priceUsd ? Number(amount) * tokenPrice.priceUsd : null
50
38
 
51
39
  return {
52
- amountUsd: amountUsd || null,
40
+ amountUsd: amountUsd ?? null,
53
41
  amountUsdFormatted: formatUsdAmountDisplay(amountUsd || 0),
54
42
  amountUsdFormattedLocale: formatUsdAmountLocaleDisplay(amountUsd || 0),
55
43
  }
@@ -12,6 +12,7 @@ import { MINUTE_MS, DAY_MS } from "../../utils/time.js"
12
12
  import { useTrails } from "../providers/TrailsProvider.js"
13
13
 
14
14
  import { addressEqual, normalizeAddress } from "../../utils/address.js"
15
+ import { isPositiveBigInt } from "../../utils/validation.js"
15
16
  interface UseCustomTokenSearchProps {
16
17
  searchQuery: string
17
18
  filteredTokensFormatted: Token[]
@@ -236,12 +237,7 @@ export function useCustomTokenSearch({
236
237
 
237
238
  // Helper function to check if a token has a balance
238
239
  const hasBalance = useCallback((token: Token): boolean => {
239
- try {
240
- const balance = token.balance || "0"
241
- return BigInt(balance) > 0n
242
- } catch {
243
- return false
244
- }
240
+ return isPositiveBigInt(token.balance || "0")
245
241
  }, [])
246
242
 
247
243
  // Apply chain filter to tokens and merge with custom tokens
@@ -5,9 +5,8 @@ import React, {
5
5
  useEffect,
6
6
  type ReactNode,
7
7
  } from "react"
8
- import { useExchangeRate } from "./useExchangeRate.js"
8
+ import { useExchangeRate, useFiatCurrencyList } from "../../query/fiat.hooks.js"
9
9
  import { forexRateStore } from "../utils/forexRateStore.js"
10
- import { useFiatCurrencyList } from "./useFiatCurrencyList.js"
11
10
 
12
11
  // For backwards compatibility, export SUPPORTED_CURRENCIES as a placeholder
13
12
  // The actual data comes from the API via useFiatCurrencyList
@@ -1,44 +1,23 @@
1
1
  import { useQuery } from "@tanstack/react-query"
2
2
  import type { TrailsOnramp } from "../../onrampClient.js"
3
3
  import { useOnrampClient } from "../../onrampClient.js"
4
- import { queryPersister } from "../../query/persister.js"
5
- import { DAY_MS } from "../../utils/time.js"
4
+ import type { MeldFiatCurrency } from "../../onramp-client/trails-onramp.gen.js"
5
+ import { meldQueries } from "../../query/meld.queries.js"
6
6
 
7
- const FIAT_CURRENCIES_CACHE_DURATION = DAY_MS
8
-
9
- export interface OnrampFiatCurrency {
10
- currencyCode: string
11
- name: string
12
- symbolImageUrl: string
13
- }
7
+ export type OnrampFiatCurrency = MeldFiatCurrency
14
8
 
15
9
  export interface UseFiatOnRampCurrenciesOptions {
16
10
  trailsClient?: TrailsOnramp | null
17
11
  countryCode?: string | null
18
- /**
19
- * Whether to enable the hook (defaults to true)
20
- */
21
12
  enabled?: boolean
22
13
  }
23
14
 
24
15
  export interface UseFiatOnRampCurrenciesResult {
25
- /**
26
- * Array of fiat currencies available for the given country
27
- */
28
- fiatCurrencies: OnrampFiatCurrency[]
29
- /**
30
- * Whether the request is currently loading
31
- */
16
+ fiatCurrencies: MeldFiatCurrency[]
32
17
  isLoading: boolean
33
- /**
34
- * Error object if the request failed, null otherwise
35
- */
36
18
  error: Error | null
37
19
  }
38
20
 
39
- /**
40
- * Hook to fetch available fiat currencies to onramp for a given country.
41
- */
42
21
  export function useFiatOnRampCurrencies(
43
22
  options: UseFiatOnRampCurrenciesOptions,
44
23
  ): UseFiatOnRampCurrenciesResult {
@@ -46,62 +25,18 @@ export function useFiatOnRampCurrencies(
46
25
 
47
26
  const defaultOnrampClient = useOnrampClient()
48
27
 
49
- // Determine if query should be enabled
50
- const isQueryEnabled = () => {
51
- if (!enabled) return false
52
- if (!countryCode) return false
53
- if (trailsClient !== undefined && !trailsClient) return false
54
- return true
55
- }
28
+ const effectiveCountryCode =
29
+ !enabled || !countryCode || (trailsClient !== undefined && !trailsClient)
30
+ ? null
31
+ : countryCode
32
+
33
+ const client = trailsClient !== undefined ? trailsClient : defaultOnrampClient
56
34
 
57
- // Use React Query for automatic caching based on countryCode
58
35
  const {
59
36
  data: fiatCurrencies = [],
60
37
  isLoading,
61
38
  error,
62
- } = useQuery({
63
- queryKey: ["meldFiatCurrencies", countryCode || "unknown", "onrampClient"],
64
- queryFn: async () => {
65
- if (!countryCode) {
66
- throw new Error("countryCode is required")
67
- }
68
-
69
- const client = trailsClient || defaultOnrampClient
70
- const response = await client.getMeldFiatCurrencies({
71
- countryCode,
72
- })
73
-
74
- // Parse fiat currencies from response
75
- const responseCurrencies = Array.isArray(response.fiatCurrencies)
76
- ? response.fiatCurrencies
77
- : []
78
-
79
- const currencies = responseCurrencies.map(
80
- (currency: {
81
- currencyCode?: string
82
- currency_code?: string
83
- name?: string
84
- symbolImageUrl?: string
85
- symbol_image_url?: string
86
- }) => ({
87
- currencyCode: currency.currencyCode || currency.currency_code || "",
88
- name: currency.name || "",
89
- symbolImageUrl:
90
- currency.symbolImageUrl || currency.symbol_image_url || "",
91
- }),
92
- )
93
-
94
- return currencies
95
- },
96
- enabled: isQueryEnabled(),
97
- staleTime: FIAT_CURRENCIES_CACHE_DURATION,
98
- gcTime: FIAT_CURRENCIES_CACHE_DURATION,
99
- refetchOnMount: false,
100
- refetchOnWindowFocus: false,
101
- refetchOnReconnect: false,
102
- retry: 2,
103
- persister: queryPersister.persisterFn,
104
- })
39
+ } = useQuery(meldQueries.fiatCurrencyList(client, effectiveCountryCode))
105
40
 
106
41
  return {
107
42
  fiatCurrencies,