0xtrails 0.2.4 → 0.2.6
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 +8 -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-BlV1Mry3.js → ccip-Xjh9d1gb.js} +7 -7
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/constants.d.ts +3 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/error.d.ts +1 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/estimate.d.ts +52 -0
- package/dist/estimate.d.ts.map +1 -1
- package/dist/fees.d.ts +19 -0
- package/dist/fees.d.ts.map +1 -0
- package/dist/{index-BNWCIGfQ.js → index-BnhdZ8Ho.js} +76406 -75798
- package/dist/index.js +726 -520
- package/dist/intents.d.ts +40 -0
- package/dist/intents.d.ts.map +1 -1
- package/dist/metaTxnMonitor.d.ts +3 -3
- package/dist/metaTxnMonitor.d.ts.map +1 -1
- package/dist/metaTxns.d.ts +3 -3
- package/dist/metaTxns.d.ts.map +1 -1
- package/dist/morpho.d.ts +8 -0
- package/dist/morpho.d.ts.map +1 -1
- package/dist/prepareSend.d.ts +19 -75
- package/dist/prepareSend.d.ts.map +1 -1
- package/dist/queryParams.d.ts.map +1 -1
- package/dist/relayer.d.ts +6 -6
- package/dist/relayer.d.ts.map +1 -1
- package/dist/sequenceWallet.d.ts +2 -2
- package/dist/sequenceWallet.d.ts.map +1 -1
- package/dist/tokens.d.ts.map +1 -1
- package/dist/transactions.d.ts +4 -2
- package/dist/transactions.d.ts.map +1 -1
- package/dist/wallets.d.ts.map +1 -1
- package/dist/widget/components/AccountActionsDropdown.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 +4 -2
- package/dist/widget/components/ClassicSwap.d.ts.map +1 -1
- package/dist/widget/components/ConnectWallet.d.ts.map +1 -1
- package/dist/widget/components/ConnectedWallets.d.ts +4 -0
- 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/Earn.d.ts +2 -2
- 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/Fund.d.ts +2 -2
- package/dist/widget/components/Fund.d.ts.map +1 -1
- package/dist/widget/components/FundMethods.d.ts.map +1 -1
- package/dist/widget/components/{FundSendForm.d.ts → FundSwap.d.ts} +13 -7
- package/dist/widget/components/FundSwap.d.ts.map +1 -0
- package/dist/widget/components/FundingMethodSelectorButton.d.ts +4 -0
- package/dist/widget/components/FundingMethodSelectorButton.d.ts.map +1 -0
- 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 -2
- package/dist/widget/components/Pay.d.ts.map +1 -1
- package/dist/widget/components/PercentageMaxButtons.d.ts +12 -0
- package/dist/widget/components/PercentageMaxButtons.d.ts.map +1 -0
- package/dist/widget/components/{PaySendForm.d.ts → PoolDeposit.d.ts} +14 -36
- package/dist/widget/components/PoolDeposit.d.ts.map +1 -0
- package/dist/widget/components/{SimpleSwap.d.ts → PoolWithdraw.d.ts} +19 -10
- package/dist/widget/components/PoolWithdraw.d.ts.map +1 -0
- package/dist/widget/components/QuoteDetails.d.ts +1 -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/Receive.d.ts.map +1 -1
- package/dist/widget/components/RecipientSelectorButton.d.ts +4 -0
- package/dist/widget/components/RecipientSelectorButton.d.ts.map +1 -0
- package/dist/widget/components/Recipients.d.ts.map +1 -1
- package/dist/widget/components/RequiredPropsError.d.ts +8 -0
- package/dist/widget/components/RequiredPropsError.d.ts.map +1 -0
- package/dist/widget/components/ScreenHeader.d.ts.map +1 -1
- package/dist/widget/components/SlippageToleranceSettings.d.ts.map +1 -1
- package/dist/widget/components/Swap.d.ts +3 -2
- package/dist/widget/components/Swap.d.ts.map +1 -1
- package/dist/widget/components/SwapSettings.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/TokenImage.d.ts +1 -0
- package/dist/widget/components/TokenImage.d.ts.map +1 -1
- package/dist/widget/components/TokenList.d.ts.map +1 -1
- package/dist/widget/components/TokenSelector.d.ts.map +1 -1
- package/dist/widget/components/TokenSelectorButton.d.ts +16 -0
- package/dist/widget/components/TokenSelectorButton.d.ts.map +1 -0
- package/dist/widget/components/Tooltip.d.ts +9 -0
- package/dist/widget/components/Tooltip.d.ts.map +1 -0
- package/dist/widget/components/UserPreferences.d.ts.map +1 -1
- package/dist/widget/components/WaasFeeOptions.d.ts +9 -0
- package/dist/widget/components/WaasFeeOptions.d.ts.map +1 -0
- package/dist/widget/components/WalletConfirmation.d.ts.map +1 -1
- package/dist/widget/components/WalletConnect.d.ts.map +1 -1
- package/dist/widget/components/WalletList.d.ts.map +1 -1
- package/dist/widget/css/compiled.css +2 -0
- package/dist/widget/css/index.css +554 -0
- package/dist/widget/hooks/useBack.d.ts +1 -0
- package/dist/widget/hooks/useBack.d.ts.map +1 -1
- package/dist/widget/hooks/useCheckout.d.ts +1 -1
- package/dist/widget/hooks/useCheckout.d.ts.map +1 -1
- package/dist/widget/hooks/useCurrentScreen.d.ts +1 -1
- package/dist/widget/hooks/useCurrentScreen.d.ts.map +1 -1
- package/dist/widget/hooks/useDefaultTokenSelection.d.ts +3 -3
- package/dist/widget/hooks/useDefaultTokenSelection.d.ts.map +1 -1
- package/dist/widget/hooks/usePayMessage.d.ts.map +1 -1
- package/dist/widget/hooks/useQuote.d.ts +83 -0
- package/dist/widget/hooks/useQuote.d.ts.map +1 -0
- package/dist/widget/hooks/useSelectedFundMethod.d.ts +12 -0
- package/dist/widget/hooks/useSelectedFundMethod.d.ts.map +1 -0
- package/dist/widget/hooks/useSelectedRecipient.d.ts.map +1 -1
- package/dist/widget/hooks/useSendForm.d.ts +2 -2
- package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
- package/dist/widget/index.js +2 -2
- package/dist/widget/widget.d.ts +9 -4
- package/dist/widget/widget.d.ts.map +1 -1
- package/package.json +18 -12
- package/src/aave.ts +32 -0
- package/src/abortController.ts +35 -0
- package/src/config.ts +12 -4
- package/src/constants.ts +5 -0
- package/src/error.ts +19 -1
- package/src/estimate.ts +416 -5
- package/src/fees.ts +199 -0
- package/src/intents.ts +161 -11
- package/src/metaTxnMonitor.ts +3 -3
- package/src/metaTxns.ts +3 -5
- package/src/morpho.ts +32 -0
- package/src/prepareSend.ts +714 -550
- package/src/queryParams.ts +2 -1
- package/src/relayer.ts +11 -11
- package/src/sequenceWallet.ts +2 -2
- package/src/tokens.ts +7 -1
- package/src/trails.ts +3 -3
- package/src/transactions.ts +62 -18
- package/src/wallets.ts +8 -0
- package/src/widget/compiled.css +2 -2
- package/src/widget/components/AccountActionsDropdown.tsx +3 -13
- package/src/widget/components/AccountIntentTransactionHistoryButton.tsx +22 -0
- package/src/widget/components/AccountSettings.tsx +48 -54
- package/src/widget/components/ChainFilterDropdown.tsx +24 -3
- package/src/widget/components/ClassicSwap.tsx +131 -213
- package/src/widget/components/ConnectWallet.tsx +8 -38
- package/src/widget/components/ConnectedWallets.tsx +132 -77
- package/src/widget/components/DynamicInputStyles.tsx +76 -0
- package/src/widget/components/Earn.tsx +82 -593
- package/src/widget/components/ErrorAnimationIcon.tsx +130 -0
- package/src/widget/components/FeeBreakdown.tsx +155 -0
- package/src/widget/components/Fund.tsx +41 -108
- package/src/widget/components/FundMethods.tsx +82 -159
- package/src/widget/components/FundSwap.tsx +52 -0
- package/src/widget/components/FundingMethodSelectorButton.tsx +70 -0
- package/src/widget/components/Identicon.tsx +164 -95
- package/src/widget/components/MeshConnectExchanges.tsx +2 -15
- package/src/widget/components/Modal.tsx +0 -8
- package/src/widget/components/Pay.tsx +214 -237
- package/src/widget/components/PercentageMaxButtons.tsx +77 -0
- package/src/widget/components/PoolDeposit.tsx +569 -0
- package/src/widget/components/PoolWithdraw.tsx +884 -0
- package/src/widget/components/PriceImpactWarning.tsx +1 -1
- package/src/widget/components/QuoteDetails.tsx +43 -12
- package/src/widget/components/Receipt.tsx +16 -2
- package/src/widget/components/Receive.tsx +0 -2
- package/src/widget/components/RecipientSelectorButton.tsx +44 -0
- package/src/widget/components/Recipients.tsx +63 -157
- package/src/widget/components/RequiredPropsError.tsx +33 -0
- package/src/widget/components/ScreenHeader.tsx +62 -34
- package/src/widget/components/SlippageToleranceSettings.tsx +2 -1
- package/src/widget/components/Swap.tsx +4 -45
- package/src/widget/components/SwapSettings.tsx +2 -14
- package/src/widget/components/ThemeProvider.tsx +2 -1
- package/src/widget/components/TokenDisplayNonSelectable.tsx +40 -0
- package/src/widget/components/TokenImage.tsx +22 -5
- package/src/widget/components/TokenList.tsx +0 -1
- package/src/widget/components/TokenSelector.tsx +63 -53
- package/src/widget/components/TokenSelectorButton.tsx +98 -0
- package/src/widget/components/Tooltip.tsx +51 -0
- package/src/widget/components/TransferPendingVertical.tsx +1 -1
- package/src/widget/components/UserPreferences.tsx +6 -24
- package/src/widget/components/WaasFeeOptions.tsx +450 -0
- package/src/widget/components/WalletConfirmation.tsx +76 -14
- package/src/widget/components/WalletConnect.tsx +93 -29
- package/src/widget/components/WalletList.tsx +4 -2
- package/src/widget/hooks/useBack.tsx +2 -0
- package/src/widget/hooks/useCheckout.ts +36 -20
- package/src/widget/hooks/useCurrentScreen.tsx +1 -0
- package/src/widget/hooks/useDefaultTokenSelection.tsx +104 -28
- package/src/widget/hooks/usePayMessage.tsx +86 -11
- package/src/widget/hooks/useQuote.ts +413 -0
- package/src/widget/hooks/useSelectedFundMethod.tsx +41 -0
- package/src/widget/hooks/useSelectedRecipient.tsx +10 -0
- package/src/widget/hooks/useSendForm.ts +32 -6
- package/src/widget/index.css +27 -0
- package/src/widget/widget.tsx +326 -283
- package/dist/widget/components/FundSendForm.d.ts.map +0 -1
- package/dist/widget/components/PaySendForm.d.ts.map +0 -1
- package/dist/widget/components/SimpleSwap.d.ts.map +0 -1
- package/dist/widget/hooks/useSwapSettings.d.ts +0 -16
- package/dist/widget/hooks/useSwapSettings.d.ts.map +0 -1
- package/src/widget/components/FundSendForm.tsx +0 -903
- package/src/widget/components/PaySendForm.tsx +0 -869
- package/src/widget/components/SimpleSwap.tsx +0 -983
- package/src/widget/hooks/useSwapSettings.tsx +0 -100
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { type CSSProperties, useEffect, useState } from "react"
|
|
2
|
+
|
|
3
|
+
export function ErrorAnimationIcon() {
|
|
4
|
+
const [animate, setAnimate] = useState(false)
|
|
5
|
+
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
const timer = setTimeout(() => {
|
|
8
|
+
setAnimate(true)
|
|
9
|
+
}, 100)
|
|
10
|
+
|
|
11
|
+
return () => clearTimeout(timer)
|
|
12
|
+
}, [])
|
|
13
|
+
|
|
14
|
+
const styles: Record<string, CSSProperties> = {
|
|
15
|
+
container: {
|
|
16
|
+
width: "80px",
|
|
17
|
+
height: "80px",
|
|
18
|
+
position: "relative" as const,
|
|
19
|
+
},
|
|
20
|
+
circleContainer: {
|
|
21
|
+
position: "relative" as const,
|
|
22
|
+
width: "100%",
|
|
23
|
+
height: "100%",
|
|
24
|
+
},
|
|
25
|
+
circleFill: {
|
|
26
|
+
position: "absolute" as const,
|
|
27
|
+
top: 0,
|
|
28
|
+
left: 0,
|
|
29
|
+
width: "100%",
|
|
30
|
+
height: "100%",
|
|
31
|
+
borderRadius: "50%",
|
|
32
|
+
backgroundColor: "#ef4444",
|
|
33
|
+
transform: animate ? "scale(1)" : "scale(0)",
|
|
34
|
+
opacity: animate ? 1 : 0,
|
|
35
|
+
transition: "transform 0.15s ease-out 0.3s, opacity 0.15s ease-out 0.3s",
|
|
36
|
+
},
|
|
37
|
+
progressRing: {
|
|
38
|
+
position: "absolute" as const,
|
|
39
|
+
top: 0,
|
|
40
|
+
left: 0,
|
|
41
|
+
width: "100%",
|
|
42
|
+
height: "100%",
|
|
43
|
+
transform: "rotate(-90deg)",
|
|
44
|
+
},
|
|
45
|
+
circle: {
|
|
46
|
+
fill: "none",
|
|
47
|
+
stroke: "url(#redGradient)",
|
|
48
|
+
strokeWidth: 4,
|
|
49
|
+
strokeLinecap: "round" as const,
|
|
50
|
+
strokeDasharray: 226,
|
|
51
|
+
strokeDashoffset: animate ? 0 : 226,
|
|
52
|
+
transition: "stroke-dashoffset 0.3s ease-out",
|
|
53
|
+
},
|
|
54
|
+
xContainer: {
|
|
55
|
+
position: "absolute" as const,
|
|
56
|
+
top: "50%",
|
|
57
|
+
left: "50%",
|
|
58
|
+
transform: animate
|
|
59
|
+
? "translate(-50%, -50%) scale(1)"
|
|
60
|
+
: "translate(-50%, -50%) scale(0)",
|
|
61
|
+
opacity: animate ? 1 : 0,
|
|
62
|
+
zIndex: 10,
|
|
63
|
+
transition: "transform 0.1s ease-out 0.4s, opacity 0.1s ease-out 0.4s",
|
|
64
|
+
},
|
|
65
|
+
xPath: {
|
|
66
|
+
fill: "none",
|
|
67
|
+
stroke: "white",
|
|
68
|
+
strokeWidth: 3,
|
|
69
|
+
strokeLinecap: "round" as const,
|
|
70
|
+
strokeLinejoin: "round" as const,
|
|
71
|
+
strokeDasharray: 15,
|
|
72
|
+
strokeDashoffset: animate ? 0 : 15,
|
|
73
|
+
transition: "stroke-dashoffset 0.15s ease-out 0.45s",
|
|
74
|
+
},
|
|
75
|
+
xPathSecond: {
|
|
76
|
+
fill: "none",
|
|
77
|
+
stroke: "white",
|
|
78
|
+
strokeWidth: 3,
|
|
79
|
+
strokeLinecap: "round" as const,
|
|
80
|
+
strokeLinejoin: "round" as const,
|
|
81
|
+
strokeDasharray: 15,
|
|
82
|
+
strokeDashoffset: animate ? 0 : 15,
|
|
83
|
+
transition: "stroke-dashoffset 0.15s ease-out 0.5s",
|
|
84
|
+
},
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return (
|
|
88
|
+
<div style={styles.container}>
|
|
89
|
+
<div style={styles.circleContainer}>
|
|
90
|
+
{/* Circle fill */}
|
|
91
|
+
<div style={styles.circleFill} />
|
|
92
|
+
|
|
93
|
+
{/* Progress ring */}
|
|
94
|
+
<svg style={styles.progressRing}>
|
|
95
|
+
<defs>
|
|
96
|
+
<radialGradient
|
|
97
|
+
id="redGradient"
|
|
98
|
+
cx="50%"
|
|
99
|
+
cy="50%"
|
|
100
|
+
r="50%"
|
|
101
|
+
gradientUnits="objectBoundingBox"
|
|
102
|
+
>
|
|
103
|
+
<stop
|
|
104
|
+
offset="0%"
|
|
105
|
+
style={{ stopColor: "#ef4444", stopOpacity: 0 }}
|
|
106
|
+
/>
|
|
107
|
+
<stop
|
|
108
|
+
offset="70%"
|
|
109
|
+
style={{ stopColor: "#ef4444", stopOpacity: 0.3 }}
|
|
110
|
+
/>
|
|
111
|
+
<stop
|
|
112
|
+
offset="100%"
|
|
113
|
+
style={{ stopColor: "#ef4444", stopOpacity: 1 }}
|
|
114
|
+
/>
|
|
115
|
+
</radialGradient>
|
|
116
|
+
</defs>
|
|
117
|
+
<circle cx="40" cy="40" r="36" style={styles.circle} />
|
|
118
|
+
</svg>
|
|
119
|
+
|
|
120
|
+
{/* X icon */}
|
|
121
|
+
<div style={styles.xContainer}>
|
|
122
|
+
<svg width="48" height="48" viewBox="0 0 24 24">
|
|
123
|
+
<path d="M6 6L18 18" style={styles.xPath} />
|
|
124
|
+
<path d="M18 6L6 18" style={styles.xPathSecond} />
|
|
125
|
+
</svg>
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
</div>
|
|
129
|
+
)
|
|
130
|
+
}
|
|
@@ -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="Provider Fee"
|
|
124
|
+
feeItem={feeBreakdown.providerFee}
|
|
125
|
+
tooltip="Fee charged by the bridge/swap 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
|
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ChevronRight,
|
|
3
|
-
Search,
|
|
4
|
-
Loader2,
|
|
5
|
-
ChevronDown,
|
|
6
|
-
ArrowDown,
|
|
7
|
-
} from "lucide-react"
|
|
1
|
+
import { ChevronRight, Search, Loader2, ArrowDown } from "lucide-react"
|
|
8
2
|
import { useEffect, useState, useMemo, useRef, useCallback } from "react"
|
|
9
3
|
import type React from "react"
|
|
10
4
|
import type { Account, WalletClient } from "viem"
|
|
5
|
+
import { zeroAddress } from "viem"
|
|
11
6
|
import type { TransactionState } from "../../transactions.js"
|
|
12
7
|
import type { OnCompleteProps } from "../hooks/useSendForm.js"
|
|
13
8
|
import type { CheckoutOnHandlers } from "../hooks/useCheckout.js"
|
|
@@ -35,11 +30,14 @@ import type { PrepareSendQuote } from "../../prepareSend.js"
|
|
|
35
30
|
import type { SupportedToken } from "../../tokens.js"
|
|
36
31
|
import { logger } from "../../logger.js"
|
|
37
32
|
import { RefundWarning } from "./RefundWarning.js"
|
|
33
|
+
import { PercentageMaxButtons } from "./PercentageMaxButtons.js"
|
|
34
|
+
import { TokenSelectorButton } from "./TokenSelectorButton.js"
|
|
35
|
+
import { useDynamicInputStyles } from "./DynamicInputStyles.js"
|
|
38
36
|
|
|
39
37
|
interface FundProps {
|
|
40
38
|
onBack?: () => void
|
|
41
|
-
account
|
|
42
|
-
walletClient
|
|
39
|
+
account?: Account
|
|
40
|
+
walletClient?: WalletClient
|
|
43
41
|
onTransactionStateChange: (transactionStates: TransactionState[]) => void
|
|
44
42
|
onError: (error: Error | string | null) => void
|
|
45
43
|
onWaitingForWalletConfirm: (props: PrepareSendQuote) => void
|
|
@@ -154,7 +152,7 @@ export const Fund: React.FC<FundProps> = ({
|
|
|
154
152
|
} = useSendForm({
|
|
155
153
|
account,
|
|
156
154
|
toAmount: undefined, // Don't pass toAmount for fund form - user enters input amount
|
|
157
|
-
toRecipient: selectedRecipient || account
|
|
155
|
+
toRecipient: selectedRecipient || account?.address,
|
|
158
156
|
toChainId,
|
|
159
157
|
toToken,
|
|
160
158
|
toCalldata,
|
|
@@ -524,27 +522,10 @@ export const Fund: React.FC<FundProps> = ({
|
|
|
524
522
|
}, [tokenAmountForBackend, isInputTypeUsd, sourceTokenPrice])
|
|
525
523
|
|
|
526
524
|
// Dynamic font size based on input length - matching Earn.tsx
|
|
527
|
-
const inputStyles =
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
if (inputLength > 12) {
|
|
532
|
-
fontSize = "0.875rem"
|
|
533
|
-
} else if (inputLength > 9) {
|
|
534
|
-
fontSize = "1rem"
|
|
535
|
-
} else if (inputLength > 6) {
|
|
536
|
-
fontSize = "1.125rem"
|
|
537
|
-
} else if (inputLength > 3) {
|
|
538
|
-
fontSize = "1.25rem"
|
|
539
|
-
} else {
|
|
540
|
-
fontSize = "1.5rem"
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
return {
|
|
544
|
-
fontSize,
|
|
545
|
-
transition: "all 0.1s ease-in-out",
|
|
546
|
-
}
|
|
547
|
-
}, [displayAmount.length])
|
|
525
|
+
const inputStyles = useDynamicInputStyles({
|
|
526
|
+
inputValue: displayAmount,
|
|
527
|
+
variant: "smaller",
|
|
528
|
+
})
|
|
548
529
|
|
|
549
530
|
const handleOriginTokenSelect = useCallback(
|
|
550
531
|
(token: any) => {
|
|
@@ -637,7 +618,6 @@ export const Fund: React.FC<FundProps> = ({
|
|
|
637
618
|
onBack={() => setShowOriginTokenSelector(false)}
|
|
638
619
|
headerContent="Select From Token"
|
|
639
620
|
headerContentAlign="left"
|
|
640
|
-
showAccountActions={true}
|
|
641
621
|
/>
|
|
642
622
|
<TokenSelector
|
|
643
623
|
onTokenSelect={handleOriginTokenSelect}
|
|
@@ -684,7 +664,6 @@ export const Fund: React.FC<FundProps> = ({
|
|
|
684
664
|
onBack={() => setShowDestinationTokenSelector(false)}
|
|
685
665
|
headerContent="Select To Token"
|
|
686
666
|
headerContentAlign="left"
|
|
687
|
-
showAccountActions={true}
|
|
688
667
|
/>
|
|
689
668
|
<TokenSelector
|
|
690
669
|
onTokenSelect={handleDestinationTokenSelect}
|
|
@@ -728,7 +707,6 @@ export const Fund: React.FC<FundProps> = ({
|
|
|
728
707
|
onBack={onBack}
|
|
729
708
|
headerContent="Fund"
|
|
730
709
|
headerContentAlign="left"
|
|
731
|
-
showAccountActions={true}
|
|
732
710
|
/>
|
|
733
711
|
|
|
734
712
|
<div className="space-y-2">
|
|
@@ -770,7 +748,7 @@ export const Fund: React.FC<FundProps> = ({
|
|
|
770
748
|
<div className="space-y-1">
|
|
771
749
|
{/* Origin Amount Input Section */}
|
|
772
750
|
<div className="trails-bg-secondary trails-bg-secondary-hover trails-border-radius-container p-3 group transition-all duration-200 border border-transparent focus-within:!bg-white dark:focus-within:!bg-gray-800 focus-within:border-gray-400 dark:focus-within:border-gray-500">
|
|
773
|
-
{/* Deposit Label
|
|
751
|
+
{/* Deposit Label */}
|
|
774
752
|
<div className="flex justify-between items-center mb-2">
|
|
775
753
|
<div className="text-sm font-medium trails-text-secondary text-left">
|
|
776
754
|
Deposit
|
|
@@ -782,40 +760,6 @@ export const Fund: React.FC<FundProps> = ({
|
|
|
782
760
|
""
|
|
783
761
|
)}
|
|
784
762
|
</div>
|
|
785
|
-
|
|
786
|
-
{/* Percentage Buttons */}
|
|
787
|
-
{originToken && (
|
|
788
|
-
<div className="flex space-x-1 opacity-0 group-hover:opacity-100 transition-opacity duration-200">
|
|
789
|
-
<button
|
|
790
|
-
type="button"
|
|
791
|
-
onClick={() => handlePercentageClick(25)}
|
|
792
|
-
className="py-1 px-2 text-xs font-medium trails-border-radius-container border border-solid transition-colors cursor-pointer border-gray-300 text-gray-600 dark:border-gray-600 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 hover:trails-hover-bg hover:border-gray-400 dark:hover:border-gray-500"
|
|
793
|
-
>
|
|
794
|
-
25%
|
|
795
|
-
</button>
|
|
796
|
-
<button
|
|
797
|
-
type="button"
|
|
798
|
-
onClick={() => handlePercentageClick(50)}
|
|
799
|
-
className="py-1 px-2 text-xs font-medium trails-border-radius-container border border-solid transition-colors cursor-pointer border-gray-300 text-gray-600 dark:border-gray-600 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 hover:trails-hover-bg hover:border-gray-400 dark:hover:border-gray-500"
|
|
800
|
-
>
|
|
801
|
-
50%
|
|
802
|
-
</button>
|
|
803
|
-
<button
|
|
804
|
-
type="button"
|
|
805
|
-
onClick={() => handlePercentageClick(75)}
|
|
806
|
-
className="py-1 px-2 text-xs font-medium trails-border-radius-container border border-solid transition-colors cursor-pointer border-gray-300 text-gray-600 dark:border-gray-600 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 hover:trails-hover-bg hover:border-gray-400 dark:hover:border-gray-500"
|
|
807
|
-
>
|
|
808
|
-
75%
|
|
809
|
-
</button>
|
|
810
|
-
<button
|
|
811
|
-
type="button"
|
|
812
|
-
onClick={() => handlePercentageClick(100)}
|
|
813
|
-
className="py-1 px-2 text-xs font-medium trails-border-radius-container border border-solid transition-colors cursor-pointer border-gray-300 text-gray-600 dark:border-gray-600 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 hover:trails-hover-bg hover:border-gray-400 dark:hover:border-gray-500"
|
|
814
|
-
>
|
|
815
|
-
Max
|
|
816
|
-
</button>
|
|
817
|
-
</div>
|
|
818
|
-
)}
|
|
819
763
|
</div>
|
|
820
764
|
|
|
821
765
|
<div className="flex items-center space-x-2">
|
|
@@ -869,39 +813,17 @@ export const Fund: React.FC<FundProps> = ({
|
|
|
869
813
|
</div>
|
|
870
814
|
|
|
871
815
|
{/* Token Selection Button */}
|
|
872
|
-
<
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
{originToken ? (
|
|
878
|
-
<>
|
|
879
|
-
<TokenImage
|
|
880
|
-
symbol={originToken.symbol}
|
|
881
|
-
imageUrl={originToken.imageUrl}
|
|
882
|
-
chainId={originToken.chainId}
|
|
883
|
-
size={20}
|
|
884
|
-
/>
|
|
885
|
-
<span className="font-medium trails-text-primary text-sm">
|
|
886
|
-
{originToken.symbol}
|
|
887
|
-
</span>
|
|
888
|
-
<ChevronDown className="w-3.5 h-3.5 trails-text-muted" />
|
|
889
|
-
</>
|
|
890
|
-
) : (
|
|
891
|
-
<>
|
|
892
|
-
<span className="font-medium trails-text-muted text-sm">
|
|
893
|
-
Select Token
|
|
894
|
-
</span>
|
|
895
|
-
<ChevronDown className="w-3.5 h-3.5 trails-text-muted" />
|
|
896
|
-
</>
|
|
897
|
-
)}
|
|
898
|
-
</button>
|
|
816
|
+
<TokenSelectorButton
|
|
817
|
+
token={originToken}
|
|
818
|
+
chainId={originToken?.chainId}
|
|
819
|
+
onSelect={() => setShowOriginTokenSelector(true)}
|
|
820
|
+
/>
|
|
899
821
|
</div>
|
|
900
822
|
|
|
901
823
|
{/* Bottom Info Row */}
|
|
902
824
|
<div className="mt-2 flex justify-between items-center">
|
|
903
825
|
{/* USD Amount */}
|
|
904
|
-
<div className="text-xs
|
|
826
|
+
<div className="text-xs text-gray-500 dark:text-gray-400">
|
|
905
827
|
{originToken?.symbol && displayAmount ? (
|
|
906
828
|
<>≈ {amountUsdDisplay || "$0.00"}</>
|
|
907
829
|
) : (
|
|
@@ -909,12 +831,12 @@ export const Fund: React.FC<FundProps> = ({
|
|
|
909
831
|
)}
|
|
910
832
|
</div>
|
|
911
833
|
|
|
912
|
-
{/* Origin Token Balance */}
|
|
913
|
-
|
|
914
|
-
|
|
834
|
+
{/* Origin Token Balance and Percentage Buttons */}
|
|
835
|
+
{originToken && balanceFormatted && (
|
|
836
|
+
<div className="flex items-center space-x-2">
|
|
915
837
|
<button
|
|
916
838
|
type="button"
|
|
917
|
-
className="text-xs
|
|
839
|
+
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"
|
|
918
840
|
onClick={() => handlePercentageClick(100)}
|
|
919
841
|
onKeyDown={(e) => {
|
|
920
842
|
if (e.key === "Enter" || e.key === " ") {
|
|
@@ -925,14 +847,25 @@ export const Fund: React.FC<FundProps> = ({
|
|
|
925
847
|
title="Click to use full balance"
|
|
926
848
|
>
|
|
927
849
|
Balance:{" "}
|
|
928
|
-
{isBalanceVisible
|
|
929
|
-
? `${balanceFormatted || "0.00"} ${originToken.symbol}`
|
|
930
|
-
: "••••••"}
|
|
850
|
+
{isBalanceVisible ? balanceFormatted || "0.00" : "••••••"}
|
|
931
851
|
</button>
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
852
|
+
|
|
853
|
+
{/* Percentage Buttons */}
|
|
854
|
+
<PercentageMaxButtons
|
|
855
|
+
userBalance={balanceFormatted}
|
|
856
|
+
isNativeToken={originToken.contractAddress === zeroAddress}
|
|
857
|
+
gasCostFormatted={prepareSendQuote?.gasCostFormatted}
|
|
858
|
+
chainId={originToken.chainId}
|
|
859
|
+
onAmountSelect={(amount) => {
|
|
860
|
+
setTokenAmountForBackend(amount)
|
|
861
|
+
setSendFormAmount(amount)
|
|
862
|
+
setGlobalAmount(amount)
|
|
863
|
+
setInputDisplayValue(amount)
|
|
864
|
+
}}
|
|
865
|
+
className="opacity-100"
|
|
866
|
+
/>
|
|
867
|
+
</div>
|
|
868
|
+
)}
|
|
936
869
|
</div>
|
|
937
870
|
</div>
|
|
938
871
|
|