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,5 +1,6 @@
|
|
|
1
1
|
import { TokenImage } from "./TokenImage.js"
|
|
2
|
-
import { InfoIcon
|
|
2
|
+
import { InfoIcon } from "@0xsequence/design-system"
|
|
3
|
+
import { Tooltip } from "./Tooltip.js"
|
|
3
4
|
import type React from "react"
|
|
4
5
|
import { getExplorerUrlForAddress } from "../../explorer.js"
|
|
5
6
|
import type { PrepareSendQuote } from "../../prepareSend.js"
|
|
@@ -7,6 +8,7 @@ import { useState, useEffect, useRef } from "react"
|
|
|
7
8
|
import { truncateAddress } from "../../utils.js"
|
|
8
9
|
import { PriceImpactWarning } from "./PriceImpactWarning.js"
|
|
9
10
|
import { usePriceImpactWarning } from "../hooks/usePriceImpactWarning.js"
|
|
11
|
+
import { FeeBreakdown } from "./FeeBreakdown.js"
|
|
10
12
|
|
|
11
13
|
interface QuoteDetailsProps {
|
|
12
14
|
quote?: PrepareSendQuote | null
|
|
@@ -14,6 +16,7 @@ interface QuoteDetailsProps {
|
|
|
14
16
|
children?: React.ReactNode
|
|
15
17
|
onExpand?: (isExpanded: boolean) => void
|
|
16
18
|
swapMode?: boolean
|
|
19
|
+
compact?: boolean
|
|
17
20
|
}
|
|
18
21
|
|
|
19
22
|
// Helper function to format completion time
|
|
@@ -44,6 +47,7 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
|
|
|
44
47
|
children,
|
|
45
48
|
onExpand,
|
|
46
49
|
swapMode,
|
|
50
|
+
compact = false,
|
|
47
51
|
}) => {
|
|
48
52
|
const [showCalldata, setShowCalldata] = useState(false)
|
|
49
53
|
const [showOriginRate, setShowOriginRate] = useState(true)
|
|
@@ -83,12 +87,12 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
|
|
|
83
87
|
|
|
84
88
|
{/* More Details Button - only visible when collapsed */}
|
|
85
89
|
{!isExpanded && (
|
|
86
|
-
<div className={`flex justify-center
|
|
90
|
+
<div className={`flex justify-center`}>
|
|
87
91
|
{swapMode ? (
|
|
88
92
|
<button
|
|
89
93
|
type="button"
|
|
90
94
|
onClick={() => setIsExpanded(true)}
|
|
91
|
-
className="w-full flex items-center justify-between py-2 px-4 trails-border-radius-button transition-colors cursor-pointer text-xs
|
|
95
|
+
className="w-full flex items-center justify-between py-2 px-4 trails-border-radius-button transition-colors cursor-pointer text-xs"
|
|
92
96
|
aria-label="Show more details"
|
|
93
97
|
>
|
|
94
98
|
<div className="flex items-center gap-2 text-gray-600 dark:text-gray-400 whitespace-nowrap max-w-48 truncate">
|
|
@@ -161,10 +165,10 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
|
|
|
161
165
|
<button
|
|
162
166
|
type="button"
|
|
163
167
|
onClick={() => setIsExpanded(true)}
|
|
164
|
-
className=
|
|
165
|
-
aria-label="Show
|
|
168
|
+
className={`w-full max-w-md flex items-center ${compact ? "justify-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`}
|
|
169
|
+
aria-label="Show transaction details"
|
|
166
170
|
>
|
|
167
|
-
<span>
|
|
171
|
+
<span>Transaction details</span>
|
|
168
172
|
<svg
|
|
169
173
|
className="w-3 h-3 transition-transform duration-300 ease-out"
|
|
170
174
|
fill="none"
|
|
@@ -191,9 +195,11 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
|
|
|
191
195
|
isExpanded ? "max-h-[250px] opacity-100" : "max-h-0 opacity-0"
|
|
192
196
|
}`}
|
|
193
197
|
>
|
|
194
|
-
<div
|
|
198
|
+
<div
|
|
199
|
+
className={`text-sm ${swapMode ? "p-2 space-y-2" : "p-4 rounded-lg space-y-4 trails-bg-secondary"}`}
|
|
200
|
+
>
|
|
195
201
|
{/* Close Button - only visible when expanded, at top center */}
|
|
196
|
-
<div className=
|
|
202
|
+
<div className={`flex justify-center mb-4 -mt-2`}>
|
|
197
203
|
{swapMode ? (
|
|
198
204
|
<button
|
|
199
205
|
type="button"
|
|
@@ -367,6 +373,7 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
|
|
|
367
373
|
imageUrl={quote.originToken.imageUrl}
|
|
368
374
|
symbol={quote.originToken.symbol}
|
|
369
375
|
chainId={quote.originChain.id}
|
|
376
|
+
contractAddress={quote.originToken.contractAddress}
|
|
370
377
|
size={16}
|
|
371
378
|
/>
|
|
372
379
|
{quote.originAmountDisplay} {quote.originToken.symbol}
|
|
@@ -393,6 +400,9 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
|
|
|
393
400
|
imageUrl={quote.originToken.imageUrl}
|
|
394
401
|
symbol={quote.originToken.symbol}
|
|
395
402
|
chainId={quote.originChain.id}
|
|
403
|
+
contractAddress={
|
|
404
|
+
quote.originToken.contractAddress
|
|
405
|
+
}
|
|
396
406
|
size={16}
|
|
397
407
|
/>
|
|
398
408
|
{quote.originAmountDisplay}{" "}
|
|
@@ -430,6 +440,9 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
|
|
|
430
440
|
imageUrl={quote.destinationToken.imageUrl}
|
|
431
441
|
symbol={quote.destinationToken.symbol}
|
|
432
442
|
chainId={quote.destinationChain.id}
|
|
443
|
+
contractAddress={
|
|
444
|
+
quote.destinationToken.contractAddress
|
|
445
|
+
}
|
|
433
446
|
size={16}
|
|
434
447
|
/>
|
|
435
448
|
{quote.destinationAmountDisplay}{" "}
|
|
@@ -457,6 +470,9 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
|
|
|
457
470
|
imageUrl={quote.destinationToken.imageUrl}
|
|
458
471
|
symbol={quote.destinationToken.symbol}
|
|
459
472
|
chainId={quote.destinationChain.id}
|
|
473
|
+
contractAddress={
|
|
474
|
+
quote.destinationToken.contractAddress
|
|
475
|
+
}
|
|
460
476
|
size={16}
|
|
461
477
|
/>
|
|
462
478
|
{quote.destinationAmountDisplay}{" "}
|
|
@@ -651,7 +667,22 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
|
|
|
651
667
|
)
|
|
652
668
|
})()}
|
|
653
669
|
|
|
654
|
-
{
|
|
670
|
+
{/* Total Fees with optional breakdown */}
|
|
671
|
+
{quote?.trailsFeeBreakdown ? (
|
|
672
|
+
<FeeBreakdown feeBreakdown={quote.trailsFeeBreakdown}>
|
|
673
|
+
<div className="flex justify-between items-center w-full">
|
|
674
|
+
<span className="text-xs text-gray-600 dark:text-gray-400 flex items-center gap-1 w-full">
|
|
675
|
+
Total Fees:
|
|
676
|
+
<Tooltip message="The total fees charged for this transaction, including gas fees, bridge fees, and any platform fees. These fees are deducted from your transaction.">
|
|
677
|
+
<InfoIcon className="w-3 h-3 text-gray-500 dark:text-gray-400 cursor-pointer" />
|
|
678
|
+
</Tooltip>
|
|
679
|
+
</span>
|
|
680
|
+
<span className="font-medium text-xs text-gray-900 dark:text-white">
|
|
681
|
+
{quote.fees.totalFeeAmountUsdDisplay}
|
|
682
|
+
</span>
|
|
683
|
+
</div>
|
|
684
|
+
</FeeBreakdown>
|
|
685
|
+
) : quote?.fees?.totalFeeAmountUsd != null ? (
|
|
655
686
|
<div className="flex justify-between items-center">
|
|
656
687
|
<span className="text-xs text-gray-600 dark:text-gray-400 flex items-center gap-1">
|
|
657
688
|
Total Fees:
|
|
@@ -663,9 +694,9 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
|
|
|
663
694
|
{quote.fees.totalFeeAmountUsdDisplay}
|
|
664
695
|
</span>
|
|
665
696
|
</div>
|
|
666
|
-
)}
|
|
697
|
+
) : null}
|
|
667
698
|
|
|
668
|
-
{quote?.quoteProvider && (
|
|
699
|
+
{quote?.quoteProvider?.name && (
|
|
669
700
|
<div className="flex justify-between items-center">
|
|
670
701
|
<span className="text-xs text-gray-600 dark:text-gray-400 flex items-center gap-1">
|
|
671
702
|
{quote.originChain.id === quote.destinationChain.id
|
|
@@ -766,7 +797,7 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
|
|
|
766
797
|
)}
|
|
767
798
|
|
|
768
799
|
{/* Children content */}
|
|
769
|
-
{children && <div className="
|
|
800
|
+
{children && <div className="mb-0">{children}</div>}
|
|
770
801
|
</div>
|
|
771
802
|
</div>
|
|
772
803
|
</div>
|
|
@@ -13,6 +13,7 @@ import { truncateAddress } from "../../utils.js"
|
|
|
13
13
|
import { formatElapsed } from "../../utils.js"
|
|
14
14
|
import { ChainImage } from "./ChainImage.js"
|
|
15
15
|
import { getChainInfo } from "../../chains.js"
|
|
16
|
+
import { useMode } from "../hooks/useMode.js"
|
|
16
17
|
|
|
17
18
|
interface ReceiptProps {
|
|
18
19
|
onSendAnother: () => void
|
|
@@ -86,6 +87,7 @@ export const Receipt: React.FC<ReceiptProps> = ({
|
|
|
86
87
|
quote,
|
|
87
88
|
showCloseButton,
|
|
88
89
|
}) => {
|
|
90
|
+
const { mode } = useMode()
|
|
89
91
|
const [showContent, setShowContent] = useState(false)
|
|
90
92
|
const [showRefundInfo, setShowRefundInfo] = useState(false)
|
|
91
93
|
const [refundMessage, setRefundMessage] = useState<string | ReactNode | null>(
|
|
@@ -111,6 +113,18 @@ export const Receipt: React.FC<ReceiptProps> = ({
|
|
|
111
113
|
return transactionStates.some((tx) => hasMetaTxError(tx))
|
|
112
114
|
}, [transactionStates, hasMetaTxError])
|
|
113
115
|
|
|
116
|
+
const buttonText = useMemo(() => {
|
|
117
|
+
if (mode === "pay") {
|
|
118
|
+
return "Pay Again"
|
|
119
|
+
} else if (mode === "fund") {
|
|
120
|
+
return "Fund Again"
|
|
121
|
+
} else if (mode === "swap") {
|
|
122
|
+
return "Swap Again"
|
|
123
|
+
} else {
|
|
124
|
+
return "Send Again"
|
|
125
|
+
}
|
|
126
|
+
}, [mode])
|
|
127
|
+
|
|
114
128
|
const {
|
|
115
129
|
finalExplorerUrl,
|
|
116
130
|
finalChainId,
|
|
@@ -154,7 +168,7 @@ export const Receipt: React.FC<ReceiptProps> = ({
|
|
|
154
168
|
// Extract QuoteDetails section to reuse in both success and failure states
|
|
155
169
|
const quoteDetailsSection = quote && (
|
|
156
170
|
<div className="mt-2">
|
|
157
|
-
<QuoteDetails quote={quote} showContent={true}>
|
|
171
|
+
<QuoteDetails quote={quote} showContent={true} compact={true}>
|
|
158
172
|
{transactionStates.length > 0 && (
|
|
159
173
|
<>
|
|
160
174
|
<div className="font-medium text-gray-700 dark:text-gray-300">
|
|
@@ -477,7 +491,7 @@ export const Receipt: React.FC<ReceiptProps> = ({
|
|
|
477
491
|
onClick={onSendAnother}
|
|
478
492
|
className="inline-flex items-center gap-1 px-4 py-2 text-sm bg-gray-100 hover:bg-gray-200 dark:bg-gray-700 dark:hover:bg-gray-600 trails-border-radius-button transition-colors duration-200 text-gray-600 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 cursor-pointer font-medium"
|
|
479
493
|
>
|
|
480
|
-
|
|
494
|
+
{buttonText}
|
|
481
495
|
<ChevronRight className="w-4 h-4" />
|
|
482
496
|
</button>
|
|
483
497
|
</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,44 @@
|
|
|
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
|
+
<div className="flex items-center mr-1">
|
|
30
|
+
<Identicon value={selectedRecipient} size={16} />
|
|
31
|
+
</div>
|
|
32
|
+
<span className="text-sm font-medium m-0">
|
|
33
|
+
{truncateAddress(selectedRecipient, 4, 4)}
|
|
34
|
+
</span>
|
|
35
|
+
</>
|
|
36
|
+
) : (
|
|
37
|
+
<span className="text-sm font-medium m-0">Select Recipient</span>
|
|
38
|
+
)}
|
|
39
|
+
<ChevronRight className="w-4 h-4 m-0" />
|
|
40
|
+
</button>
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
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
|
-
<div className="text-sm font-medium text-gray-
|
|
230
|
-
|
|
236
|
+
<div className="text-sm font-medium text-gray-900 dark:text-gray-100 text-left">
|
|
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
|
+
}
|