0xtrails 0.13.1 → 0.13.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 (229) hide show
  1. package/dist/{ccip-DStzFCYT.js → ccip-CT_An6eM.js} +28 -28
  2. package/dist/chains.d.ts +1 -1
  3. package/dist/chains.d.ts.map +1 -1
  4. package/dist/constants.d.ts +1 -0
  5. package/dist/constants.d.ts.map +1 -1
  6. package/dist/customTokens.d.ts.map +1 -1
  7. package/dist/{index-HY9_ppit.js → index-RfqL5Foz.js} +56523 -43196
  8. package/dist/index.d.ts +1 -0
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +383 -332
  11. package/dist/intents.d.ts +8 -2
  12. package/dist/intents.d.ts.map +1 -1
  13. package/dist/keyMachineClient.d.ts +9 -0
  14. package/dist/keyMachineClient.d.ts.map +1 -0
  15. package/dist/keymachine/index.d.ts +14 -0
  16. package/dist/keymachine/index.d.ts.map +1 -0
  17. package/dist/keymachine/key-machine.gen.d.ts +461 -0
  18. package/dist/keymachine/key-machine.gen.d.ts.map +1 -0
  19. package/dist/onramp/MeshConnectFlow.d.ts +18 -0
  20. package/dist/onramp/MeshConnectFlow.d.ts.map +1 -0
  21. package/dist/onramp/MeshConnectIframe.d.ts +13 -0
  22. package/dist/onramp/MeshConnectIframe.d.ts.map +1 -0
  23. package/dist/onramp/SendFromExchangeButton.d.ts +16 -0
  24. package/dist/onramp/SendFromExchangeButton.d.ts.map +1 -0
  25. package/dist/onramp/TrailsOnRampProvider.d.ts +31 -0
  26. package/dist/onramp/TrailsOnRampProvider.d.ts.map +1 -0
  27. package/dist/onramp/index.d.ts +13 -0
  28. package/dist/onramp/index.d.ts.map +1 -0
  29. package/dist/onramp/meshconnect.d.ts +30 -0
  30. package/dist/onramp/meshconnect.d.ts.map +1 -0
  31. package/dist/onramp/trailsOnramp.d.ts +24 -0
  32. package/dist/onramp/trailsOnramp.d.ts.map +1 -0
  33. package/dist/onramp-client/index.d.ts +3 -3
  34. package/dist/onramp-client/index.d.ts.map +1 -1
  35. package/dist/prepareSend.d.ts.map +1 -1
  36. package/dist/query/balance.fetchers.d.ts +27 -0
  37. package/dist/query/balance.fetchers.d.ts.map +1 -1
  38. package/dist/query/balance.hooks.d.ts +19 -0
  39. package/dist/query/balance.hooks.d.ts.map +1 -1
  40. package/dist/query/balance.queries.d.ts +18 -1
  41. package/dist/query/balance.queries.d.ts.map +1 -1
  42. package/dist/query/chains.queries.d.ts.map +1 -1
  43. package/dist/query/meld.fetchers.d.ts +1 -1
  44. package/dist/query/meld.fetchers.d.ts.map +1 -1
  45. package/dist/query/meld.hooks.d.ts +3 -3
  46. package/dist/query/meld.hooks.d.ts.map +1 -1
  47. package/dist/query/meld.queries.d.ts +1 -1
  48. package/dist/query/meld.queries.d.ts.map +1 -1
  49. package/dist/query/tokenList.queries.d.ts +54 -0
  50. package/dist/query/tokenList.queries.d.ts.map +1 -0
  51. package/dist/recover.d.ts +3 -1
  52. package/dist/recover.d.ts.map +1 -1
  53. package/dist/tokens.d.ts +13 -0
  54. package/dist/tokens.d.ts.map +1 -1
  55. package/dist/transactionIntent/deposits/depositOrchestrator.d.ts +2 -2
  56. package/dist/transactionIntent/deposits/depositOrchestrator.d.ts.map +1 -1
  57. package/dist/transactionIntent/deposits/gaslessDeposit.d.ts +2 -2
  58. package/dist/transactionIntent/deposits/gaslessDeposit.d.ts.map +1 -1
  59. package/dist/transactionIntent/deposits/standardDeposit.d.ts +1 -1
  60. package/dist/transactionIntent/deposits/standardDeposit.d.ts.map +1 -1
  61. package/dist/transactionIntent/handlers/intentHandler.d.ts.map +1 -1
  62. package/dist/transactionIntent/helpers/transactionStateHelpers.d.ts.map +1 -1
  63. package/dist/transactionIntent/quote/normalizeQuote.d.ts.map +1 -1
  64. package/dist/transactionIntent/types.d.ts +1 -1
  65. package/dist/transactionIntent/types.d.ts.map +1 -1
  66. package/dist/transactions.d.ts +3 -0
  67. package/dist/transactions.d.ts.map +1 -1
  68. package/dist/umd/trails.min.js +291 -202
  69. package/dist/walletUtils.d.ts +2 -1
  70. package/dist/walletUtils.d.ts.map +1 -1
  71. package/dist/wallets.d.ts +13 -54
  72. package/dist/wallets.d.ts.map +1 -1
  73. package/dist/widget/components/ClassicSwap.d.ts.map +1 -1
  74. package/dist/widget/components/ConnectWallet.d.ts.map +1 -1
  75. package/dist/widget/components/ConnectedWallets.d.ts.map +1 -1
  76. package/dist/widget/components/DirectTransfer.d.ts +1 -1
  77. package/dist/widget/components/DirectTransfer.d.ts.map +1 -1
  78. package/dist/widget/components/Fund.d.ts.map +1 -1
  79. package/dist/widget/components/FundMethods.d.ts.map +1 -1
  80. package/dist/widget/components/MeshExchangeSelection.d.ts +11 -0
  81. package/dist/widget/components/MeshExchangeSelection.d.ts.map +1 -0
  82. package/dist/widget/components/OnrampHistoryRow.d.ts +1 -1
  83. package/dist/widget/components/OnrampHistoryRow.d.ts.map +1 -1
  84. package/dist/widget/components/Pay.d.ts.map +1 -1
  85. package/dist/widget/components/PoolDeposit.d.ts.map +1 -1
  86. package/dist/widget/components/QRCodeWalletSelect.d.ts +1 -1
  87. package/dist/widget/components/QRCodeWalletSelect.d.ts.map +1 -1
  88. package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
  89. package/dist/widget/components/Recipients.d.ts.map +1 -1
  90. package/dist/widget/components/RefundWarning.d.ts.map +1 -1
  91. package/dist/widget/components/TokenSelector.d.ts.map +1 -1
  92. package/dist/widget/components/TransactionDetails.d.ts.map +1 -1
  93. package/dist/widget/components/TransferPendingVertical.d.ts +1 -0
  94. package/dist/widget/components/TransferPendingVertical.d.ts.map +1 -1
  95. package/dist/widget/components/WalletConnect.d.ts.map +1 -1
  96. package/dist/widget/components/WalletImage.d.ts.map +1 -1
  97. package/dist/widget/components/WalletList.d.ts.map +1 -1
  98. package/dist/widget/components/Withdraw.d.ts.map +1 -1
  99. package/dist/widget/css/compiled.css +1 -1
  100. package/dist/widget/hooks/useAddressWalletIcon.d.ts.map +1 -1
  101. package/dist/widget/hooks/useCustomTokenSearch.d.ts +6 -1
  102. package/dist/widget/hooks/useCustomTokenSearch.d.ts.map +1 -1
  103. package/dist/widget/hooks/useDefaultDestinationToken.d.ts.map +1 -1
  104. package/dist/widget/hooks/useDefaultOriginToken.d.ts.map +1 -1
  105. package/dist/widget/hooks/useFiatOnRampCurrencies.d.ts +1 -1
  106. package/dist/widget/hooks/useFiatOnRampCurrencies.d.ts.map +1 -1
  107. package/dist/widget/hooks/useIntentTransactionHistory.d.ts.map +1 -1
  108. package/dist/widget/hooks/useQuote.d.ts +1 -1
  109. package/dist/widget/hooks/useQuote.d.ts.map +1 -1
  110. package/dist/widget/hooks/useSelectedFundMethod.d.ts +7 -0
  111. package/dist/widget/hooks/useSelectedFundMethod.d.ts.map +1 -1
  112. package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
  113. package/dist/widget/hooks/useTokenList.d.ts +7 -1
  114. package/dist/widget/hooks/useTokenList.d.ts.map +1 -1
  115. package/dist/widget/hooks/useViewManager.d.ts +1 -1
  116. package/dist/widget/hooks/useViewManager.d.ts.map +1 -1
  117. package/dist/widget/index.js +1 -1
  118. package/dist/widget/providers/TrailsProvider.d.ts +2 -0
  119. package/dist/widget/providers/TrailsProvider.d.ts.map +1 -1
  120. package/dist/widget/utils/createWagmiConfig.d.ts +2 -2
  121. package/dist/widget/utils/createWagmiConfig.d.ts.map +1 -1
  122. package/dist/widget/utils/fundMethodSwitchState.d.ts +1 -0
  123. package/dist/widget/utils/fundMethodSwitchState.d.ts.map +1 -1
  124. package/dist/widget/utils/meldProviderUtils.d.ts +1 -1
  125. package/dist/widget/utils/meldProviderUtils.d.ts.map +1 -1
  126. package/dist/widget/utils/meshSupportedTokens.d.ts +4 -0
  127. package/dist/widget/utils/meshSupportedTokens.d.ts.map +1 -0
  128. package/dist/widget/utils/onrampConfig.d.ts +11 -0
  129. package/dist/widget/utils/onrampConfig.d.ts.map +1 -0
  130. package/dist/widget/utils/trailsOnrampConfig.d.ts +18 -0
  131. package/dist/widget/utils/trailsOnrampConfig.d.ts.map +1 -0
  132. package/dist/widget/widget.d.ts +24 -8
  133. package/dist/widget/widget.d.ts.map +1 -1
  134. package/package.json +9 -7
  135. package/src/chains.ts +9 -4
  136. package/src/constants.ts +2 -0
  137. package/src/customTokens.ts +21 -0
  138. package/src/index.ts +1 -0
  139. package/src/intents.ts +49 -41
  140. package/src/keyMachineClient.ts +29 -0
  141. package/src/keymachine/index.ts +175 -0
  142. package/src/keymachine/key-machine.gen.ts +993 -0
  143. package/src/onramp/MeshConnectFlow.tsx +86 -0
  144. package/src/onramp/MeshConnectIframe.tsx +661 -0
  145. package/src/onramp/SendFromExchangeButton.tsx +81 -0
  146. package/src/onramp/TrailsOnRampProvider.tsx +59 -0
  147. package/src/onramp/index.ts +31 -0
  148. package/src/onramp/meshconnect.ts +277 -0
  149. package/src/onramp/trailsOnramp.tsx +130 -0
  150. package/src/onramp-client/index.ts +4 -6
  151. package/src/prepareSend.ts +45 -44
  152. package/src/query/balance.fetchers.ts +134 -4
  153. package/src/query/balance.hooks.ts +61 -2
  154. package/src/query/balance.queries.ts +63 -0
  155. package/src/query/chains.queries.ts +1 -6
  156. package/src/query/meld.fetchers.ts +1 -1
  157. package/src/query/meld.hooks.ts +1 -1
  158. package/src/query/meld.queries.ts +1 -1
  159. package/src/query/tokenList.queries.ts +118 -0
  160. package/src/recover.ts +86 -23
  161. package/src/tokens.ts +108 -26
  162. package/src/transactionIntent/deposits/depositOrchestrator.ts +11 -11
  163. package/src/transactionIntent/deposits/gaslessDeposit.ts +38 -38
  164. package/src/transactionIntent/deposits/standardDeposit.ts +0 -4
  165. package/src/transactionIntent/handlers/intentHandler.ts +28 -11
  166. package/src/transactionIntent/helpers/transactionStateHelpers.ts +5 -2
  167. package/src/transactionIntent/quote/normalizeQuote.ts +11 -5
  168. package/src/transactionIntent/types.ts +1 -1
  169. package/src/transactions.ts +3 -0
  170. package/src/walletUtils.ts +2 -1
  171. package/src/wallets.ts +184 -380
  172. package/src/widget/compiled.css +1 -1
  173. package/src/widget/components/ClassicSwap.tsx +22 -5
  174. package/src/widget/components/ConnectWallet.tsx +4 -2
  175. package/src/widget/components/ConnectedWallets.tsx +2 -5
  176. package/src/widget/components/DirectTransfer.tsx +5 -2
  177. package/src/widget/components/Fund.tsx +144 -12
  178. package/src/widget/components/FundMethods.tsx +5 -9
  179. package/src/widget/components/MeldHistory.tsx +1 -1
  180. package/src/widget/components/MeshExchangeSelection.tsx +218 -0
  181. package/src/widget/components/OnrampHistoryRow.tsx +1 -1
  182. package/src/widget/components/Pay.tsx +20 -36
  183. package/src/widget/components/PoolDeposit.tsx +13 -22
  184. package/src/widget/components/QRCodeWalletSelect.tsx +5 -2
  185. package/src/widget/components/QuoteDetails.tsx +77 -68
  186. package/src/widget/components/Recipients.tsx +2 -1
  187. package/src/widget/components/RefundWarning.tsx +5 -10
  188. package/src/widget/components/TokenSelector.tsx +85 -16
  189. package/src/widget/components/TransactionDetails.tsx +46 -0
  190. package/src/widget/components/TransferPendingVertical.tsx +27 -19
  191. package/src/widget/components/WalletConnect.tsx +2 -5
  192. package/src/widget/components/WalletImage.tsx +6 -18
  193. package/src/widget/components/WalletList.tsx +1 -1
  194. package/src/widget/components/Withdraw.tsx +22 -4
  195. package/src/widget/hooks/useAddressWalletIcon.ts +2 -1
  196. package/src/widget/hooks/useCustomTokenSearch.tsx +63 -33
  197. package/src/widget/hooks/useDefaultDestinationToken.tsx +2 -5
  198. package/src/widget/hooks/useDefaultOriginToken.tsx +2 -5
  199. package/src/widget/hooks/useFiatOnRampCurrencies.ts +1 -1
  200. package/src/widget/hooks/useIntentTransactionHistory.ts +5 -0
  201. package/src/widget/hooks/useMeldTransactionStatus.ts +1 -1
  202. package/src/widget/hooks/useQuote.ts +51 -45
  203. package/src/widget/hooks/useSelectedFundMethod.tsx +14 -1
  204. package/src/widget/hooks/useSendForm.ts +26 -10
  205. package/src/widget/hooks/useTokenList.ts +208 -139
  206. package/src/widget/hooks/useViewManager.tsx +1 -0
  207. package/src/widget/providers/TrailsProvider.tsx +5 -0
  208. package/src/widget/styles.ts +1 -1
  209. package/src/widget/utils/createWagmiConfig.ts +7 -2
  210. package/src/widget/utils/fundMethodSwitchState.ts +2 -0
  211. package/src/widget/utils/meldProviderUtils.ts +8 -2
  212. package/src/widget/utils/meshSupportedTokens.ts +28 -0
  213. package/src/widget/utils/onrampConfig.ts +15 -0
  214. package/src/widget/utils/trailsOnrampConfig.ts +39 -0
  215. package/src/widget/widget.tsx +164 -98
  216. package/dist/onramp-client/trails-onramp.gen.d.ts +0 -570
  217. package/dist/onramp-client/trails-onramp.gen.d.ts.map +0 -1
  218. package/dist/widget/hooks/useCustomTokenFetch.d.ts +0 -19
  219. package/dist/widget/hooks/useCustomTokenFetch.d.ts.map +0 -1
  220. package/dist/widget/hooks/useTokenWithFreshBalance.d.ts +0 -18
  221. package/dist/widget/hooks/useTokenWithFreshBalance.d.ts.map +0 -1
  222. package/src/onramp-client/trails-onramp.gen.ts +0 -1320
  223. package/src/widget/assets/Binance_Icon_Logo.svg +0 -14
  224. package/src/widget/assets/Bitfinex_Icon_Logo.svg +0 -5
  225. package/src/widget/assets/Coinbase_Icon_Logo.svg +0 -1
  226. package/src/widget/assets/WalletConnect-logo-blue-bg.svg +0 -11
  227. package/src/widget/assets/sequence-logo.svg +0 -15
  228. package/src/widget/hooks/useCustomTokenFetch.tsx +0 -74
  229. package/src/widget/hooks/useTokenWithFreshBalance.ts +0 -246
@@ -1,3 +1,4 @@
1
+ import { useQuery } from "@tanstack/react-query"
1
2
  import { ArrowLeftRight } from "lucide-react"
2
3
  import type React from "react"
3
4
  import { useCallback, useEffect, useMemo, useRef, useState } from "react"
@@ -17,6 +18,9 @@ import { useSupportedTokens, type Token } from "../../tokens.js"
17
18
  import type { FundMethod } from "../../transactionIntent/types.js"
18
19
  import { isPassthroughEligible } from "../../utils/passthrough.js"
19
20
  import { useWidgetProps } from "../hooks/useWidgetProps.js"
21
+ import { getMatchingMeshSupportedTokens } from "../utils/meshSupportedTokens.js"
22
+ import { getActiveMeshEnvironment } from "../utils/onrampConfig.js"
23
+ import { getWidgetOnrampConfig } from "../utils/trailsOnrampConfig.js"
20
24
  import type { Screen } from "../hooks/useViewManager.js"
21
25
  import { useViewManager } from "../hooks/useViewManager.js"
22
26
  import { useDefaultDestinationToken } from "../hooks/useDefaultDestinationToken.js"
@@ -33,9 +37,9 @@ import { useOriginSelectedToken } from "../hooks/useOriginSelectedToken.js"
33
37
  import type { ProcessedFeeOption } from "../hooks/useSelectedFeeOption.js"
34
38
  import { useSelectedFundMethod } from "../hooks/useSelectedFundMethod.js"
35
39
  import { useSelectedRecipient } from "../hooks/useSelectedRecipient.js"
36
- import { useSendForm } from "../hooks/useSendForm.js"
40
+ import { useSendForm, type OnCompleteProps } from "../hooks/useSendForm.js"
37
41
  import { useSwapState } from "../hooks/useSwapState.js"
38
- import { useTokenWithFreshBalance } from "../hooks/useTokenWithFreshBalance.js"
42
+ import { useAccountTokenBalanceOnchain } from "../../query/balance.hooks.js"
39
43
  import type { BaseProps, OnrampConfirmCallback } from "../types/commonProps.js"
40
44
  import { isWithinCooldown, SECOND_MS } from "../../utils/time.js"
41
45
  import { forexRateStore } from "../utils/forexRateStore.js"
@@ -58,6 +62,7 @@ import { TokenSelectorButton } from "./TokenSelectorButton.js"
58
62
  import LoadingSpinner from "./LoadingSpinner.js"
59
63
 
60
64
  import { addressEqual } from "../../utils/address.js"
65
+ import { useOnrampClient } from "../../onrampClient.js"
61
66
  interface FundProps extends BaseProps {
62
67
  onWaitingForOnrampConfirm?: OnrampConfirmCallback
63
68
  title?: string
@@ -102,7 +107,14 @@ const Fund: React.FC<FundProps> = ({
102
107
  defaultInputMode,
103
108
  }) => {
104
109
  const { mode, navigate } = useViewManager()
105
- const { fundOptions } = useWidgetProps()
110
+ const widgetProps = useWidgetProps()
111
+ const {
112
+ fundOptions,
113
+ onramp: onrampFactory,
114
+ apiKey,
115
+ trailsApiUrl,
116
+ } = widgetProps
117
+ const onrampClient = useOnrampClient()
106
118
  const {
107
119
  selectedToken: originToken,
108
120
  setSelectedToken: setOriginToken,
@@ -116,7 +128,21 @@ const Fund: React.FC<FundProps> = ({
116
128
  setHasManualSelection: setHasManualDestinationSelection,
117
129
  isControlledByProps: isDestinationControlledByProps,
118
130
  } = useDestinationSelectedToken()
119
- const { paymentMethod } = useSelectedFundMethod()
131
+ const { paymentMethod, selectedMeshExchange } = useSelectedFundMethod()
132
+ const meshOnrampConfig = getWidgetOnrampConfig(onrampFactory)
133
+ const meshEnvironment = getActiveMeshEnvironment(meshOnrampConfig)
134
+ const meshEnabled = !!meshOnrampConfig?.mesh
135
+ const meshAllowedExchanges = meshOnrampConfig?.mesh?.exchanges ?? null
136
+ const activeMeshIntegrationIds = selectedMeshExchange
137
+ ? [selectedMeshExchange.integrationId]
138
+ : null
139
+ const activeMeshExchangeKeys = selectedMeshExchange
140
+ ? null
141
+ : meshAllowedExchanges
142
+ const isCoinbaseMeshOnramp =
143
+ fundMethod === "onramp-mesh" &&
144
+ (selectedMeshExchange?.exchangeKey === "coinbase" ||
145
+ selectedMeshExchange?.exchangeKey === "coinbaseRamp")
120
146
 
121
147
  // Check if fee options will be shown (not needed for onramp/direct-transfer modes)
122
148
  const skipFeeBalanceFetch =
@@ -129,11 +155,9 @@ const Fund: React.FC<FundProps> = ({
129
155
  const {
130
156
  token: freshOriginToken,
131
157
  isLoadingBalance: isLoadingFreshOriginBalance,
132
- } = useTokenWithFreshBalance(
133
- originToken,
134
- account?.address,
135
- skipFeeBalanceFetch,
136
- )
158
+ } = useAccountTokenBalanceOnchain(originToken, account?.address, {
159
+ disabled: skipFeeBalanceFetch,
160
+ })
137
161
 
138
162
  const { selectedRecipient, setSelectedRecipient } = useSelectedRecipient()
139
163
  const {
@@ -179,6 +203,14 @@ const Fund: React.FC<FundProps> = ({
179
203
  const [isUserTyping, setIsUserTyping] = useState(false)
180
204
  const typingTimeoutRef = useRef<NodeJS.Timeout | null>(null)
181
205
 
206
+ useEffect(() => {
207
+ return () => {
208
+ if (typingTimeoutRef.current) {
209
+ clearTimeout(typingTimeoutRef.current)
210
+ }
211
+ }
212
+ }, [])
213
+
182
214
  // Get country defaults when onramp is active
183
215
  const {
184
216
  countryCode: detectedCountryCode,
@@ -314,6 +346,7 @@ const Fund: React.FC<FundProps> = ({
314
346
  setSellAmount,
315
347
  buyAmount,
316
348
  setBuyAmount,
349
+ resetSwapState,
317
350
  enterFormMode,
318
351
  } = useSwapState()
319
352
 
@@ -351,6 +384,16 @@ const Fund: React.FC<FundProps> = ({
351
384
  const [isCreatingWidgetSession, setIsCreatingWidgetSession] = useState(false)
352
385
  const [widgetError, setWidgetError] = useState<string | null>(null)
353
386
 
387
+ const handleCompleteAndClearAmounts = useCallback(
388
+ (result: OnCompleteProps) => {
389
+ setInputDisplayValue("")
390
+ setSellFiatAmount("")
391
+ resetSwapState()
392
+ onComplete(result)
393
+ },
394
+ [onComplete, resetSwapState, setSellFiatAmount],
395
+ )
396
+
354
397
  // Initialize and update selected recipient from toRecipient prop (but don't auto-set to account address)
355
398
  // biome-ignore lint/correctness/useExhaustiveDependencies: selectedRecipient is intentionally excluded to avoid infinite loops
356
399
  useEffect(() => {
@@ -462,7 +505,7 @@ const Fund: React.FC<FundProps> = ({
462
505
  paymasterUrls,
463
506
  onSend,
464
507
  onConfirm,
465
- onComplete,
508
+ onComplete: handleCompleteAndClearAmounts,
466
509
  selectedToken: effectiveOriginToken as any,
467
510
  setWalletConfirmRetryHandler,
468
511
  tradeType: tradeType,
@@ -489,6 +532,60 @@ const Fund: React.FC<FundProps> = ({
489
532
  : undefined,
490
533
  })
491
534
 
535
+ const {
536
+ data: isMeshRouteSupported = true,
537
+ isLoading: isLoadingMeshRouteSupport,
538
+ } = useQuery({
539
+ queryKey: [
540
+ "mesh-route-support",
541
+ meshEnvironment,
542
+ activeMeshExchangeKeys,
543
+ prepareSendQuote?.originChain?.id,
544
+ prepareSendQuote?.originToken?.symbol,
545
+ trailsApiUrl,
546
+ apiKey,
547
+ ],
548
+ queryFn: async () => {
549
+ const response = await onrampClient.getMeshSupportedTokens({
550
+ environment: meshEnvironment,
551
+ })
552
+
553
+ const allowedTokens = !activeMeshExchangeKeys?.length
554
+ ? !activeMeshIntegrationIds?.length
555
+ ? response.tokens || []
556
+ : (response.tokens || []).filter((token) =>
557
+ (token.integrationIds || []).some((integrationId) =>
558
+ activeMeshIntegrationIds.includes(integrationId),
559
+ ),
560
+ )
561
+ : (response.tokens || []).filter((token) =>
562
+ (token.exchangeKeys || []).some((exchangeKey) =>
563
+ activeMeshExchangeKeys.includes(exchangeKey),
564
+ ),
565
+ )
566
+
567
+ return (
568
+ getMatchingMeshSupportedTokens(
569
+ allowedTokens,
570
+ prepareSendQuote?.originChain?.id,
571
+ prepareSendQuote?.originToken?.symbol,
572
+ ).length > 0
573
+ )
574
+ },
575
+ enabled:
576
+ fundMethod === "onramp-mesh" &&
577
+ meshEnabled &&
578
+ !!prepareSendQuote?.originChain?.id &&
579
+ !!prepareSendQuote?.originToken?.symbol &&
580
+ !!apiKey &&
581
+ !!trailsApiUrl,
582
+ staleTime: 24 * 60 * 60 * 1000,
583
+ gcTime: 24 * 60 * 60 * 1000,
584
+ refetchOnMount: false,
585
+ refetchOnWindowFocus: false,
586
+ refetchOnReconnect: false,
587
+ })
588
+
492
589
  const selectedOnrampProviderQuote =
493
590
  selectedOnrampProvider || autoSelectedOnrampQuote
494
591
 
@@ -705,8 +802,7 @@ const Fund: React.FC<FundProps> = ({
705
802
  useState(false)
706
803
 
707
804
  const { supportedTokens } = useSupportedTokens({
708
- disabled:
709
- !!toToken || showSourceTokenSelector || showDestinationTokenSelector,
805
+ disabled: !toToken,
710
806
  })
711
807
 
712
808
  // Use a ref to track if we've already auto-selected from toToken prop
@@ -890,9 +986,33 @@ const Fund: React.FC<FundProps> = ({
890
986
  setHasManualOriginSelection,
891
987
  ])
892
988
 
989
+ useEffect(() => {
990
+ if (hasManualOriginSelection || !isCoinbaseMeshOnramp) {
991
+ return
992
+ }
993
+
994
+ const isUsdcBaseSelected =
995
+ !!originToken &&
996
+ originToken.chainId === USDC_BASE.chainId &&
997
+ addressEqual(originToken.contractAddress, USDC_BASE.contractAddress)
998
+
999
+ if (!isUsdcBaseSelected) {
1000
+ logger.console.log(
1001
+ "[Fund] Preselecting USDC on Base for Coinbase Mesh onramp",
1002
+ )
1003
+ setOriginToken(USDC_BASE as Token)
1004
+ }
1005
+ }, [
1006
+ hasManualOriginSelection,
1007
+ isCoinbaseMeshOnramp,
1008
+ originToken,
1009
+ setOriginToken,
1010
+ ])
1011
+
893
1012
  // Auto-select origin token using separated hook
894
1013
  useEffect(() => {
895
1014
  if (
1015
+ fundMethod !== "onramp-mesh" &&
896
1016
  !originToken &&
897
1017
  !isLoadingOriginDefaults &&
898
1018
  defaultOriginToken &&
@@ -910,6 +1030,7 @@ const Fund: React.FC<FundProps> = ({
910
1030
  defaultOriginToken,
911
1031
  setOriginToken,
912
1032
  hasManualOriginSelection,
1033
+ fundMethod,
913
1034
  ])
914
1035
 
915
1036
  // Auto-select destination token using separated hook
@@ -2258,6 +2379,8 @@ const Fund: React.FC<FundProps> = ({
2258
2379
  !isValidCustomToken ||
2259
2380
  isLoadingQuote ||
2260
2381
  !prepareSendQuote ||
2382
+ (fundMethod === "onramp-mesh" &&
2383
+ (isLoadingMeshRouteSupport || !isMeshRouteSupported)) ||
2261
2384
  (!isMeldOnRampActive &&
2262
2385
  fundMethod !== "direct-transfer" &&
2263
2386
  prepareSendQuote?.noSufficientBalance) ||
@@ -2295,6 +2418,15 @@ const Fund: React.FC<FundProps> = ({
2295
2418
  ) : fundMethod !== "direct-transfer" &&
2296
2419
  prepareSendQuote?.noSufficientBalance ? (
2297
2420
  "Insufficient Balance"
2421
+ ) : fundMethod === "onramp-mesh" && isLoadingMeshRouteSupport ? (
2422
+ <div className="flex items-center justify-center">
2423
+ <LoadingSpinner className="mr-2" />
2424
+ <span>Checking exchange funding...</span>
2425
+ </div>
2426
+ ) : fundMethod === "onramp-mesh" &&
2427
+ prepareSendQuote &&
2428
+ !isMeshRouteSupported ? (
2429
+ "Exchange funding unavailable"
2298
2430
  ) : isMeldOnRampActive && !sellFiatAmount ? (
2299
2431
  "Enter amount"
2300
2432
  ) : !isMeldOnRampActive && !sellAmount ? (
@@ -1,18 +1,18 @@
1
1
  import type React from "react"
2
2
  import { ChevronRight, CreditCard, Wallet, ZapIcon } from "lucide-react"
3
+ import { wagmiConnectorToWalletId } from "@0xtrails/wallet-registry"
3
4
  import { useAccount, useConnections, useSwitchAccount } from "wagmi"
4
5
  import { ScreenHeader } from "./ScreenHeader.js"
5
6
  import { useSelectedFundMethod } from "../hooks/useSelectedFundMethod.js"
6
7
  import { useViewManager } from "../hooks/useViewManager.js"
7
8
  import { useWalletConnectionContext } from "../hooks/useWalletConnectionContext.js"
8
- import { useWallets, wagmiConnectorToWalletId } from "../../wallets.js"
9
+ import { useWallets } from "../../wallets.js"
9
10
  import ExchangeIcon from "../assets/Exchange-icon-black.svg"
10
11
  import WalletChange from "../assets/WalletChange-black.svg"
11
12
  import { truncateAddress } from "../../utils/address.js"
12
13
  import { useResolveEns } from "../../ens.js"
13
14
  import { AddressWalletIcon } from "./AddressWalletIcon.js"
14
15
  import { useWidgetProps } from "../hooks/useWidgetProps.js"
15
- import { useAccountTotalBalanceUsd } from "../../query/balance.hooks.js"
16
16
  import type { FundMethod } from "../../transactionIntent/types.js"
17
17
  import type { FundMethodListOption } from "../widget.js"
18
18
 
@@ -107,17 +107,13 @@ const FundMethods: React.FC<FundMethodsProps> = ({
107
107
  eligibleConnectedWallets.find((wallet) => wallet.isActive) ||
108
108
  eligibleConnectedWallets[0]
109
109
 
110
- const { data: activeWalletBalanceUsd = 0 } = useAccountTotalBalanceUsd(
111
- activeConnection?.address || null,
112
- )
113
- const hasActiveWalletBalance = activeWalletBalanceUsd > 0
114
-
115
- const showWalletInline = !!activeConnection && hasActiveWalletBalance
110
+ const showWalletInline = !!activeConnection
116
111
 
117
112
  const fundMethodAliases: Record<FundMethodListOption, FundMethod> = {
118
113
  "connected-wallet": "wallet",
119
114
  "crypto-transfer": "direct-transfer",
120
115
  "cc-onramp": "onramp-meld",
116
+ exchange: "onramp-mesh",
121
117
  "exchange-onramp": "onramp-mesh",
122
118
  }
123
119
 
@@ -170,7 +166,7 @@ const FundMethods: React.FC<FundMethodsProps> = ({
170
166
  listedInternalSet.size > 0 &&
171
167
  !listedInternalSet.has(method)
172
168
 
173
- const displayMeshExchange = !!onramp // MeshConnect Exchange enabled when onramp prop is provided
169
+ const displayMeshExchange = !!onramp
174
170
 
175
171
  const renderFundMethod = (method: FundMethod) => {
176
172
  const forceDisabled = isUnlisted(method)
@@ -6,7 +6,7 @@ import { isValidNumber } from "../../utils/validation.js"
6
6
  import { getChainName } from "../../chains.js"
7
7
  import { logger } from "../../logger.js"
8
8
  import { useMeldServiceProviders } from "../../query/meld.hooks.js"
9
- import type { MeldServiceProvider } from "../../onramp-client/trails-onramp.gen.js"
9
+ import type { MeldServiceProvider } from "@0xtrails/api/onramp"
10
10
  import { SECOND_MS, formatRelativeDate } from "../../utils/time.js"
11
11
  import {
12
12
  useMeldTransactionHistory,
@@ -0,0 +1,218 @@
1
+ import { useQuery } from "@tanstack/react-query"
2
+ import { ChevronRight } from "lucide-react"
3
+ import type React from "react"
4
+ import { useState } from "react"
5
+ import { useOnrampClient } from "../../onrampClient.js"
6
+ import { logger } from "../../logger.js"
7
+ import { ScreenHeader } from "./ScreenHeader.js"
8
+ import { useWidgetProps } from "../hooks/useWidgetProps.js"
9
+ import { getActiveMeshEnvironment } from "../utils/onrampConfig.js"
10
+ import { getWidgetOnrampConfig } from "../utils/trailsOnrampConfig.js"
11
+
12
+ const INITIAL_VISIBLE_EXCHANGES = 3
13
+
14
+ export interface MeshExchangeSelectionProps {
15
+ onBack: () => void
16
+ onSelectExchange: (exchange: {
17
+ integrationId: string
18
+ exchangeKey: string
19
+ exchangeName: string
20
+ }) => void
21
+ }
22
+
23
+ function getExchangeBackgroundClassName(exchangeKey: string): string {
24
+ switch (exchangeKey) {
25
+ case "coinbase":
26
+ case "coinbaseRamp":
27
+ case "sandboxCoinbase":
28
+ return "bg-white"
29
+ case "binanceInternational":
30
+ case "binanceInternationalDirect":
31
+ case "binanceUs":
32
+ case "binanceUsDirect":
33
+ case "sandbox":
34
+ case "binanceConnect":
35
+ return "bg-black"
36
+ case "bitfinex":
37
+ case "bitfinexDirect":
38
+ return "bg-[#0e3452]"
39
+ case "kraken":
40
+ case "krakenDirect":
41
+ return "bg-[#5841d7]"
42
+ case "uphold":
43
+ case "upholdDirect":
44
+ return "bg-[#49cc68]"
45
+ case "paribu":
46
+ case "paribuOAuth":
47
+ return "bg-[#9cba3b]"
48
+ case "robinhood":
49
+ case "robinhoodDirect":
50
+ case "robinhoodConnect":
51
+ return "bg-[#ccff00]"
52
+ default:
53
+ return "bg-gray-700"
54
+ }
55
+ }
56
+
57
+ export const MeshExchangeSelection: React.FC<MeshExchangeSelectionProps> = ({
58
+ onBack,
59
+ onSelectExchange,
60
+ }) => {
61
+ const { onramp: onrampFactory, apiKey, trailsApiUrl } = useWidgetProps()
62
+ const onrampClient = useOnrampClient()
63
+ const meshOnrampConfig = getWidgetOnrampConfig(onrampFactory)
64
+ const [showAllExchanges, setShowAllExchanges] = useState(false)
65
+ const [failedLogos, setFailedLogos] = useState<Record<string, true>>({})
66
+
67
+ const meshEnvironment = getActiveMeshEnvironment(meshOnrampConfig)
68
+
69
+ const {
70
+ data: exchangeOptions = [],
71
+ isLoading,
72
+ error,
73
+ } = useQuery({
74
+ queryKey: ["mesh-exchange-options", meshEnvironment, trailsApiUrl, apiKey],
75
+ queryFn: async () => {
76
+ const response = await onrampClient.getMeshIntegrations({
77
+ environment: meshEnvironment,
78
+ })
79
+
80
+ return (response.integrations || []).map((integration) => {
81
+ return {
82
+ key: integration.key,
83
+ integrationId: integration.id,
84
+ exchangeName: integration.displayName || integration.key,
85
+ imageUrl: integration.imageUrl || "",
86
+ }
87
+ })
88
+ },
89
+ enabled: !!apiKey && !!trailsApiUrl,
90
+ staleTime: 24 * 60 * 60 * 1000,
91
+ gcTime: 24 * 60 * 60 * 1000,
92
+ refetchOnMount: false,
93
+ refetchOnWindowFocus: false,
94
+ refetchOnReconnect: false,
95
+ })
96
+ const visibleExchangeOptions = showAllExchanges
97
+ ? exchangeOptions
98
+ : exchangeOptions.slice(0, INITIAL_VISIBLE_EXCHANGES)
99
+
100
+ return (
101
+ <div className="flex flex-col h-full">
102
+ <ScreenHeader
103
+ onBack={onBack}
104
+ headerContent="Select Exchange"
105
+ headerContentAlign="left"
106
+ />
107
+
108
+ <div className="flex-1">
109
+ {isLoading ? (
110
+ <div className="flex h-full items-center justify-center">
111
+ <div className="text-center">
112
+ <div className="mt-4 mx-auto mb-4 h-8 w-8 animate-spin rounded-full border-2 border-solid border-blue-500 border-t-transparent" />
113
+ <p className="text-sm text-gray-500 dark:text-gray-400">
114
+ Loading exchanges...
115
+ </p>
116
+ </div>
117
+ </div>
118
+ ) : error ? (
119
+ <div className="flex h-full items-center justify-center">
120
+ <div className="rounded-lg border border-solid border-red-200 bg-red-50 p-4 text-sm text-red-700 dark:border-red-800 dark:bg-red-900/20 dark:text-red-300">
121
+ {error instanceof Error
122
+ ? error.message
123
+ : "Failed to load exchanges"}
124
+ </div>
125
+ </div>
126
+ ) : exchangeOptions.length === 0 ? (
127
+ <div className="flex h-full items-center justify-center">
128
+ <div className="rounded-lg border border-solid border-gray-200 bg-gray-50 p-4 text-sm text-gray-600 dark:border-gray-700 dark:bg-gray-800/70 dark:text-gray-300">
129
+ No supported exchanges are currently available.
130
+ </div>
131
+ </div>
132
+ ) : (
133
+ <div className="max-h-[420px] overflow-y-auto pr-1 pt-4">
134
+ <div className="space-y-4">
135
+ {visibleExchangeOptions.map((exchange) => (
136
+ <button
137
+ key={exchange.integrationId}
138
+ type="button"
139
+ onClick={() => {
140
+ logger.console.log(
141
+ "[trails-sdk] Selected Mesh exchange in widget:",
142
+ exchange,
143
+ )
144
+ onSelectExchange({
145
+ integrationId: exchange.integrationId,
146
+ exchangeKey: exchange.key,
147
+ exchangeName: exchange.exchangeName,
148
+ })
149
+ }}
150
+ className="w-full flex items-center justify-between cursor-pointer font-semibold py-4 px-6 rounded-lg transition-all duration-200 bg-gray-50 dark:bg-gray-800 hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-900 dark:text-white"
151
+ >
152
+ <div className="flex items-center space-x-3 flex-1">
153
+ <div
154
+ className={`flex h-12 w-12 items-center justify-center overflow-hidden rounded-lg border border-solid border-gray-200 dark:border-gray-700 ${getExchangeBackgroundClassName(exchange.key)}`}
155
+ >
156
+ {exchange.imageUrl &&
157
+ !failedLogos[exchange.integrationId] ? (
158
+ <img
159
+ src={exchange.imageUrl}
160
+ alt={`${exchange.exchangeName} logo`}
161
+ className="h-8 w-8 rounded object-contain"
162
+ loading="lazy"
163
+ referrerPolicy="no-referrer"
164
+ onError={() => {
165
+ setFailedLogos((current) => ({
166
+ ...current,
167
+ [exchange.integrationId]: true,
168
+ }))
169
+ }}
170
+ />
171
+ ) : (
172
+ <span className="text-sm font-semibold text-white">
173
+ {exchange.exchangeName.slice(0, 2).toUpperCase()}
174
+ </span>
175
+ )}
176
+ </div>
177
+ <div className="flex-1 text-left">
178
+ <h4 className="font-semibold text-gray-900 dark:text-gray-100">
179
+ {exchange.exchangeName}
180
+ </h4>
181
+ <p className="text-sm text-gray-600 dark:text-gray-400">
182
+ Connect your account to transfer funds
183
+ </p>
184
+ </div>
185
+ </div>
186
+ <ChevronRight className="w-5 h-5 text-gray-400" />
187
+ </button>
188
+ ))}
189
+ {!showAllExchanges &&
190
+ exchangeOptions.length > INITIAL_VISIBLE_EXCHANGES && (
191
+ <button
192
+ type="button"
193
+ onClick={() => setShowAllExchanges(true)}
194
+ className="w-full cursor-pointer rounded-lg border border-solid border-gray-200 px-6 py-3 text-sm font-medium text-gray-700 transition-colors hover:bg-gray-50 dark:border-gray-700 dark:text-gray-300 dark:hover:bg-gray-800"
195
+ >
196
+ Show more
197
+ </button>
198
+ )}
199
+ </div>
200
+ </div>
201
+ )}
202
+ </div>
203
+
204
+ {meshEnvironment === "sandbox" && (
205
+ <div className="mt-4 border border-solid border-yellow-200 bg-yellow-50 p-3 dark:border-yellow-800 dark:bg-yellow-900/20">
206
+ <div className="text-center">
207
+ <p className="text-sm font-medium text-yellow-800 dark:text-yellow-200">
208
+ Sandbox environment
209
+ </p>
210
+ <p className="text-xs text-yellow-600 dark:text-yellow-300">
211
+ No real funds are used
212
+ </p>
213
+ </div>
214
+ </div>
215
+ )}
216
+ </div>
217
+ )
218
+ }
@@ -4,7 +4,7 @@ import { useState } from "react"
4
4
  import { getChainName } from "../../chains.js"
5
5
  import { isValidNumber } from "../../utils/validation.js"
6
6
  import { logger } from "../../logger.js"
7
- import type { MeldServiceProvider } from "../../onramp-client/trails-onramp.gen.js"
7
+ import type { MeldServiceProvider } from "@0xtrails/api/onramp"
8
8
  import { SECOND_MS, formatRelativeDate } from "../../utils/time.js"
9
9
  import { truncateAddress } from "../../utils/address.js"
10
10
  import type { MeldTransactionData } from "../hooks/useMeldTransactionHistory.js"
@@ -21,7 +21,7 @@ import { useSendForm } from "../hooks/useSendForm.js"
21
21
  import { useSwapAmount } from "../hooks/useSwapAmount.js"
22
22
  import { useSwapState } from "../hooks/useSwapState.js"
23
23
  import { useTargetAmount } from "../hooks/useTargetAmount.js"
24
- import { useTokenList } from "../hooks/useTokenList.js"
24
+ import { useAccountTokenBalanceOnchain } from "../../query/balance.hooks.js"
25
25
  import type { BaseProps } from "../types/commonProps.js"
26
26
  import { AddressOrEnsName } from "./AddressOrEnsName.js"
27
27
  import { AddressWalletIcon } from "./AddressWalletIcon.js"
@@ -130,27 +130,11 @@ export const Pay: React.FC<PayProps> = ({
130
130
  const { trackClick } = useClickTracking()
131
131
  const paymentRequestInputRef = useRef<HTMLInputElement>(null)
132
132
 
133
- // Get sorted tokens to auto-select origin and destination tokens
134
- const { filteredTokensFormatted, isLoadingTokens } = useTokenList({
135
- onContinue: () => {}, // Not used for auto-selection
136
- onError: () => {}, // Not used for auto-selection
137
- fundMethod: fundMethod,
138
- allSupportedTokens: true, // Show all tokens for destination selection
139
- })
140
-
141
- // Get origin token balance for display
142
- const originTokenBalance = useMemo(() => {
143
- if (!originToken || !filteredTokensFormatted) return null
144
-
145
- const foundToken = filteredTokensFormatted.find(
146
- (token) =>
147
- token.contractAddress?.toLowerCase() ===
148
- originToken.contractAddress?.toLowerCase() &&
149
- token.chainId === originToken.chainId,
150
- )
151
-
152
- return foundToken
153
- }, [originToken, filteredTokensFormatted])
133
+ // Get origin token with fresh balance for display and fee option checks
134
+ const {
135
+ token: freshOriginToken,
136
+ isLoadingBalance: isLoadingFreshOriginBalance,
137
+ } = useAccountTokenBalanceOnchain(originToken, account?.address)
154
138
 
155
139
  // Calculate effective recipient for useSendForm
156
140
  const effectiveRecipient =
@@ -782,9 +766,9 @@ export const Pay: React.FC<PayProps> = ({
782
766
  type="button"
783
767
  className="text-xs text-gray-500 dark:text-gray-400 cursor-pointer hover:text-gray-700 dark:hover:text-gray-200 transition-colors bg-transparent border-none p-0"
784
768
  onClick={() => {
785
- if (originTokenBalance?.balanceFormatted) {
769
+ if (freshOriginToken?.balanceFormatted) {
786
770
  const balance = parseFloat(
787
- originTokenBalance.balanceFormatted,
771
+ freshOriginToken.balanceFormatted,
788
772
  )
789
773
  if (isValidNumber(balance)) {
790
774
  setTokenAmountForBackend(balance.toFixed(6))
@@ -794,9 +778,9 @@ export const Pay: React.FC<PayProps> = ({
794
778
  onKeyDown={(e) => {
795
779
  if (e.key === "Enter" || e.key === " ") {
796
780
  e.preventDefault()
797
- if (originTokenBalance?.balanceFormatted) {
781
+ if (freshOriginToken?.balanceFormatted) {
798
782
  const balance = parseFloat(
799
- originTokenBalance.balanceFormatted,
783
+ freshOriginToken.balanceFormatted,
800
784
  )
801
785
  if (isValidNumber(balance)) {
802
786
  setTokenAmountForBackend(balance.toFixed(6))
@@ -805,26 +789,26 @@ export const Pay: React.FC<PayProps> = ({
805
789
  }
806
790
  }}
807
791
  title="Click to use full balance"
808
- disabled={!originTokenBalance?.balanceFormatted}
792
+ disabled={!freshOriginToken?.balanceFormatted}
809
793
  >
810
794
  <span translate="no">
811
795
  Balance:{" "}
812
- {isLoadingTokens ? (
796
+ {isLoadingFreshOriginBalance ? (
813
797
  <span className="inline-block w-12 h-3 bg-gray-200 dark:bg-gray-700 rounded animate-pulse"></span>
814
798
  ) : (
815
- originTokenBalance?.balanceLocaleDisplay ||
816
- originTokenBalance?.balanceFormatted ||
799
+ freshOriginToken?.balanceLocaleDisplay ||
800
+ freshOriginToken?.balanceFormatted ||
817
801
  ""
818
802
  )}
819
803
  </span>
820
804
  </button>
821
805
 
822
806
  {/* Percentage Buttons - Only show if toAmount is not set */}
823
- {!toAmount && originTokenBalance?.balanceFormatted && (
807
+ {!toAmount && freshOriginToken?.balanceFormatted && (
824
808
  <PercentageMaxButtons
825
- userBalance={originTokenBalance.balanceFormatted}
826
- userBalanceRaw={originTokenBalance.balance ?? "0"}
827
- decimals={originTokenBalance.decimals ?? 18}
809
+ userBalance={freshOriginToken.balanceFormatted}
810
+ userBalanceRaw={freshOriginToken.balance ?? "0"}
811
+ decimals={freshOriginToken.decimals ?? 18}
828
812
  isNativeToken={originToken.isNativeToken ?? false}
829
813
  gasCostFormatted={prepareSendQuote?.gasCostFormatted}
830
814
  chainId={originToken.chainId}
@@ -1064,7 +1048,7 @@ export const Pay: React.FC<PayProps> = ({
1064
1048
  originToken
1065
1049
  ? {
1066
1050
  originToken,
1067
- originTokenBalance: originTokenBalance?.balance ?? "0",
1051
+ originTokenBalance: freshOriginToken?.balance ?? "0",
1068
1052
  originTokenAmount:
1069
1053
  prepareSendQuote?.originAmountFormatted ?? "0",
1070
1054
  }
@@ -1129,7 +1113,7 @@ export const Pay: React.FC<PayProps> = ({
1129
1113
  (selectedFeeOption && originToken
1130
1114
  ? isFeeOptionDisabled(selectedFeeOption as ProcessedFeeOption, {
1131
1115
  originToken: originToken,
1132
- originTokenBalance: originTokenBalance?.balance ?? "0",
1116
+ originTokenBalance: freshOriginToken?.balance ?? "0",
1133
1117
  originTokenAmount:
1134
1118
  prepareSendQuote?.originAmountFormatted ?? "0",
1135
1119
  })