0xtrails 0.2.5 → 0.3.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/abortController.d.ts +8 -0
- package/dist/abortController.d.ts.map +1 -0
- package/dist/{ccip-CXlshvBY.js → ccip-BMB3uDZt.js} +1 -1
- package/dist/config.d.ts +0 -5
- package/dist/config.d.ts.map +1 -1
- package/dist/constants.d.ts +4 -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 +19 -0
- package/dist/fees.d.ts.map +1 -0
- package/dist/{index-_QuyGrjU.js → index-QXPUrZVv.js} +48719 -50852
- package/dist/index.d.ts +9 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +811 -784
- 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 +7 -258
- 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/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 +6 -3
- package/dist/transactions.d.ts.map +1 -1
- package/dist/widget/components/AccountIntentTransactionHistoryButton.d.ts +4 -0
- package/dist/widget/components/AccountIntentTransactionHistoryButton.d.ts.map +1 -0
- package/dist/widget/components/AccountSettings.d.ts.map +1 -1
- package/dist/widget/components/ChainFilterDropdown.d.ts.map +1 -1
- package/dist/widget/components/ClassicSwap.d.ts +2 -3
- package/dist/widget/components/ClassicSwap.d.ts.map +1 -1
- package/dist/widget/components/ConfigDisplay.d.ts.map +1 -1
- package/dist/widget/components/ConnectWallet.d.ts.map +1 -1
- package/dist/widget/components/ConnectedWallets.d.ts.map +1 -1
- package/dist/widget/components/DynamicInputStyles.d.ts +18 -0
- package/dist/widget/components/DynamicInputStyles.d.ts.map +1 -0
- 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 +2 -3
- package/dist/widget/components/Earn.d.ts.map +1 -1
- package/dist/widget/components/ErrorAnimationIcon.d.ts +2 -0
- package/dist/widget/components/ErrorAnimationIcon.d.ts.map +1 -0
- package/dist/widget/components/FeeBreakdown.d.ts +9 -0
- package/dist/widget/components/FeeBreakdown.d.ts.map +1 -0
- 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 +2 -3
- 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 +2 -3
- package/dist/widget/components/FundSwap.d.ts.map +1 -1
- package/dist/widget/components/FundingMethodSelectorButton.d.ts.map +1 -1
- package/dist/widget/components/Identicon.d.ts.map +1 -1
- package/dist/widget/components/MeshConnectExchanges.d.ts +0 -3
- package/dist/widget/components/MeshConnectExchanges.d.ts.map +1 -1
- package/dist/widget/components/Modal.d.ts.map +1 -1
- package/dist/widget/components/Pay.d.ts +2 -3
- package/dist/widget/components/Pay.d.ts.map +1 -1
- package/dist/widget/components/PoolDeposit.d.ts +3 -3
- package/dist/widget/components/PoolDeposit.d.ts.map +1 -1
- package/dist/widget/components/PoolWithdraw.d.ts +3 -20
- package/dist/widget/components/PoolWithdraw.d.ts.map +1 -1
- package/dist/widget/components/QuoteDetails.d.ts +2 -0
- package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
- package/dist/widget/components/Receipt.d.ts.map +1 -1
- package/dist/widget/components/RecipientSelectorButton.d.ts.map +1 -1
- package/dist/widget/components/ScreenHeader.d.ts.map +1 -1
- package/dist/widget/components/Swap.d.ts +2 -3
- package/dist/widget/components/Swap.d.ts.map +1 -1
- package/dist/widget/components/ThemeProvider.d.ts.map +1 -1
- package/dist/widget/components/TokenDisplayNonSelectable.d.ts +11 -0
- package/dist/widget/components/TokenDisplayNonSelectable.d.ts.map +1 -0
- package/dist/widget/components/TokenSelector.d.ts.map +1 -1
- package/dist/widget/components/TokenSelectorButton.d.ts.map +1 -1
- package/dist/widget/components/Tooltip.d.ts +9 -0
- package/dist/widget/components/Tooltip.d.ts.map +1 -0
- package/dist/widget/components/TransferPendingVertical.d.ts.map +1 -1
- package/dist/widget/components/WaasFeeOptions.d.ts +1 -0
- package/dist/widget/components/WaasFeeOptions.d.ts.map +1 -1
- package/dist/widget/components/WalletConfirmation.d.ts.map +1 -1
- package/dist/widget/components/WalletConnect.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 +82 -0
- package/dist/widget/hooks/useQuote.d.ts.map +1 -0
- 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 +5 -6
- 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 +2 -2
- package/dist/widget/widget.d.ts +17 -7
- package/dist/widget/widget.d.ts.map +1 -1
- package/package.json +19 -21
- package/src/aave.ts +54 -1
- package/src/abortController.ts +35 -0
- package/src/config.ts +57 -58
- package/src/constants.ts +11 -9
- package/src/error.ts +21 -3
- package/src/fees.ts +210 -0
- package/src/index.ts +35 -13
- package/src/intentReceiptMonitor.ts +102 -0
- package/src/intentReceiptPoller.ts +299 -0
- package/src/intents.ts +205 -171
- package/src/morpho.ts +58 -9
- package/src/mutations.ts +129 -0
- package/src/preconditions.ts +16 -21
- package/src/prepareSend.ts +92 -4699
- 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/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 +98 -71
- package/src/widget/compiled.css +2 -2
- package/src/widget/components/AccountIntentTransactionHistory.tsx +36 -36
- package/src/widget/components/AccountIntentTransactionHistoryButton.tsx +22 -0
- package/src/widget/components/AccountSettings.tsx +70 -41
- package/src/widget/components/ChainFilterDropdown.tsx +24 -3
- package/src/widget/components/ClassicSwap.tsx +44 -107
- package/src/widget/components/ConfigDisplay.tsx +0 -11
- package/src/widget/components/ConnectWallet.tsx +4 -1
- package/src/widget/components/ConnectedWallets.tsx +51 -25
- package/src/widget/components/DynamicInputStyles.tsx +76 -0
- package/src/widget/components/DynamicSizeInputField.tsx +109 -0
- package/src/widget/components/Earn.tsx +34 -45
- package/src/widget/components/ErrorAnimationIcon.tsx +130 -0
- package/src/widget/components/FeeBreakdown.tsx +155 -0
- package/src/widget/components/FeeOption.tsx +2 -2
- package/src/widget/components/FeeOptions.tsx +151 -112
- package/src/widget/components/Fund.tsx +10 -29
- package/src/widget/components/FundMethods.tsx +4 -3
- package/src/widget/components/FundSwap.tsx +2 -3
- package/src/widget/components/FundingMethodSelectorButton.tsx +24 -14
- package/src/widget/components/Identicon.tsx +164 -95
- package/src/widget/components/MeshConnectExchanges.tsx +2 -15
- package/src/widget/components/Modal.tsx +0 -12
- package/src/widget/components/Pay.tsx +72 -75
- package/src/widget/components/PoolDeposit.tsx +221 -242
- package/src/widget/components/PoolWithdraw.tsx +347 -469
- package/src/widget/components/PriceImpactWarning.tsx +1 -1
- package/src/widget/components/QuoteDetails.tsx +906 -484
- package/src/widget/components/Receipt.tsx +16 -2
- package/src/widget/components/RecipientSelectorButton.tsx +7 -5
- package/src/widget/components/Recipients.tsx +1 -1
- package/src/widget/components/ScreenHeader.tsx +60 -36
- package/src/widget/components/Swap.tsx +2 -3
- package/src/widget/components/ThemeProvider.tsx +2 -1
- package/src/widget/components/TokenDisplayNonSelectable.tsx +40 -0
- package/src/widget/components/TokenImage.tsx +1 -1
- package/src/widget/components/TokenSelector.tsx +62 -53
- package/src/widget/components/TokenSelectorButton.tsx +38 -15
- package/src/widget/components/Tooltip.tsx +51 -0
- package/src/widget/components/TransferPendingVertical.tsx +12 -8
- package/src/widget/components/WaasFeeOptions.tsx +139 -4
- package/src/widget/components/WalletConfirmation.tsx +23 -13
- package/src/widget/components/WalletConnect.tsx +93 -29
- 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 +466 -0
- package/src/widget/hooks/useSelectedFeeToken.tsx +32 -37
- package/src/widget/hooks/useSendForm.ts +45 -51
- package/src/widget/hooks/useTokenList.ts +34 -26
- package/src/widget/hooks/useWalletConnectionContext.tsx +128 -0
- package/src/widget/widget.tsx +365 -390
- 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
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import type React from "react"
|
|
2
|
+
import { useState } from "react"
|
|
3
|
+
import { InfoIcon } from "@0xsequence/design-system"
|
|
4
|
+
import { Tooltip } from "./Tooltip.js"
|
|
5
|
+
import { TokenImage } from "./TokenImage.js"
|
|
6
|
+
import type { TrailsFeeBreakdown, FeeItem } from "../../fees.js"
|
|
7
|
+
|
|
8
|
+
interface FeeBreakdownProps {
|
|
9
|
+
feeBreakdown: TrailsFeeBreakdown
|
|
10
|
+
children?: React.ReactNode
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface FeeRowProps {
|
|
14
|
+
label: string
|
|
15
|
+
feeItem: FeeItem
|
|
16
|
+
tooltip?: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const FeeRow: React.FC<FeeRowProps> = ({ label, feeItem, tooltip }) => (
|
|
20
|
+
<div className="flex justify-between items-center py-1 items-start">
|
|
21
|
+
<span className="text-xs text-gray-600 dark:text-gray-400 flex items-center gap-1">
|
|
22
|
+
{label}
|
|
23
|
+
{tooltip && (
|
|
24
|
+
<Tooltip message={tooltip}>
|
|
25
|
+
<InfoIcon className="w-3 h-3 text-gray-500 dark:text-gray-400 cursor-pointer" />
|
|
26
|
+
</Tooltip>
|
|
27
|
+
)}
|
|
28
|
+
</span>
|
|
29
|
+
<div className="text-right">
|
|
30
|
+
<div className="font-medium text-xs text-gray-900 dark:text-white flex items-center gap-1 justify-end">
|
|
31
|
+
<TokenImage
|
|
32
|
+
imageUrl=""
|
|
33
|
+
symbol={feeItem.tokenSymbol}
|
|
34
|
+
chainId={feeItem.chainId}
|
|
35
|
+
contractAddress={feeItem.tokenAddress}
|
|
36
|
+
size={16}
|
|
37
|
+
/>
|
|
38
|
+
{feeItem.amount} {feeItem.tokenSymbol}
|
|
39
|
+
</div>
|
|
40
|
+
<div className="text-xs text-gray-500 dark:text-gray-400">
|
|
41
|
+
≈ {feeItem.usdValue}
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
export const FeeBreakdown: React.FC<FeeBreakdownProps> = ({
|
|
48
|
+
feeBreakdown,
|
|
49
|
+
children,
|
|
50
|
+
}) => {
|
|
51
|
+
const [isExpanded, setIsExpanded] = useState(false)
|
|
52
|
+
|
|
53
|
+
// Don't render at all if there are no fees
|
|
54
|
+
const hasAnyFees =
|
|
55
|
+
feeBreakdown.originRelayFee ||
|
|
56
|
+
feeBreakdown.destinationRelayFee ||
|
|
57
|
+
feeBreakdown.providerFee ||
|
|
58
|
+
feeBreakdown.trailsFee
|
|
59
|
+
|
|
60
|
+
if (!hasAnyFees) {
|
|
61
|
+
return null
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<div className="space-y-2">
|
|
66
|
+
{/* Accordion header */}
|
|
67
|
+
<button
|
|
68
|
+
type="button"
|
|
69
|
+
onClick={() => setIsExpanded(!isExpanded)}
|
|
70
|
+
className="w-full flex items-center justify-between py-1 text-xs transition-colors duration-200 text-gray-600 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 cursor-pointer"
|
|
71
|
+
aria-label={isExpanded ? "Hide fee breakdown" : "Show fee breakdown"}
|
|
72
|
+
>
|
|
73
|
+
<span className="flex items-center gap-1 w-full">
|
|
74
|
+
{children ? (
|
|
75
|
+
children
|
|
76
|
+
) : (
|
|
77
|
+
<Tooltip message="Detailed breakdown of the Trails platform fees">
|
|
78
|
+
<InfoIcon className="w-3 h-3 text-gray-500 dark:text-gray-400 cursor-pointer" />
|
|
79
|
+
</Tooltip>
|
|
80
|
+
)}
|
|
81
|
+
</span>
|
|
82
|
+
<svg
|
|
83
|
+
className={`w-3 h-3 transition-transform duration-300 ease-out ml-2 ${
|
|
84
|
+
isExpanded ? "rotate-180" : ""
|
|
85
|
+
}`}
|
|
86
|
+
fill="none"
|
|
87
|
+
stroke="currentColor"
|
|
88
|
+
viewBox="0 0 24 24"
|
|
89
|
+
aria-hidden="true"
|
|
90
|
+
>
|
|
91
|
+
<path
|
|
92
|
+
strokeLinecap="round"
|
|
93
|
+
strokeLinejoin="round"
|
|
94
|
+
strokeWidth={2}
|
|
95
|
+
d="M19 9l-7 7-7-7"
|
|
96
|
+
/>
|
|
97
|
+
</svg>
|
|
98
|
+
</button>
|
|
99
|
+
|
|
100
|
+
{/* Collapsible content */}
|
|
101
|
+
<div
|
|
102
|
+
className={`overflow-hidden transition-all duration-300 ease-out ${
|
|
103
|
+
isExpanded ? "max-h-96 opacity-100" : "max-h-0 opacity-0"
|
|
104
|
+
}`}
|
|
105
|
+
>
|
|
106
|
+
<div className="space-y-1 pl-2">
|
|
107
|
+
{feeBreakdown.originRelayFee && (
|
|
108
|
+
<FeeRow
|
|
109
|
+
label="Origin Relay Fee"
|
|
110
|
+
feeItem={feeBreakdown.originRelayFee}
|
|
111
|
+
tooltip="Fee for relaying the origin chain transaction"
|
|
112
|
+
/>
|
|
113
|
+
)}
|
|
114
|
+
{feeBreakdown.destinationRelayFee && (
|
|
115
|
+
<FeeRow
|
|
116
|
+
label="Destination Relay Fee"
|
|
117
|
+
feeItem={feeBreakdown.destinationRelayFee}
|
|
118
|
+
tooltip="Fee for relaying the destination chain transaction"
|
|
119
|
+
/>
|
|
120
|
+
)}
|
|
121
|
+
{feeBreakdown.providerFee && (
|
|
122
|
+
<FeeRow
|
|
123
|
+
label="Liquidity Provider Fee"
|
|
124
|
+
feeItem={feeBreakdown.providerFee}
|
|
125
|
+
tooltip="Fee charged by the bridge/swap liquidity provider for executing the transaction"
|
|
126
|
+
/>
|
|
127
|
+
)}
|
|
128
|
+
{feeBreakdown.trailsFee && (
|
|
129
|
+
<FeeRow
|
|
130
|
+
label="Trails Platform Fee"
|
|
131
|
+
feeItem={feeBreakdown.trailsFee}
|
|
132
|
+
tooltip="Platform fee for using the Trails service"
|
|
133
|
+
/>
|
|
134
|
+
)}
|
|
135
|
+
|
|
136
|
+
{/* Total line - only show if we have a total value */}
|
|
137
|
+
{/* {feeBreakdown.totalUsdValue && (
|
|
138
|
+
<div className="flex justify-between items-center py-1 pt-2 border-t border-gray-200 dark:border-gray-700">
|
|
139
|
+
<span className="text-xs font-medium text-gray-700 dark:text-gray-300">
|
|
140
|
+
Total Fees
|
|
141
|
+
</span>
|
|
142
|
+
<div className="text-right">
|
|
143
|
+
<div className="font-medium text-xs text-gray-900 dark:text-white">
|
|
144
|
+
~{feeBreakdown.totalUsdValue}
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
)} */}
|
|
149
|
+
</div>
|
|
150
|
+
</div>
|
|
151
|
+
</div>
|
|
152
|
+
)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export default FeeBreakdown
|
|
@@ -47,7 +47,7 @@ export const FeeOption: React.FC<FeeOptionProps> = ({
|
|
|
47
47
|
chainId={option.chainId || chainId}
|
|
48
48
|
size={16}
|
|
49
49
|
/>
|
|
50
|
-
<div className="text-left">
|
|
50
|
+
<div className="ml-2 text-left">
|
|
51
51
|
<div
|
|
52
52
|
className={`text-xs font-medium ${
|
|
53
53
|
option.notEnoughBalance
|
|
@@ -68,7 +68,7 @@ export const FeeOption: React.FC<FeeOptionProps> = ({
|
|
|
68
68
|
: "trails-text-primary"
|
|
69
69
|
}`}
|
|
70
70
|
>
|
|
71
|
-
{option.amountUsdDisplay}
|
|
71
|
+
≈ {option.amountUsdDisplay}
|
|
72
72
|
</div>
|
|
73
73
|
</div>
|
|
74
74
|
</button>
|
|
@@ -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}
|
|
@@ -32,11 +32,12 @@ import { logger } from "../../logger.js"
|
|
|
32
32
|
import { RefundWarning } from "./RefundWarning.js"
|
|
33
33
|
import { PercentageMaxButtons } from "./PercentageMaxButtons.js"
|
|
34
34
|
import { TokenSelectorButton } from "./TokenSelectorButton.js"
|
|
35
|
+
import { useDynamicInputStyles } from "./DynamicInputStyles.js"
|
|
35
36
|
|
|
36
37
|
interface FundProps {
|
|
37
38
|
onBack?: () => void
|
|
38
|
-
account
|
|
39
|
-
walletClient
|
|
39
|
+
account?: Account
|
|
40
|
+
walletClient?: WalletClient
|
|
40
41
|
onTransactionStateChange: (transactionStates: TransactionState[]) => void
|
|
41
42
|
onError: (error: Error | string | null) => void
|
|
42
43
|
onWaitingForWalletConfirm: (props: PrepareSendQuote) => void
|
|
@@ -44,7 +45,6 @@ interface FundProps {
|
|
|
44
45
|
onComplete: (result: OnCompleteProps) => void
|
|
45
46
|
onSend: (amount: string, recipient: string) => void
|
|
46
47
|
paymasterUrls?: Array<{ chainId: number; url: string }>
|
|
47
|
-
gasless?: boolean
|
|
48
48
|
isSequenceWallet?: boolean
|
|
49
49
|
setWalletConfirmRetryHandler: (handler: () => Promise<void>) => void
|
|
50
50
|
quoteProvider?: string
|
|
@@ -80,7 +80,6 @@ export const Fund: React.FC<FundProps> = ({
|
|
|
80
80
|
onComplete,
|
|
81
81
|
onSend,
|
|
82
82
|
paymasterUrls,
|
|
83
|
-
gasless,
|
|
84
83
|
isSequenceWallet = false,
|
|
85
84
|
setWalletConfirmRetryHandler,
|
|
86
85
|
quoteProvider,
|
|
@@ -151,7 +150,7 @@ export const Fund: React.FC<FundProps> = ({
|
|
|
151
150
|
} = useSendForm({
|
|
152
151
|
account,
|
|
153
152
|
toAmount: undefined, // Don't pass toAmount for fund form - user enters input amount
|
|
154
|
-
toRecipient: selectedRecipient || account
|
|
153
|
+
toRecipient: selectedRecipient || account?.address,
|
|
155
154
|
toChainId,
|
|
156
155
|
toToken,
|
|
157
156
|
toCalldata,
|
|
@@ -160,7 +159,6 @@ export const Fund: React.FC<FundProps> = ({
|
|
|
160
159
|
onError,
|
|
161
160
|
onWaitingForWalletConfirm,
|
|
162
161
|
paymasterUrls,
|
|
163
|
-
gasless,
|
|
164
162
|
onConfirm,
|
|
165
163
|
onComplete,
|
|
166
164
|
onSend,
|
|
@@ -521,27 +519,10 @@ export const Fund: React.FC<FundProps> = ({
|
|
|
521
519
|
}, [tokenAmountForBackend, isInputTypeUsd, sourceTokenPrice])
|
|
522
520
|
|
|
523
521
|
// Dynamic font size based on input length - matching Earn.tsx
|
|
524
|
-
const inputStyles =
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
if (inputLength > 12) {
|
|
529
|
-
fontSize = "0.875rem"
|
|
530
|
-
} else if (inputLength > 9) {
|
|
531
|
-
fontSize = "1rem"
|
|
532
|
-
} else if (inputLength > 6) {
|
|
533
|
-
fontSize = "1.125rem"
|
|
534
|
-
} else if (inputLength > 3) {
|
|
535
|
-
fontSize = "1.25rem"
|
|
536
|
-
} else {
|
|
537
|
-
fontSize = "1.5rem"
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
return {
|
|
541
|
-
fontSize,
|
|
542
|
-
transition: "all 0.1s ease-in-out",
|
|
543
|
-
}
|
|
544
|
-
}, [displayAmount.length])
|
|
522
|
+
const inputStyles = useDynamicInputStyles({
|
|
523
|
+
inputValue: displayAmount,
|
|
524
|
+
variant: "smaller",
|
|
525
|
+
})
|
|
545
526
|
|
|
546
527
|
const handleOriginTokenSelect = useCallback(
|
|
547
528
|
(token: any) => {
|
|
@@ -839,7 +820,7 @@ export const Fund: React.FC<FundProps> = ({
|
|
|
839
820
|
{/* Bottom Info Row */}
|
|
840
821
|
<div className="mt-2 flex justify-between items-center">
|
|
841
822
|
{/* USD Amount */}
|
|
842
|
-
<div className="text-xs
|
|
823
|
+
<div className="text-xs text-gray-500 dark:text-gray-400">
|
|
843
824
|
{originToken?.symbol && displayAmount ? (
|
|
844
825
|
<>≈ {amountUsdDisplay || "$0.00"}</>
|
|
845
826
|
) : (
|
|
@@ -852,7 +833,7 @@ export const Fund: React.FC<FundProps> = ({
|
|
|
852
833
|
<div className="flex items-center space-x-2">
|
|
853
834
|
<button
|
|
854
835
|
type="button"
|
|
855
|
-
className="text-xs
|
|
836
|
+
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"
|
|
856
837
|
onClick={() => handlePercentageClick(100)}
|
|
857
838
|
onKeyDown={(e) => {
|
|
858
839
|
if (e.key === "Enter" || e.key === " ") {
|
|
@@ -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" />
|
|
@@ -13,18 +13,17 @@ interface FundProps {
|
|
|
13
13
|
onBack?: () => void
|
|
14
14
|
onConfirm: () => void
|
|
15
15
|
onComplete: (result: OnCompleteProps) => void
|
|
16
|
-
account
|
|
16
|
+
account?: Account
|
|
17
17
|
toRecipient?: string
|
|
18
18
|
toAmount?: string
|
|
19
19
|
toChainId?: number
|
|
20
20
|
toToken?: string
|
|
21
21
|
toCalldata?: string
|
|
22
|
-
walletClient
|
|
22
|
+
walletClient?: WalletClient
|
|
23
23
|
onTransactionStateChange: (transactionStates: TransactionState[]) => void
|
|
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
|