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
@@ -1,21 +1,20 @@
1
- import { useState, useCallback, useEffect } from "react"
1
+ import { useMemo } from "react"
2
2
  import { useQuery } from "@tanstack/react-query"
3
3
  import { useAccount } from "wagmi"
4
4
  import { useOnrampClient } from "../../onrampClient.js"
5
- import { MINUTE_MS, SECOND_MS } from "../../utils/time.js"
6
- import { logger } from "../../logger.js"
7
- import { addressEqual, normalizeAddress } from "../../utils/address.js"
5
+ import { SECOND_MS } from "../../utils/time.js"
6
+ import { addressEqual } from "../../utils/address.js"
8
7
  import {
9
8
  getCurrencySymbol,
10
9
  parseCurrencyCode,
11
10
  getCountryFlag,
12
11
  } from "../../utils.js"
13
- import { useMeldPaymentMethods } from "../../meld/utils/meld.js"
12
+ import { useMeldPaymentMethods } from "../../query/meld.hooks.js"
13
+ import { meldQueries } from "../../query/meld.queries.js"
14
14
  import type {
15
- SearchMeldTransactionsRequest,
16
- SearchMeldTransactionsResponse,
17
15
  MeldTransaction,
18
- } from "../../onramp-client/trails-onramp.gen.js"
16
+ MeldPaymentMethod,
17
+ } from "../../query/meld.fetchers.js"
19
18
 
20
19
  export type MeldTransactionStatus =
21
20
  | "PENDING"
@@ -43,7 +42,6 @@ export interface MeldTransactionData {
43
42
  transactionHash?: string
44
43
  externalSessionId?: string
45
44
  externalCustomerId?: string
46
- // Additional display data
47
45
  countryCode?: string
48
46
  exchangeRate?: number
49
47
  totalFee?: number
@@ -51,12 +49,10 @@ export interface MeldTransactionData {
51
49
  transactionFee?: number
52
50
  institutionName?: string
53
51
  lowKyc?: boolean
54
- // UI enhancement fields
55
52
  sourceCurrencySymbol?: string
56
53
  destinationCurrencySymbol?: string
57
54
  paymentMethodLogo?: string
58
55
  currencyFlag?: string
59
- // Token info for UI components
60
56
  sourceTokenSymbol?: string
61
57
  sourceTokenChainId?: number
62
58
  sourceTokenAddress?: string
@@ -82,13 +78,10 @@ export interface UseMeldTransactionHistoryReturn {
82
78
 
83
79
  function parseMeldTransaction(
84
80
  transaction: MeldTransaction,
85
- paymentMethods?: Array<any>,
81
+ paymentMethods?: MeldPaymentMethod[],
86
82
  ): MeldTransactionData {
87
- // Parse the transaction data from the API response
88
- // The API currently only defines id, but we expect more fields from the actual response
89
83
  const txn = transaction as any
90
84
 
91
- // Parse source and destination currency information
92
85
  const sourceCurrencyCode = txn.sourceCurrencyCode || txn.fiatCurrency
93
86
  const destinationCurrencyCode =
94
87
  txn.destinationCurrencyCode || txn.cryptoCurrency
@@ -111,7 +104,6 @@ function parseMeldTransaction(
111
104
  transactionHash: txn.transactionHash || txn.hash,
112
105
  externalSessionId: txn.externalSessionId || txn.sessionId,
113
106
  externalCustomerId: txn.externalCustomerId || txn.customerId,
114
- // Additional data
115
107
  countryCode: txn.countryCode,
116
108
  exchangeRate: txn.exchangeRate,
117
109
  totalFee: txn.totalFee,
@@ -119,7 +111,6 @@ function parseMeldTransaction(
119
111
  transactionFee: txn.transactionFee,
120
112
  institutionName: txn.institutionName,
121
113
  lowKyc: txn.lowKyc,
122
- // UI enhancement fields - we'll populate these
123
114
  sourceCurrencySymbol: getCurrencySymbol(sourceToken.symbol),
124
115
  destinationCurrencySymbol: getCurrencySymbol(destinationToken.symbol),
125
116
  paymentMethodLogo: getPaymentMethodLogo(
@@ -127,24 +118,21 @@ function parseMeldTransaction(
127
118
  paymentMethods,
128
119
  ),
129
120
  currencyFlag: getCountryFlag(txn.countryCode),
130
- // Add parsed token info for UI components
131
121
  sourceTokenSymbol: sourceToken.symbol,
132
122
  sourceTokenChainId: sourceToken.chainId,
133
- sourceTokenAddress: undefined, // Token contract address not available from parsed currency code
123
+ sourceTokenAddress: undefined,
134
124
  destinationTokenSymbol: destinationToken.symbol,
135
125
  destinationTokenChainId: destinationToken.chainId,
136
- destinationTokenAddress: undefined, // Token contract address not available from parsed currency code
126
+ destinationTokenAddress: undefined,
137
127
  }
138
128
  }
139
129
 
140
- // Helper function to get payment method logo
141
130
  function getPaymentMethodLogo(
142
131
  paymentMethod?: string,
143
- paymentMethods?: Array<any>,
132
+ paymentMethods?: MeldPaymentMethod[],
144
133
  ): string {
145
134
  if (!paymentMethod || !paymentMethods) return ""
146
135
 
147
- // Find the payment method in the data
148
136
  const methodData = paymentMethods.find(
149
137
  (method) =>
150
138
  addressEqual(method.paymentMethod, paymentMethod) ||
@@ -152,7 +140,6 @@ function getPaymentMethodLogo(
152
140
  )
153
141
 
154
142
  if (methodData?.logos) {
155
- // Prefer light logo, fallback to dark
156
143
  return methodData.logos.light || methodData.logos.dark || ""
157
144
  }
158
145
 
@@ -163,85 +150,33 @@ export function useMeldTransactionHistory({
163
150
  enabled = true,
164
151
  limit = 20,
165
152
  autoRefetch = false,
166
- refetchInterval = 10 * SECOND_MS, // 10 seconds
153
+ refetchInterval = 10 * SECOND_MS,
167
154
  }: UseMeldTransactionHistoryParams = {}): UseMeldTransactionHistoryReturn {
168
155
  const { address: walletAddress } = useAccount()
169
156
  const onrampClient = useOnrampClient()
170
- const [hasMore, setHasMore] = useState(false)
171
157
 
172
- // Fetch payment methods for logo data
173
- const { paymentMethods } = useMeldPaymentMethods(onrampClient, "USD")
158
+ const { data: paymentMethods } = useMeldPaymentMethods("USD")
174
159
 
175
160
  const { data, isLoading, error, refetch, isFetching } = useQuery({
176
- queryKey: ["meldTransactionHistory", walletAddress, limit],
177
- queryFn: async () => {
178
- if (!walletAddress) {
179
- throw new Error("Wallet address required")
180
- }
181
-
182
- // Use wallet address as the external customer ID
183
- const request: SearchMeldTransactionsRequest = {
184
- externalCustomerIds: normalizeAddress(walletAddress),
185
- limit: limit,
186
- // Sort by most recent first (API may support this in the future)
187
- // from: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString(), // Last 30 days
188
- }
189
-
190
- logger.console.log(
191
- "[trails-sdk] searchMeldTransactions request:",
192
- request,
193
- )
194
-
195
- try {
196
- const response: SearchMeldTransactionsResponse =
197
- await onrampClient.searchMeldTransactions(request)
198
-
199
- logger.console.log("[trails-sdk] searchMeldTransactions response:", {
200
- transactionCount: response.transactions?.transactions?.length || 0,
201
- })
202
-
203
- // Parse transactions with payment method data for logos
204
- const parsedTransactions: MeldTransactionData[] = (
205
- response.transactions?.transactions || []
206
- ).map((txn) => parseMeldTransaction(txn, paymentMethods))
207
-
208
- // Check if there might be more transactions
209
- setHasMore(parsedTransactions.length >= limit)
210
-
211
- return {
212
- transactions: parsedTransactions,
213
- }
214
- } catch (apiError) {
215
- logger.console.error(
216
- "[trails-sdk] searchMeldTransactions error:",
217
- apiError,
218
- )
219
- throw apiError
220
- }
221
- },
222
- enabled: enabled && !!walletAddress,
223
- staleTime: autoRefetch ? 0 : 5 * MINUTE_MS, // 5 minutes if not auto-refetching
161
+ ...meldQueries.transactionHistoryList(onrampClient, walletAddress, limit),
162
+ enabled,
163
+ ...(autoRefetch && { staleTime: 0 }),
224
164
  refetchInterval: autoRefetch ? refetchInterval : false,
225
165
  placeholderData: (previousData) => previousData,
226
166
  })
227
167
 
228
- const transactions = data?.transactions ?? []
229
-
230
- const refetchTransactions = useCallback(() => {
231
- refetch()
232
- }, [refetch])
233
-
234
- // Reset hasMore when wallet address changes
235
- // biome-ignore lint/correctness/useExhaustiveDependencies: we intentionally want this to run when walletAddress changes
236
- useEffect(() => {
237
- setHasMore(false)
238
- }, [walletAddress])
168
+ const transactions = useMemo(() => {
169
+ if (!data?.transactions?.length) return []
170
+ return data.transactions.map((txn) =>
171
+ parseMeldTransaction(txn, paymentMethods),
172
+ )
173
+ }, [data, paymentMethods])
239
174
 
240
175
  return {
241
176
  transactions,
242
177
  loading: isLoading || isFetching,
243
178
  error: error instanceof Error ? error.message : null,
244
- refetch: refetchTransactions,
245
- hasMore,
179
+ refetch,
180
+ hasMore: data?.hasMore ?? false,
246
181
  }
247
182
  }
@@ -1,7 +1,7 @@
1
1
  import { useQuery } from "@tanstack/react-query"
2
2
  import { useCountryCode } from "../../query/geo.hooks.js"
3
- import { MINUTE_MS } from "../../utils/time.js"
4
3
  import { useOnrampClient } from "../../onrampClient.js"
4
+ import { meldQueries } from "../../query/meld.queries.js"
5
5
 
6
6
  export interface OnRampCountryDefaults {
7
7
  countryCode: string
@@ -11,32 +11,14 @@ export interface OnRampCountryDefaults {
11
11
  }
12
12
 
13
13
  export interface UseOnRampCountryDefaultsOptions {
14
- /**
15
- * Whether to enable the hook (defaults to true)
16
- */
17
14
  enabled?: boolean
18
15
  }
19
16
 
20
17
  export interface UseOnRampCountryDefaultsResult {
21
- /**
22
- * Detected country code (ISO 2-letter code, e.g., "US", "GB")
23
- */
24
18
  countryCode: string | null
25
- /**
26
- * Default fiat currency code for the detected country (e.g., "USD")
27
- */
28
19
  defaultCurrencyCode: string | null
29
- /**
30
- * Default payment methods for the detected country
31
- */
32
20
  defaultPaymentMethods: Array<string>
33
- /**
34
- * Whether the request is currently loading
35
- */
36
21
  isLoading: boolean
37
- /**
38
- * Error object if the request failed, null otherwise
39
- */
40
22
  error: Error | null
41
23
  }
42
24
 
@@ -45,49 +27,21 @@ export function useOnRampCountryDefaults(
45
27
  ): UseOnRampCountryDefaultsResult {
46
28
  const { enabled = true } = options
47
29
 
48
- // Get country code using the dedicated hook
49
30
  const {
50
31
  data: countryCode,
51
32
  isLoading: isCountryLoading,
52
33
  error: countryError,
53
34
  } = useCountryCode({ enabled })
54
35
 
55
- // Get onramp client
56
36
  const onrampClient = useOnrampClient()
57
37
 
58
- // Fetch country defaults once we have the country code
59
38
  const {
60
39
  data: countryDefaults,
61
40
  isLoading: isDefaultsLoading,
62
41
  error: defaultsError,
63
42
  } = useQuery({
64
- queryKey: ["meldCountryDefaults", countryCode],
65
- queryFn: async () => {
66
- if (!countryCode) {
67
- throw new Error("Country code is required")
68
- }
69
-
70
- const responseData = await onrampClient.getMeldCountryDefaults({
71
- countryCode,
72
- })
73
-
74
- // Extract data from response - only use API value; caller will fall back to USD if missing
75
- const defaultCurrencyCode =
76
- responseData.defaults?.[0]?.defaultCurrencyCode ?? undefined
77
- const defaultPaymentMethods =
78
- responseData.defaults?.[0]?.defaultPaymentMethods || []
79
-
80
- return {
81
- defaultCurrencyCode,
82
- defaultPaymentMethods,
83
- }
84
- },
85
- enabled: enabled && !!countryCode && !!onrampClient,
86
- staleTime: 10 * MINUTE_MS, // 10 minutes - country defaults don't change frequently
87
- gcTime: 30 * MINUTE_MS, // 30 minutes cache time
88
- retry: 2,
89
- refetchOnWindowFocus: false,
90
- refetchOnReconnect: true,
43
+ ...meldQueries.countryDefaultsByCode(onrampClient, countryCode ?? null),
44
+ enabled,
91
45
  })
92
46
 
93
47
  const isLoading = isCountryLoading || isDefaultsLoading
@@ -1,18 +1,11 @@
1
1
  import { useQuery } from "@tanstack/react-query"
2
- import { MINUTE_MS } from "../../utils/time.js"
2
+ import type { MeldPaymentMethod } from "../../query/meld.fetchers.js"
3
3
  import { useOnRampCountryDefaults } from "./useOnRampCountryDefaults.js"
4
4
  import type { TrailsOnramp } from "../../onrampClient.js"
5
5
  import { useOnrampClient } from "../../onrampClient.js"
6
+ import { meldQueries } from "../../query/meld.queries.js"
6
7
 
7
- export interface PaymentMethod {
8
- paymentMethod: string
9
- name: string
10
- paymentType: string
11
- logos?: {
12
- dark?: string
13
- light?: string
14
- }
15
- }
8
+ export type PaymentMethod = MeldPaymentMethod
16
9
 
17
10
  export interface UseOnRampPaymentMethodsOptions {
18
11
  trailsClient?: TrailsOnramp | null
@@ -21,28 +14,11 @@ export interface UseOnRampPaymentMethodsOptions {
21
14
  }
22
15
 
23
16
  export interface UseOnRampPaymentMethodsResult {
24
- /**
25
- * Array of payment methods available for the resolved fiat currency
26
- */
27
17
  paymentMethods: PaymentMethod[]
28
- /**
29
- * Whether the request is currently loading
30
- */
31
18
  isLoading: boolean
32
- /**
33
- * Error object if the request failed, null otherwise
34
- */
35
19
  error: Error | null
36
20
  }
37
21
 
38
- /**
39
- * Hook to fetch Meld payment methods for a given fiat currency.
40
- *
41
- * Can use either TrailsApi client or direct fetch to localhost API.
42
- * If fiatCurrency is not provided, will fall back to `defaultCurrencyCode` if given,
43
- * otherwise it will use "USD".
44
- */
45
- // Allowed payment methods to filter from the API response
46
22
  const ALLOWED_PAYMENT_METHODS = [
47
23
  "CREDIT_DEBIT_CARD",
48
24
  "EXCHANGE",
@@ -52,6 +28,13 @@ const ALLOWED_PAYMENT_METHODS = [
52
28
  "SEPA",
53
29
  ] as const
54
30
 
31
+ const selectAllowedPaymentMethods = (methods: MeldPaymentMethod[]) =>
32
+ methods.filter((method) =>
33
+ ALLOWED_PAYMENT_METHODS.includes(
34
+ method.paymentMethod as (typeof ALLOWED_PAYMENT_METHODS)[number],
35
+ ),
36
+ )
37
+
55
38
  export function useOnRampPaymentMethods(
56
39
  options: UseOnRampPaymentMethodsOptions,
57
40
  ): UseOnRampPaymentMethodsResult {
@@ -59,88 +42,26 @@ export function useOnRampPaymentMethods(
59
42
 
60
43
  const defaultOnrampClient = useOnrampClient()
61
44
 
62
- const {
63
- countryCode,
64
- defaultCurrencyCode,
65
- isLoading: isLoadingCountryDefaults,
66
- } = useOnRampCountryDefaults({
67
- enabled: enabled,
68
- })
45
+ const { defaultCurrencyCode, isLoading: isLoadingCountryDefaults } =
46
+ useOnRampCountryDefaults({ enabled })
69
47
 
70
48
  const currencyToUse = fiatCurrency || defaultCurrencyCode || null
71
49
 
72
- // Determine if query should be enabled
73
- const isQueryEnabled = () => {
74
- if (!enabled) return false
75
- if (trailsClient !== undefined && !trailsClient) return false
76
- if (!currencyToUse) return false
77
- if (!fiatCurrency && isLoadingCountryDefaults) return false
78
- return true
79
- }
50
+ const client = trailsClient !== undefined ? trailsClient : defaultOnrampClient
51
+
52
+ const factoryOptions = meldQueries.paymentMethodList(client, currencyToUse)
53
+
54
+ const isQueryEnabled =
55
+ enabled && !(fiatCurrency === undefined && isLoadingCountryDefaults)
80
56
 
81
- // Use React Query for automatic caching based on countryCode and currency
82
57
  const {
83
58
  data: paymentMethods = [],
84
59
  isLoading,
85
60
  error,
86
61
  } = useQuery({
87
- queryKey: [
88
- "meldPaymentMethods",
89
- countryCode || "unknown",
90
- currencyToUse,
91
- "onrampClient",
92
- ],
93
- queryFn: async () => {
94
- if (!currencyToUse) {
95
- throw new Error("Currency is required but not available")
96
- }
97
-
98
- const client = trailsClient || defaultOnrampClient
99
- const response = await client.getMeldPaymentMethods({
100
- fiatCurrency: currencyToUse,
101
- })
102
-
103
- // Parse payment methods from response
104
- const responseMethods = Array.isArray(response.paymentMethods)
105
- ? response.paymentMethods
106
- : []
107
-
108
- const methods = responseMethods.map(
109
- (method: {
110
- paymentMethod?: string
111
- payment_method?: string
112
- name?: string
113
- paymentType?: string
114
- payment_type?: string
115
- logos?: { dark?: string; light?: string }
116
- }) => ({
117
- paymentMethod: method.paymentMethod || method.payment_method || "",
118
- name: method.name || "",
119
- paymentType: method.paymentType || method.payment_type || "",
120
- logos: method.logos
121
- ? {
122
- dark: method.logos.dark,
123
- light: method.logos.light,
124
- }
125
- : undefined,
126
- }),
127
- )
128
-
129
- // Filter to only include allowed payment methods
130
- const filteredMethods = methods.filter((method) =>
131
- ALLOWED_PAYMENT_METHODS.includes(
132
- method.paymentMethod as (typeof ALLOWED_PAYMENT_METHODS)[number],
133
- ),
134
- )
135
-
136
- return filteredMethods
137
- },
138
- enabled: isQueryEnabled(),
139
- staleTime: 5 * MINUTE_MS, // 5 minutes - payment methods don't change frequently
140
- gcTime: 30 * MINUTE_MS, // 30 minutes cache time
141
- retry: 2,
142
- refetchOnWindowFocus: false,
143
- refetchOnReconnect: true,
62
+ ...factoryOptions,
63
+ enabled: isQueryEnabled,
64
+ select: selectAllowedPaymentMethods,
144
65
  })
145
66
 
146
67
  return {
@@ -1,5 +1,6 @@
1
1
  import { useMemo } from "react"
2
2
  import { useQuery } from "@tanstack/react-query"
3
+ import { isValidStringAmount } from "../../utils/validation.js"
3
4
  import { logger } from "../../logger.js"
4
5
  import { SECOND_MS, MINUTE_MS } from "../../utils/time.js"
5
6
  import type { MeldQuote } from "../../meld/utils/meld.js"
@@ -70,11 +71,7 @@ export function useOnRampQuote(
70
71
  // Check if all required params are present
71
72
  const hasRequiredParams = useMemo(() => {
72
73
  // Validate amount is present and is a valid positive number
73
- const isValidAmount =
74
- Boolean(amount) &&
75
- amount !== "0" &&
76
- !Number.isNaN(Number(amount)) &&
77
- Number(amount) > 0
74
+ const isValidAmount = isValidStringAmount(amount ?? "")
78
75
 
79
76
  return (
80
77
  isValidAmount &&
@@ -82,6 +82,10 @@ export type UseQuoteProps = {
82
82
  swapProvider?: RouteProvider | null
83
83
  /** Optional quote bridge provider ID to use. If not specified, the best available provider will be selected. */
84
84
  bridgeProvider?: RouteProvider | null
85
+ /** Optional swap provider fallback flag passed to QuoteIntent request options. */
86
+ swapProviderFallback?: boolean
87
+ /** Optional bridge provider fallback flag passed to QuoteIntent request options. */
88
+ bridgeProviderFallback?: boolean
85
89
  /**
86
90
  * Optional checkout event handlers for tracking the states of a Trails transaction.
87
91
  *
@@ -439,6 +443,8 @@ export function useQuote({
439
443
  checkoutOnHandlers,
440
444
  swapProvider,
441
445
  bridgeProvider,
446
+ swapProviderFallback,
447
+ bridgeProviderFallback,
442
448
  paymasterUrl,
443
449
  selectedFeeOption,
444
450
  nodeGatewayEnv,
@@ -675,6 +681,8 @@ export function useQuote({
675
681
  slippageTolerance,
676
682
  swapProvider,
677
683
  bridgeProvider,
684
+ swapProviderFallback,
685
+ bridgeProviderFallback,
678
686
  apiKey,
679
687
  isSmartWallet,
680
688
  fundMethod,
@@ -913,18 +921,6 @@ export function useQuote({
913
921
  ? parseUnits("100", sourceTokenDecimals).toString()
914
922
  : originTokenBalanceAmount
915
923
 
916
- // Validate effectiveOriginTokenBalance for EXACT_INPUT trade type
917
- if (
918
- tradeType === TradeType.EXACT_INPUT &&
919
- (!effectiveOriginTokenBalance ||
920
- effectiveOriginTokenBalance === "0")
921
- ) {
922
- logger.console.log(
923
- "[trails-sdk] [useQuote] Skipping quote for EXACT_INPUT with zero effectiveOriginTokenBalance",
924
- )
925
- return null
926
- }
927
-
928
924
  const options: PrepareSendOptions = {
929
925
  queryClient,
930
926
  account: walletClient.account!,
@@ -948,6 +944,8 @@ export function useQuote({
948
944
  slippageTolerance: slippageTolerance?.toString(),
949
945
  swapProvider: effectiveSwapProvider,
950
946
  bridgeProvider: effectiveBridgeProvider,
947
+ swapProviderFallback,
948
+ bridgeProviderFallback,
951
949
  paymasterUrl: paymasterUrl,
952
950
  selectedFeeOption: selectedFeeOption ?? null,
953
951
  abortSignal: combinedAbortSignal,
@@ -104,6 +104,8 @@ export type UseSendProps = {
104
104
  tradeType?: TradeType
105
105
  swapProvider?: string
106
106
  bridgeProvider?: string
107
+ swapProviderFallback?: boolean
108
+ bridgeProviderFallback?: boolean
107
109
  fundMethod?: FundMethod
108
110
  mode?: "pay" | "fund" | "earn" | "swap" | "withdraw"
109
111
  checkoutOnHandlers?: CheckoutOnHandlers
@@ -206,6 +208,8 @@ export function useSendForm({
206
208
  tradeType = TradeType.EXACT_OUTPUT,
207
209
  swapProvider,
208
210
  bridgeProvider,
211
+ swapProviderFallback,
212
+ bridgeProviderFallback,
209
213
  fundMethod,
210
214
  mode,
211
215
  checkoutOnHandlers,
@@ -888,6 +892,8 @@ export function useSendForm({
888
892
  onStatusUpdate: handleTransactionStateChange,
889
893
  swapProvider: swapProvider as RouteProvider | null | undefined,
890
894
  bridgeProvider: bridgeProvider as RouteProvider | null | undefined,
895
+ swapProviderFallback,
896
+ bridgeProviderFallback,
891
897
  checkoutOnHandlers,
892
898
  paymasterUrl,
893
899
  selectedFeeOption: selectedFeeOption ?? null,
@@ -12,6 +12,7 @@ import {
12
12
  isNativeToken as isNativeTokenUtil,
13
13
  normalizeAddress,
14
14
  } from "../../utils/address.js"
15
+ import { isValidDecimals } from "../../utils/validation.js"
15
16
  import {
16
17
  useAccountTotalBalanceUsd,
17
18
  useHasSufficientBalanceUsd,
@@ -433,9 +434,7 @@ export function useTokenList({
433
434
 
434
435
  return chainFilteredTokenList.tokens
435
436
  .filter((tokenInfo: ApiTokenInfo) => {
436
- // Validate decimals - must be between 1 and 18
437
- const decimals = tokenInfo.decimals
438
- if (!Number.isInteger(decimals) || decimals < 1 || decimals > 18) {
437
+ if (!isValidDecimals(tokenInfo.decimals)) {
439
438
  logger.console.warn(
440
439
  "[trails-sdk] Skipping token with invalid decimals:",
441
440
  {
@@ -685,9 +684,7 @@ export function useTokenList({
685
684
 
686
685
  return searchTokensResult.tokens
687
686
  .filter((tokenInfo: ApiTokenInfo) => {
688
- // Validate decimals - must be between 1 and 18 (formatRawAmount requires 1-18)
689
- const decimals = tokenInfo.decimals
690
- if (!Number.isInteger(decimals) || decimals < 1 || decimals > 18) {
687
+ if (!isValidDecimals(tokenInfo.decimals)) {
691
688
  logger.console.warn(
692
689
  "[trails-sdk] Skipping token with invalid decimals:",
693
690
  {