0xtrails 0.2.5 → 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/abortController.d.ts +8 -0
- package/dist/abortController.d.ts.map +1 -0
- package/dist/{ccip-CXlshvBY.js → ccip-Xjh9d1gb.js} +7 -7
- package/dist/constants.d.ts +2 -0
- package/dist/constants.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-BnhdZ8Ho.js} +34769 -34247
- package/dist/index.js +726 -520
- package/dist/prepareSend.d.ts +11 -77
- package/dist/prepareSend.d.ts.map +1 -1
- package/dist/transactions.d.ts +4 -2
- 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 -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/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/FundSwap.d.ts +2 -2
- 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 -2
- package/dist/widget/components/Pay.d.ts.map +1 -1
- package/dist/widget/components/PoolDeposit.d.ts +3 -2
- package/dist/widget/components/PoolDeposit.d.ts.map +1 -1
- package/dist/widget/components/PoolWithdraw.d.ts +3 -2
- 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/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 -2
- 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/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 +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/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 +5 -0
- package/dist/widget/widget.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/abortController.ts +35 -0
- package/src/constants.ts +3 -0
- package/src/fees.ts +199 -0
- package/src/prepareSend.ts +225 -398
- package/src/trails.ts +3 -3
- package/src/transactions.ts +62 -18
- package/src/widget/compiled.css +1 -1
- package/src/widget/components/AccountIntentTransactionHistoryButton.tsx +22 -0
- package/src/widget/components/AccountSettings.tsx +48 -36
- package/src/widget/components/ChainFilterDropdown.tsx +24 -3
- package/src/widget/components/ClassicSwap.tsx +24 -62
- package/src/widget/components/ConnectWallet.tsx +4 -1
- package/src/widget/components/ConnectedWallets.tsx +21 -21
- package/src/widget/components/DynamicInputStyles.tsx +76 -0
- package/src/widget/components/Earn.tsx +34 -29
- package/src/widget/components/ErrorAnimationIcon.tsx +130 -0
- package/src/widget/components/FeeBreakdown.tsx +155 -0
- package/src/widget/components/Fund.tsx +10 -26
- package/src/widget/components/FundSwap.tsx +2 -2
- 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 +65 -63
- package/src/widget/components/PoolDeposit.tsx +206 -230
- package/src/widget/components/PoolWithdraw.tsx +219 -238
- package/src/widget/components/PriceImpactWarning.tsx +1 -1
- package/src/widget/components/QuoteDetails.tsx +25 -8
- 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 -2
- 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 +1 -1
- package/src/widget/components/WaasFeeOptions.tsx +124 -5
- package/src/widget/components/WalletConfirmation.tsx +23 -13
- package/src/widget/components/WalletConnect.tsx +93 -29
- package/src/widget/hooks/useQuote.ts +413 -0
- package/src/widget/hooks/useSendForm.ts +8 -4
- package/src/widget/widget.tsx +175 -190
|
@@ -3,6 +3,7 @@ import type React from "react"
|
|
|
3
3
|
import { useEffect, useMemo, useRef, useState } from "react"
|
|
4
4
|
import { ChainImage } from "./ChainImage.js"
|
|
5
5
|
import { AllChainsIcon } from "./AllChainsIcon.js"
|
|
6
|
+
import { getChainInfo } from "../../chains.js"
|
|
6
7
|
|
|
7
8
|
export interface Chain {
|
|
8
9
|
chainId: number
|
|
@@ -94,9 +95,29 @@ export const ChainFilterDropdown: React.FC<ChainFilterDropdownProps> = ({
|
|
|
94
95
|
}
|
|
95
96
|
}
|
|
96
97
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
)
|
|
98
|
+
// Find selected chain in the chains array, or get it from getChainInfo if not found
|
|
99
|
+
// This handles the case where user selects a chain with no tokens
|
|
100
|
+
const selectedChain = useMemo(() => {
|
|
101
|
+
if (selectedChainId === null) return null
|
|
102
|
+
|
|
103
|
+
const chainInList = chains.find(
|
|
104
|
+
(chain) => chain.chainId === selectedChainId,
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
if (chainInList) return chainInList
|
|
108
|
+
|
|
109
|
+
// If chain not in list (e.g., no tokens on that chain), get info from getChainInfo
|
|
110
|
+
const chainInfo = getChainInfo(selectedChainId)
|
|
111
|
+
if (chainInfo) {
|
|
112
|
+
return {
|
|
113
|
+
chainId: chainInfo.id,
|
|
114
|
+
name: chainInfo.name,
|
|
115
|
+
imageUrl: chainInfo.imageUrl,
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return null
|
|
120
|
+
}, [chains, selectedChainId])
|
|
100
121
|
|
|
101
122
|
return (
|
|
102
123
|
<div className={`relative ${className}`} ref={dropdownRef}>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Loader2, ArrowDown } from "lucide-react"
|
|
2
2
|
import type React from "react"
|
|
3
|
-
import { useCallback, useEffect, useRef, useState
|
|
3
|
+
import { useCallback, useEffect, useRef, useState } from "react"
|
|
4
4
|
import type { Account, WalletClient } from "viem"
|
|
5
5
|
import { zeroAddress } from "viem"
|
|
6
6
|
import type { TransactionState } from "../../transactions.js"
|
|
@@ -28,6 +28,7 @@ import { RecipientSelectorButton } from "./RecipientSelectorButton.js"
|
|
|
28
28
|
import { RefundWarning } from "./RefundWarning.js"
|
|
29
29
|
import { Identicon } from "./Identicon.js"
|
|
30
30
|
import { truncateAddress } from "../../utils.js"
|
|
31
|
+
import { useDynamicInputStyles } from "./DynamicInputStyles.js"
|
|
31
32
|
|
|
32
33
|
interface ClassicSwapProps {
|
|
33
34
|
selectedToken: Token | null
|
|
@@ -35,13 +36,13 @@ interface ClassicSwapProps {
|
|
|
35
36
|
onBack?: () => void
|
|
36
37
|
onConfirm: () => void
|
|
37
38
|
onComplete: (result: OnCompleteProps) => void
|
|
38
|
-
account
|
|
39
|
+
account?: Account
|
|
39
40
|
toRecipient?: string
|
|
40
41
|
toAmount?: string
|
|
41
42
|
toChainId?: number
|
|
42
43
|
toToken?: string
|
|
43
44
|
toCalldata?: string
|
|
44
|
-
walletClient
|
|
45
|
+
walletClient?: WalletClient
|
|
45
46
|
onTransactionStateChange: (transactionStates: TransactionState[]) => void
|
|
46
47
|
onError: (error: Error | string | null) => void
|
|
47
48
|
onWaitingForWalletConfirm: (props: PrepareSendQuote) => void
|
|
@@ -146,7 +147,7 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
|
|
|
146
147
|
} = useSendForm({
|
|
147
148
|
account,
|
|
148
149
|
toAmount: tradeType === TradeType.EXACT_OUTPUT ? buyAmount : toAmount,
|
|
149
|
-
toRecipient: toRecipient || account
|
|
150
|
+
toRecipient: toRecipient || account?.address,
|
|
150
151
|
toChainId,
|
|
151
152
|
toToken,
|
|
152
153
|
toCalldata,
|
|
@@ -363,51 +364,12 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
|
|
|
363
364
|
}
|
|
364
365
|
|
|
365
366
|
// Dynamic font size based on input length
|
|
366
|
-
const sellInputStyles =
|
|
367
|
-
const inputLength = sellAmount.length
|
|
368
|
-
let fontSize: string
|
|
369
|
-
|
|
370
|
-
if (inputLength > 12) {
|
|
371
|
-
fontSize = "1rem"
|
|
372
|
-
} else if (inputLength > 9) {
|
|
373
|
-
fontSize = "1.25rem"
|
|
374
|
-
} else if (inputLength > 6) {
|
|
375
|
-
fontSize = "1.5rem"
|
|
376
|
-
} else if (inputLength > 3) {
|
|
377
|
-
fontSize = "1.75rem"
|
|
378
|
-
} else {
|
|
379
|
-
fontSize = "2rem"
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
return {
|
|
383
|
-
fontSize,
|
|
384
|
-
transition: "all 0.1s ease-in-out",
|
|
385
|
-
}
|
|
386
|
-
}, [sellAmount.length])
|
|
387
|
-
|
|
388
|
-
const buyInputStyles = useMemo(() => {
|
|
389
|
-
const inputValue =
|
|
390
|
-
tradeType === TradeType.EXACT_OUTPUT ? buyAmount : toAmountDisplay || ""
|
|
391
|
-
const inputLength = inputValue.length
|
|
392
|
-
let fontSize: string
|
|
393
|
-
|
|
394
|
-
if (inputLength > 12) {
|
|
395
|
-
fontSize = "1rem"
|
|
396
|
-
} else if (inputLength > 9) {
|
|
397
|
-
fontSize = "1.25rem"
|
|
398
|
-
} else if (inputLength > 6) {
|
|
399
|
-
fontSize = "1.5rem"
|
|
400
|
-
} else if (inputLength > 3) {
|
|
401
|
-
fontSize = "1.75rem"
|
|
402
|
-
} else {
|
|
403
|
-
fontSize = "2rem"
|
|
404
|
-
}
|
|
367
|
+
const sellInputStyles = useDynamicInputStyles({ inputValue: sellAmount })
|
|
405
368
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
}, [tradeType, buyAmount, toAmountDisplay])
|
|
369
|
+
const buyInputStyles = useDynamicInputStyles({
|
|
370
|
+
inputValue:
|
|
371
|
+
tradeType === TradeType.EXACT_OUTPUT ? buyAmount : toAmountDisplay || "",
|
|
372
|
+
})
|
|
411
373
|
|
|
412
374
|
// Handle source token selection from full-screen selector
|
|
413
375
|
const handleSourceTokenSelectorSelect = useCallback(
|
|
@@ -585,10 +547,10 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
|
|
|
585
547
|
|
|
586
548
|
<form onSubmit={handleSubmit} className="space-y-1">
|
|
587
549
|
{/* Input Section - Amount + Token Selection */}
|
|
588
|
-
<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 trails-focus-border-secondary min-h-[120px] flex flex-col">
|
|
550
|
+
<div className="pt-4 pb-4 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 trails-focus-border-secondary min-h-[120px] flex flex-col">
|
|
589
551
|
{/* Sell Label */}
|
|
590
|
-
<div className="flex justify-between items-center
|
|
591
|
-
<div className="text-sm font-medium trails-text-secondary text-left">
|
|
552
|
+
<div className="mb-4 flex justify-between items-center">
|
|
553
|
+
<div className="text-sm font-medium trails-text-secondary text-left m-0">
|
|
592
554
|
{mode === "fund" ? "Payment method" : "Sell"}
|
|
593
555
|
</div>
|
|
594
556
|
<FundingMethodSelectorButton />
|
|
@@ -604,7 +566,7 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
|
|
|
604
566
|
type="text"
|
|
605
567
|
value={sellAmount}
|
|
606
568
|
onChange={(e) => handleSellAmountChange(e.target.value)}
|
|
607
|
-
placeholder={
|
|
569
|
+
placeholder={"0"}
|
|
608
570
|
className={`w-full bg-transparent font-bold trails-text-primary placeholder:trails-text-muted border-none outline-none ${
|
|
609
571
|
isLoadingQuote && tradeType === TradeType.EXACT_OUTPUT
|
|
610
572
|
? "animate-pulse"
|
|
@@ -632,10 +594,10 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
|
|
|
632
594
|
</div>
|
|
633
595
|
|
|
634
596
|
{/* Bottom Info Row for sell */}
|
|
635
|
-
<div className="mt-
|
|
597
|
+
<div className="mt-4 flex justify-between items-center">
|
|
636
598
|
{/* USD Amount */}
|
|
637
599
|
{originToken?.symbol && (
|
|
638
|
-
<div className="text-xs
|
|
600
|
+
<div className="text-xs text-gray-500 dark:text-gray-400">
|
|
639
601
|
≈{" "}
|
|
640
602
|
{tradeType === TradeType.EXACT_INPUT
|
|
641
603
|
? amountUsdDisplay || "$0.00"
|
|
@@ -650,7 +612,7 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
|
|
|
650
612
|
<div className="flex items-center space-x-2">
|
|
651
613
|
<button
|
|
652
614
|
type="button"
|
|
653
|
-
className="text-xs
|
|
615
|
+
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"
|
|
654
616
|
onClick={() => {
|
|
655
617
|
if (balanceFormatted) {
|
|
656
618
|
const balance = parseFloat(balanceFormatted)
|
|
@@ -716,10 +678,10 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
|
|
|
716
678
|
</div>
|
|
717
679
|
|
|
718
680
|
{/* Output Section - Amount + Token Selection */}
|
|
719
|
-
<div className="trails-bg-secondary trails-bg-secondary-hover trails-border-radius-container p-3 transition-all duration-200 border border-transparent focus-within:!bg-white dark:focus-within:!bg-gray-800 trails-focus-border-secondary min-h-[120px] flex flex-col">
|
|
681
|
+
<div className="pt-4 pb-4 trails-bg-secondary trails-bg-secondary-hover trails-border-radius-container p-3 transition-all duration-200 border border-transparent focus-within:!bg-white dark:focus-within:!bg-gray-800 trails-focus-border-secondary min-h-[120px] flex flex-col mb-4">
|
|
720
682
|
{/* Buy Label */}
|
|
721
|
-
<div className="flex justify-between items-center mb-2">
|
|
722
|
-
<div className="text-sm font-medium trails-text-secondary text-left">
|
|
683
|
+
<div className="mb-4 flex justify-between items-center mb-2">
|
|
684
|
+
<div className="text-sm font-medium trails-text-secondary text-left m-0">
|
|
723
685
|
{mode === "fund" ? "Recipient" : "Buy"}
|
|
724
686
|
</div>
|
|
725
687
|
{toRecipient ? (
|
|
@@ -747,7 +709,7 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
|
|
|
747
709
|
}
|
|
748
710
|
onChange={(e) => handleBuyAmountChange(e.target.value)}
|
|
749
711
|
onFocus={handleBuyInputFocus}
|
|
750
|
-
placeholder={
|
|
712
|
+
placeholder={"0"}
|
|
751
713
|
className={`w-full bg-transparent font-bold placeholder:trails-text-muted border-none outline-none ${
|
|
752
714
|
!amount
|
|
753
715
|
? "text-gray-400 dark:text-gray-500"
|
|
@@ -777,11 +739,11 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
|
|
|
777
739
|
</div>
|
|
778
740
|
|
|
779
741
|
{/* Bottom Info Row */}
|
|
780
|
-
<div className="mt-
|
|
742
|
+
<div className="mt-4 flex justify-between items-center">
|
|
781
743
|
{/* Destination Amount USD from Quote */}
|
|
782
744
|
{(prepareSendQuote?.destinationAmountUsdDisplay ||
|
|
783
745
|
(isLoadingQuote && tradeType === TradeType.EXACT_INPUT)) && (
|
|
784
|
-
<div className="text-xs
|
|
746
|
+
<div className="text-xs text-gray-500 dark:text-gray-400">
|
|
785
747
|
≈{" "}
|
|
786
748
|
{isLoadingQuote && tradeType === TradeType.EXACT_INPUT
|
|
787
749
|
? "$0.00"
|
|
@@ -833,7 +795,7 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
|
|
|
833
795
|
|
|
834
796
|
{/* Quote Details */}
|
|
835
797
|
{prepareSendQuote && (
|
|
836
|
-
<div className="
|
|
798
|
+
<div className="mb-4">
|
|
837
799
|
<QuoteDetails
|
|
838
800
|
quote={prepareSendQuote}
|
|
839
801
|
showContent={true}
|
|
@@ -36,7 +36,7 @@ export const ConnectWallet: React.FC<ConnectWalletProps> = ({
|
|
|
36
36
|
lastClickedWallet,
|
|
37
37
|
showDisconnect = true,
|
|
38
38
|
}) => {
|
|
39
|
-
const {
|
|
39
|
+
const { address, connector } = useAccount()
|
|
40
40
|
const connections = useConnections()
|
|
41
41
|
const { switchAccount } = useSwitchAccount()
|
|
42
42
|
const { setCurrentScreen } = useCurrentScreen()
|
|
@@ -45,6 +45,9 @@ export const ConnectWallet: React.FC<ConnectWalletProps> = ({
|
|
|
45
45
|
const connectors = useConnectors()
|
|
46
46
|
const [error, setError] = useState<string | null>(null)
|
|
47
47
|
|
|
48
|
+
// Check if there are any connected accounts across all connectors
|
|
49
|
+
const isConnected = connections.length > 0
|
|
50
|
+
|
|
48
51
|
useEffect(() => {
|
|
49
52
|
if (error) {
|
|
50
53
|
if (onError) {
|
|
@@ -86,25 +86,8 @@ const WalletItem: React.FC<WalletItemProps> = ({
|
|
|
86
86
|
{/* Identicon */}
|
|
87
87
|
<Identicon value={wallet.address} size={32} />
|
|
88
88
|
<div className="flex flex-col items-start space-y-1">
|
|
89
|
-
<div className="flex items-center space-x-
|
|
90
|
-
|
|
91
|
-
{typeof wallet.walletConfig?.icon === "string" ? (
|
|
92
|
-
<img
|
|
93
|
-
src={wallet.walletConfig.icon}
|
|
94
|
-
alt={wallet.walletConfig.name}
|
|
95
|
-
className="h-4 w-4"
|
|
96
|
-
/>
|
|
97
|
-
) : (
|
|
98
|
-
<Wallet className="h-4 w-4 text-gray-600 dark:text-gray-400" />
|
|
99
|
-
)}
|
|
100
|
-
<span className="text-sm font-bold text-gray-900 dark:text-gray-100">
|
|
101
|
-
{wallet.walletConfig?.name ||
|
|
102
|
-
wallet.connector?.name ||
|
|
103
|
-
"Wallet"}
|
|
104
|
-
</span>
|
|
105
|
-
</div>
|
|
106
|
-
<div className="flex items-center space-x-1">
|
|
107
|
-
<span className="text-xs text-gray-500 dark:text-gray-400 font-mono">
|
|
89
|
+
<div className="flex items-center space-x-1 m-0">
|
|
90
|
+
<span className="text-sm font-bold text-gray-900 dark:text-gray-100 whitespace-nowrap">
|
|
108
91
|
{truncateAddress(wallet.address)}
|
|
109
92
|
</span>
|
|
110
93
|
<div
|
|
@@ -147,6 +130,23 @@ const WalletItem: React.FC<WalletItemProps> = ({
|
|
|
147
130
|
)}
|
|
148
131
|
</div>
|
|
149
132
|
</div>
|
|
133
|
+
<div className="flex items-center space-x-2">
|
|
134
|
+
{/* Wallet Icon */}
|
|
135
|
+
{typeof wallet.walletConfig?.icon === "string" ? (
|
|
136
|
+
<img
|
|
137
|
+
src={wallet.walletConfig.icon}
|
|
138
|
+
alt={wallet.walletConfig.name}
|
|
139
|
+
className="h-3.5 w-3.5 mr-1"
|
|
140
|
+
/>
|
|
141
|
+
) : (
|
|
142
|
+
<Wallet className="h-3.5 w-3.5 text-gray-600 dark:text-gray-400 mr-1" />
|
|
143
|
+
)}
|
|
144
|
+
<span className="text-xs text-gray-500 dark:text-gray-400">
|
|
145
|
+
{wallet.walletConfig?.name ||
|
|
146
|
+
wallet.connector?.name ||
|
|
147
|
+
"Wallet"}
|
|
148
|
+
</span>
|
|
149
|
+
</div>
|
|
150
150
|
</div>
|
|
151
151
|
</div>
|
|
152
152
|
|
|
@@ -156,7 +156,7 @@ const WalletItem: React.FC<WalletItemProps> = ({
|
|
|
156
156
|
Active
|
|
157
157
|
</span>
|
|
158
158
|
) : !onWalletSelect ? (
|
|
159
|
-
<span className="text-xs px-2 py-1 rounded font-medium bg-gray-200 text-gray-700 dark:bg-gray-600 dark:text-gray-300 opacity-0 group-hover:opacity-100 transition-opacity duration-200">
|
|
159
|
+
<span className="whitespace-nowrap text-xs px-2 py-1 rounded font-medium bg-gray-200 text-gray-700 dark:bg-gray-600 dark:text-gray-300 opacity-0 group-hover:opacity-100 transition-opacity duration-200">
|
|
160
160
|
Set as active
|
|
161
161
|
</span>
|
|
162
162
|
) : null}
|
|
@@ -324,7 +324,7 @@ export const ConnectedWallets: React.FC<ConnectedWalletsProps> = ({
|
|
|
324
324
|
return (
|
|
325
325
|
<div className={`space-y-2 ${className}`}>
|
|
326
326
|
{/* Header */}
|
|
327
|
-
<div className="text-sm font-medium text-gray-
|
|
327
|
+
<div className="text-sm font-medium text-gray-900 dark:text-gray-100 text-left mb-2">
|
|
328
328
|
Connected Wallets
|
|
329
329
|
</div>
|
|
330
330
|
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { useMemo } from "react"
|
|
2
|
+
|
|
3
|
+
interface DynamicInputStylesProps {
|
|
4
|
+
inputValue: string
|
|
5
|
+
variant?: "default" | "smaller" | "inline"
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const useDynamicInputStyles = ({
|
|
9
|
+
inputValue,
|
|
10
|
+
variant = "default",
|
|
11
|
+
}: DynamicInputStylesProps) => {
|
|
12
|
+
return useMemo(() => {
|
|
13
|
+
const inputLength = inputValue.length
|
|
14
|
+
let fontSize: string
|
|
15
|
+
|
|
16
|
+
if (variant === "smaller") {
|
|
17
|
+
// Used in Fund.tsx - smaller font sizes
|
|
18
|
+
if (inputLength > 15) {
|
|
19
|
+
fontSize = "1rem"
|
|
20
|
+
} else if (inputLength > 12) {
|
|
21
|
+
fontSize = "1.125rem"
|
|
22
|
+
} else if (inputLength > 9) {
|
|
23
|
+
fontSize = "1.25rem"
|
|
24
|
+
} else if (inputLength > 6) {
|
|
25
|
+
fontSize = "1.375rem"
|
|
26
|
+
} else {
|
|
27
|
+
fontSize = "1.5rem"
|
|
28
|
+
}
|
|
29
|
+
} else if (variant === "inline") {
|
|
30
|
+
// Used in PoolWithdraw.tsx and PoolDeposit.tsx - inline styles with width
|
|
31
|
+
if (inputLength > 15) {
|
|
32
|
+
fontSize = "1rem"
|
|
33
|
+
} else if (inputLength > 12) {
|
|
34
|
+
fontSize = "1.125rem"
|
|
35
|
+
} else if (inputLength > 9) {
|
|
36
|
+
fontSize = "1.25rem"
|
|
37
|
+
} else if (inputLength > 6) {
|
|
38
|
+
fontSize = "1.375rem"
|
|
39
|
+
} else {
|
|
40
|
+
fontSize = "1.5rem"
|
|
41
|
+
}
|
|
42
|
+
} else {
|
|
43
|
+
// Default variant - used in Pay.tsx and ClassicSwap.tsx
|
|
44
|
+
if (inputLength > 15) {
|
|
45
|
+
fontSize = "1.25rem"
|
|
46
|
+
} else if (inputLength > 12) {
|
|
47
|
+
fontSize = "1.5rem"
|
|
48
|
+
} else if (inputLength > 9) {
|
|
49
|
+
fontSize = "1.75rem"
|
|
50
|
+
} else if (inputLength > 6) {
|
|
51
|
+
fontSize = "2rem"
|
|
52
|
+
} else {
|
|
53
|
+
fontSize = "2.25rem"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const baseStyles = {
|
|
58
|
+
fontSize,
|
|
59
|
+
transition: "all 0.1s ease-in-out",
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Add width and other properties for inline variant
|
|
63
|
+
if (variant === "inline") {
|
|
64
|
+
return {
|
|
65
|
+
...baseStyles,
|
|
66
|
+
width: `${Math.max((inputValue || "0").length, 1)}ch`,
|
|
67
|
+
minWidth: "1ch",
|
|
68
|
+
maxWidth: "270px",
|
|
69
|
+
padding: "0",
|
|
70
|
+
margin: "0",
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return baseStyles
|
|
75
|
+
}, [inputValue, variant])
|
|
76
|
+
}
|
|
@@ -14,8 +14,8 @@ import type { SupportedToken } from "../../tokens.js"
|
|
|
14
14
|
interface EarnProps {
|
|
15
15
|
onBack?: () => void
|
|
16
16
|
onContinue: () => void
|
|
17
|
-
account
|
|
18
|
-
walletClient
|
|
17
|
+
account?: Account
|
|
18
|
+
walletClient?: WalletClient
|
|
19
19
|
onTransactionStateChange: (transactionStates: TransactionState[]) => void
|
|
20
20
|
onError: (error: Error | string | null) => void
|
|
21
21
|
onWaitingForWalletConfirm: (props: PrepareSendQuote) => void
|
|
@@ -64,6 +64,7 @@ export const Earn: React.FC<EarnProps> = ({
|
|
|
64
64
|
onTrackToken,
|
|
65
65
|
}) => {
|
|
66
66
|
const [activeTab, setActiveTab] = useState<"deposit" | "withdraw">("deposit")
|
|
67
|
+
const [isShowingPoolSelector, setIsShowingPoolSelector] = useState(false) // Track if pool selector is shown
|
|
67
68
|
|
|
68
69
|
return (
|
|
69
70
|
<div className="space-y-2">
|
|
@@ -74,33 +75,35 @@ export const Earn: React.FC<EarnProps> = ({
|
|
|
74
75
|
showAccountActions={true}
|
|
75
76
|
/>
|
|
76
77
|
|
|
77
|
-
{/* Tabs */}
|
|
78
|
-
|
|
79
|
-
<
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
78
|
+
{/* Tabs - only show when not in pool selector mode */}
|
|
79
|
+
{!isShowingPoolSelector && (
|
|
80
|
+
<div className="flex justify-start space-x-2">
|
|
81
|
+
<button
|
|
82
|
+
type="button"
|
|
83
|
+
onClick={() => setActiveTab("deposit")}
|
|
84
|
+
className={`flex items-center space-x-2 py-2 px-4 text-xs font-bold cursor-pointer trails-border-radius-input ${
|
|
85
|
+
activeTab === "deposit"
|
|
86
|
+
? "trails-bg-secondary text-blue-500"
|
|
87
|
+
: "trails-text-secondary"
|
|
88
|
+
}`}
|
|
89
|
+
>
|
|
90
|
+
<ArrowDownCircle className="w-4 h-4" />
|
|
91
|
+
<span>Deposit</span>
|
|
92
|
+
</button>
|
|
93
|
+
<button
|
|
94
|
+
type="button"
|
|
95
|
+
onClick={() => setActiveTab("withdraw")}
|
|
96
|
+
className={`flex items-center space-x-2 py-2 px-4 text-xs font-bold cursor-pointer trails-border-radius-input ${
|
|
97
|
+
activeTab === "withdraw"
|
|
98
|
+
? "trails-bg-secondary text-blue-500"
|
|
99
|
+
: "trails-text-secondary"
|
|
100
|
+
}`}
|
|
101
|
+
>
|
|
102
|
+
<ArrowUpCircle className="w-4 h-4" />
|
|
103
|
+
<span>Withdraw</span>
|
|
104
|
+
</button>
|
|
105
|
+
</div>
|
|
106
|
+
)}
|
|
104
107
|
|
|
105
108
|
{/* Content */}
|
|
106
109
|
{activeTab === "deposit" ? (
|
|
@@ -123,6 +126,7 @@ export const Earn: React.FC<EarnProps> = ({
|
|
|
123
126
|
recentTokens={recentTokens}
|
|
124
127
|
onRecentTokenSelect={onRecentTokenSelect}
|
|
125
128
|
onTrackToken={onTrackToken}
|
|
129
|
+
onPoolSelectorStateChange={setIsShowingPoolSelector}
|
|
126
130
|
/>
|
|
127
131
|
) : (
|
|
128
132
|
<PoolWithdraw
|
|
@@ -144,6 +148,7 @@ export const Earn: React.FC<EarnProps> = ({
|
|
|
144
148
|
recentTokens={recentTokens}
|
|
145
149
|
onRecentTokenSelect={onRecentTokenSelect}
|
|
146
150
|
onTrackToken={onTrackToken}
|
|
151
|
+
onPoolSelectorStateChange={setIsShowingPoolSelector}
|
|
147
152
|
/>
|
|
148
153
|
)}
|
|
149
154
|
</div>
|
|
@@ -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
|
+
}
|