0xtrails 0.2.6 → 0.4.0
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/aave.d.ts +2 -0
- package/dist/aave.d.ts.map +1 -1
- package/dist/{ccip-Xjh9d1gb.js → ccip-BpQGQiWq.js} +7 -7
- package/dist/config.d.ts +0 -5
- package/dist/config.d.ts.map +1 -1
- package/dist/constants.d.ts +2 -4
- package/dist/constants.d.ts.map +1 -1
- package/dist/error.d.ts +4 -1
- package/dist/error.d.ts.map +1 -1
- package/dist/fees.d.ts +2 -2
- package/dist/fees.d.ts.map +1 -1
- package/dist/{index-BnhdZ8Ho.js → index-DsJM5F-V.js} +46084 -48697
- package/dist/index.d.ts +9 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +741 -923
- package/dist/intentReceiptMonitor.d.ts +24 -0
- package/dist/intentReceiptMonitor.d.ts.map +1 -0
- package/dist/intentReceiptPoller.d.ts +69 -0
- package/dist/intentReceiptPoller.d.ts.map +1 -0
- package/dist/intents.d.ts +15 -11
- package/dist/intents.d.ts.map +1 -1
- package/dist/morpho.d.ts +6 -5
- package/dist/morpho.d.ts.map +1 -1
- package/dist/mutations.d.ts +16 -0
- package/dist/mutations.d.ts.map +1 -0
- package/dist/preconditions.d.ts +5 -4
- package/dist/preconditions.d.ts.map +1 -1
- package/dist/prepareSend.d.ts +5 -190
- package/dist/prepareSend.d.ts.map +1 -1
- package/dist/prices.d.ts +9 -6
- package/dist/prices.d.ts.map +1 -1
- package/dist/sequenceWallet.d.ts +3 -16
- package/dist/sequenceWallet.d.ts.map +1 -1
- package/dist/tokenBalances.d.ts +17 -13
- package/dist/tokenBalances.d.ts.map +1 -1
- package/dist/trails.d.ts +24 -40
- package/dist/trails.d.ts.map +1 -1
- package/dist/trailsClient.d.ts +5 -6
- package/dist/trailsClient.d.ts.map +1 -1
- package/dist/transactionIntent/constants.d.ts +7 -0
- package/dist/transactionIntent/constants.d.ts.map +1 -0
- package/dist/transactionIntent/deposits/depositOrchestrator.d.ts +44 -0
- package/dist/transactionIntent/deposits/depositOrchestrator.d.ts.map +1 -0
- package/dist/transactionIntent/deposits/gaslessDeposit.d.ts +30 -0
- package/dist/transactionIntent/deposits/gaslessDeposit.d.ts.map +1 -0
- package/dist/transactionIntent/deposits/index.d.ts +4 -0
- package/dist/transactionIntent/deposits/index.d.ts.map +1 -0
- package/dist/transactionIntent/deposits/standardDeposit.d.ts +30 -0
- package/dist/transactionIntent/deposits/standardDeposit.d.ts.map +1 -0
- package/dist/transactionIntent/execution/index.d.ts +2 -0
- package/dist/transactionIntent/execution/index.d.ts.map +1 -0
- package/dist/transactionIntent/execution/transactionState.d.ts +5 -0
- package/dist/transactionIntent/execution/transactionState.d.ts.map +1 -0
- package/dist/transactionIntent/handlers/crossChain.d.ts +82 -0
- package/dist/transactionIntent/handlers/crossChain.d.ts.map +1 -0
- package/dist/transactionIntent/handlers/index.d.ts +4 -0
- package/dist/transactionIntent/handlers/index.d.ts.map +1 -0
- package/dist/transactionIntent/handlers/sameChainDifferentToken.d.ts +62 -0
- package/dist/transactionIntent/handlers/sameChainDifferentToken.d.ts.map +1 -0
- package/dist/transactionIntent/handlers/sameChainSameToken.d.ts +72 -0
- package/dist/transactionIntent/handlers/sameChainSameToken.d.ts.map +1 -0
- package/dist/transactionIntent/index.d.ts +9 -0
- package/dist/transactionIntent/index.d.ts.map +1 -0
- package/dist/transactionIntent/quote/feeExtractors.d.ts +17 -0
- package/dist/transactionIntent/quote/feeExtractors.d.ts.map +1 -0
- package/dist/transactionIntent/quote/index.d.ts +4 -0
- package/dist/transactionIntent/quote/index.d.ts.map +1 -0
- package/dist/transactionIntent/quote/normalizeQuote.d.ts +34 -0
- package/dist/transactionIntent/quote/normalizeQuote.d.ts.map +1 -0
- package/dist/transactionIntent/quote/quoteHelpers.d.ts +5 -0
- package/dist/transactionIntent/quote/quoteHelpers.d.ts.map +1 -0
- package/dist/transactionIntent/types.d.ts +131 -0
- package/dist/transactionIntent/types.d.ts.map +1 -0
- package/dist/transactionIntent/utils/balanceChecker.d.ts +18 -0
- package/dist/transactionIntent/utils/balanceChecker.d.ts.map +1 -0
- package/dist/transactionIntent/utils/index.d.ts +4 -0
- package/dist/transactionIntent/utils/index.d.ts.map +1 -0
- package/dist/transactionIntent/utils/lifiHelpers.d.ts +10 -0
- package/dist/transactionIntent/utils/lifiHelpers.d.ts.map +1 -0
- package/dist/transactionIntent/utils/testnetHelpers.d.ts +3 -0
- package/dist/transactionIntent/utils/testnetHelpers.d.ts.map +1 -0
- package/dist/transactionIntent/validators.d.ts +6 -0
- package/dist/transactionIntent/validators.d.ts.map +1 -0
- package/dist/transactions.d.ts +2 -1
- package/dist/transactions.d.ts.map +1 -1
- package/dist/widget/components/AccountSettings.d.ts.map +1 -1
- package/dist/widget/components/ClassicSwap.d.ts +0 -1
- package/dist/widget/components/ClassicSwap.d.ts.map +1 -1
- package/dist/widget/components/ConfigDisplay.d.ts.map +1 -1
- package/dist/widget/components/ConnectedWallets.d.ts.map +1 -1
- package/dist/widget/components/DynamicSizeInputField.d.ts +13 -0
- package/dist/widget/components/DynamicSizeInputField.d.ts.map +1 -0
- package/dist/widget/components/Earn.d.ts +0 -1
- package/dist/widget/components/Earn.d.ts.map +1 -1
- package/dist/widget/components/FeeOptions.d.ts +5 -13
- package/dist/widget/components/FeeOptions.d.ts.map +1 -1
- package/dist/widget/components/Fund.d.ts +0 -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/FundSwap.d.ts +0 -1
- package/dist/widget/components/FundSwap.d.ts.map +1 -1
- package/dist/widget/components/Pay.d.ts +0 -1
- package/dist/widget/components/Pay.d.ts.map +1 -1
- package/dist/widget/components/PoolDeposit.d.ts +0 -1
- package/dist/widget/components/PoolDeposit.d.ts.map +1 -1
- package/dist/widget/components/PoolWithdraw.d.ts +0 -18
- package/dist/widget/components/PoolWithdraw.d.ts.map +1 -1
- package/dist/widget/components/QuoteDetails.d.ts +1 -0
- package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
- package/dist/widget/components/Swap.d.ts +0 -1
- package/dist/widget/components/Swap.d.ts.map +1 -1
- package/dist/widget/components/TransferPendingVertical.d.ts.map +1 -1
- package/dist/widget/components/WaasFeeOptions.d.ts.map +1 -1
- package/dist/widget/css/compiled.css +2 -2
- package/dist/widget/hooks/useCheckout.d.ts +17 -4
- package/dist/widget/hooks/useCheckout.d.ts.map +1 -1
- package/dist/widget/hooks/useDefaultTokenSelection.d.ts.map +1 -1
- package/dist/widget/hooks/useQuote.d.ts +3 -4
- package/dist/widget/hooks/useQuote.d.ts.map +1 -1
- package/dist/widget/hooks/useSelectedFeeToken.d.ts +1 -0
- package/dist/widget/hooks/useSelectedFeeToken.d.ts.map +1 -1
- package/dist/widget/hooks/useSendForm.d.ts +3 -4
- package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
- package/dist/widget/hooks/useTokenList.d.ts.map +1 -1
- package/dist/widget/hooks/useWalletConnectionContext.d.ts +25 -0
- package/dist/widget/hooks/useWalletConnectionContext.d.ts.map +1 -0
- package/dist/widget/index.js +1 -1
- package/dist/widget/widget.d.ts +12 -7
- package/dist/widget/widget.d.ts.map +1 -1
- package/package.json +21 -23
- package/src/aave.ts +54 -1
- package/src/config.ts +57 -58
- package/src/constants.ts +8 -9
- package/src/error.ts +21 -3
- package/src/fees.ts +53 -42
- package/src/index.ts +35 -13
- package/src/intentReceiptMonitor.ts +102 -0
- package/src/intentReceiptPoller.ts +299 -0
- package/src/intents.ts +206 -172
- package/src/morpho.ts +58 -9
- package/src/mutations.ts +129 -0
- package/src/preconditions.ts +16 -21
- package/src/prepareSend.ts +80 -4514
- package/src/prices.ts +26 -22
- package/src/relaySdk.ts +2 -2
- package/src/sequenceWallet.ts +6 -73
- package/src/tokenBalances.ts +175 -69
- package/src/trails.ts +230 -722
- package/src/trailsClient.ts +10 -23
- package/src/transactionIntent/constants.ts +11 -0
- package/src/transactionIntent/deposits/depositOrchestrator.ts +210 -0
- package/src/transactionIntent/deposits/gaslessDeposit.ts +588 -0
- package/src/transactionIntent/deposits/index.ts +3 -0
- package/src/transactionIntent/deposits/standardDeposit.ts +379 -0
- package/src/transactionIntent/execution/index.ts +1 -0
- package/src/transactionIntent/execution/transactionState.ts +35 -0
- package/src/transactionIntent/handlers/crossChain.ts +1707 -0
- package/src/transactionIntent/handlers/index.ts +3 -0
- package/src/transactionIntent/handlers/sameChainDifferentToken.ts +323 -0
- package/src/transactionIntent/handlers/sameChainSameToken.ts +712 -0
- package/src/transactionIntent/index.ts +9 -0
- package/src/transactionIntent/quote/feeExtractors.ts +81 -0
- package/src/transactionIntent/quote/index.ts +3 -0
- package/src/transactionIntent/quote/normalizeQuote.ts +367 -0
- package/src/transactionIntent/quote/quoteHelpers.ts +53 -0
- package/src/transactionIntent/types.ts +157 -0
- package/src/transactionIntent/utils/balanceChecker.ts +96 -0
- package/src/transactionIntent/utils/index.ts +3 -0
- package/src/transactionIntent/utils/lifiHelpers.ts +68 -0
- package/src/transactionIntent/utils/testnetHelpers.ts +10 -0
- package/src/transactionIntent/validators.ts +57 -0
- package/src/transactions.ts +36 -53
- package/src/widget/compiled.css +2 -2
- package/src/widget/components/AccountIntentTransactionHistory.tsx +36 -36
- package/src/widget/components/AccountSettings.tsx +23 -6
- package/src/widget/components/ClassicSwap.tsx +28 -53
- package/src/widget/components/ConfigDisplay.tsx +0 -11
- package/src/widget/components/ConnectedWallets.tsx +30 -4
- package/src/widget/components/DynamicSizeInputField.tsx +109 -0
- package/src/widget/components/Earn.tsx +0 -16
- package/src/widget/components/FeeBreakdown.tsx +3 -3
- package/src/widget/components/FeeOption.tsx +2 -2
- package/src/widget/components/FeeOptions.tsx +151 -112
- package/src/widget/components/Fund.tsx +0 -3
- package/src/widget/components/FundMethods.tsx +4 -3
- package/src/widget/components/FundSwap.tsx +0 -1
- package/src/widget/components/Pay.tsx +11 -16
- package/src/widget/components/PoolDeposit.tsx +35 -32
- package/src/widget/components/PoolWithdraw.tsx +153 -256
- package/src/widget/components/QuoteDetails.tsx +899 -494
- package/src/widget/components/Swap.tsx +0 -1
- package/src/widget/components/TransferPendingVertical.tsx +12 -8
- package/src/widget/components/WaasFeeOptions.tsx +23 -7
- package/src/widget/components/WalletConfirmation.tsx +1 -1
- package/src/widget/hooks/useAmountUsd.ts +9 -9
- package/src/widget/hooks/useCheckout.ts +97 -9
- package/src/widget/hooks/useDefaultTokenSelection.tsx +27 -21
- package/src/widget/hooks/useQuote.ts +86 -33
- package/src/widget/hooks/useSelectedFeeToken.tsx +32 -37
- package/src/widget/hooks/useSendForm.ts +37 -47
- package/src/widget/hooks/useTokenList.ts +34 -26
- package/src/widget/hooks/useWalletConnectionContext.tsx +128 -0
- package/src/widget/widget.tsx +197 -207
- package/dist/apiClient.d.ts +0 -9
- package/dist/apiClient.d.ts.map +0 -1
- package/dist/intentEntrypoint.d.ts +0 -114
- package/dist/intentEntrypoint.d.ts.map +0 -1
- package/dist/metaTxnMonitor.d.ts +0 -15
- package/dist/metaTxnMonitor.d.ts.map +0 -1
- package/dist/metaTxns.d.ts +0 -11
- package/dist/metaTxns.d.ts.map +0 -1
- package/dist/relayer.d.ts +0 -43
- package/dist/relayer.d.ts.map +0 -1
- package/src/apiClient.ts +0 -35
- package/src/intentEntrypoint.ts +0 -203
- package/src/metaTxnMonitor.ts +0 -171
- package/src/metaTxns.ts +0 -45
- package/src/relayer.ts +0 -289
|
@@ -1,34 +1,76 @@
|
|
|
1
1
|
import { ChevronDown } from "lucide-react"
|
|
2
2
|
import type React from "react"
|
|
3
|
-
import { useRef, useState } from "react"
|
|
3
|
+
import { useRef, useState, useEffect } from "react"
|
|
4
4
|
import { formatUsdAmountDisplay, formatRawAmount } from "../../tokenBalances.js"
|
|
5
5
|
import {
|
|
6
6
|
FeeOption,
|
|
7
7
|
type FeeOption as EnhancedFeeOptionType,
|
|
8
8
|
} from "./FeeOption.js"
|
|
9
9
|
import { logger } from "../../logger.js"
|
|
10
|
-
import { getChainInfo } from "../../chains.js"
|
|
11
|
-
import { TokenImage } from "./TokenImage.js"
|
|
12
10
|
import { getTokenImageUrl } from "../../tokens.js"
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
11
|
+
import { TokenImage } from "./TokenImage.js"
|
|
12
|
+
import { ethAddress, zeroAddress } from "viem"
|
|
13
|
+
import type { FeeOption as APIFeeOption } from "../../widget/hooks/useSelectedFeeToken.js"
|
|
14
|
+
|
|
15
|
+
const ZERO_ADDRESS = zeroAddress.toLowerCase()
|
|
16
|
+
const ETH_ADDRESS = ethAddress.toLowerCase()
|
|
17
|
+
|
|
18
|
+
const normalizeAddress = (address?: string | null): string =>
|
|
19
|
+
(address ?? "").toLowerCase()
|
|
20
|
+
|
|
21
|
+
const isNativeTokenAddress = (address?: string | null): boolean => {
|
|
22
|
+
const normalized = normalizeAddress(address)
|
|
23
|
+
return normalized === ZERO_ADDRESS || normalized === ETH_ADDRESS
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const safeFormatAmountWithSymbol = (option: APIFeeOption): string => {
|
|
27
|
+
const tokenDecimals =
|
|
28
|
+
typeof option.tokenDecimals === "number" &&
|
|
29
|
+
option.tokenDecimals > 0 &&
|
|
30
|
+
option.tokenDecimals <= 18
|
|
31
|
+
? option.tokenDecimals
|
|
32
|
+
: isNativeTokenAddress(option.tokenAddress)
|
|
33
|
+
? 18
|
|
34
|
+
: undefined
|
|
35
|
+
|
|
36
|
+
if (tokenDecimals === undefined) {
|
|
37
|
+
logger.console.warn("[trails-sdk] [FEE-OPTIONS] Missing token decimals", {
|
|
38
|
+
tokenAddress: option.tokenAddress,
|
|
39
|
+
tokenSymbol: option.tokenSymbol,
|
|
40
|
+
})
|
|
41
|
+
return option.tokenSymbol ? `-- ${option.tokenSymbol}` : "--"
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
const formattedAmount = formatRawAmount(option.amount, tokenDecimals)
|
|
46
|
+
return option.tokenSymbol
|
|
47
|
+
? `${formattedAmount} ${option.tokenSymbol}`
|
|
48
|
+
: formattedAmount
|
|
49
|
+
} catch (error) {
|
|
50
|
+
logger.console.warn(
|
|
51
|
+
"[trails-sdk] [FEE-OPTIONS] Failed to format fee option amount",
|
|
52
|
+
{
|
|
53
|
+
option,
|
|
54
|
+
tokenDecimals,
|
|
55
|
+
error,
|
|
56
|
+
},
|
|
57
|
+
)
|
|
58
|
+
return option.tokenSymbol ? `-- ${option.tokenSymbol}` : "--"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const safeFormatUsdDisplay = (option: APIFeeOption): string => {
|
|
63
|
+
const usdValue =
|
|
64
|
+
(option as { amountUsd?: number }).amountUsd ?? option.amountUSD ?? 0
|
|
65
|
+
return formatUsdAmountDisplay(usdValue)
|
|
25
66
|
}
|
|
26
67
|
|
|
27
68
|
interface FeeOptionsProps {
|
|
28
|
-
feeOptions:
|
|
29
|
-
selectedFeeToken:
|
|
30
|
-
setSelectedFeeToken: (token:
|
|
69
|
+
feeOptions: APIFeeOption[]
|
|
70
|
+
selectedFeeToken: APIFeeOption | null
|
|
71
|
+
setSelectedFeeToken: (token: APIFeeOption | null) => void
|
|
31
72
|
chainId?: number
|
|
73
|
+
isRefetching?: boolean // When true, the fee quote is stale and being refreshed, so hide the component
|
|
32
74
|
}
|
|
33
75
|
|
|
34
76
|
export const FeeOptions: React.FC<FeeOptionsProps> = ({
|
|
@@ -36,23 +78,53 @@ export const FeeOptions: React.FC<FeeOptionsProps> = ({
|
|
|
36
78
|
selectedFeeToken,
|
|
37
79
|
setSelectedFeeToken,
|
|
38
80
|
chainId,
|
|
81
|
+
isRefetching,
|
|
39
82
|
}) => {
|
|
40
|
-
|
|
41
|
-
|
|
83
|
+
// Early returns BEFORE any hooks - this prevents "Rendered more hooks" error
|
|
84
|
+
// Hide component when fee quote is stale and being refreshed
|
|
85
|
+
if (isRefetching) {
|
|
86
|
+
return null
|
|
87
|
+
}
|
|
42
88
|
|
|
43
89
|
// Don't render if no fee options available
|
|
44
90
|
if (!feeOptions || feeOptions.length === 0) {
|
|
45
91
|
return null
|
|
46
92
|
}
|
|
47
93
|
|
|
94
|
+
// Check if there are non-native options before calling hooks
|
|
95
|
+
const hasNonNativeOptions = feeOptions.some(
|
|
96
|
+
(opt) => !isNativeTokenAddress(opt.tokenAddress),
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
// Don't render if only native token is available
|
|
100
|
+
if (!hasNonNativeOptions) {
|
|
101
|
+
return null
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// NOW we can safely call hooks after all early returns
|
|
105
|
+
const [isOpen, setIsOpen] = useState(false)
|
|
106
|
+
const accordionRef = useRef<HTMLDivElement>(null)
|
|
107
|
+
|
|
108
|
+
// Clear selected fee token when feeOptions change (stale quote)
|
|
109
|
+
// This resets the user's fee selection when they pick a different token
|
|
110
|
+
// Use comprehensive key that includes token addresses and amounts
|
|
111
|
+
const feeOptionsKey = feeOptions
|
|
112
|
+
.map((opt) => `${opt.tokenAddress}-${opt.tokenSymbol}-${opt.amount}`)
|
|
113
|
+
.join("|")
|
|
114
|
+
|
|
115
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: setSelectedFeeToken is stable
|
|
116
|
+
useEffect(() => {
|
|
117
|
+
setSelectedFeeToken(null)
|
|
118
|
+
}, [feeOptionsKey])
|
|
119
|
+
|
|
48
120
|
// Enhance ALL fee options with formatted values and image URLs (including native gas)
|
|
49
121
|
const enhancedFeeOptions: EnhancedFeeOptionType[] = feeOptions.map(
|
|
50
122
|
(option) => ({
|
|
51
123
|
...option,
|
|
52
|
-
amountFormatted:
|
|
53
|
-
amountUsdDisplay:
|
|
124
|
+
amountFormatted: safeFormatAmountWithSymbol(option),
|
|
125
|
+
amountUsdDisplay: safeFormatUsdDisplay(option),
|
|
54
126
|
tokenImageUrl: getTokenImageUrl({
|
|
55
|
-
chainId: option.chainId || chainId,
|
|
127
|
+
chainId: option.chainId || chainId,
|
|
56
128
|
contractAddress: option.tokenAddress,
|
|
57
129
|
symbol: option.tokenSymbol,
|
|
58
130
|
}),
|
|
@@ -60,92 +132,54 @@ export const FeeOptions: React.FC<FeeOptionsProps> = ({
|
|
|
60
132
|
)
|
|
61
133
|
|
|
62
134
|
// Find native gas option (zero address) for header display
|
|
63
|
-
const nativeGasOption = enhancedFeeOptions.find(
|
|
64
|
-
(opt
|
|
135
|
+
const nativeGasOption = enhancedFeeOptions.find((opt) =>
|
|
136
|
+
isNativeTokenAddress(opt.tokenAddress),
|
|
65
137
|
)
|
|
66
138
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
139
|
+
// Find the currently selected option from enhancedFeeOptions for header display
|
|
140
|
+
const getSelectedOption = (): EnhancedFeeOptionType | undefined => {
|
|
141
|
+
if (
|
|
142
|
+
selectedFeeToken === null ||
|
|
143
|
+
isNativeTokenAddress(selectedFeeToken?.tokenAddress)
|
|
144
|
+
) {
|
|
145
|
+
return nativeGasOption
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (!selectedFeeToken) {
|
|
149
|
+
return undefined
|
|
75
150
|
}
|
|
76
151
|
|
|
77
|
-
|
|
78
|
-
|
|
152
|
+
const selectedAddress = normalizeAddress(selectedFeeToken.tokenAddress)
|
|
153
|
+
|
|
154
|
+
return enhancedFeeOptions.find(
|
|
155
|
+
(opt) => normalizeAddress(opt.tokenAddress) === selectedAddress,
|
|
156
|
+
)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const selectedOption = getSelectedOption()
|
|
160
|
+
|
|
161
|
+
// Use nativeGasOption as fallback when selectedOption is null/undefined
|
|
162
|
+
const displayOption = selectedOption || nativeGasOption
|
|
163
|
+
|
|
164
|
+
const handleFeeTokenSelect = (option: EnhancedFeeOptionType) => {
|
|
165
|
+
// For native gas (zero/ETH address), set to null to trigger non-gasless flow
|
|
166
|
+
if (isNativeTokenAddress(option.tokenAddress)) {
|
|
79
167
|
setSelectedFeeToken(null)
|
|
80
168
|
logger.console.log(
|
|
81
169
|
"[trails-sdk] [FEE-SELECT] Selected native gas fee option",
|
|
82
170
|
)
|
|
83
171
|
} else {
|
|
84
|
-
|
|
172
|
+
// Use the option directly - it already has all required fields
|
|
173
|
+
setSelectedFeeToken(option as APIFeeOption)
|
|
85
174
|
logger.console.log(
|
|
86
175
|
"[trails-sdk] [FEE-SELECT] Selected ERC20 fee option:",
|
|
87
|
-
|
|
176
|
+
option,
|
|
88
177
|
)
|
|
89
178
|
}
|
|
90
179
|
|
|
91
180
|
setIsOpen(false)
|
|
92
181
|
}
|
|
93
182
|
|
|
94
|
-
// Get display text and image for selected option
|
|
95
|
-
const getSelectedDisplayText = () => {
|
|
96
|
-
if (
|
|
97
|
-
selectedFeeToken === null ||
|
|
98
|
-
selectedFeeToken?.tokenAddress?.toLowerCase() ===
|
|
99
|
-
zeroAddress.toLowerCase()
|
|
100
|
-
) {
|
|
101
|
-
// Native gas selected - use native gas option data
|
|
102
|
-
const nativeSymbol =
|
|
103
|
-
nativeGasOption?.tokenSymbol ||
|
|
104
|
-
(chainId ? getNativeSymbol(chainId) : "ETH")
|
|
105
|
-
const nativeImageUrl = getTokenImageUrl({
|
|
106
|
-
chainId,
|
|
107
|
-
contractAddress: zeroAddress,
|
|
108
|
-
symbol: nativeSymbol,
|
|
109
|
-
})
|
|
110
|
-
const amountDisplay = nativeGasOption
|
|
111
|
-
? `${formatRawAmount(nativeGasOption.amount, nativeGasOption.tokenDecimals)} ${nativeGasOption.tokenSymbol}`
|
|
112
|
-
: ""
|
|
113
|
-
const usdDisplay = nativeGasOption
|
|
114
|
-
? formatUsdAmountDisplay(nativeGasOption.amountUSD)
|
|
115
|
-
: ""
|
|
116
|
-
return {
|
|
117
|
-
title: nativeSymbol,
|
|
118
|
-
amountDisplay,
|
|
119
|
-
usdDisplay,
|
|
120
|
-
symbol: nativeSymbol,
|
|
121
|
-
imageUrl: nativeImageUrl,
|
|
122
|
-
}
|
|
123
|
-
} else {
|
|
124
|
-
const tokenImageUrl = getTokenImageUrl({
|
|
125
|
-
chainId: selectedFeeToken.chainId || chainId, // Use fee token's chain ID, fallback to prop
|
|
126
|
-
contractAddress: selectedFeeToken.tokenAddress,
|
|
127
|
-
symbol: selectedFeeToken.tokenSymbol,
|
|
128
|
-
})
|
|
129
|
-
const amountDisplay = `${formatRawAmount(selectedFeeToken.amount, selectedFeeToken.tokenDecimals)} ${selectedFeeToken.tokenSymbol}`
|
|
130
|
-
const usdDisplay = formatUsdAmountDisplay(selectedFeeToken.amountUSD)
|
|
131
|
-
return {
|
|
132
|
-
title: selectedFeeToken.tokenSymbol,
|
|
133
|
-
amountDisplay,
|
|
134
|
-
usdDisplay,
|
|
135
|
-
symbol: selectedFeeToken.tokenSymbol,
|
|
136
|
-
imageUrl: tokenImageUrl,
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// Helper function to get native symbol for a chain
|
|
142
|
-
const getNativeSymbol = (chainId: number) => {
|
|
143
|
-
const chainInfo = getChainInfo(chainId)
|
|
144
|
-
return chainInfo?.nativeCurrency.symbol || "ETH"
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
const selectedDisplay = getSelectedDisplayText()
|
|
148
|
-
|
|
149
183
|
return (
|
|
150
184
|
<div className="space-y-1" ref={accordionRef}>
|
|
151
185
|
<div className="p-2">
|
|
@@ -165,24 +199,30 @@ export const FeeOptions: React.FC<FeeOptionsProps> = ({
|
|
|
165
199
|
className="w-full flex items-center justify-between p-1.5 trails-border-radius-input border trails-border-primary hover:trails-hover-bg transition-colors cursor-pointer"
|
|
166
200
|
>
|
|
167
201
|
<div className="flex items-center space-x-2">
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
202
|
+
{displayOption && (
|
|
203
|
+
<>
|
|
204
|
+
<TokenImage
|
|
205
|
+
imageUrl={displayOption.tokenImageUrl}
|
|
206
|
+
symbol={displayOption.tokenSymbol}
|
|
207
|
+
chainId={displayOption.chainId || chainId}
|
|
208
|
+
size={16}
|
|
209
|
+
/>
|
|
210
|
+
<div className="ml-2 text-left">
|
|
211
|
+
<div className="text-xs font-medium trails-text-primary">
|
|
212
|
+
{displayOption.amountFormatted}
|
|
213
|
+
</div>
|
|
214
|
+
</div>
|
|
215
|
+
</>
|
|
216
|
+
)}
|
|
179
217
|
</div>
|
|
180
218
|
<div className="flex items-center space-x-2">
|
|
181
|
-
|
|
182
|
-
<div className="text-
|
|
183
|
-
|
|
219
|
+
{displayOption && (
|
|
220
|
+
<div className="text-right">
|
|
221
|
+
<div className="text-xs font-medium trails-text-primary">
|
|
222
|
+
≈ {displayOption.amountUsdDisplay}
|
|
223
|
+
</div>
|
|
184
224
|
</div>
|
|
185
|
-
|
|
225
|
+
)}
|
|
186
226
|
<ChevronDown
|
|
187
227
|
className={`w-3 h-3 trails-text-muted transition-transform ${
|
|
188
228
|
isOpen ? "transform rotate-180" : ""
|
|
@@ -200,12 +240,11 @@ export const FeeOptions: React.FC<FeeOptionsProps> = ({
|
|
|
200
240
|
key={`${option.tokenAddress}-${index}`}
|
|
201
241
|
option={option}
|
|
202
242
|
isSelected={
|
|
203
|
-
option.tokenAddress
|
|
204
|
-
zeroAddress.toLowerCase()
|
|
243
|
+
isNativeTokenAddress(option.tokenAddress)
|
|
205
244
|
? selectedFeeToken === null ||
|
|
206
|
-
selectedFeeToken?.tokenAddress
|
|
207
|
-
|
|
208
|
-
|
|
245
|
+
isNativeTokenAddress(selectedFeeToken?.tokenAddress)
|
|
246
|
+
: normalizeAddress(selectedFeeToken?.tokenAddress) ===
|
|
247
|
+
normalizeAddress(option.tokenAddress)
|
|
209
248
|
}
|
|
210
249
|
onClick={() => handleFeeTokenSelect(option)}
|
|
211
250
|
chainId={option.chainId || chainId}
|
|
@@ -45,7 +45,6 @@ interface FundProps {
|
|
|
45
45
|
onComplete: (result: OnCompleteProps) => void
|
|
46
46
|
onSend: (amount: string, recipient: string) => void
|
|
47
47
|
paymasterUrls?: Array<{ chainId: number; url: string }>
|
|
48
|
-
gasless?: boolean
|
|
49
48
|
isSequenceWallet?: boolean
|
|
50
49
|
setWalletConfirmRetryHandler: (handler: () => Promise<void>) => void
|
|
51
50
|
quoteProvider?: string
|
|
@@ -81,7 +80,6 @@ export const Fund: React.FC<FundProps> = ({
|
|
|
81
80
|
onComplete,
|
|
82
81
|
onSend,
|
|
83
82
|
paymasterUrls,
|
|
84
|
-
gasless,
|
|
85
83
|
isSequenceWallet = false,
|
|
86
84
|
setWalletConfirmRetryHandler,
|
|
87
85
|
quoteProvider,
|
|
@@ -161,7 +159,6 @@ export const Fund: React.FC<FundProps> = ({
|
|
|
161
159
|
onError,
|
|
162
160
|
onWaitingForWalletConfirm,
|
|
163
161
|
paymasterUrls,
|
|
164
|
-
gasless,
|
|
165
162
|
onConfirm,
|
|
166
163
|
onComplete,
|
|
167
164
|
onSend,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type React from "react"
|
|
2
|
-
import { QrCode,
|
|
2
|
+
import { QrCode, ArrowLeftRight, ChevronRight } from "lucide-react"
|
|
3
3
|
import { useSwitchAccount } from "wagmi"
|
|
4
4
|
import { ScreenHeader } from "./ScreenHeader.js"
|
|
5
5
|
import { ConnectedWallets } from "./ConnectedWallets.js"
|
|
@@ -103,10 +103,11 @@ const FundMethods: React.FC<FundMethodsProps> = ({
|
|
|
103
103
|
<button
|
|
104
104
|
type="button"
|
|
105
105
|
onClick={onSelectExchangeList}
|
|
106
|
-
|
|
106
|
+
disabled
|
|
107
|
+
className="w-full text-left px-3 py-4 text-sm flex items-center justify-between cursor-not-allowed transition-colors opacity-50"
|
|
107
108
|
>
|
|
108
109
|
<div className="flex items-center gap-3">
|
|
109
|
-
<
|
|
110
|
+
<ArrowLeftRight className="w-4 h-4" />
|
|
110
111
|
<span className="text-sm font-bold">Send from Exchange</span>
|
|
111
112
|
</div>
|
|
112
113
|
<ChevronRight className="w-5 h-5 text-gray-400" />
|
|
@@ -24,7 +24,6 @@ interface FundProps {
|
|
|
24
24
|
onError: (error: Error | string | null) => void
|
|
25
25
|
onWaitingForWalletConfirm: (props: PrepareSendQuote) => void
|
|
26
26
|
paymasterUrls?: Array<{ chainId: number; url: string }>
|
|
27
|
-
gasless?: boolean
|
|
28
27
|
setWalletConfirmRetryHandler: (handler: () => Promise<void>) => void
|
|
29
28
|
quoteProvider?: string
|
|
30
29
|
fundMethod?: string
|
|
@@ -37,6 +37,7 @@ import { RequiredPropsError } from "./RequiredPropsError.js"
|
|
|
37
37
|
import { FundingMethodSelectorButton } from "./FundingMethodSelectorButton.js"
|
|
38
38
|
import { PercentageMaxButtons } from "./PercentageMaxButtons.js"
|
|
39
39
|
import { useDynamicInputStyles } from "./DynamicInputStyles.js"
|
|
40
|
+
import { DynamicSizeInputField } from "./DynamicSizeInputField.js"
|
|
40
41
|
|
|
41
42
|
interface PayProps {
|
|
42
43
|
selectedToken?: any // Origin token (optional - user can select)
|
|
@@ -50,7 +51,6 @@ interface PayProps {
|
|
|
50
51
|
onComplete: (result: OnCompleteProps) => void
|
|
51
52
|
onSend: (amount: string, recipient: string) => void
|
|
52
53
|
paymasterUrls?: Array<{ chainId: number; url: string }>
|
|
53
|
-
gasless?: boolean
|
|
54
54
|
isSequenceWallet?: boolean
|
|
55
55
|
setWalletConfirmRetryHandler: (handler: () => Promise<void>) => void
|
|
56
56
|
quoteProvider?: string
|
|
@@ -88,7 +88,6 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
88
88
|
onComplete,
|
|
89
89
|
onSend,
|
|
90
90
|
paymasterUrls,
|
|
91
|
-
gasless,
|
|
92
91
|
isSequenceWallet = false,
|
|
93
92
|
setWalletConfirmRetryHandler,
|
|
94
93
|
quoteProvider,
|
|
@@ -210,7 +209,6 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
210
209
|
onError,
|
|
211
210
|
onWaitingForWalletConfirm,
|
|
212
211
|
paymasterUrls,
|
|
213
|
-
gasless,
|
|
214
212
|
onConfirm,
|
|
215
213
|
onComplete,
|
|
216
214
|
onSend,
|
|
@@ -457,11 +455,6 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
457
455
|
// Dynamic font size based on input length for destination amount
|
|
458
456
|
const inputStyles = useDynamicInputStyles({ inputValue: displayAmount })
|
|
459
457
|
|
|
460
|
-
// Dynamic font size based on input length for origin amount (Pay with section)
|
|
461
|
-
const originInputStyles = useDynamicInputStyles({
|
|
462
|
-
inputValue: prepareSendQuote?.originAmountFormatted || "",
|
|
463
|
-
})
|
|
464
|
-
|
|
465
458
|
const handleOriginTokenSelect = useCallback(
|
|
466
459
|
(token: any) => {
|
|
467
460
|
const formattedToken = {
|
|
@@ -705,16 +698,12 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
705
698
|
{/* Amount Display - Non-editable */}
|
|
706
699
|
<div className="flex-1">
|
|
707
700
|
<div className="flex items-center space-x-2">
|
|
708
|
-
<
|
|
701
|
+
<DynamicSizeInputField
|
|
709
702
|
ref={paymentRequestInputRef}
|
|
710
|
-
type="text"
|
|
711
703
|
value={prepareSendQuote?.originAmountFormatted || ""}
|
|
712
|
-
placeholder={"0"}
|
|
713
704
|
readOnly={true}
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
}`}
|
|
717
|
-
style={originInputStyles}
|
|
705
|
+
isLoading={isLoadingQuote}
|
|
706
|
+
variant="default"
|
|
718
707
|
/>
|
|
719
708
|
{isLoadingQuote && (
|
|
720
709
|
<div className="animate-spin rounded-full h-4 w-4 border-solid border-b-2 trails-primary" />
|
|
@@ -951,6 +940,7 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
951
940
|
onChange={(e) => handleAmountChange(e.target.value)}
|
|
952
941
|
placeholder={`0 ${selectedDestToken?.symbol || ""}`}
|
|
953
942
|
readOnly={!!toAmount}
|
|
943
|
+
autoComplete="off"
|
|
954
944
|
className={`w-full bg-transparent font-bold trails-text-primary placeholder:trails-text-muted border-none outline-none ${
|
|
955
945
|
isLoadingQuote ? "animate-pulse" : ""
|
|
956
946
|
}`}
|
|
@@ -1034,12 +1024,17 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
1034
1024
|
selectedFeeToken={selectedFeeToken}
|
|
1035
1025
|
setSelectedFeeToken={(token) => setSelectedFeeToken(token as any)}
|
|
1036
1026
|
chainId={originToken?.chainId}
|
|
1027
|
+
isRefetching={isLoadingQuote}
|
|
1037
1028
|
/>
|
|
1038
1029
|
|
|
1039
1030
|
{/* Quote Details */}
|
|
1040
1031
|
{prepareSendQuote && (
|
|
1041
1032
|
<div className="mb-4">
|
|
1042
|
-
<QuoteDetails
|
|
1033
|
+
<QuoteDetails
|
|
1034
|
+
quote={prepareSendQuote}
|
|
1035
|
+
showContent={true}
|
|
1036
|
+
isRefetching={isLoadingQuote}
|
|
1037
|
+
/>
|
|
1043
1038
|
</div>
|
|
1044
1039
|
)}
|
|
1045
1040
|
|
|
@@ -13,7 +13,6 @@ import type { TransactionState } from "../../transactions.js"
|
|
|
13
13
|
import type { OnCompleteProps } from "../hooks/useSendForm.js"
|
|
14
14
|
import type { CheckoutOnHandlers } from "../hooks/useCheckout.js"
|
|
15
15
|
import { useSendForm } from "../hooks/useSendForm.js"
|
|
16
|
-
import { TradeType } from "../../prepareSend.js"
|
|
17
16
|
import { useOriginSelectedToken } from "../hooks/useOriginSelectedToken.js"
|
|
18
17
|
import { useEarnPool } from "../hooks/useEarnPool.js"
|
|
19
18
|
import { useTokenList } from "../hooks/useTokenList.js"
|
|
@@ -32,10 +31,11 @@ import { useAmountUsd } from "../hooks/useAmountUsd.js"
|
|
|
32
31
|
import { getExplorerUrlForAddress } from "../../explorer.js"
|
|
33
32
|
import aaveLogo from "../assets/aave.svg"
|
|
34
33
|
import morphoLogo from "../assets/morpho.svg"
|
|
35
|
-
import type
|
|
34
|
+
import { TradeType, type PrepareSendQuote } from "../../prepareSend.js"
|
|
36
35
|
import type { SupportedToken } from "../../tokens.js"
|
|
37
36
|
import { logger } from "../../logger.js"
|
|
38
|
-
import {
|
|
37
|
+
import { DynamicSizeInputField } from "./DynamicSizeInputField.js"
|
|
38
|
+
import { FeeOptions } from "./FeeOptions.js"
|
|
39
39
|
|
|
40
40
|
interface PoolDepositProps {
|
|
41
41
|
account?: Account
|
|
@@ -47,7 +47,6 @@ interface PoolDepositProps {
|
|
|
47
47
|
onComplete: (result: OnCompleteProps) => void
|
|
48
48
|
onSend: (amount: string, recipient: string) => void
|
|
49
49
|
paymasterUrls?: Array<{ chainId: number; url: string }>
|
|
50
|
-
gasless?: boolean
|
|
51
50
|
setWalletConfirmRetryHandler: (handler: () => Promise<void>) => void
|
|
52
51
|
quoteProvider?: string
|
|
53
52
|
fundMethod?: string
|
|
@@ -77,7 +76,6 @@ export const PoolDeposit: React.FC<PoolDepositProps> = ({
|
|
|
77
76
|
onComplete,
|
|
78
77
|
onSend,
|
|
79
78
|
paymasterUrls,
|
|
80
|
-
gasless,
|
|
81
79
|
setWalletConfirmRetryHandler,
|
|
82
80
|
quoteProvider,
|
|
83
81
|
fundMethod,
|
|
@@ -118,6 +116,9 @@ export const PoolDeposit: React.FC<PoolDepositProps> = ({
|
|
|
118
116
|
isSubmitting,
|
|
119
117
|
buttonText,
|
|
120
118
|
isValidRecipient,
|
|
119
|
+
feeOptions,
|
|
120
|
+
selectedFeeToken,
|
|
121
|
+
setSelectedFeeToken,
|
|
121
122
|
} = useSendForm({
|
|
122
123
|
account,
|
|
123
124
|
toAmount: undefined,
|
|
@@ -130,10 +131,9 @@ export const PoolDeposit: React.FC<PoolDepositProps> = ({
|
|
|
130
131
|
onError,
|
|
131
132
|
onWaitingForWalletConfirm,
|
|
132
133
|
paymasterUrls,
|
|
133
|
-
|
|
134
|
+
onSend,
|
|
134
135
|
onConfirm,
|
|
135
136
|
onComplete,
|
|
136
|
-
onSend,
|
|
137
137
|
selectedToken: originToken as any,
|
|
138
138
|
setWalletConfirmRetryHandler,
|
|
139
139
|
tradeType: TradeType.EXACT_INPUT,
|
|
@@ -183,20 +183,22 @@ export const PoolDeposit: React.FC<PoolDepositProps> = ({
|
|
|
183
183
|
}
|
|
184
184
|
}, [])
|
|
185
185
|
|
|
186
|
-
// Notify parent component about pool selector visibility
|
|
186
|
+
// Notify parent component about pool selector and token selector visibility
|
|
187
187
|
useEffect(() => {
|
|
188
188
|
if (onPoolSelectorStateChange) {
|
|
189
|
-
//
|
|
190
|
-
onPoolSelectorStateChange(
|
|
189
|
+
// Hide tabs when showing EarnPools selector, token selector, or chain list
|
|
190
|
+
onPoolSelectorStateChange(
|
|
191
|
+
showEarnPools || showOriginTokenSelector || showOriginChainList,
|
|
192
|
+
)
|
|
191
193
|
}
|
|
192
|
-
}, [
|
|
194
|
+
}, [
|
|
195
|
+
showEarnPools,
|
|
196
|
+
showOriginTokenSelector,
|
|
197
|
+
showOriginChainList,
|
|
198
|
+
onPoolSelectorStateChange,
|
|
199
|
+
])
|
|
193
200
|
|
|
194
201
|
const handleAmountChange = (value: string) => {
|
|
195
|
-
// Validate decimal places (max 8 decimals)
|
|
196
|
-
const decimalMatch = value.match(/^\d*\.?\d{0,8}$/)
|
|
197
|
-
if (!decimalMatch && value !== "") {
|
|
198
|
-
return // Don't update if more than 8 decimals
|
|
199
|
-
}
|
|
200
202
|
setAmount(value)
|
|
201
203
|
setSendFormAmount(value) // Sync with useSendForm for quote functionality
|
|
202
204
|
}
|
|
@@ -231,12 +233,6 @@ export const PoolDeposit: React.FC<PoolDepositProps> = ({
|
|
|
231
233
|
setSendFormAmount(selectedAmount)
|
|
232
234
|
}
|
|
233
235
|
|
|
234
|
-
// Dynamic font size based on input length
|
|
235
|
-
const inputStyles = useDynamicInputStyles({
|
|
236
|
-
inputValue: amount,
|
|
237
|
-
variant: "default",
|
|
238
|
-
})
|
|
239
|
-
|
|
240
236
|
if (showOriginChainList) {
|
|
241
237
|
return (
|
|
242
238
|
<ChainList
|
|
@@ -295,18 +291,12 @@ export const PoolDeposit: React.FC<PoolDepositProps> = ({
|
|
|
295
291
|
{/* Amount Input */}
|
|
296
292
|
<div className="flex-1">
|
|
297
293
|
<div className="flex items-center space-x-2">
|
|
298
|
-
<
|
|
294
|
+
<DynamicSizeInputField
|
|
299
295
|
ref={inputRef}
|
|
300
|
-
id="amount"
|
|
301
|
-
type="text"
|
|
302
296
|
value={amount}
|
|
303
297
|
onChange={(e) => handleAmountChange(e.target.value)}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
isLoadingQuote ? "animate-pulse" : ""
|
|
307
|
-
}`}
|
|
308
|
-
style={inputStyles}
|
|
309
|
-
inputMode="decimal"
|
|
298
|
+
isLoading={isLoadingQuote}
|
|
299
|
+
variant="default"
|
|
310
300
|
/>
|
|
311
301
|
{isLoadingQuote && (
|
|
312
302
|
<div className="animate-spin rounded-full h-4 w-4 border-solid border-b-2 trails-primary" />
|
|
@@ -528,10 +518,23 @@ export const PoolDeposit: React.FC<PoolDepositProps> = ({
|
|
|
528
518
|
</div>
|
|
529
519
|
) : null}
|
|
530
520
|
|
|
521
|
+
{/* Fee Options */}
|
|
522
|
+
<FeeOptions
|
|
523
|
+
feeOptions={feeOptions || []}
|
|
524
|
+
selectedFeeToken={selectedFeeToken}
|
|
525
|
+
setSelectedFeeToken={(token) => setSelectedFeeToken(token as any)}
|
|
526
|
+
chainId={originToken?.chainId}
|
|
527
|
+
isRefetching={isLoadingQuote}
|
|
528
|
+
/>
|
|
529
|
+
|
|
531
530
|
{/* Quote Details */}
|
|
532
531
|
{prepareSendQuote && (
|
|
533
532
|
<div className="mb-4">
|
|
534
|
-
<QuoteDetails
|
|
533
|
+
<QuoteDetails
|
|
534
|
+
quote={prepareSendQuote}
|
|
535
|
+
showContent={true}
|
|
536
|
+
isRefetching={isLoadingQuote}
|
|
537
|
+
/>
|
|
535
538
|
</div>
|
|
536
539
|
)}
|
|
537
540
|
|