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.
- package/dist/analytics.d.ts +65 -50
- package/dist/analytics.d.ts.map +1 -1
- package/dist/{ccip-DtfgR432.js → ccip-62W6LwH2.js} +28 -28
- package/dist/chains.d.ts.map +1 -1
- package/dist/error.d.ts +2 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/estimate.d.ts.map +1 -1
- package/dist/fees.d.ts.map +1 -1
- package/dist/{index-CHiCSmCD.js → index-C0QTNYIA.js} +43750 -41806
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +199 -171
- package/dist/localeUtils.d.ts.map +1 -1
- package/dist/meld/components/MeldCountriesList.d.ts +0 -2
- package/dist/meld/components/MeldCountriesList.d.ts.map +1 -1
- package/dist/meld/components/MeldFundMethods.d.ts.map +1 -1
- package/dist/meld/components/MeldTokensList.d.ts.map +1 -1
- package/dist/meld/utils/meld.d.ts +2 -52
- package/dist/meld/utils/meld.d.ts.map +1 -1
- package/dist/poolUtils.d.ts.map +1 -1
- package/dist/prepareSend.d.ts.map +1 -1
- package/dist/prices.d.ts +1 -2
- package/dist/prices.d.ts.map +1 -1
- package/dist/query/balance.fetchers.d.ts +2 -2
- package/dist/query/balance.fetchers.d.ts.map +1 -1
- package/dist/query/fiat.fetchers.d.ts +11 -0
- package/dist/query/fiat.fetchers.d.ts.map +1 -0
- package/dist/query/fiat.hooks.d.ts +18 -0
- package/dist/query/fiat.hooks.d.ts.map +1 -0
- package/dist/query/fiat.queries.d.ts +24 -0
- package/dist/query/fiat.queries.d.ts.map +1 -0
- package/dist/query/meld.fetchers.d.ts +19 -0
- package/dist/query/meld.fetchers.d.ts.map +1 -0
- package/dist/query/meld.hooks.d.ts +4 -0
- package/dist/query/meld.hooks.d.ts.map +1 -0
- package/dist/query/meld.queries.d.ts +61 -0
- package/dist/query/meld.queries.d.ts.map +1 -0
- package/dist/recover.d.ts.map +1 -1
- package/dist/tokens.d.ts.map +1 -1
- package/dist/transactionIntent/deposits/depositOrchestrator.d.ts.map +1 -1
- package/dist/transactionIntent/deposits/gaslessDeposit.d.ts.map +1 -1
- package/dist/transactionIntent/deposits/standardDeposit.d.ts +7 -1
- package/dist/transactionIntent/deposits/standardDeposit.d.ts.map +1 -1
- package/dist/transactionIntent/handlers/intentHandler.d.ts +2 -0
- package/dist/transactionIntent/handlers/intentHandler.d.ts.map +1 -1
- package/dist/transactionIntent/quote/normalizeQuote.d.ts +2 -2
- package/dist/transactionIntent/quote/normalizeQuote.d.ts.map +1 -1
- package/dist/transactionIntent/quote/quoteHelpers.d.ts +1 -1
- package/dist/transactionIntent/quote/quoteHelpers.d.ts.map +1 -1
- package/dist/transactionIntent/types.d.ts +2 -0
- package/dist/transactionIntent/types.d.ts.map +1 -1
- package/dist/transactionIntent/utils/balanceChecker.d.ts +3 -1
- package/dist/transactionIntent/utils/balanceChecker.d.ts.map +1 -1
- package/dist/transactions.d.ts +2 -9
- package/dist/transactions.d.ts.map +1 -1
- package/dist/umd/trails.min.js +206 -152
- package/dist/utils/fiat.d.ts +8 -0
- package/dist/utils/fiat.d.ts.map +1 -0
- package/dist/utils/format.d.ts.map +1 -1
- package/dist/utils/passthrough.d.ts +5 -2
- package/dist/utils/passthrough.d.ts.map +1 -1
- package/dist/utils/validation.d.ts +33 -0
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/walletUtils.d.ts +1 -1
- package/dist/walletUtils.d.ts.map +1 -1
- package/dist/widget/components/ClassicSwap.d.ts.map +1 -1
- package/dist/widget/components/DepositTracker.d.ts.map +1 -1
- package/dist/widget/components/Earn.d.ts +2 -0
- package/dist/widget/components/Earn.d.ts.map +1 -1
- package/dist/widget/components/FeeOption.d.ts.map +1 -1
- package/dist/widget/components/Fund.d.ts.map +1 -1
- package/dist/widget/components/FundMethods.d.ts.map +1 -1
- package/dist/widget/components/HookModalContent.d.ts.map +1 -1
- package/dist/widget/components/MeldForm.d.ts.map +1 -1
- package/dist/widget/components/MeldHistory.d.ts.map +1 -1
- package/dist/widget/components/MeldStepsFlow.d.ts.map +1 -1
- package/dist/widget/components/OFTProgressBar.d.ts +2 -0
- package/dist/widget/components/OFTProgressBar.d.ts.map +1 -1
- package/dist/widget/components/OnRampProviderSelector.d.ts.map +1 -1
- package/dist/widget/components/OnrampHistoryRow.d.ts.map +1 -1
- package/dist/widget/components/Pay.d.ts.map +1 -1
- package/dist/widget/components/PercentageMaxButtons.d.ts.map +1 -1
- package/dist/widget/components/PoolDeposit.d.ts +2 -0
- package/dist/widget/components/PoolDeposit.d.ts.map +1 -1
- package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
- package/dist/widget/components/Receipt.d.ts.map +1 -1
- package/dist/widget/components/SlippageToleranceSettings.d.ts.map +1 -1
- package/dist/widget/components/Swap.d.ts +2 -0
- package/dist/widget/components/Swap.d.ts.map +1 -1
- package/dist/widget/components/TransferPendingVertical.d.ts.map +1 -1
- package/dist/widget/components/Withdraw.d.ts.map +1 -1
- package/dist/widget/hooks/useAmountUsd.d.ts.map +1 -1
- package/dist/widget/hooks/useCustomTokenSearch.d.ts.map +1 -1
- package/dist/widget/hooks/useDisplayCurrencyPreference.d.ts.map +1 -1
- package/dist/widget/hooks/useFiatOnRampCurrencies.d.ts +3 -21
- package/dist/widget/hooks/useFiatOnRampCurrencies.d.ts.map +1 -1
- package/dist/widget/hooks/useMeldTransactionHistory.d.ts.map +1 -1
- package/dist/widget/hooks/useOnRampCountryDefaults.d.ts +0 -18
- package/dist/widget/hooks/useOnRampCountryDefaults.d.ts.map +1 -1
- package/dist/widget/hooks/useOnRampPaymentMethods.d.ts +2 -18
- package/dist/widget/hooks/useOnRampPaymentMethods.d.ts.map +1 -1
- package/dist/widget/hooks/useOnRampQuote.d.ts.map +1 -1
- package/dist/widget/hooks/useQuote.d.ts +5 -1
- package/dist/widget/hooks/useQuote.d.ts.map +1 -1
- package/dist/widget/hooks/useSendForm.d.ts +3 -1
- package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
- package/dist/widget/hooks/useTokenList.d.ts.map +1 -1
- package/dist/widget/hooks/useTokenWithFreshBalance.d.ts +3 -2
- package/dist/widget/hooks/useTokenWithFreshBalance.d.ts.map +1 -1
- package/dist/widget/index.js +1 -1
- package/dist/widget/types/commonProps.d.ts +2 -0
- package/dist/widget/types/commonProps.d.ts.map +1 -1
- package/dist/widget/utils/transactionFailure.d.ts +20 -0
- package/dist/widget/utils/transactionFailure.d.ts.map +1 -0
- package/dist/widget/widget.d.ts +44 -3
- package/dist/widget/widget.d.ts.map +1 -1
- package/dist/widget/workers/intentExecutionWorker.d.ts.map +1 -1
- package/package.json +22 -22
- package/src/analytics.ts +115 -79
- package/src/chains.ts +0 -1
- package/src/error.ts +11 -0
- package/src/estimate.ts +12 -7
- package/src/fees.ts +0 -1
- package/src/index.ts +11 -0
- package/src/localeUtils.ts +3 -1
- package/src/meld/components/MeldCountriesList.tsx +30 -15
- package/src/meld/components/MeldFundMethods.tsx +8 -4
- package/src/meld/components/MeldTokensList.tsx +90 -2
- package/src/meld/utils/meld.ts +3 -400
- package/src/poolUtils.ts +5 -19
- package/src/prepareSend.ts +32 -5
- package/src/prices.ts +7 -33
- package/src/query/balance.fetchers.ts +128 -168
- package/src/query/fiat.fetchers.ts +33 -0
- package/src/query/fiat.hooks.ts +71 -0
- package/src/query/fiat.queries.ts +67 -0
- package/src/query/meld.fetchers.ts +97 -0
- package/src/query/meld.hooks.ts +18 -0
- package/src/query/meld.queries.ts +184 -0
- package/src/recover.ts +6 -1
- package/src/tokens.ts +31 -6
- package/src/transactionIntent/deposits/depositOrchestrator.ts +2 -0
- package/src/transactionIntent/deposits/gaslessDeposit.ts +9 -2
- package/src/transactionIntent/deposits/standardDeposit.ts +35 -14
- package/src/transactionIntent/handlers/intentHandler.ts +134 -138
- package/src/transactionIntent/quote/normalizeQuote.ts +31 -22
- package/src/transactionIntent/quote/quoteHelpers.ts +24 -7
- package/src/transactionIntent/types.ts +2 -0
- package/src/transactionIntent/utils/balanceChecker.ts +10 -4
- package/src/transactions.ts +22 -13
- package/src/umd.tsx +1 -1
- package/src/utils/fiat.ts +32 -0
- package/src/utils/format.ts +1 -3
- package/src/utils/passthrough.ts +19 -3
- package/src/utils/validation.ts +88 -0
- package/src/utils.ts +2 -1
- package/src/walletUtils.ts +2 -2
- package/src/widget/components/AccountIntentTransactionHistory.tsx +2 -2
- package/src/widget/components/ClassicSwap.tsx +10 -4
- package/src/widget/components/DepositTracker.tsx +2 -5
- package/src/widget/components/Earn.tsx +6 -0
- package/src/widget/components/FeeOption.tsx +15 -8
- package/src/widget/components/Fund.tsx +16 -11
- package/src/widget/components/FundMethods.tsx +255 -192
- package/src/widget/components/HookModalContent.tsx +4 -0
- package/src/widget/components/MeldForm.tsx +44 -42
- package/src/widget/components/MeldHistory.tsx +4 -3
- package/src/widget/components/MeldStepsFlow.tsx +33 -71
- package/src/widget/components/OFTProgressBar.tsx +32 -12
- package/src/widget/components/OnRampProviderSelector.tsx +2 -1
- package/src/widget/components/OnrampHistoryRow.tsx +2 -1
- package/src/widget/components/Pay.tsx +8 -2
- package/src/widget/components/PercentageMaxButtons.tsx +5 -3
- package/src/widget/components/PoolDeposit.tsx +6 -0
- package/src/widget/components/PoolWithdraw.tsx +1 -1
- package/src/widget/components/QuoteDetails.tsx +5 -4
- package/src/widget/components/Receipt.tsx +4 -3
- package/src/widget/components/SlippageToleranceSettings.tsx +3 -2
- package/src/widget/components/Swap.tsx +2 -0
- package/src/widget/components/TransferPendingVertical.tsx +21 -28
- package/src/widget/components/UserPreferences.tsx +1 -1
- package/src/widget/components/Withdraw.tsx +20 -14
- package/src/widget/hooks/useAmountUsd.ts +3 -15
- package/src/widget/hooks/useCustomTokenSearch.tsx +2 -6
- package/src/widget/hooks/useDisplayCurrencyPreference.tsx +1 -2
- package/src/widget/hooks/useFiatOnRampCurrencies.ts +11 -76
- package/src/widget/hooks/useMeldTransactionHistory.ts +24 -89
- package/src/widget/hooks/useOnRampCountryDefaults.ts +3 -49
- package/src/widget/hooks/useOnRampPaymentMethods.ts +21 -100
- package/src/widget/hooks/useOnRampQuote.ts +2 -5
- package/src/widget/hooks/useQuote.ts +10 -12
- package/src/widget/hooks/useSendForm.ts +6 -0
- package/src/widget/hooks/useTokenList.ts +3 -6
- package/src/widget/hooks/useTokenWithFreshBalance.ts +141 -11
- package/src/widget/types/commonProps.ts +2 -0
- package/src/widget/utils/transactionFailure.ts +52 -0
- package/src/widget/widget.tsx +137 -59
- package/src/widget/workers/intentExecutionWorker.ts +3 -1
- package/dist/widget/hooks/useExchangeRate.d.ts +0 -31
- package/dist/widget/hooks/useExchangeRate.d.ts.map +0 -1
- package/dist/widget/hooks/useFiatCurrencyList.d.ts +0 -3
- package/dist/widget/hooks/useFiatCurrencyList.d.ts.map +0 -1
- package/src/widget/hooks/useExchangeRate.ts +0 -257
- package/src/widget/hooks/useFiatCurrencyList.ts +0 -66
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type React from "react"
|
|
2
2
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react"
|
|
3
|
+
import { useQuery } from "@tanstack/react-query"
|
|
3
4
|
import { zeroAddress } from "viem"
|
|
4
5
|
import { useCountryList } from "../../query/geo.hooks.js"
|
|
5
6
|
import { getCountryFlag, getCountryName } from "../utils/countryUtils.js"
|
|
@@ -17,10 +18,8 @@ import { useAccount } from "wagmi"
|
|
|
17
18
|
import { getFullErrorMessage } from "../../error.js"
|
|
18
19
|
import type { MeldPaymentMethod } from "../../meld/components/MeldFundMethods.js"
|
|
19
20
|
import type { Country, MeldQuote, MeldToken } from "../../meld/utils/meld.js"
|
|
20
|
-
import {
|
|
21
|
-
|
|
22
|
-
useMeldPaymentMethods,
|
|
23
|
-
} from "../../meld/utils/meld.js"
|
|
21
|
+
import { getMeldOnrampClient } from "../../meld/utils/meld.js"
|
|
22
|
+
import { meldQueries } from "../../query/meld.queries.js"
|
|
24
23
|
import type { TransactionStatusInfo } from "../hooks/useMeldTransactionStatus.js"
|
|
25
24
|
import { useOnRampCountryDefaults } from "../hooks/useOnRampCountryDefaults.js"
|
|
26
25
|
import { useTrails } from "../providers/TrailsProvider.js"
|
|
@@ -54,11 +53,11 @@ export interface MeldFormProps {
|
|
|
54
53
|
|
|
55
54
|
// Common countries for Meld
|
|
56
55
|
const COMMON_COUNTRIES: Country[] = [
|
|
57
|
-
{
|
|
58
|
-
{
|
|
59
|
-
{
|
|
60
|
-
{
|
|
61
|
-
{
|
|
56
|
+
{ countryCode: "US", name: "United States" },
|
|
57
|
+
{ countryCode: "CA", name: "Canada" },
|
|
58
|
+
{ countryCode: "GB", name: "United Kingdom" },
|
|
59
|
+
{ countryCode: "EU", name: "European Union" },
|
|
60
|
+
{ countryCode: "AU", name: "Australia" },
|
|
62
61
|
]
|
|
63
62
|
|
|
64
63
|
// Simplified payment methods
|
|
@@ -113,6 +112,10 @@ const COMMON_TOKENS: MeldToken[] = [
|
|
|
113
112
|
// Amount presets
|
|
114
113
|
const AMOUNT_PRESETS = [10, 25, 50, 100]
|
|
115
114
|
|
|
115
|
+
// TODO: Temporary localStorage for redirect/session recovery. Should this be sessionStorage?
|
|
116
|
+
const MELD_SESSION_ID_STORAGE_KEY = "meld-current-session-id"
|
|
117
|
+
const MELD_EXTERNAL_SESSION_ID_STORAGE_KEY = "meld-current-external-session-id"
|
|
118
|
+
|
|
116
119
|
// Helper function to map Meld chain names to chain IDs
|
|
117
120
|
function getChainId(chainName?: string): number | undefined {
|
|
118
121
|
const chainMap: Record<string, number> = {
|
|
@@ -161,19 +164,19 @@ export const MeldForm: React.FC<MeldFormProps> = ({
|
|
|
161
164
|
if (detectedCountryCode) {
|
|
162
165
|
// First try to find in common countries list
|
|
163
166
|
const foundCountry = COMMON_COUNTRIES.find(
|
|
164
|
-
(c) => c.
|
|
167
|
+
(c) => c.countryCode === detectedCountryCode,
|
|
165
168
|
)
|
|
166
169
|
if (foundCountry) return foundCountry
|
|
167
170
|
|
|
168
171
|
// If not found, create a country object for it using API data
|
|
169
172
|
return {
|
|
170
|
-
|
|
173
|
+
countryCode: detectedCountryCode,
|
|
171
174
|
name: getCountryName(detectedCountryCode, countries),
|
|
172
175
|
}
|
|
173
176
|
}
|
|
174
177
|
|
|
175
178
|
// Final fallback
|
|
176
|
-
return COMMON_COUNTRIES[0] || {
|
|
179
|
+
return COMMON_COUNTRIES[0] || { countryCode: "US", name: "United States" }
|
|
177
180
|
}, [propSelectedCountry, detectedCountryCode, countries])
|
|
178
181
|
const selectedPaymentMethod = propSelectedPaymentMethod || "CREDIT_DEBIT_CARD"
|
|
179
182
|
|
|
@@ -190,7 +193,9 @@ export const MeldForm: React.FC<MeldFormProps> = ({
|
|
|
190
193
|
}, [trailsApiKey, trailsConfig?.trailsApiUrl])
|
|
191
194
|
|
|
192
195
|
// Fetch payment methods to get details including images
|
|
193
|
-
const { paymentMethods } =
|
|
196
|
+
const { data: paymentMethods = [] } = useQuery(
|
|
197
|
+
meldQueries.paymentMethodList(trailsClient, currency),
|
|
198
|
+
)
|
|
194
199
|
|
|
195
200
|
// Find the selected payment method details
|
|
196
201
|
const selectedPaymentMethodDetails = useMemo(() => {
|
|
@@ -242,34 +247,31 @@ export const MeldForm: React.FC<MeldFormProps> = ({
|
|
|
242
247
|
}, [onTransactionStatus])
|
|
243
248
|
|
|
244
249
|
// Handle status changes from new component
|
|
245
|
-
const handleTransactionStatusChange =
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
}
|
|
250
|
+
const handleTransactionStatusChange = (statusInfo: TransactionStatusInfo) => {
|
|
251
|
+
// Convert to legacy format for backwards compatibility
|
|
252
|
+
const legacyStatus = {
|
|
253
|
+
type:
|
|
254
|
+
statusInfo.state === "success"
|
|
255
|
+
? ("success" as const)
|
|
256
|
+
: statusInfo.state === "failed" || statusInfo.state === "error"
|
|
257
|
+
? ("error" as const)
|
|
258
|
+
: statusInfo.state === "polling"
|
|
259
|
+
? ("pending" as const)
|
|
260
|
+
: null,
|
|
261
|
+
message: statusInfo.message,
|
|
262
|
+
}
|
|
259
263
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
[], // No dependencies needed since we use ref
|
|
264
|
-
)
|
|
264
|
+
// Call the latest callback using ref to prevent infinite loop
|
|
265
|
+
onTransactionStatusRef.current?.(legacyStatus)
|
|
266
|
+
}
|
|
265
267
|
|
|
266
268
|
// Handle popup window closed
|
|
267
|
-
const handleWindowClosed =
|
|
269
|
+
const handleWindowClosed = () => {
|
|
268
270
|
logger.console.log("[MeldForm] Popup window was closed")
|
|
269
271
|
setPopupWindowRef(null)
|
|
270
272
|
setHasClickedContinue(false) // Reset button state when window closes
|
|
271
273
|
setIsPopupOpen(false) // Reset popup state
|
|
272
|
-
}
|
|
274
|
+
}
|
|
273
275
|
|
|
274
276
|
// Check for transaction status from URL parameters (in case of redirect)
|
|
275
277
|
useEffect(() => {
|
|
@@ -286,7 +288,7 @@ export const MeldForm: React.FC<MeldFormProps> = ({
|
|
|
286
288
|
)
|
|
287
289
|
setCurrentTransactionId(urlSessionId)
|
|
288
290
|
setCurrentSessionId(urlSessionId)
|
|
289
|
-
localStorage.setItem(
|
|
291
|
+
localStorage.setItem(MELD_SESSION_ID_STORAGE_KEY, urlSessionId)
|
|
290
292
|
}
|
|
291
293
|
}, [currentTransactionId])
|
|
292
294
|
|
|
@@ -306,7 +308,7 @@ export const MeldForm: React.FC<MeldFormProps> = ({
|
|
|
306
308
|
|
|
307
309
|
logger.console.log("[MeldForm] Loading providers with params:", {
|
|
308
310
|
walletAddress: walletAddress || "fallback",
|
|
309
|
-
countryCode: selectedCountry.
|
|
311
|
+
countryCode: selectedCountry.countryCode,
|
|
310
312
|
sourceCurrencyCode: currency,
|
|
311
313
|
sourceAmount: amount,
|
|
312
314
|
destinationCurrencyCode: selectedToken.code,
|
|
@@ -322,7 +324,7 @@ export const MeldForm: React.FC<MeldFormProps> = ({
|
|
|
322
324
|
const quoteResponse = await trailsClient.getMeldQuote({
|
|
323
325
|
walletAddress:
|
|
324
326
|
walletAddress || "0x1234567890123456789012345678901234567890",
|
|
325
|
-
countryCode: selectedCountry.
|
|
327
|
+
countryCode: selectedCountry.countryCode,
|
|
326
328
|
sourceCurrencyCode: currency,
|
|
327
329
|
sourceAmount: amount,
|
|
328
330
|
destinationCurrencyCode: selectedToken.code,
|
|
@@ -394,7 +396,7 @@ export const MeldForm: React.FC<MeldFormProps> = ({
|
|
|
394
396
|
const sessionResponse = await trailsClient.createMeldWidgetSession({
|
|
395
397
|
sessionData: {
|
|
396
398
|
walletAddress: walletAddress,
|
|
397
|
-
countryCode: selectedCountry.
|
|
399
|
+
countryCode: selectedCountry.countryCode,
|
|
398
400
|
sourceCurrencyCode: currency,
|
|
399
401
|
sourceAmount: amount,
|
|
400
402
|
destinationCurrencyCode: selectedToken.code,
|
|
@@ -437,9 +439,9 @@ export const MeldForm: React.FC<MeldFormProps> = ({
|
|
|
437
439
|
setCurrentSessionId(sessionId)
|
|
438
440
|
setCurrentExternalSessionId(responseExternalSessionId)
|
|
439
441
|
setCurrentTransactionId(sessionId)
|
|
440
|
-
localStorage.setItem(
|
|
442
|
+
localStorage.setItem(MELD_SESSION_ID_STORAGE_KEY, sessionId)
|
|
441
443
|
localStorage.setItem(
|
|
442
|
-
|
|
444
|
+
MELD_EXTERNAL_SESSION_ID_STORAGE_KEY,
|
|
443
445
|
responseExternalSessionId,
|
|
444
446
|
)
|
|
445
447
|
} catch (error) {
|
|
@@ -549,9 +551,9 @@ export const MeldForm: React.FC<MeldFormProps> = ({
|
|
|
549
551
|
className="flex items-center gap-2 bg-transparent border border-gray-300 dark:border-gray-600 rounded-lg px-2 py-1 text-sm trails-text-primary hover:bg-gray-50 dark:hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-blue-500 transition-colors cursor-pointer"
|
|
550
552
|
>
|
|
551
553
|
<span className="text-base">
|
|
552
|
-
{getCountryFlag(selectedCountry.
|
|
554
|
+
{getCountryFlag(selectedCountry.countryCode, countries)}
|
|
553
555
|
</span>
|
|
554
|
-
<span className="font-medium">{selectedCountry.
|
|
556
|
+
<span className="font-medium">{selectedCountry.countryCode}</span>
|
|
555
557
|
<ChevronDown className="w-4 h-4 text-gray-500" />
|
|
556
558
|
</button>
|
|
557
559
|
</div>
|
|
@@ -2,9 +2,10 @@ import { Building2, Check, Copy, CreditCard, RefreshCw } from "lucide-react"
|
|
|
2
2
|
import type React from "react"
|
|
3
3
|
import { useState } from "react"
|
|
4
4
|
import { useAccount } from "wagmi"
|
|
5
|
+
import { isValidNumber } from "../../utils/validation.js"
|
|
5
6
|
import { getChainName } from "../../chains.js"
|
|
6
7
|
import { logger } from "../../logger.js"
|
|
7
|
-
import {
|
|
8
|
+
import { useMeldServiceProviders } from "../../query/meld.hooks.js"
|
|
8
9
|
import type { MeldServiceProvider } from "../../onramp-client/trails-onramp.gen.js"
|
|
9
10
|
import { SECOND_MS, formatRelativeDate } from "../../utils/time.js"
|
|
10
11
|
import {
|
|
@@ -79,7 +80,7 @@ function formatAmount(amount?: string): string {
|
|
|
79
80
|
if (!amount) return "-"
|
|
80
81
|
|
|
81
82
|
const numAmount = parseFloat(amount)
|
|
82
|
-
if (
|
|
83
|
+
if (!isValidNumber(numAmount)) return amount
|
|
83
84
|
|
|
84
85
|
// Format with appropriate decimal places
|
|
85
86
|
// Use 'en-US' to ensure consistent decimal formatting (period as decimal separator)
|
|
@@ -361,7 +362,7 @@ export const MeldHistory: React.FC<MeldHistoryProps> = ({
|
|
|
361
362
|
})
|
|
362
363
|
|
|
363
364
|
// Fetch Meld providers once and cache for 24 hours (already built into useMeldProviders)
|
|
364
|
-
const {
|
|
365
|
+
const { data: meldProviders = [] } = useMeldServiceProviders()
|
|
365
366
|
|
|
366
367
|
if (!address) {
|
|
367
368
|
return (
|
|
@@ -2,6 +2,7 @@ import { ExternalLink } from "lucide-react"
|
|
|
2
2
|
import type React from "react"
|
|
3
3
|
import { useCallback, useEffect, useMemo, useState } from "react"
|
|
4
4
|
import { useAccount } from "wagmi"
|
|
5
|
+
import { isPositiveNumber } from "../../utils/validation.js"
|
|
5
6
|
import { getChainName } from "../../chains.js"
|
|
6
7
|
import { MeldCountriesList } from "../../meld/components/MeldCountriesList.js"
|
|
7
8
|
import type { MeldPaymentMethod } from "../../meld/components/MeldFundMethods.js"
|
|
@@ -14,8 +15,6 @@ import { normalizeAddress, truncateAddress } from "../../utils/address.js"
|
|
|
14
15
|
import { MINUTE_MS, SECOND_MS } from "../../utils/time.js"
|
|
15
16
|
import { useCurrentScreen } from "../hooks/useCurrentScreen.js"
|
|
16
17
|
import type { MeldTransaction } from "../hooks/useOnRampTransactionStatus.js"
|
|
17
|
-
import { useOriginSelectedToken } from "../hooks/useOriginSelectedToken.js"
|
|
18
|
-
import { useTokenList } from "../hooks/useTokenList.js"
|
|
19
18
|
import { useTrails } from "../providers/TrailsProvider.js"
|
|
20
19
|
import { MeldForm } from "./MeldForm.js"
|
|
21
20
|
import { ScreenHeader } from "./ScreenHeader.js"
|
|
@@ -37,12 +36,33 @@ type Screen =
|
|
|
37
36
|
const MELD_AMOUNT_STORAGE_KEY = "meld-form-amount"
|
|
38
37
|
const MELD_CURRENCY_STORAGE_KEY = "meld-debug-currency"
|
|
39
38
|
|
|
39
|
+
function parseStoredCountry(raw: string | null): Country | null {
|
|
40
|
+
if (!raw) return null
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
// TODO: Temporary legacy `{ code }` compatibility until storage migration is centralized.
|
|
44
|
+
const parsed = JSON.parse(raw) as Partial<Country> & { code?: string }
|
|
45
|
+
const countryCode =
|
|
46
|
+
typeof parsed.countryCode === "string"
|
|
47
|
+
? parsed.countryCode
|
|
48
|
+
: typeof parsed.code === "string"
|
|
49
|
+
? parsed.code
|
|
50
|
+
: null
|
|
51
|
+
|
|
52
|
+
if (!countryCode) return null
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
countryCode,
|
|
56
|
+
name: typeof parsed.name === "string" ? parsed.name : countryCode,
|
|
57
|
+
}
|
|
58
|
+
} catch {
|
|
59
|
+
return null
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
40
63
|
interface AmountInputScreenProps {
|
|
41
64
|
onBack: (amount: string, currency: string) => void
|
|
42
65
|
onContinue: (amount: string, currency: string) => void
|
|
43
|
-
_selectedCountry: Country | null
|
|
44
|
-
_selectedToken: MeldToken | null
|
|
45
|
-
_selectedPaymentMethod: MeldPaymentMethod | null
|
|
46
66
|
initialAmount?: string
|
|
47
67
|
initialCurrency?: string
|
|
48
68
|
}
|
|
@@ -50,9 +70,6 @@ interface AmountInputScreenProps {
|
|
|
50
70
|
const AmountInputScreen: React.FC<AmountInputScreenProps> = ({
|
|
51
71
|
onBack,
|
|
52
72
|
onContinue,
|
|
53
|
-
_selectedCountry,
|
|
54
|
-
_selectedToken,
|
|
55
|
-
_selectedPaymentMethod,
|
|
56
73
|
initialAmount = "",
|
|
57
74
|
initialCurrency = "USD",
|
|
58
75
|
}) => {
|
|
@@ -61,10 +78,7 @@ const AmountInputScreen: React.FC<AmountInputScreenProps> = ({
|
|
|
61
78
|
|
|
62
79
|
const numAmount = parseFloat(amount)
|
|
63
80
|
const isValid =
|
|
64
|
-
amount.trim() !== "" &&
|
|
65
|
-
!Number.isNaN(numAmount) &&
|
|
66
|
-
numAmount > 0 &&
|
|
67
|
-
numAmount <= 10000
|
|
81
|
+
amount.trim() !== "" && isPositiveNumber(numAmount) && numAmount <= 10000
|
|
68
82
|
|
|
69
83
|
// Local storage persistence
|
|
70
84
|
useEffect(() => {
|
|
@@ -165,11 +179,6 @@ export const MeldStepsFlow: React.FC<MeldStepsFlowProps> = ({
|
|
|
165
179
|
}) => {
|
|
166
180
|
const trailsConfig = useTrails()
|
|
167
181
|
const { setCurrentScreen: setGlobalScreen } = useCurrentScreen()
|
|
168
|
-
const { setSelectedToken: setOriginToken } = useOriginSelectedToken()
|
|
169
|
-
const { filteredTokens } = useTokenList({
|
|
170
|
-
onContinue: () => {},
|
|
171
|
-
onError: () => {},
|
|
172
|
-
})
|
|
173
182
|
const { address: walletAddress } = useAccount()
|
|
174
183
|
|
|
175
184
|
// Create OnrampClient using trails API key from config
|
|
@@ -192,12 +201,7 @@ export const MeldStepsFlow: React.FC<MeldStepsFlowProps> = ({
|
|
|
192
201
|
|
|
193
202
|
// Load from local storage on mount
|
|
194
203
|
const [selectedCountry, setSelectedCountry] = useState<Country | null>(() => {
|
|
195
|
-
|
|
196
|
-
const saved = localStorage.getItem("meld-debug-country")
|
|
197
|
-
return saved ? JSON.parse(saved) : null
|
|
198
|
-
} catch {
|
|
199
|
-
return null
|
|
200
|
-
}
|
|
204
|
+
return parseStoredCountry(localStorage.getItem("meld-debug-country"))
|
|
201
205
|
})
|
|
202
206
|
|
|
203
207
|
const [selectedPaymentMethod, setSelectedPaymentMethod] =
|
|
@@ -243,6 +247,8 @@ export const MeldStepsFlow: React.FC<MeldStepsFlowProps> = ({
|
|
|
243
247
|
}>({ status: "", message: "", type: null })
|
|
244
248
|
|
|
245
249
|
// Check for transaction status from URL parameters (when user returns from Meld)
|
|
250
|
+
// TODO: temporary ignore this Biome warning for now; do not refactor code in this pass.
|
|
251
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: Preserve current dependency shape per requested no-code-change rollback.
|
|
246
252
|
useEffect(() => {
|
|
247
253
|
const urlParams = new URLSearchParams(window.location.search)
|
|
248
254
|
|
|
@@ -943,11 +949,8 @@ export const MeldStepsFlow: React.FC<MeldStepsFlowProps> = ({
|
|
|
943
949
|
"[MeldStepsFlow] Stored external session ID in localStorage",
|
|
944
950
|
)
|
|
945
951
|
|
|
946
|
-
// Build redirect URL (current page URL without query params)
|
|
947
|
-
const _redirectUrl = window.location.origin + window.location.pathname
|
|
948
|
-
|
|
949
952
|
logger.console.log("[MeldStepsFlow] Creating widget session with:", {
|
|
950
|
-
countryCode: selectedCountry.
|
|
953
|
+
countryCode: selectedCountry.countryCode,
|
|
951
954
|
destinationCurrencyCode: selectedToken.code,
|
|
952
955
|
serviceProvider: selectedProvider.serviceProvider,
|
|
953
956
|
paymentMethodType: selectedPaymentMethod,
|
|
@@ -962,7 +965,7 @@ export const MeldStepsFlow: React.FC<MeldStepsFlowProps> = ({
|
|
|
962
965
|
const sessionResponse = await trailsClient.createMeldWidgetSession({
|
|
963
966
|
sessionData: {
|
|
964
967
|
walletAddress: walletAddress,
|
|
965
|
-
countryCode: selectedCountry.
|
|
968
|
+
countryCode: selectedCountry.countryCode,
|
|
966
969
|
sourceCurrencyCode: selectedCurrency,
|
|
967
970
|
sourceAmount: selectedAmount,
|
|
968
971
|
destinationCurrencyCode: selectedToken.code,
|
|
@@ -1062,43 +1065,6 @@ export const MeldStepsFlow: React.FC<MeldStepsFlowProps> = ({
|
|
|
1062
1065
|
trailsClient,
|
|
1063
1066
|
])
|
|
1064
1067
|
|
|
1065
|
-
// Declare unused functions with underscore prefix to avoid linting warnings
|
|
1066
|
-
const _handleOpenWidget = useCallback(async () => {
|
|
1067
|
-
await generateWidgetUrl()
|
|
1068
|
-
if (
|
|
1069
|
-
widgetUrl &&
|
|
1070
|
-
!widgetUrl.startsWith("Error") &&
|
|
1071
|
-
!widgetUrl.startsWith("Please") &&
|
|
1072
|
-
!widgetUrl.startsWith("No")
|
|
1073
|
-
) {
|
|
1074
|
-
window.open(widgetUrl, "_blank")
|
|
1075
|
-
}
|
|
1076
|
-
}, [widgetUrl, generateWidgetUrl])
|
|
1077
|
-
|
|
1078
|
-
const _handleContinue = useCallback(() => {
|
|
1079
|
-
if (!selectedToken) {
|
|
1080
|
-
return
|
|
1081
|
-
}
|
|
1082
|
-
|
|
1083
|
-
// Find the matching token in the widget's token list
|
|
1084
|
-
// Meld token has symbol (e.g., "USDC") and chainId
|
|
1085
|
-
// We need to match by symbol and chainId
|
|
1086
|
-
const matchingToken = filteredTokens.find((token) => {
|
|
1087
|
-
// Match by symbol and chainId
|
|
1088
|
-
return (
|
|
1089
|
-
token.symbol.toUpperCase() === selectedToken.symbol.toUpperCase() &&
|
|
1090
|
-
token.chainId === selectedToken.chainId
|
|
1091
|
-
)
|
|
1092
|
-
})
|
|
1093
|
-
|
|
1094
|
-
if (matchingToken) {
|
|
1095
|
-
// Set as origin token
|
|
1096
|
-
setOriginToken(matchingToken)
|
|
1097
|
-
// Navigate to home screen
|
|
1098
|
-
setGlobalScreen("home")
|
|
1099
|
-
}
|
|
1100
|
-
}, [selectedToken, filteredTokens, setOriginToken, setGlobalScreen])
|
|
1101
|
-
|
|
1102
1068
|
// Poll transaction status when we have a pending transaction
|
|
1103
1069
|
useEffect(() => {
|
|
1104
1070
|
logger.console.log("[MeldStepsFlow] Polling useEffect triggered:", {
|
|
@@ -1184,7 +1150,7 @@ export const MeldStepsFlow: React.FC<MeldStepsFlowProps> = ({
|
|
|
1184
1150
|
// First, get a quote to find the best service provider
|
|
1185
1151
|
const quoteResponse = await trailsClient.getMeldQuote({
|
|
1186
1152
|
walletAddress: "0x1234567890123456789012345678901234567890",
|
|
1187
|
-
countryCode: selectedCountry.
|
|
1153
|
+
countryCode: selectedCountry.countryCode,
|
|
1188
1154
|
sourceCurrencyCode: selectedCurrency,
|
|
1189
1155
|
sourceAmount: selectedAmount,
|
|
1190
1156
|
destinationCurrencyCode: selectedToken.code,
|
|
@@ -1334,7 +1300,6 @@ export const MeldStepsFlow: React.FC<MeldStepsFlowProps> = ({
|
|
|
1334
1300
|
onBack={handleBackFromSubScreen}
|
|
1335
1301
|
onSelectCountry={handleSelectCountry}
|
|
1336
1302
|
selectedCountry={selectedCountry}
|
|
1337
|
-
trailsClient={trailsClient}
|
|
1338
1303
|
/>
|
|
1339
1304
|
)
|
|
1340
1305
|
}
|
|
@@ -1361,7 +1326,7 @@ export const MeldStepsFlow: React.FC<MeldStepsFlowProps> = ({
|
|
|
1361
1326
|
onSelectToken={handleSelectToken}
|
|
1362
1327
|
selectedToken={selectedToken}
|
|
1363
1328
|
trailsClient={trailsClient}
|
|
1364
|
-
countryCode={selectedCountry?.
|
|
1329
|
+
countryCode={selectedCountry?.countryCode}
|
|
1365
1330
|
/>
|
|
1366
1331
|
)
|
|
1367
1332
|
}
|
|
@@ -1382,9 +1347,6 @@ export const MeldStepsFlow: React.FC<MeldStepsFlowProps> = ({
|
|
|
1382
1347
|
setCurrentScreen("menu")
|
|
1383
1348
|
}}
|
|
1384
1349
|
onContinue={handleAmountContinue}
|
|
1385
|
-
_selectedCountry={selectedCountry}
|
|
1386
|
-
_selectedToken={selectedToken}
|
|
1387
|
-
_selectedPaymentMethod={selectedPaymentMethod}
|
|
1388
1350
|
initialAmount={selectedAmount}
|
|
1389
1351
|
initialCurrency={selectedCurrency}
|
|
1390
1352
|
/>
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type React from "react"
|
|
2
2
|
import { useEffect, useState } from "react"
|
|
3
|
-
|
|
4
|
-
// OFT progress bar duration: 20 minutes
|
|
5
|
-
const OFT_PROGRESS_DURATION_MS = 20 * 60 * 1000
|
|
3
|
+
import { formatDuration } from "../../utils/time.js"
|
|
6
4
|
|
|
7
5
|
interface OFTProgressBarProps {
|
|
8
6
|
/** Timestamp when the deposit was confirmed */
|
|
9
7
|
depositConfirmedAt: number
|
|
8
|
+
/** Estimated total duration in seconds */
|
|
9
|
+
estimatedDurationSeconds: number
|
|
10
10
|
/** Whether to show with animation */
|
|
11
11
|
showContent?: boolean
|
|
12
12
|
}
|
|
@@ -17,21 +17,32 @@ interface OFTProgressBarProps {
|
|
|
17
17
|
*/
|
|
18
18
|
export const OFTProgressBar: React.FC<OFTProgressBarProps> = ({
|
|
19
19
|
depositConfirmedAt,
|
|
20
|
+
estimatedDurationSeconds,
|
|
20
21
|
showContent = true,
|
|
21
22
|
}) => {
|
|
23
|
+
const hasValidDuration =
|
|
24
|
+
Number.isFinite(estimatedDurationSeconds) && estimatedDurationSeconds > 0
|
|
25
|
+
const clampedDurationSeconds = hasValidDuration ? estimatedDurationSeconds : 0
|
|
26
|
+
const progressDurationMs = clampedDurationSeconds * 1000
|
|
27
|
+
|
|
22
28
|
const [progress, setProgress] = useState(0)
|
|
23
|
-
const [remainingMinutes, setRemainingMinutes] = useState(
|
|
29
|
+
const [remainingMinutes, setRemainingMinutes] = useState(
|
|
30
|
+
Math.ceil(clampedDurationSeconds / 60),
|
|
31
|
+
)
|
|
24
32
|
|
|
25
33
|
useEffect(() => {
|
|
34
|
+
if (!hasValidDuration) {
|
|
35
|
+
setProgress(0)
|
|
36
|
+
setRemainingMinutes(0)
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
|
|
26
40
|
const updateProgress = () => {
|
|
27
41
|
const elapsed = Date.now() - depositConfirmedAt
|
|
28
|
-
const newProgress = Math.min(
|
|
29
|
-
(elapsed / OFT_PROGRESS_DURATION_MS) * 100,
|
|
30
|
-
100,
|
|
31
|
-
)
|
|
42
|
+
const newProgress = Math.min((elapsed / progressDurationMs) * 100, 100)
|
|
32
43
|
const remaining = Math.max(
|
|
33
44
|
0,
|
|
34
|
-
Math.ceil((
|
|
45
|
+
Math.ceil((progressDurationMs - elapsed) / 60000),
|
|
35
46
|
)
|
|
36
47
|
setProgress(newProgress)
|
|
37
48
|
setRemainingMinutes(remaining)
|
|
@@ -41,7 +52,11 @@ export const OFTProgressBar: React.FC<OFTProgressBarProps> = ({
|
|
|
41
52
|
|
|
42
53
|
const interval = setInterval(updateProgress, 1000)
|
|
43
54
|
return () => clearInterval(interval)
|
|
44
|
-
}, [depositConfirmedAt])
|
|
55
|
+
}, [depositConfirmedAt, hasValidDuration, progressDurationMs])
|
|
56
|
+
|
|
57
|
+
if (!hasValidDuration) {
|
|
58
|
+
return null
|
|
59
|
+
}
|
|
45
60
|
|
|
46
61
|
return (
|
|
47
62
|
<div
|
|
@@ -51,7 +66,11 @@ export const OFTProgressBar: React.FC<OFTProgressBarProps> = ({
|
|
|
51
66
|
>
|
|
52
67
|
<div className="flex justify-between text-sm text-gray-600 dark:text-gray-400 mb-2">
|
|
53
68
|
<span>Bridging via LayerZero</span>
|
|
54
|
-
<span>
|
|
69
|
+
<span>
|
|
70
|
+
{remainingMinutes > 0
|
|
71
|
+
? `${remainingMinutes} min remaining`
|
|
72
|
+
: "completing soon"}
|
|
73
|
+
</span>
|
|
55
74
|
</div>
|
|
56
75
|
<div className="w-full h-2 bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden">
|
|
57
76
|
<div
|
|
@@ -60,7 +79,8 @@ export const OFTProgressBar: React.FC<OFTProgressBarProps> = ({
|
|
|
60
79
|
/>
|
|
61
80
|
</div>
|
|
62
81
|
<p className="text-xs text-gray-500 dark:text-gray-400 mt-2 text-center">
|
|
63
|
-
LayerZero OFT transfers typically complete
|
|
82
|
+
LayerZero OFT transfers typically complete in about{" "}
|
|
83
|
+
{formatDuration(clampedDurationSeconds)}
|
|
64
84
|
</p>
|
|
65
85
|
</div>
|
|
66
86
|
)
|
|
@@ -2,6 +2,7 @@ import { ChevronDown } from "lucide-react"
|
|
|
2
2
|
import type React from "react"
|
|
3
3
|
import { useEffect, useRef, useState } from "react"
|
|
4
4
|
import { formatUnits } from "viem"
|
|
5
|
+
import { isValidNumber } from "../../utils/validation.js"
|
|
5
6
|
import type { MeldQuote } from "../../meld/utils/meld.js"
|
|
6
7
|
import type { PrepareSendQuote } from "../../prepareSend.js"
|
|
7
8
|
|
|
@@ -106,7 +107,7 @@ export const OnRampProviderSelector: React.FC<OnRampProviderSelectorProps> = ({
|
|
|
106
107
|
|
|
107
108
|
if (isUsdStablecoin && trailsQuote?.destinationAmountFormatted) {
|
|
108
109
|
const amount = parseFloat(trailsQuote.destinationAmountFormatted)
|
|
109
|
-
if (
|
|
110
|
+
if (isValidNumber(amount)) {
|
|
110
111
|
return `$${amount.toFixed(2)}`
|
|
111
112
|
}
|
|
112
113
|
}
|
|
@@ -2,6 +2,7 @@ import { Building2, Check, Copy, CreditCard } from "lucide-react"
|
|
|
2
2
|
import type React from "react"
|
|
3
3
|
import { useState } from "react"
|
|
4
4
|
import { getChainName } from "../../chains.js"
|
|
5
|
+
import { isValidNumber } from "../../utils/validation.js"
|
|
5
6
|
import { logger } from "../../logger.js"
|
|
6
7
|
import type { MeldServiceProvider } from "../../onramp-client/trails-onramp.gen.js"
|
|
7
8
|
import { SECOND_MS, formatRelativeDate } from "../../utils/time.js"
|
|
@@ -61,7 +62,7 @@ function formatAmount(amount?: string): string {
|
|
|
61
62
|
if (!amount) return "-"
|
|
62
63
|
|
|
63
64
|
const numAmount = parseFloat(amount)
|
|
64
|
-
if (
|
|
65
|
+
if (!isValidNumber(numAmount)) return amount
|
|
65
66
|
|
|
66
67
|
return numAmount.toLocaleString("en-US", {
|
|
67
68
|
minimumFractionDigits: 2,
|
|
@@ -2,6 +2,7 @@ import { ChevronRight, Search } from "lucide-react"
|
|
|
2
2
|
import type React from "react"
|
|
3
3
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react"
|
|
4
4
|
import { getChainInfo } from "../../chains.js"
|
|
5
|
+
import { isValidNumber } from "../../utils/validation.js"
|
|
5
6
|
import { logger } from "../../logger.js"
|
|
6
7
|
import { TradeType } from "../../prepareSend.js"
|
|
7
8
|
import { formatUsdAmountLocaleDisplay } from "../../utils/format.js"
|
|
@@ -61,6 +62,8 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
61
62
|
setWalletConfirmRetryHandler,
|
|
62
63
|
swapProvider,
|
|
63
64
|
bridgeProvider,
|
|
65
|
+
swapProviderFallback,
|
|
66
|
+
bridgeProviderFallback,
|
|
64
67
|
fundMethod,
|
|
65
68
|
checkoutOnHandlers,
|
|
66
69
|
recentTokens,
|
|
@@ -223,6 +226,8 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
223
226
|
tradeType: TradeType.EXACT_OUTPUT, // Key difference: using EXACT_OUTPUT
|
|
224
227
|
swapProvider,
|
|
225
228
|
bridgeProvider,
|
|
229
|
+
swapProviderFallback,
|
|
230
|
+
bridgeProviderFallback,
|
|
226
231
|
fundMethod,
|
|
227
232
|
mode,
|
|
228
233
|
checkoutOnHandlers,
|
|
@@ -761,7 +766,7 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
761
766
|
const balance = parseFloat(
|
|
762
767
|
originTokenBalance.balanceFormatted,
|
|
763
768
|
)
|
|
764
|
-
if (
|
|
769
|
+
if (isValidNumber(balance)) {
|
|
765
770
|
setTokenAmountForBackend(balance.toFixed(6))
|
|
766
771
|
}
|
|
767
772
|
}
|
|
@@ -773,7 +778,7 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
773
778
|
const balance = parseFloat(
|
|
774
779
|
originTokenBalance.balanceFormatted,
|
|
775
780
|
)
|
|
776
|
-
if (
|
|
781
|
+
if (isValidNumber(balance)) {
|
|
777
782
|
setTokenAmountForBackend(balance.toFixed(6))
|
|
778
783
|
}
|
|
779
784
|
}
|
|
@@ -1059,6 +1064,7 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
1059
1064
|
isPassthrough={isPassthroughEligible(
|
|
1060
1065
|
prepareSendQuote.passthroughEligible,
|
|
1061
1066
|
selectedFeeOption,
|
|
1067
|
+
processedFeeOptions,
|
|
1062
1068
|
)}
|
|
1063
1069
|
/>
|
|
1064
1070
|
</div>
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
getDefaultGasCostEstimate,
|
|
6
6
|
} from "../../estimate.js"
|
|
7
7
|
import { useClickTracking } from "../hooks/useClickTracking.js"
|
|
8
|
+
import { isValidNumber } from "../../utils/validation.js"
|
|
8
9
|
|
|
9
10
|
interface PercentageMaxButtonsProps {
|
|
10
11
|
userBalance: string | undefined
|
|
@@ -47,7 +48,7 @@ export const PercentageMaxButtons: React.FC<PercentageMaxButtonsProps> = ({
|
|
|
47
48
|
})
|
|
48
49
|
|
|
49
50
|
const balance = parseFloat(userBalance)
|
|
50
|
-
if (
|
|
51
|
+
if (!isValidNumber(balance)) return
|
|
51
52
|
|
|
52
53
|
const amount = (balance * percentage) / 100
|
|
53
54
|
onAmountSelect(amount.toFixed(6))
|
|
@@ -69,8 +70,9 @@ export const PercentageMaxButtons: React.FC<PercentageMaxButtonsProps> = ({
|
|
|
69
70
|
// For native tokens, subtract gas cost
|
|
70
71
|
// Priority: 1) Use actual gas cost from quote, 2) Fetch real gas price, 3) Fallback to 1% of balance
|
|
71
72
|
const effectiveGasCost =
|
|
72
|
-
gasCostFormatted
|
|
73
|
-
|
|
73
|
+
gasCostFormatted && gasCostFormatted !== "0"
|
|
74
|
+
? gasCostFormatted
|
|
75
|
+
: await getDefaultGasCostEstimate(userBalance, chainId)
|
|
74
76
|
const maxAmount = calculateMaxNativeAmount(userBalance, effectiveGasCost)
|
|
75
77
|
onAmountSelect(maxAmount)
|
|
76
78
|
} else {
|
|
@@ -56,6 +56,8 @@ interface PoolDepositProps {
|
|
|
56
56
|
setWalletConfirmRetryHandler: (handler: () => Promise<void>) => void
|
|
57
57
|
swapProvider?: string
|
|
58
58
|
bridgeProvider?: string
|
|
59
|
+
swapProviderFallback?: boolean
|
|
60
|
+
bridgeProviderFallback?: boolean
|
|
59
61
|
fundMethod?: FundMethod
|
|
60
62
|
checkoutOnHandlers?: CheckoutOnHandlers
|
|
61
63
|
recentTokens?: Token[]
|
|
@@ -77,6 +79,8 @@ export const PoolDeposit: React.FC<PoolDepositProps> = ({
|
|
|
77
79
|
setWalletConfirmRetryHandler,
|
|
78
80
|
swapProvider,
|
|
79
81
|
bridgeProvider,
|
|
82
|
+
swapProviderFallback,
|
|
83
|
+
bridgeProviderFallback,
|
|
80
84
|
fundMethod,
|
|
81
85
|
checkoutOnHandlers,
|
|
82
86
|
recentTokens,
|
|
@@ -207,6 +211,8 @@ export const PoolDeposit: React.FC<PoolDepositProps> = ({
|
|
|
207
211
|
tradeType: TradeType.EXACT_INPUT,
|
|
208
212
|
swapProvider,
|
|
209
213
|
bridgeProvider,
|
|
214
|
+
swapProviderFallback,
|
|
215
|
+
bridgeProviderFallback,
|
|
210
216
|
fundMethod,
|
|
211
217
|
mode,
|
|
212
218
|
checkoutOnHandlers,
|