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
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import { ChevronLeft } from "lucide-react"
|
|
1
|
+
import { ChevronLeft, X } from "lucide-react"
|
|
2
2
|
import type React from "react"
|
|
3
|
-
import {
|
|
3
|
+
import { useConnections } from "wagmi"
|
|
4
4
|
import AccountActionsDropdown from "./AccountActionsDropdown.js"
|
|
5
|
+
import AccountIntentTransactionHistoryButton from "./AccountIntentTransactionHistoryButton.js"
|
|
6
|
+
import { useWidgetProps } from "../hooks/useWidgetProps.js"
|
|
7
|
+
import { useModal } from "../widget.js"
|
|
5
8
|
|
|
6
9
|
interface ScreenHeaderProps {
|
|
7
10
|
onBack?: () => void
|
|
@@ -19,42 +22,67 @@ export const ScreenHeader: React.FC<ScreenHeaderProps> = ({
|
|
|
19
22
|
headerContentAlign = "left",
|
|
20
23
|
showAccountActions = false,
|
|
21
24
|
}) => {
|
|
22
|
-
const
|
|
25
|
+
const connections = useConnections()
|
|
26
|
+
const { renderInline } = useWidgetProps()
|
|
27
|
+
const { closeModal, isModalOpen } = useModal()
|
|
28
|
+
|
|
29
|
+
// Check if there are any connected accounts across all connectors
|
|
30
|
+
const isConnected = connections.length > 0
|
|
31
|
+
|
|
32
|
+
// Show close button when in modal mode (not renderInline) and modal is open
|
|
33
|
+
const showCloseButton = !renderInline && isModalOpen
|
|
23
34
|
return (
|
|
24
|
-
<div className="
|
|
25
|
-
{/* Left side - Back button
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
35
|
+
<div className="flex items-center justify-between w-full mb-4">
|
|
36
|
+
{/* Left side - Back button */}
|
|
37
|
+
<div className="flex items-center">
|
|
38
|
+
{onBack && (
|
|
39
|
+
<button
|
|
40
|
+
type="button"
|
|
41
|
+
onClick={onBack}
|
|
42
|
+
className="flex h-8 w-8 justify-center items-center rounded-full bg-gray-50 dark:bg-gray-700 cursor-pointer transition-colors text-gray-900 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-600 mr-2"
|
|
43
|
+
title="Back"
|
|
44
|
+
>
|
|
45
|
+
<ChevronLeft className="h-4 w-4" />
|
|
46
|
+
</button>
|
|
47
|
+
)}
|
|
48
|
+
|
|
49
|
+
{/* Header content */}
|
|
50
|
+
<h2
|
|
51
|
+
className={`text-lg font-semibold ${
|
|
52
|
+
headerContentAlign === "center" ? "text-center" : "text-left"
|
|
53
|
+
} text-gray-900 dark:text-white`}
|
|
31
54
|
>
|
|
32
|
-
|
|
33
|
-
</
|
|
34
|
-
|
|
55
|
+
{headerContent}
|
|
56
|
+
</h2>
|
|
57
|
+
</div>
|
|
35
58
|
|
|
36
|
-
{/*
|
|
37
|
-
<
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
59
|
+
{/* Right side - Content, Account Actions, and Close button */}
|
|
60
|
+
<div className="flex items-center gap-2">
|
|
61
|
+
{/* Right side content and Account Actions */}
|
|
62
|
+
{rightSideContent && (
|
|
63
|
+
<div className="text-right max-w-[280px]">{rightSideContent}</div>
|
|
64
|
+
)}
|
|
65
|
+
{isConnected && showAccountActions && (
|
|
66
|
+
<>
|
|
67
|
+
<div className="m-0">
|
|
68
|
+
<AccountIntentTransactionHistoryButton />
|
|
69
|
+
</div>
|
|
70
|
+
<AccountActionsDropdown />
|
|
71
|
+
</>
|
|
72
|
+
)}
|
|
48
73
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
74
|
+
{/* Close button (always rightmost) */}
|
|
75
|
+
{showCloseButton && (
|
|
76
|
+
<button
|
|
77
|
+
type="button"
|
|
78
|
+
onClick={closeModal}
|
|
79
|
+
className="flex h-8 w-8 justify-center items-center rounded-full bg-gray-50 dark:bg-gray-700 cursor-pointer transition-colors text-gray-900 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-600"
|
|
80
|
+
title="Close"
|
|
81
|
+
>
|
|
82
|
+
<X className="h-4 w-4" />
|
|
83
|
+
</button>
|
|
84
|
+
)}
|
|
85
|
+
</div>
|
|
58
86
|
</div>
|
|
59
87
|
)
|
|
60
88
|
}
|
|
@@ -142,7 +142,8 @@ export const SlippageToleranceSettings: React.FC<
|
|
|
142
142
|
onBlur={handleInputBlur}
|
|
143
143
|
onKeyDown={handleKeyDown}
|
|
144
144
|
placeholder="5"
|
|
145
|
-
className="w-full px-2 py-1.5 text-sm border border-solid border-gray-200 dark:border-gray-700
|
|
145
|
+
className="w-full px-2 py-1.5 text-sm border border-solid border-gray-200 dark:border-gray-700 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 trails-input pr-6"
|
|
146
|
+
style={{ borderRadius: "10px" }}
|
|
146
147
|
/>
|
|
147
148
|
<div className="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
|
|
148
149
|
<span className="text-xs text-gray-500 dark:text-gray-400">%</span>
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
import type React from "react"
|
|
2
|
-
import { useEffect } from "react"
|
|
3
2
|
import type { Account, WalletClient } from "viem"
|
|
4
3
|
import type { TransactionState } from "../../transactions.js"
|
|
5
4
|
import type { OnCompleteProps, Token } from "../hooks/useSendForm.js"
|
|
6
5
|
import type { SupportedToken } from "../../tokens.js"
|
|
7
6
|
import type { CheckoutOnHandlers } from "../hooks/useCheckout.js"
|
|
8
7
|
import type { PrepareSendQuote } from "../../prepareSend.js"
|
|
9
|
-
import { SimpleSwap } from "./SimpleSwap.js"
|
|
10
8
|
import { ClassicSwap } from "./ClassicSwap.js"
|
|
11
|
-
import { useSwapSettings } from "../hooks/useSwapSettings.js"
|
|
12
|
-
import { useWidgetProps } from "../hooks/useWidgetProps.js"
|
|
13
9
|
|
|
14
10
|
interface SwapProps {
|
|
15
11
|
selectedToken: Token | null
|
|
@@ -17,13 +13,13 @@ interface SwapProps {
|
|
|
17
13
|
onBack?: () => void
|
|
18
14
|
onConfirm: () => void
|
|
19
15
|
onComplete: (result: OnCompleteProps) => void
|
|
20
|
-
account
|
|
16
|
+
account?: Account
|
|
21
17
|
toRecipient?: string
|
|
22
18
|
toAmount?: string
|
|
23
19
|
toChainId?: number
|
|
24
20
|
toToken?: string
|
|
25
21
|
toCalldata?: string
|
|
26
|
-
walletClient
|
|
22
|
+
walletClient?: WalletClient
|
|
27
23
|
onTransactionStateChange: (transactionStates: TransactionState[]) => void
|
|
28
24
|
onError: (error: Error | string | null) => void
|
|
29
25
|
onWaitingForWalletConfirm: (props: PrepareSendQuote) => void
|
|
@@ -46,48 +42,11 @@ interface SwapProps {
|
|
|
46
42
|
recentTokens?: SupportedToken[]
|
|
47
43
|
onRecentTokenSelect?: (token: SupportedToken) => void
|
|
48
44
|
onTrackToken?: (token: any) => void
|
|
45
|
+
isSequenceWallet?: boolean
|
|
49
46
|
}
|
|
50
47
|
|
|
51
48
|
export const Swap: React.FC<SwapProps> = (props) => {
|
|
52
|
-
|
|
53
|
-
const {
|
|
54
|
-
isSimpleSwapMode: isSimpleMode,
|
|
55
|
-
setIsSimpleSwapMode: setIsSimpleMode,
|
|
56
|
-
} = useSwapSettings()
|
|
57
|
-
|
|
58
|
-
// Update isSimpleMode when swapMode changes
|
|
59
|
-
useEffect(() => {
|
|
60
|
-
if (swapMode === "simple") {
|
|
61
|
-
setIsSimpleMode(true)
|
|
62
|
-
}
|
|
63
|
-
}, [swapMode, setIsSimpleMode])
|
|
64
|
-
|
|
65
|
-
// Render SimpleSwap or ClassicSwap based on mode
|
|
66
|
-
if (isSimpleMode) {
|
|
67
|
-
return (
|
|
68
|
-
<SimpleSwap
|
|
69
|
-
onBack={props.onBack}
|
|
70
|
-
account={props.account}
|
|
71
|
-
walletClient={props.walletClient}
|
|
72
|
-
onTransactionStateChange={props.onTransactionStateChange}
|
|
73
|
-
onError={props.onError}
|
|
74
|
-
onWaitingForWalletConfirm={props.onWaitingForWalletConfirm}
|
|
75
|
-
onConfirm={props.onConfirm}
|
|
76
|
-
onComplete={props.onComplete}
|
|
77
|
-
onSend={props.onSend}
|
|
78
|
-
paymasterUrls={props.paymasterUrls}
|
|
79
|
-
gasless={props.gasless}
|
|
80
|
-
setWalletConfirmRetryHandler={props.setWalletConfirmRetryHandler}
|
|
81
|
-
quoteProvider={props.quoteProvider}
|
|
82
|
-
fundMethod={props.fundMethod}
|
|
83
|
-
checkoutOnHandlers={props.checkoutOnHandlers}
|
|
84
|
-
showHeader={true}
|
|
85
|
-
onTokenSelectorVisibilityChange={() => {}}
|
|
86
|
-
/>
|
|
87
|
-
)
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Default to ClassicSwap
|
|
49
|
+
// Always render ClassicSwap
|
|
91
50
|
return <ClassicSwap {...props} />
|
|
92
51
|
}
|
|
93
52
|
|
|
@@ -3,10 +3,8 @@ import type React from "react"
|
|
|
3
3
|
import { useEffect, useRef, useState } from "react"
|
|
4
4
|
// import { SwapDisplayMode } from "./SwapDisplayMode.js"
|
|
5
5
|
import { SlippageToleranceSettings } from "./SlippageToleranceSettings.js"
|
|
6
|
-
// import { useSwapSettings } from "../hooks/useSwapSettings.js"
|
|
7
6
|
|
|
8
7
|
export const SwapSettings: React.FC = () => {
|
|
9
|
-
//const { isSimpleSwapMode, setIsSimpleSwapModeWithStorage } = useSwapSettings()
|
|
10
8
|
const [isSettingsDropdownOpen, setIsSettingsDropdownOpen] = useState(false)
|
|
11
9
|
const settingsDropdownRef = useRef<HTMLDivElement>(null)
|
|
12
10
|
|
|
@@ -27,13 +25,8 @@ export const SwapSettings: React.FC = () => {
|
|
|
27
25
|
}
|
|
28
26
|
}, [isSettingsDropdownOpen])
|
|
29
27
|
|
|
30
|
-
// const handleModeSelect = (isSimple: boolean) => {
|
|
31
|
-
// setIsSimpleSwapModeWithStorage(isSimple)
|
|
32
|
-
// setIsSettingsDropdownOpen(false)
|
|
33
|
-
// }
|
|
34
|
-
|
|
35
28
|
return (
|
|
36
|
-
<div
|
|
29
|
+
<div ref={settingsDropdownRef}>
|
|
37
30
|
<button
|
|
38
31
|
type="button"
|
|
39
32
|
onClick={() => setIsSettingsDropdownOpen(!isSettingsDropdownOpen)}
|
|
@@ -47,12 +40,7 @@ export const SwapSettings: React.FC = () => {
|
|
|
47
40
|
{isSettingsDropdownOpen && (
|
|
48
41
|
<div className="absolute right-0 top-full mt-2 w-80 trails-bg-card rounded-lg shadow-lg border trails-border-primary z-20">
|
|
49
42
|
<div className="p-4 space-y-4">
|
|
50
|
-
|
|
51
|
-
isSimpleMode={isSimpleSwapMode}
|
|
52
|
-
onModeChange={handleModeSelect}
|
|
53
|
-
/> */}
|
|
54
|
-
|
|
55
|
-
<div className="border-t border-gray-200 dark:border-gray-700 pt-4">
|
|
43
|
+
<div>
|
|
56
44
|
<SlippageToleranceSettings />
|
|
57
45
|
</div>
|
|
58
46
|
</div>
|
|
@@ -3,6 +3,7 @@ import { createContext, useContext, useEffect, useState } from "react"
|
|
|
3
3
|
import type { Theme } from "../../theme.js"
|
|
4
4
|
import { ThemeProvider as DesignSystemThemeProvider } from "@0xsequence/design-system"
|
|
5
5
|
import { logger } from "../../logger.js"
|
|
6
|
+
import { DEFAULT_THEME } from "../../constants.js"
|
|
6
7
|
|
|
7
8
|
interface ThemeContextType {
|
|
8
9
|
theme: Theme
|
|
@@ -31,7 +32,7 @@ const getIsDark = (theme: Theme): boolean => {
|
|
|
31
32
|
|
|
32
33
|
export const ThemeProvider: React.FC<ThemeProviderProps> = ({
|
|
33
34
|
children,
|
|
34
|
-
initialTheme =
|
|
35
|
+
initialTheme = DEFAULT_THEME,
|
|
35
36
|
}) => {
|
|
36
37
|
const [theme, setTheme] = useState<Theme>(initialTheme)
|
|
37
38
|
const [isDark, setIsDark] = useState(getIsDark(initialTheme))
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type React from "react"
|
|
2
|
+
import { TokenImage } from "./TokenImage.js"
|
|
3
|
+
|
|
4
|
+
interface TokenDisplayNonSelectableProps {
|
|
5
|
+
symbol: string
|
|
6
|
+
imageUrl?: string
|
|
7
|
+
chainId: number
|
|
8
|
+
contractAddress: string
|
|
9
|
+
chainName?: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const TokenDisplayNonSelectable: React.FC<
|
|
13
|
+
TokenDisplayNonSelectableProps
|
|
14
|
+
> = ({ symbol, imageUrl, chainId, contractAddress, chainName }) => {
|
|
15
|
+
return (
|
|
16
|
+
<div className="relative max-w-[120px]">
|
|
17
|
+
<div className="flex items-center space-x-1.5 trails-bg-card trails-border-radius-input px-2.5 py-1.5 border trails-border-primary">
|
|
18
|
+
<div className="flex items-center flex-shrink-0">
|
|
19
|
+
<TokenImage
|
|
20
|
+
symbol={symbol}
|
|
21
|
+
imageUrl={imageUrl}
|
|
22
|
+
chainId={chainId}
|
|
23
|
+
contractAddress={contractAddress}
|
|
24
|
+
size={28}
|
|
25
|
+
/>
|
|
26
|
+
</div>
|
|
27
|
+
<div className="flex flex-col items-start min-w-0 overflow-hidden">
|
|
28
|
+
<span className="font-bold trails-text-primary text-sm leading-tight truncate max-w-full text-left">
|
|
29
|
+
{symbol}
|
|
30
|
+
</span>
|
|
31
|
+
{chainName && (
|
|
32
|
+
<span className="text-xs trails-text-muted leading-tight truncate max-w-full text-left">
|
|
33
|
+
{chainName}
|
|
34
|
+
</span>
|
|
35
|
+
)}
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
)
|
|
40
|
+
}
|
|
@@ -1,19 +1,28 @@
|
|
|
1
1
|
import React, { useMemo } from "react"
|
|
2
2
|
import { ChainImage } from "./ChainImage.js"
|
|
3
3
|
import { getCommonTokenImageUrl } from "../../tokens.js"
|
|
4
|
+
import { logger } from "../../logger.js"
|
|
4
5
|
|
|
5
6
|
function normalizeImageUrl(
|
|
6
7
|
imageUrl?: string | null,
|
|
7
8
|
symbol?: string | null,
|
|
8
9
|
chainId?: number | null,
|
|
10
|
+
contractAddress?: string | null,
|
|
9
11
|
) {
|
|
10
12
|
if (symbol === "ETH") {
|
|
11
13
|
return "https://assets.sequence.info/images/tokens/large/1/0x0000000000000000000000000000000000000000.webp"
|
|
12
14
|
}
|
|
15
|
+
const commonImageUrl = getCommonTokenImageUrl({
|
|
16
|
+
symbol,
|
|
17
|
+
chainId,
|
|
18
|
+
contractAddress,
|
|
19
|
+
})
|
|
20
|
+
if (commonImageUrl) {
|
|
21
|
+
return commonImageUrl
|
|
22
|
+
}
|
|
23
|
+
|
|
13
24
|
if (imageUrl) {
|
|
14
25
|
return imageUrl.replace("/small/", "/large/")
|
|
15
|
-
} else if (symbol) {
|
|
16
|
-
return getCommonTokenImageUrl({ symbol, chainId })
|
|
17
26
|
}
|
|
18
27
|
|
|
19
28
|
return null
|
|
@@ -23,6 +32,7 @@ interface TokenImageProps {
|
|
|
23
32
|
imageUrl?: string | null
|
|
24
33
|
symbol?: string | null
|
|
25
34
|
chainId?: number | null
|
|
35
|
+
contractAddress?: string | null
|
|
26
36
|
size?: number
|
|
27
37
|
}
|
|
28
38
|
|
|
@@ -30,12 +40,19 @@ export const TokenImage: React.FC<TokenImageProps> = ({
|
|
|
30
40
|
imageUrl,
|
|
31
41
|
symbol,
|
|
32
42
|
chainId,
|
|
43
|
+
contractAddress,
|
|
33
44
|
size = 24,
|
|
34
45
|
}) => {
|
|
35
46
|
const [imageError, setImageError] = React.useState(false)
|
|
36
47
|
const effectiveImageUrl = useMemo(() => {
|
|
37
|
-
|
|
38
|
-
|
|
48
|
+
logger.console.log("[TokenImage] normalizeImageUrl", {
|
|
49
|
+
imageUrl,
|
|
50
|
+
symbol,
|
|
51
|
+
chainId,
|
|
52
|
+
contractAddress,
|
|
53
|
+
})
|
|
54
|
+
return normalizeImageUrl(imageUrl, symbol, chainId, contractAddress)
|
|
55
|
+
}, [imageUrl, symbol, chainId, contractAddress])
|
|
39
56
|
|
|
40
57
|
const displaySymbol = symbol?.[0]?.toUpperCase() || "?"
|
|
41
58
|
|
|
@@ -47,7 +64,7 @@ export const TokenImage: React.FC<TokenImageProps> = ({
|
|
|
47
64
|
|
|
48
65
|
return (
|
|
49
66
|
<div
|
|
50
|
-
className={`rounded-full flex items-center justify-center text-sm relative ${
|
|
67
|
+
className={`rounded-full flex items-center justify-center text-sm relative m-0 ${
|
|
51
68
|
symbol !== "ETH" ? "bg-gray-400 dark:bg-gray-900" : ""
|
|
52
69
|
}`}
|
|
53
70
|
style={{
|
|
@@ -2,6 +2,7 @@ import { ChevronLeft, Copy } from "lucide-react"
|
|
|
2
2
|
import type React from "react"
|
|
3
3
|
import { useState, useMemo } from "react"
|
|
4
4
|
import { AnimatePresence, motion } from "framer-motion"
|
|
5
|
+
import { zeroAddress } from "viem"
|
|
5
6
|
import type { Token, TokenFormatted } from "../hooks/useTokenList.js"
|
|
6
7
|
import { useTokenList } from "../hooks/useTokenList.js"
|
|
7
8
|
import { useChainFilter } from "../hooks/useChainFilter.js"
|
|
@@ -14,6 +15,7 @@ import { ChainFilterDropdown } from "./ChainFilterDropdown.js"
|
|
|
14
15
|
import { SearchInputField } from "./SearchInputField.js"
|
|
15
16
|
import { truncateAddress } from "../../utils.js"
|
|
16
17
|
import { logger } from "../../logger.js"
|
|
18
|
+
import { useAccount } from "wagmi"
|
|
17
19
|
|
|
18
20
|
interface TokenSelectorProps {
|
|
19
21
|
onTokenSelect: (selectedToken: Token) => void
|
|
@@ -55,6 +57,7 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
|
|
|
55
57
|
}) => {
|
|
56
58
|
const [copiedAddress, setCopiedAddress] = useState<string | null>(null)
|
|
57
59
|
const { isBalanceVisible } = useBalanceVisible()
|
|
60
|
+
const { address } = useAccount()
|
|
58
61
|
|
|
59
62
|
const {
|
|
60
63
|
searchQuery,
|
|
@@ -224,7 +227,9 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
|
|
|
224
227
|
? "No tokens found matching your search."
|
|
225
228
|
: fundMethod === "qr-code" || fundMethod === "exchange"
|
|
226
229
|
? ""
|
|
227
|
-
:
|
|
230
|
+
: address
|
|
231
|
+
? "No available tokens found"
|
|
232
|
+
: ""}
|
|
228
233
|
</p>
|
|
229
234
|
</div>
|
|
230
235
|
)}
|
|
@@ -295,6 +300,7 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
|
|
|
295
300
|
symbol={symbol}
|
|
296
301
|
imageUrl={imageUrl}
|
|
297
302
|
chainId={chainId}
|
|
303
|
+
contractAddress={contractAddress}
|
|
298
304
|
size={32}
|
|
299
305
|
/>
|
|
300
306
|
) : (
|
|
@@ -329,7 +335,9 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
|
|
|
329
335
|
{/* Default state: show symbol */}
|
|
330
336
|
<div
|
|
331
337
|
className={`flex items-center transition-all duration-300 ease-in-out ${
|
|
332
|
-
contractAddress
|
|
338
|
+
contractAddress &&
|
|
339
|
+
contractAddress.toLowerCase() !==
|
|
340
|
+
zeroAddress.toLowerCase()
|
|
333
341
|
? "group-hover:opacity-0 group-hover:transform group-hover:-translate-x-2"
|
|
334
342
|
: ""
|
|
335
343
|
} ${
|
|
@@ -345,58 +353,60 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
|
|
|
345
353
|
</span>
|
|
346
354
|
</div>
|
|
347
355
|
|
|
348
|
-
{/* Hover state: show address with copy button */}
|
|
349
|
-
{contractAddress &&
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
{truncateAddress(contractAddress)}
|
|
361
|
-
</span>
|
|
362
|
-
<button
|
|
363
|
-
type="button"
|
|
364
|
-
onClick={(e) =>
|
|
365
|
-
handleCopyAddress(contractAddress, e)
|
|
366
|
-
}
|
|
367
|
-
className={`ml-1 p-0.5 rounded transition-all duration-200 cursor-pointer ${
|
|
368
|
-
copiedAddress === contractAddress
|
|
369
|
-
? "bg-green-100 dark:bg-green-900/30"
|
|
370
|
-
: "hover:bg-gray-200 dark:hover:bg-gray-600"
|
|
371
|
-
}`}
|
|
372
|
-
title={
|
|
373
|
-
copiedAddress === contractAddress
|
|
374
|
-
? "Copied!"
|
|
375
|
-
: "Copy full address"
|
|
376
|
-
}
|
|
356
|
+
{/* Hover state: show address with copy button (only for non-zero addresses) */}
|
|
357
|
+
{contractAddress &&
|
|
358
|
+
contractAddress.toLowerCase() !==
|
|
359
|
+
zeroAddress.toLowerCase() && (
|
|
360
|
+
<div
|
|
361
|
+
className={`absolute top-0 left-0 flex items-center transition-all duration-300 ease-in-out opacity-0 transform translate-x-2 ${
|
|
362
|
+
!isSufficientBalance &&
|
|
363
|
+
fundMethod !== "qr-code" &&
|
|
364
|
+
fundMethod !== "exchange"
|
|
365
|
+
? "group-hover:opacity-70"
|
|
366
|
+
: "group-hover:opacity-100"
|
|
367
|
+
} group-hover:translate-x-0`}
|
|
377
368
|
>
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
369
|
+
<span className="text-xs text-gray-500 dark:text-gray-400 whitespace-nowrap">
|
|
370
|
+
{truncateAddress(contractAddress)}
|
|
371
|
+
</span>
|
|
372
|
+
<button
|
|
373
|
+
type="button"
|
|
374
|
+
onClick={(e) =>
|
|
375
|
+
handleCopyAddress(contractAddress, e)
|
|
376
|
+
}
|
|
377
|
+
className={`ml-1 p-0.5 rounded transition-all duration-200 cursor-pointer ${
|
|
378
|
+
copiedAddress === contractAddress
|
|
379
|
+
? "bg-green-100 dark:bg-green-900/30"
|
|
380
|
+
: "hover:bg-gray-200 dark:hover:bg-gray-600"
|
|
381
|
+
}`}
|
|
382
|
+
title={
|
|
383
|
+
copiedAddress === contractAddress
|
|
384
|
+
? "Copied!"
|
|
385
|
+
: "Copy full address"
|
|
386
|
+
}
|
|
387
|
+
>
|
|
388
|
+
{copiedAddress === contractAddress ? (
|
|
389
|
+
<svg
|
|
390
|
+
className="w-3 h-3 text-green-600 dark:text-green-400"
|
|
391
|
+
fill="none"
|
|
392
|
+
viewBox="0 0 24 24"
|
|
393
|
+
stroke="currentColor"
|
|
394
|
+
aria-label="Copied"
|
|
395
|
+
>
|
|
396
|
+
<title>Copied</title>
|
|
397
|
+
<path
|
|
398
|
+
strokeLinecap="round"
|
|
399
|
+
strokeLinejoin="round"
|
|
400
|
+
strokeWidth={2}
|
|
401
|
+
d="M5 13l4 4L19 7"
|
|
402
|
+
/>
|
|
403
|
+
</svg>
|
|
404
|
+
) : (
|
|
405
|
+
<Copy className="w-3 h-3 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300" />
|
|
406
|
+
)}
|
|
407
|
+
</button>
|
|
408
|
+
</div>
|
|
409
|
+
)}
|
|
400
410
|
</div>
|
|
401
411
|
</div>
|
|
402
412
|
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { ChevronRight } from "lucide-react"
|
|
2
|
+
import type React from "react"
|
|
3
|
+
import { useMemo } from "react"
|
|
4
|
+
import { useConnections } from "wagmi"
|
|
5
|
+
import { TokenImage } from "./TokenImage.js"
|
|
6
|
+
import { getChainInfo } from "../../chains.js"
|
|
7
|
+
import { useCurrentScreen } from "../hooks/useCurrentScreen.js"
|
|
8
|
+
import { useSelectedFundMethod } from "../hooks/useSelectedFundMethod.js"
|
|
9
|
+
|
|
10
|
+
interface TokenSelectorButtonProps {
|
|
11
|
+
token?: {
|
|
12
|
+
symbol: string
|
|
13
|
+
imageUrl?: string
|
|
14
|
+
contractAddress?: string
|
|
15
|
+
chainId?: number | null
|
|
16
|
+
} | null
|
|
17
|
+
chainId?: number | null
|
|
18
|
+
onSelect: () => void
|
|
19
|
+
className?: string
|
|
20
|
+
unselectable?: boolean
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const TokenSelectorButton: React.FC<TokenSelectorButtonProps> = ({
|
|
24
|
+
token,
|
|
25
|
+
chainId,
|
|
26
|
+
onSelect,
|
|
27
|
+
className = "flex items-center space-x-1.5 trails-border-radius-input px-2.5 py-1.5 border transition-all duration-200",
|
|
28
|
+
unselectable = false,
|
|
29
|
+
}) => {
|
|
30
|
+
const connections = useConnections()
|
|
31
|
+
const { setCurrentScreen } = useCurrentScreen()
|
|
32
|
+
const { selectedFundMethod } = useSelectedFundMethod()
|
|
33
|
+
const displayChainId = token?.chainId || chainId
|
|
34
|
+
|
|
35
|
+
// Check if there are any connected accounts across all connectors
|
|
36
|
+
const isConnected = connections.length > 0
|
|
37
|
+
|
|
38
|
+
const chainInfo = useMemo(() => {
|
|
39
|
+
return displayChainId ? getChainInfo(displayChainId) : null
|
|
40
|
+
}, [displayChainId])
|
|
41
|
+
|
|
42
|
+
const handleClick = () => {
|
|
43
|
+
if (unselectable) return
|
|
44
|
+
|
|
45
|
+
// If no wallet connected and fund method is "wallet", redirect to connect screen
|
|
46
|
+
if (!isConnected && selectedFundMethod === "wallet") {
|
|
47
|
+
setCurrentScreen("connect")
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
onSelect()
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<button
|
|
56
|
+
type="button"
|
|
57
|
+
onClick={handleClick}
|
|
58
|
+
disabled={unselectable}
|
|
59
|
+
className={`${className} ${token ? "max-w-[120px]" : ""} ${
|
|
60
|
+
token
|
|
61
|
+
? "bg-white dark:bg-gray-900 border-gray-200 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-800 hover:border-gray-300 dark:hover:border-gray-600"
|
|
62
|
+
: "bg-blue-500 hover:bg-blue-600 border-blue-500 text-white"
|
|
63
|
+
} ${unselectable ? "cursor-default" : "cursor-pointer"}`}
|
|
64
|
+
>
|
|
65
|
+
{token ? (
|
|
66
|
+
<>
|
|
67
|
+
<div className="flex items-center flex-shrink-0">
|
|
68
|
+
<TokenImage
|
|
69
|
+
symbol={token.symbol}
|
|
70
|
+
imageUrl={token.imageUrl}
|
|
71
|
+
chainId={displayChainId}
|
|
72
|
+
contractAddress={token.contractAddress}
|
|
73
|
+
size={28}
|
|
74
|
+
/>
|
|
75
|
+
</div>
|
|
76
|
+
<div className="flex flex-col items-start min-w-0 overflow-hidden">
|
|
77
|
+
<span className="font-bold trails-text-primary text-sm leading-tight truncate max-w-full text-left">
|
|
78
|
+
{token.symbol}
|
|
79
|
+
</span>
|
|
80
|
+
{chainInfo && (
|
|
81
|
+
<span className="text-xs trails-text-muted leading-tight truncate max-w-full text-left">
|
|
82
|
+
{chainInfo.name}
|
|
83
|
+
</span>
|
|
84
|
+
)}
|
|
85
|
+
</div>
|
|
86
|
+
{!unselectable && (
|
|
87
|
+
<ChevronRight className="w-3.5 h-3.5 trails-text-muted flex-shrink-0" />
|
|
88
|
+
)}
|
|
89
|
+
</>
|
|
90
|
+
) : (
|
|
91
|
+
<>
|
|
92
|
+
<span className="font-medium text-sm text-white">Select Token</span>
|
|
93
|
+
{!unselectable && <ChevronRight className="w-3.5 h-3.5 text-white" />}
|
|
94
|
+
</>
|
|
95
|
+
)}
|
|
96
|
+
</button>
|
|
97
|
+
)
|
|
98
|
+
}
|