0xtrails 0.2.4 → 0.2.5
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/{ccip-BlV1Mry3.js → ccip-CXlshvBY.js} +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/constants.d.ts +1 -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/{index-BNWCIGfQ.js → index-_QuyGrjU.js} +72332 -72246
- package/dist/index.js +2 -2
- 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 +16 -6
- 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/wallets.d.ts.map +1 -1
- package/dist/widget/components/AccountActionsDropdown.d.ts.map +1 -1
- package/dist/widget/components/AccountSettings.d.ts.map +1 -1
- package/dist/widget/components/ClassicSwap.d.ts +2 -0
- 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/Earn.d.ts.map +1 -1
- package/dist/widget/components/Fund.d.ts.map +1 -1
- package/dist/widget/components/FundMethods.d.ts.map +1 -1
- package/dist/widget/components/{FundSendForm.d.ts → FundSwap.d.ts} +11 -5
- 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/Modal.d.ts.map +1 -1
- 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} +11 -34
- package/dist/widget/components/PoolDeposit.d.ts.map +1 -0
- package/dist/widget/components/{SimpleSwap.d.ts → PoolWithdraw.d.ts} +16 -8
- package/dist/widget/components/PoolWithdraw.d.ts.map +1 -0
- package/dist/widget/components/QuoteDetails.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 +1 -0
- package/dist/widget/components/Swap.d.ts.map +1 -1
- package/dist/widget/components/SwapSettings.d.ts.map +1 -1
- 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/UserPreferences.d.ts.map +1 -1
- package/dist/widget/components/WaasFeeOptions.d.ts +8 -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/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/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.map +1 -1
- package/dist/widget/index.js +1 -1
- package/dist/widget/widget.d.ts +4 -4
- package/dist/widget/widget.d.ts.map +1 -1
- package/package.json +18 -12
- package/src/aave.ts +32 -0
- package/src/config.ts +12 -4
- package/src/constants.ts +2 -0
- package/src/error.ts +19 -1
- package/src/estimate.ts +416 -5
- 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 +503 -166
- 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/wallets.ts +8 -0
- package/src/widget/compiled.css +2 -2
- package/src/widget/components/AccountActionsDropdown.tsx +3 -13
- package/src/widget/components/AccountSettings.tsx +6 -24
- package/src/widget/components/ClassicSwap.tsx +111 -155
- package/src/widget/components/ConnectWallet.tsx +4 -37
- package/src/widget/components/ConnectedWallets.tsx +113 -58
- package/src/widget/components/Earn.tsx +73 -589
- package/src/widget/components/Fund.tsx +31 -82
- package/src/widget/components/FundMethods.tsx +82 -159
- package/src/widget/components/FundSwap.tsx +52 -0
- package/src/widget/components/FundingMethodSelectorButton.tsx +60 -0
- package/src/widget/components/Modal.tsx +6 -2
- package/src/widget/components/Pay.tsx +183 -208
- package/src/widget/components/PercentageMaxButtons.tsx +77 -0
- package/src/widget/components/PoolDeposit.tsx +593 -0
- package/src/widget/components/PoolWithdraw.tsx +903 -0
- package/src/widget/components/QuoteDetails.tsx +22 -8
- package/src/widget/components/Receive.tsx +0 -2
- package/src/widget/components/RecipientSelectorButton.tsx +42 -0
- package/src/widget/components/Recipients.tsx +62 -156
- package/src/widget/components/RequiredPropsError.tsx +33 -0
- package/src/widget/components/ScreenHeader.tsx +5 -1
- package/src/widget/components/SlippageToleranceSettings.tsx +2 -1
- package/src/widget/components/Swap.tsx +2 -43
- package/src/widget/components/SwapSettings.tsx +2 -14
- package/src/widget/components/TokenImage.tsx +21 -4
- package/src/widget/components/TokenList.tsx +0 -1
- package/src/widget/components/TokenSelector.tsx +1 -0
- package/src/widget/components/TokenSelectorButton.tsx +75 -0
- package/src/widget/components/UserPreferences.tsx +6 -24
- package/src/widget/components/WaasFeeOptions.tsx +331 -0
- package/src/widget/components/WalletConfirmation.tsx +55 -3
- 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/useSelectedFundMethod.tsx +41 -0
- package/src/widget/hooks/useSelectedRecipient.tsx +10 -0
- package/src/widget/hooks/useSendForm.ts +24 -2
- package/src/widget/index.css +27 -0
- package/src/widget/widget.tsx +169 -111
- 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
|
@@ -83,7 +83,7 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
|
|
|
83
83
|
|
|
84
84
|
{/* More Details Button - only visible when collapsed */}
|
|
85
85
|
{!isExpanded && (
|
|
86
|
-
<div className={`flex justify-center
|
|
86
|
+
<div className={`flex justify-center`}>
|
|
87
87
|
{swapMode ? (
|
|
88
88
|
<button
|
|
89
89
|
type="button"
|
|
@@ -161,10 +161,10 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
|
|
|
161
161
|
<button
|
|
162
162
|
type="button"
|
|
163
163
|
onClick={() => setIsExpanded(true)}
|
|
164
|
-
className="w-full flex items-center justify-
|
|
165
|
-
aria-label="Show
|
|
164
|
+
className="w-full max-w-md flex items-center justify-between gap-2 py-1 px-1 trails-border-radius-button transition-colors cursor-pointer text-xs text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300"
|
|
165
|
+
aria-label="Show transaction details"
|
|
166
166
|
>
|
|
167
|
-
<span>
|
|
167
|
+
<span>Transaction details</span>
|
|
168
168
|
<svg
|
|
169
169
|
className="w-3 h-3 transition-transform duration-300 ease-out"
|
|
170
170
|
fill="none"
|
|
@@ -191,9 +191,13 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
|
|
|
191
191
|
isExpanded ? "max-h-[250px] opacity-100" : "max-h-0 opacity-0"
|
|
192
192
|
}`}
|
|
193
193
|
>
|
|
194
|
-
<div
|
|
194
|
+
<div
|
|
195
|
+
className={`text-sm ${swapMode ? "p-2 space-y-2" : "p-4 rounded-lg space-y-4 trails-bg-secondary"}`}
|
|
196
|
+
>
|
|
195
197
|
{/* Close Button - only visible when expanded, at top center */}
|
|
196
|
-
<div
|
|
198
|
+
<div
|
|
199
|
+
className={`flex justify-center ${swapMode ? "mb-2 -mt-1" : "mb-4 -mt-2"}`}
|
|
200
|
+
>
|
|
197
201
|
{swapMode ? (
|
|
198
202
|
<button
|
|
199
203
|
type="button"
|
|
@@ -367,6 +371,7 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
|
|
|
367
371
|
imageUrl={quote.originToken.imageUrl}
|
|
368
372
|
symbol={quote.originToken.symbol}
|
|
369
373
|
chainId={quote.originChain.id}
|
|
374
|
+
contractAddress={quote.originToken.contractAddress}
|
|
370
375
|
size={16}
|
|
371
376
|
/>
|
|
372
377
|
{quote.originAmountDisplay} {quote.originToken.symbol}
|
|
@@ -393,6 +398,9 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
|
|
|
393
398
|
imageUrl={quote.originToken.imageUrl}
|
|
394
399
|
symbol={quote.originToken.symbol}
|
|
395
400
|
chainId={quote.originChain.id}
|
|
401
|
+
contractAddress={
|
|
402
|
+
quote.originToken.contractAddress
|
|
403
|
+
}
|
|
396
404
|
size={16}
|
|
397
405
|
/>
|
|
398
406
|
{quote.originAmountDisplay}{" "}
|
|
@@ -430,6 +438,9 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
|
|
|
430
438
|
imageUrl={quote.destinationToken.imageUrl}
|
|
431
439
|
symbol={quote.destinationToken.symbol}
|
|
432
440
|
chainId={quote.destinationChain.id}
|
|
441
|
+
contractAddress={
|
|
442
|
+
quote.destinationToken.contractAddress
|
|
443
|
+
}
|
|
433
444
|
size={16}
|
|
434
445
|
/>
|
|
435
446
|
{quote.destinationAmountDisplay}{" "}
|
|
@@ -457,6 +468,9 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
|
|
|
457
468
|
imageUrl={quote.destinationToken.imageUrl}
|
|
458
469
|
symbol={quote.destinationToken.symbol}
|
|
459
470
|
chainId={quote.destinationChain.id}
|
|
471
|
+
contractAddress={
|
|
472
|
+
quote.destinationToken.contractAddress
|
|
473
|
+
}
|
|
460
474
|
size={16}
|
|
461
475
|
/>
|
|
462
476
|
{quote.destinationAmountDisplay}{" "}
|
|
@@ -665,7 +679,7 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
|
|
|
665
679
|
</div>
|
|
666
680
|
)}
|
|
667
681
|
|
|
668
|
-
{quote?.quoteProvider && (
|
|
682
|
+
{quote?.quoteProvider?.name && (
|
|
669
683
|
<div className="flex justify-between items-center">
|
|
670
684
|
<span className="text-xs text-gray-600 dark:text-gray-400 flex items-center gap-1">
|
|
671
685
|
{quote.originChain.id === quote.destinationChain.id
|
|
@@ -766,7 +780,7 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
|
|
|
766
780
|
)}
|
|
767
781
|
|
|
768
782
|
{/* Children content */}
|
|
769
|
-
{children && <div className="
|
|
783
|
+
{children && <div className="mb-0">{children}</div>}
|
|
770
784
|
</div>
|
|
771
785
|
</div>
|
|
772
786
|
</div>
|
|
@@ -60,7 +60,6 @@ export const Receive: React.FC<ReceiveProps> = ({
|
|
|
60
60
|
onBack={onBack}
|
|
61
61
|
headerContent="Receive"
|
|
62
62
|
headerContentAlign="left"
|
|
63
|
-
showAccountActions={true}
|
|
64
63
|
/>
|
|
65
64
|
|
|
66
65
|
<div className="flex flex-col justify-center min-h-full space-y-6 pt-8">
|
|
@@ -97,7 +96,6 @@ export const Receive: React.FC<ReceiveProps> = ({
|
|
|
97
96
|
onBack={onBack}
|
|
98
97
|
headerContent={`Pay ${ensName ? ensName : truncateAddress(resolvedAddress)}`}
|
|
99
98
|
headerContentAlign="left"
|
|
100
|
-
showAccountActions={true}
|
|
101
99
|
/>
|
|
102
100
|
|
|
103
101
|
<div className="flex flex-col justify-center min-h-full space-y-6 pt-2">
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ChevronRight } from "lucide-react"
|
|
2
|
+
import type React from "react"
|
|
3
|
+
import { truncateAddress } from "../../utils.js"
|
|
4
|
+
import { Identicon } from "./Identicon.js"
|
|
5
|
+
import { useBack } from "../hooks/useBack.js"
|
|
6
|
+
import { useSelectedRecipient } from "../hooks/useSelectedRecipient.js"
|
|
7
|
+
|
|
8
|
+
export const RecipientSelectorButton: React.FC = () => {
|
|
9
|
+
const { setCurrentScreenWithBack } = useBack()
|
|
10
|
+
const { selectedRecipient } = useSelectedRecipient()
|
|
11
|
+
|
|
12
|
+
const handleClick = () => {
|
|
13
|
+
setCurrentScreenWithBack("recipients")
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<button
|
|
18
|
+
type="button"
|
|
19
|
+
onClick={handleClick}
|
|
20
|
+
className="flex items-center space-x-2 text-blue-500 hover:text-blue-600 transition-colors cursor-pointer bg-transparent border-none p-0"
|
|
21
|
+
title={
|
|
22
|
+
selectedRecipient
|
|
23
|
+
? `Selected: ${selectedRecipient}`
|
|
24
|
+
: "Select recipient"
|
|
25
|
+
}
|
|
26
|
+
>
|
|
27
|
+
{selectedRecipient ? (
|
|
28
|
+
<>
|
|
29
|
+
<Identicon value={selectedRecipient} size={16} />
|
|
30
|
+
<span className="text-sm font-medium">
|
|
31
|
+
{truncateAddress(selectedRecipient, 4, 2)}
|
|
32
|
+
</span>
|
|
33
|
+
</>
|
|
34
|
+
) : (
|
|
35
|
+
<span className="text-sm font-medium">Select Recipient</span>
|
|
36
|
+
)}
|
|
37
|
+
<ChevronRight className="w-4 h-4" />
|
|
38
|
+
</button>
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export default RecipientSelectorButton
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useEffect, useState, useCallback } from "react"
|
|
2
2
|
import type React from "react"
|
|
3
3
|
import { isAddress } from "viem"
|
|
4
|
-
import { Copy, RotateCcw } from "lucide-react"
|
|
4
|
+
import { Copy, RotateCcw, ChevronRight } from "lucide-react"
|
|
5
5
|
import { useAccount, useConnections } from "wagmi"
|
|
6
6
|
import { ScreenHeader } from "./ScreenHeader.js"
|
|
7
7
|
import { SearchInputField } from "./SearchInputField.js"
|
|
@@ -12,8 +12,8 @@ import { useRecipients, type RecentRecipient } from "../hooks/useRecipients.js"
|
|
|
12
12
|
import { useResolveEnsAddress, useResolveEnsName } from "../../ens.js"
|
|
13
13
|
import { truncateAddress } from "../../utils.js"
|
|
14
14
|
import { logger } from "../../logger.js"
|
|
15
|
-
import { useMode } from "../hooks/useMode.js"
|
|
16
15
|
import { useWallets, wagmiConnectorToWalletId } from "../../wallets.js"
|
|
16
|
+
import { ConnectedWallets } from "./ConnectedWallets.js"
|
|
17
17
|
|
|
18
18
|
interface RecipientsProps {
|
|
19
19
|
onBack?: () => void
|
|
@@ -26,7 +26,6 @@ export const Recipients: React.FC<RecipientsProps> = ({
|
|
|
26
26
|
selectedRecipient = "",
|
|
27
27
|
onRecipientSelect,
|
|
28
28
|
}) => {
|
|
29
|
-
const { mode } = useMode()
|
|
30
29
|
const { setCurrentScreen } = useCurrentScreen()
|
|
31
30
|
const { setSelectedRecipient } = useSelectedRecipient()
|
|
32
31
|
const { recentRecipients, addRecentRecipient, clearRecentRecipients } =
|
|
@@ -136,9 +135,9 @@ export const Recipients: React.FC<RecipientsProps> = ({
|
|
|
136
135
|
logger.console.log("[trails-sdk] Selected recent recipient:", recipient)
|
|
137
136
|
setSelectedRecipient(recipient.address)
|
|
138
137
|
onRecipientSelect?.(recipient.address)
|
|
139
|
-
setCurrentScreen(
|
|
138
|
+
setCurrentScreen("home")
|
|
140
139
|
},
|
|
141
|
-
[setSelectedRecipient, onRecipientSelect, setCurrentScreen
|
|
140
|
+
[setSelectedRecipient, onRecipientSelect, setCurrentScreen],
|
|
142
141
|
)
|
|
143
142
|
|
|
144
143
|
// Handle connected wallet selection
|
|
@@ -150,9 +149,9 @@ export const Recipients: React.FC<RecipientsProps> = ({
|
|
|
150
149
|
)
|
|
151
150
|
setSelectedRecipient(walletAddress)
|
|
152
151
|
onRecipientSelect?.(walletAddress)
|
|
153
|
-
setCurrentScreen(
|
|
152
|
+
setCurrentScreen("home")
|
|
154
153
|
},
|
|
155
|
-
[setSelectedRecipient, onRecipientSelect, setCurrentScreen
|
|
154
|
+
[setSelectedRecipient, onRecipientSelect, setCurrentScreen],
|
|
156
155
|
)
|
|
157
156
|
|
|
158
157
|
// Handle copy to clipboard with success indication
|
|
@@ -202,7 +201,6 @@ export const Recipients: React.FC<RecipientsProps> = ({
|
|
|
202
201
|
onBack={onBack}
|
|
203
202
|
headerContent="Recipient address"
|
|
204
203
|
headerContentAlign="left"
|
|
205
|
-
showAccountActions={true}
|
|
206
204
|
/>
|
|
207
205
|
|
|
208
206
|
<div className="space-y-4">
|
|
@@ -223,14 +221,23 @@ export const Recipients: React.FC<RecipientsProps> = ({
|
|
|
223
221
|
)}
|
|
224
222
|
</div>
|
|
225
223
|
|
|
224
|
+
{/* Connected Wallets - only show when no input */}
|
|
225
|
+
{connectedWallets.length > 0 && !recipientInput.trim() && (
|
|
226
|
+
<ConnectedWallets
|
|
227
|
+
showConnectNewWallet={true}
|
|
228
|
+
onWalletSelect={handleConnectedWalletSelect}
|
|
229
|
+
backScreen="recipients"
|
|
230
|
+
/>
|
|
231
|
+
)}
|
|
232
|
+
|
|
226
233
|
{/* Recent Recipients */}
|
|
227
234
|
{recentRecipients.length > 0 && (
|
|
228
235
|
<div className="space-y-2">
|
|
229
236
|
<div className="text-sm font-medium text-gray-700 dark:text-gray-300 text-left">
|
|
230
|
-
|
|
237
|
+
Recent wallets
|
|
231
238
|
</div>
|
|
232
|
-
<div className="
|
|
233
|
-
{recentRecipients.map((recipient) => {
|
|
239
|
+
<div className="trails-border-radius-container border trails-border-primary">
|
|
240
|
+
{recentRecipients.map((recipient, index) => {
|
|
234
241
|
// Only highlight if search field contains a valid address that matches this recipient
|
|
235
242
|
const searchQuery = recipientInput.trim()
|
|
236
243
|
const isHighlighted =
|
|
@@ -240,53 +247,51 @@ export const Recipients: React.FC<RecipientsProps> = ({
|
|
|
240
247
|
searchQuery.trim().toLowerCase()
|
|
241
248
|
|
|
242
249
|
return (
|
|
243
|
-
<
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
<div className="flex-1 min-w-0 text-left">
|
|
270
|
-
<div className="flex items-start">
|
|
271
|
-
<div className="flex-1">
|
|
272
|
-
<div className="flex items-center">
|
|
273
|
-
<span className="text-sm font-medium text-gray-900 dark:text-white">
|
|
250
|
+
<div key={recipient.address}>
|
|
251
|
+
<button
|
|
252
|
+
type="button"
|
|
253
|
+
className={`w-full text-left px-3 py-4 text-sm flex items-center justify-between cursor-pointer transition-colors ${
|
|
254
|
+
isHighlighted
|
|
255
|
+
? "trails-list-item-selected border border-blue-200 dark:border-blue-800"
|
|
256
|
+
: "trails-text-primary trails-hover-bg"
|
|
257
|
+
}`}
|
|
258
|
+
onClick={() => handleRecentRecipientSelect(recipient)}
|
|
259
|
+
onKeyDown={(e) => {
|
|
260
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
261
|
+
e.preventDefault()
|
|
262
|
+
handleRecentRecipientSelect(recipient)
|
|
263
|
+
}
|
|
264
|
+
}}
|
|
265
|
+
aria-label={`Select recipient ${recipient.ensName || recipient.address}`}
|
|
266
|
+
>
|
|
267
|
+
<div className="flex items-center gap-3">
|
|
268
|
+
<Identicon
|
|
269
|
+
value={recipient.address}
|
|
270
|
+
size={32}
|
|
271
|
+
className="flex-shrink-0"
|
|
272
|
+
/>
|
|
273
|
+
<div className="text-left">
|
|
274
|
+
<div className="flex items-center space-x-1">
|
|
275
|
+
<span className="text-sm font-bold">
|
|
274
276
|
{truncateAddress(recipient.address, 8, 4)}
|
|
275
277
|
</span>
|
|
276
|
-
<
|
|
277
|
-
|
|
278
|
-
|
|
278
|
+
<div
|
|
279
|
+
onClick={(e) => {
|
|
280
|
+
e.preventDefault()
|
|
281
|
+
e.stopPropagation()
|
|
279
282
|
handleCopyAddress(recipient.address, e)
|
|
280
|
-
}
|
|
281
|
-
|
|
283
|
+
}}
|
|
284
|
+
onMouseDown={(e) => e.stopPropagation()}
|
|
285
|
+
onMouseUp={(e) => e.stopPropagation()}
|
|
286
|
+
className={`p-0.5 rounded transition-all duration-200 cursor-pointer z-10 relative ${
|
|
282
287
|
copiedAddress === recipient.address
|
|
283
|
-
? "bg-green-100 dark:bg-green-900/30
|
|
288
|
+
? "bg-green-100 dark:bg-green-900/30"
|
|
284
289
|
: "hover:bg-gray-200 dark:hover:bg-gray-600"
|
|
285
290
|
}`}
|
|
286
291
|
title={
|
|
287
292
|
copiedAddress === recipient.address
|
|
288
293
|
? "Copied!"
|
|
289
|
-
: "Copy address"
|
|
294
|
+
: "Copy full address"
|
|
290
295
|
}
|
|
291
296
|
>
|
|
292
297
|
{copiedAddress === recipient.address ? (
|
|
@@ -308,7 +313,7 @@ export const Recipients: React.FC<RecipientsProps> = ({
|
|
|
308
313
|
) : (
|
|
309
314
|
<Copy className="w-3 h-3 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300" />
|
|
310
315
|
)}
|
|
311
|
-
</
|
|
316
|
+
</div>
|
|
312
317
|
</div>
|
|
313
318
|
{recipient.ensName && (
|
|
314
319
|
<div className="text-xs text-gray-500 dark:text-gray-400">
|
|
@@ -317,112 +322,13 @@ export const Recipients: React.FC<RecipientsProps> = ({
|
|
|
317
322
|
)}
|
|
318
323
|
</div>
|
|
319
324
|
</div>
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
{/* Connected Wallets - only show when no input */}
|
|
329
|
-
{connectedWallets.length > 0 && !recipientInput.trim() && (
|
|
330
|
-
<div className="space-y-2">
|
|
331
|
-
<div className="flex items-center gap-2">
|
|
332
|
-
<div className="text-sm font-medium text-gray-700 dark:text-gray-300 text-left">
|
|
333
|
-
Connected Wallets
|
|
334
|
-
</div>
|
|
335
|
-
</div>
|
|
336
|
-
<div className="space-y-1 max-h-48 overflow-y-auto trails-scrollbar">
|
|
337
|
-
{connectedWallets.map((wallet) => {
|
|
338
|
-
// Only highlight if search field contains a valid address that matches this wallet
|
|
339
|
-
const searchQuery = recipientInput.trim()
|
|
340
|
-
const isHighlighted =
|
|
341
|
-
searchQuery &&
|
|
342
|
-
isAddress(searchQuery) &&
|
|
343
|
-
wallet.address.toLowerCase() ===
|
|
344
|
-
searchQuery.trim().toLowerCase()
|
|
345
|
-
|
|
346
|
-
return (
|
|
347
|
-
<button
|
|
348
|
-
key={wallet.address}
|
|
349
|
-
type="button"
|
|
350
|
-
className={`w-full py-2 px-4 flex items-center space-x-3 transition-all duration-200 trails-border-radius-list-button cursor-pointer group ${
|
|
351
|
-
isHighlighted
|
|
352
|
-
? "trails-list-item-selected border border-blue-200 dark:border-blue-800"
|
|
353
|
-
: "trails-list-item"
|
|
354
|
-
}`}
|
|
355
|
-
onClick={() => handleConnectedWalletSelect(wallet.address)}
|
|
356
|
-
onKeyDown={(e) => {
|
|
357
|
-
if (e.key === "Enter" || e.key === " ") {
|
|
358
|
-
e.preventDefault()
|
|
359
|
-
handleConnectedWalletSelect(wallet.address)
|
|
360
|
-
}
|
|
361
|
-
}}
|
|
362
|
-
aria-label={`Select wallet ${wallet.walletConfig?.name || "Wallet"} - ${wallet.address}`}
|
|
363
|
-
>
|
|
364
|
-
{/* Identicon */}
|
|
365
|
-
<div className="relative flex-shrink-0 mr-2">
|
|
366
|
-
<Identicon
|
|
367
|
-
value={wallet.address}
|
|
368
|
-
size={32}
|
|
369
|
-
className="flex-shrink-0"
|
|
370
|
-
/>
|
|
371
|
-
</div>
|
|
372
|
-
|
|
373
|
-
<div className="flex-1 min-w-0 text-left">
|
|
374
|
-
<div className="flex items-start">
|
|
375
|
-
<div className="flex-1">
|
|
376
|
-
<div className="flex items-center">
|
|
377
|
-
<span className="text-sm font-medium text-gray-900 dark:text-white">
|
|
378
|
-
{truncateAddress(wallet.address, 8, 4)}
|
|
379
|
-
</span>
|
|
380
|
-
<button
|
|
381
|
-
type="button"
|
|
382
|
-
onClick={(e) =>
|
|
383
|
-
handleCopyAddress(wallet.address, e)
|
|
384
|
-
}
|
|
385
|
-
className={`ml-1 p-0.5 rounded opacity-0 group-hover:opacity-100 transition-all duration-200 cursor-pointer ${
|
|
386
|
-
copiedAddress === wallet.address
|
|
387
|
-
? "bg-green-100 dark:bg-green-900/30 opacity-100"
|
|
388
|
-
: "hover:bg-gray-200 dark:hover:bg-gray-600"
|
|
389
|
-
}`}
|
|
390
|
-
title={
|
|
391
|
-
copiedAddress === wallet.address
|
|
392
|
-
? "Copied!"
|
|
393
|
-
: "Copy address"
|
|
394
|
-
}
|
|
395
|
-
>
|
|
396
|
-
{copiedAddress === wallet.address ? (
|
|
397
|
-
<svg
|
|
398
|
-
className="w-3 h-3 text-green-600 dark:text-green-400"
|
|
399
|
-
fill="none"
|
|
400
|
-
viewBox="0 0 24 24"
|
|
401
|
-
stroke="currentColor"
|
|
402
|
-
aria-label="Copied"
|
|
403
|
-
>
|
|
404
|
-
<title>Copied</title>
|
|
405
|
-
<path
|
|
406
|
-
strokeLinecap="round"
|
|
407
|
-
strokeLinejoin="round"
|
|
408
|
-
strokeWidth={2}
|
|
409
|
-
d="M5 13l4 4L19 7"
|
|
410
|
-
/>
|
|
411
|
-
</svg>
|
|
412
|
-
) : (
|
|
413
|
-
<Copy className="w-3 h-3 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300" />
|
|
414
|
-
)}
|
|
415
|
-
</button>
|
|
416
|
-
</div>
|
|
417
|
-
<div className="text-xs text-gray-500 dark:text-gray-400">
|
|
418
|
-
{wallet.walletConfig?.name ||
|
|
419
|
-
wallet.connector?.name ||
|
|
420
|
-
"Wallet"}
|
|
421
|
-
</div>
|
|
422
|
-
</div>
|
|
423
|
-
</div>
|
|
424
|
-
</div>
|
|
425
|
-
</button>
|
|
325
|
+
<ChevronRight className="w-5 h-5 text-gray-400" />
|
|
326
|
+
</button>
|
|
327
|
+
{/* Add divider between items */}
|
|
328
|
+
{index < recentRecipients.length - 1 && (
|
|
329
|
+
<div className="border-b border-gray-200 dark:border-gray-700"></div>
|
|
330
|
+
)}
|
|
331
|
+
</div>
|
|
426
332
|
)
|
|
427
333
|
})}
|
|
428
334
|
</div>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type React from "react"
|
|
2
|
+
import { ErrorDisplay } from "./ErrorDisplay.js"
|
|
3
|
+
|
|
4
|
+
interface RequiredPropsErrorProps {
|
|
5
|
+
missingProps: string[]
|
|
6
|
+
componentName: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const RequiredPropsError: React.FC<RequiredPropsErrorProps> = ({
|
|
10
|
+
missingProps,
|
|
11
|
+
componentName,
|
|
12
|
+
}) => {
|
|
13
|
+
if (missingProps.length === 0) {
|
|
14
|
+
return null
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const isMultiple = missingProps.length > 1
|
|
18
|
+
|
|
19
|
+
const prettifiedMessage = `Missing required ${componentName} prop${isMultiple ? "s" : ""}`
|
|
20
|
+
|
|
21
|
+
const detailedMessage = `The following required props are missing for the ${componentName} component:
|
|
22
|
+
${missingProps.map((prop) => `- ${prop}`).join("\n")}
|
|
23
|
+
|
|
24
|
+
Please ensure all required props are provided when rendering the ${componentName} component.`
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<ErrorDisplay
|
|
28
|
+
errorPrettified={prettifiedMessage}
|
|
29
|
+
error={detailedMessage}
|
|
30
|
+
severity="error"
|
|
31
|
+
/>
|
|
32
|
+
)
|
|
33
|
+
}
|
|
@@ -2,6 +2,7 @@ import { ChevronLeft } from "lucide-react"
|
|
|
2
2
|
import type React from "react"
|
|
3
3
|
import { useAccount } from "wagmi"
|
|
4
4
|
import AccountActionsDropdown from "./AccountActionsDropdown.js"
|
|
5
|
+
import { useWidgetProps } from "../hooks/useWidgetProps.js"
|
|
5
6
|
|
|
6
7
|
interface ScreenHeaderProps {
|
|
7
8
|
onBack?: () => void
|
|
@@ -20,6 +21,7 @@ export const ScreenHeader: React.FC<ScreenHeaderProps> = ({
|
|
|
20
21
|
showAccountActions = false,
|
|
21
22
|
}) => {
|
|
22
23
|
const { isConnected } = useAccount()
|
|
24
|
+
const { renderInline } = useWidgetProps()
|
|
23
25
|
return (
|
|
24
26
|
<div className="relative w-full mb-4">
|
|
25
27
|
{/* Left side - Back button (absolute positioned) */}
|
|
@@ -48,7 +50,9 @@ export const ScreenHeader: React.FC<ScreenHeaderProps> = ({
|
|
|
48
50
|
|
|
49
51
|
{/* Right side - Optional content and Account Actions */}
|
|
50
52
|
{(rightSideContent || (isConnected && showAccountActions)) && (
|
|
51
|
-
<div
|
|
53
|
+
<div
|
|
54
|
+
className={`absolute ${renderInline ? "right-0" : "right-8"} top-1/2 -translate-y-1/2 -translate-x-0 flex items-center gap-2 z-10`}
|
|
55
|
+
>
|
|
52
56
|
{rightSideContent && (
|
|
53
57
|
<div className="text-right max-w-[280px]">{rightSideContent}</div>
|
|
54
58
|
)}
|
|
@@ -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
|
|
@@ -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>
|