0xtrails 0.1.2 → 0.1.4
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/address.d.ts.map +1 -1
- package/dist/analytics.d.ts +86 -1
- package/dist/analytics.d.ts.map +1 -1
- package/dist/apiClient.d.ts +1 -1
- package/dist/apiClient.d.ts.map +1 -1
- package/dist/{ccip-BmFTEOaB.js → ccip-dLSEJjCf.js} +55 -55
- package/dist/cctpqueue.d.ts +1 -1
- package/dist/cctpqueue.d.ts.map +1 -1
- package/dist/chains.d.ts +9 -3
- package/dist/chains.d.ts.map +1 -1
- package/dist/constants.d.ts +1 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/decoders.d.ts +58 -0
- package/dist/decoders.d.ts.map +1 -0
- package/dist/ens.d.ts +13 -0
- package/dist/ens.d.ts.map +1 -0
- package/dist/error.d.ts +9 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/{index-BPsVj7zK.js → index-BXbaLmtt.js} +28779 -25738
- package/dist/index.js +2 -2
- package/dist/intents.d.ts +4 -4
- package/dist/intents.d.ts.map +1 -1
- package/dist/lifi.d.ts +4 -0
- package/dist/lifi.d.ts.map +1 -0
- package/dist/metaTxns.d.ts +1 -1
- package/dist/metaTxns.d.ts.map +1 -1
- package/dist/mode.d.ts +1 -1
- package/dist/mode.d.ts.map +1 -1
- package/dist/preconditions.d.ts +1 -1
- package/dist/preconditions.d.ts.map +1 -1
- package/dist/prepareSend.d.ts +32 -24
- package/dist/prepareSend.d.ts.map +1 -1
- package/dist/prices.d.ts +3 -1
- package/dist/prices.d.ts.map +1 -1
- package/dist/proxyCaller.d.ts +0 -1
- package/dist/proxyCaller.d.ts.map +1 -1
- package/dist/relaySdk.d.ts.map +1 -1
- package/dist/relayer.d.ts.map +1 -1
- package/dist/tokenBalances.d.ts +1 -1
- package/dist/tokenBalances.d.ts.map +1 -1
- package/dist/tokens.d.ts +2 -1
- package/dist/tokens.d.ts.map +1 -1
- package/dist/trails.d.ts +4 -4
- package/dist/trails.d.ts.map +1 -1
- package/dist/transactions.d.ts +4 -0
- package/dist/transactions.d.ts.map +1 -1
- package/dist/utils.d.ts +6 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/wallets.d.ts +247 -5
- package/dist/wallets.d.ts.map +1 -1
- package/dist/widget/components/ChainFilterDropdown.d.ts +2 -0
- package/dist/widget/components/ChainFilterDropdown.d.ts.map +1 -1
- package/dist/widget/components/ConnectWallet.d.ts +1 -0
- package/dist/widget/components/ConnectWallet.d.ts.map +1 -1
- package/dist/widget/components/DebugScreensDropdown.d.ts.map +1 -1
- package/dist/widget/components/ErrorDisplay.d.ts +9 -0
- package/dist/widget/components/ErrorDisplay.d.ts.map +1 -0
- package/dist/widget/components/FundSendForm.d.ts +2 -2
- package/dist/widget/components/FundSendForm.d.ts.map +1 -1
- package/dist/widget/components/OriginTransferInformation.d.ts +10 -0
- package/dist/widget/components/OriginTransferInformation.d.ts.map +1 -0
- package/dist/widget/components/PaySendForm.d.ts +2 -2
- package/dist/widget/components/PaySendForm.d.ts.map +1 -1
- package/dist/widget/components/QrCode.d.ts +1 -1
- package/dist/widget/components/QrCode.d.ts.map +1 -1
- 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 +12 -0
- package/dist/widget/components/Receive.d.ts.map +1 -0
- package/dist/widget/components/RefundAddressInput.d.ts +13 -0
- package/dist/widget/components/RefundAddressInput.d.ts.map +1 -0
- package/dist/widget/components/Swap.d.ts +47 -0
- package/dist/widget/components/Swap.d.ts.map +1 -0
- package/dist/widget/components/SwapDisplay.d.ts +9 -0
- package/dist/widget/components/SwapDisplay.d.ts.map +1 -0
- package/dist/widget/components/TokenList.d.ts +0 -2
- package/dist/widget/components/TokenList.d.ts.map +1 -1
- package/dist/widget/components/TokenSelector.d.ts +26 -0
- package/dist/widget/components/TokenSelector.d.ts.map +1 -0
- package/dist/widget/components/TransferPendingVertical.d.ts +2 -0
- package/dist/widget/components/TransferPendingVertical.d.ts.map +1 -1
- package/dist/widget/components/WalletConnect.d.ts.map +1 -1
- package/dist/widget/components/WalletConnectionPending.d.ts +12 -0
- package/dist/widget/components/WalletConnectionPending.d.ts.map +1 -0
- package/dist/widget/components/WalletList.d.ts.map +1 -1
- package/dist/widget/components/YellowWarningAnimation.d.ts +2 -0
- package/dist/widget/components/YellowWarningAnimation.d.ts.map +1 -0
- package/dist/widget/hooks/useAmountUsd.d.ts +1 -3
- package/dist/widget/hooks/useAmountUsd.d.ts.map +1 -1
- package/dist/widget/hooks/useCheckout.d.ts.map +1 -1
- package/dist/widget/hooks/useDebugScreens.d.ts +22 -0
- package/dist/widget/hooks/useDebugScreens.d.ts.map +1 -0
- package/dist/widget/hooks/useSendForm.d.ts +12 -6
- package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
- package/dist/widget/hooks/useTokenList.d.ts +2 -3
- package/dist/widget/hooks/useTokenList.d.ts.map +1 -1
- package/dist/widget/index.js +1 -1
- package/dist/widget/widget.d.ts.map +1 -1
- package/package.json +19 -15
- package/src/aave.ts +13 -13
- package/src/address.ts +3 -0
- package/src/analytics.ts +192 -8
- package/src/apiClient.ts +1 -1
- package/src/cctpqueue.ts +1 -1
- package/src/chains.ts +45 -7
- package/src/constants.ts +7 -4
- package/src/decoders.ts +310 -0
- package/src/ens.ts +32 -0
- package/src/error.ts +101 -1
- package/src/intents.ts +10 -2
- package/src/lifi.ts +58 -0
- package/src/metaTxns.ts +1 -1
- package/src/mode.ts +1 -1
- package/src/morpho.ts +3 -3
- package/src/pools.ts +18 -18
- package/src/preconditions.ts +1 -1
- package/src/prepareSend.ts +463 -113
- package/src/prices.ts +26 -1
- package/src/proxyCaller.ts +2 -14
- package/src/relaySdk.ts +1 -0
- package/src/relayer.ts +8 -0
- package/src/tokenBalances.ts +24 -17
- package/src/tokens.ts +147 -22
- package/src/trails.ts +4 -4
- package/src/transactions.ts +35 -17
- package/src/utils.ts +28 -0
- package/src/wallets.ts +275 -35
- package/src/widget/compiled.css +2 -2
- package/src/widget/components/ChainFilterDropdown.tsx +42 -33
- package/src/widget/components/ChainImage.tsx +1 -1
- package/src/widget/components/ConnectWallet.tsx +92 -128
- package/src/widget/components/DebugScreensDropdown.tsx +6 -0
- package/src/widget/components/ErrorDisplay.tsx +150 -0
- package/src/widget/components/FundSendForm.tsx +78 -11
- package/src/widget/components/OriginTransferInformation.tsx +59 -0
- package/src/widget/components/PaySendForm.tsx +80 -13
- package/src/widget/components/QRCodeDeposit.tsx +6 -6
- package/src/widget/components/QrCode.tsx +278 -17
- package/src/widget/components/QuoteDetails.tsx +93 -25
- package/src/widget/components/Receipt.tsx +296 -103
- package/src/widget/components/Receive.tsx +146 -0
- package/src/widget/components/RecentTokens.tsx +1 -1
- package/src/widget/components/RefundAddressInput.tsx +149 -0
- package/src/widget/components/Swap.tsx +769 -0
- package/src/widget/components/SwapDisplay.tsx +68 -0
- package/src/widget/components/TokenList.tsx +27 -363
- package/src/widget/components/TokenSelector.tsx +405 -0
- package/src/widget/components/TransferPendingVertical.tsx +162 -112
- package/src/widget/components/WalletConnect.tsx +9 -7
- package/src/widget/components/WalletConnectionPending.tsx +157 -0
- package/src/widget/components/WalletList.tsx +6 -5
- package/src/widget/components/YellowWarningAnimation.tsx +146 -0
- package/src/widget/hooks/useAmountUsd.ts +3 -8
- package/src/widget/hooks/useCheckout.ts +3 -2
- package/src/widget/hooks/useDebugScreens.ts +583 -0
- package/src/widget/hooks/useSendForm.ts +111 -35
- package/src/widget/hooks/useTokenList.ts +155 -122
- package/src/widget/widget.tsx +503 -523
|
@@ -390,7 +390,7 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
|
|
|
390
390
|
</div>
|
|
391
391
|
)}
|
|
392
392
|
|
|
393
|
-
{quote?.
|
|
393
|
+
{quote?.originDepositAddress && (
|
|
394
394
|
<div className="flex justify-between items-center">
|
|
395
395
|
<span className="text-xs text-gray-600 dark:text-gray-400 flex items-center gap-1">
|
|
396
396
|
Origin Deposit Address:
|
|
@@ -400,14 +400,14 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
|
|
|
400
400
|
</span>
|
|
401
401
|
<a
|
|
402
402
|
href={getExplorerUrlForAddress({
|
|
403
|
-
address: quote.
|
|
403
|
+
address: quote.originDepositAddress,
|
|
404
404
|
chainId: quote.originChain.id,
|
|
405
405
|
})}
|
|
406
406
|
target="_blank"
|
|
407
407
|
rel="noopener noreferrer"
|
|
408
408
|
className="font-mono text-xs hover:underline flex items-center gap-1 text-gray-700 dark:text-gray-300"
|
|
409
409
|
>
|
|
410
|
-
{truncateAddress(quote.
|
|
410
|
+
{truncateAddress(quote.originDepositAddress)}
|
|
411
411
|
<svg
|
|
412
412
|
className="w-3 h-3"
|
|
413
413
|
fill="none"
|
|
@@ -426,11 +426,49 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
|
|
|
426
426
|
</div>
|
|
427
427
|
)}
|
|
428
428
|
|
|
429
|
+
{quote?.destinationDepositAddress &&
|
|
430
|
+
quote?.destinationDepositAddress !==
|
|
431
|
+
quote?.originDepositAddress && (
|
|
432
|
+
<div className="flex justify-between items-center">
|
|
433
|
+
<span className="text-xs text-gray-600 dark:text-gray-400 flex items-center gap-1">
|
|
434
|
+
Destination Deposit Address:
|
|
435
|
+
<Tooltip message="This is the address that will receive the tokens after any swap and/or bridge from the origin chain">
|
|
436
|
+
<InfoIcon className="w-3 h-3 text-gray-500 dark:text-gray-400 cursor-pointer" />
|
|
437
|
+
</Tooltip>
|
|
438
|
+
</span>
|
|
439
|
+
<a
|
|
440
|
+
href={getExplorerUrlForAddress({
|
|
441
|
+
address: quote.destinationDepositAddress,
|
|
442
|
+
chainId: quote.destinationChain.id,
|
|
443
|
+
})}
|
|
444
|
+
target="_blank"
|
|
445
|
+
rel="noopener noreferrer"
|
|
446
|
+
className="font-mono text-xs hover:underline flex items-center gap-1 text-gray-700 dark:text-gray-300"
|
|
447
|
+
>
|
|
448
|
+
{truncateAddress(quote.destinationDepositAddress)}
|
|
449
|
+
<svg
|
|
450
|
+
className="w-3 h-3"
|
|
451
|
+
fill="none"
|
|
452
|
+
stroke="currentColor"
|
|
453
|
+
viewBox="0 0 24 24"
|
|
454
|
+
aria-hidden="true"
|
|
455
|
+
>
|
|
456
|
+
<path
|
|
457
|
+
strokeLinecap="round"
|
|
458
|
+
strokeLinejoin="round"
|
|
459
|
+
strokeWidth={2}
|
|
460
|
+
d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
|
|
461
|
+
/>
|
|
462
|
+
</svg>
|
|
463
|
+
</a>
|
|
464
|
+
</div>
|
|
465
|
+
)}
|
|
466
|
+
|
|
429
467
|
{quote?.destinationAddress && (
|
|
430
468
|
<div className="flex justify-between items-center">
|
|
431
469
|
<span className="text-xs text-gray-600 dark:text-gray-400 flex items-center gap-1">
|
|
432
470
|
Destination Target Address:
|
|
433
|
-
<Tooltip message="This is the
|
|
471
|
+
<Tooltip message="This is the final execution address or recipient address">
|
|
434
472
|
<InfoIcon className="w-3 h-3 text-gray-500 dark:text-gray-400 cursor-pointer" />
|
|
435
473
|
</Tooltip>
|
|
436
474
|
</span>
|
|
@@ -476,28 +514,58 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
|
|
|
476
514
|
</div>
|
|
477
515
|
)}
|
|
478
516
|
|
|
479
|
-
{quote?.priceImpact != null &&
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
<
|
|
485
|
-
<
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
517
|
+
{quote?.priceImpact != null &&
|
|
518
|
+
(() => {
|
|
519
|
+
const priceImpactNum = Math.abs(Number(quote.priceImpact))
|
|
520
|
+
return (
|
|
521
|
+
<div className="space-y-1">
|
|
522
|
+
<div className="flex justify-between items-center">
|
|
523
|
+
<span className="text-xs text-gray-600 dark:text-gray-400 flex items-center gap-1">
|
|
524
|
+
Price Impact:
|
|
525
|
+
<Tooltip message="The percentage change in the token price caused by your trade. Higher impact means your trade affects the market price more, potentially resulting in worse rates.">
|
|
526
|
+
<InfoIcon className="w-3 h-3 text-gray-500 dark:text-gray-400 cursor-pointer" />
|
|
527
|
+
</Tooltip>
|
|
528
|
+
</span>
|
|
529
|
+
<span
|
|
530
|
+
className={`font-medium text-xs flex items-center gap-1 ${
|
|
531
|
+
priceImpactNum > 5
|
|
532
|
+
? "text-red-600 dark:text-red-400"
|
|
533
|
+
: priceImpactNum > 0.5
|
|
534
|
+
? "text-orange-600 dark:text-orange-400"
|
|
535
|
+
: "text-gray-900 dark:text-white"
|
|
536
|
+
}`}
|
|
537
|
+
>
|
|
538
|
+
{priceImpactNum > 0.5 && (
|
|
539
|
+
<span title="High price impact">
|
|
540
|
+
<svg
|
|
541
|
+
className="w-3 h-3"
|
|
542
|
+
fill="none"
|
|
543
|
+
stroke="currentColor"
|
|
544
|
+
viewBox="0 0 24 24"
|
|
545
|
+
aria-hidden="true"
|
|
546
|
+
>
|
|
547
|
+
<path
|
|
548
|
+
strokeLinecap="round"
|
|
549
|
+
strokeLinejoin="round"
|
|
550
|
+
strokeWidth={2}
|
|
551
|
+
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"
|
|
552
|
+
/>
|
|
553
|
+
</svg>
|
|
554
|
+
</span>
|
|
555
|
+
)}
|
|
556
|
+
{quote.priceImpact}%
|
|
557
|
+
</span>
|
|
558
|
+
</div>
|
|
559
|
+
{quote.priceImpactUsdDisplay && (
|
|
560
|
+
<div className="text-right">
|
|
561
|
+
<span className="text-xs text-gray-500 dark:text-gray-400">
|
|
562
|
+
≈ {quote.priceImpactUsdDisplay}
|
|
563
|
+
</span>
|
|
564
|
+
</div>
|
|
565
|
+
)}
|
|
497
566
|
</div>
|
|
498
|
-
)
|
|
499
|
-
|
|
500
|
-
)}
|
|
567
|
+
)
|
|
568
|
+
})()}
|
|
501
569
|
|
|
502
570
|
{quote?.fees?.totalFeeAmountUsd != null && (
|
|
503
571
|
<div className="flex justify-between items-center">
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { useQuery } from "@tanstack/react-query"
|
|
2
2
|
import type React from "react"
|
|
3
|
-
import { useEffect, useState } from "react"
|
|
3
|
+
import { useEffect, useState, useCallback, useMemo } from "react"
|
|
4
|
+
import { ChevronRight } from "lucide-react"
|
|
4
5
|
import type { TransactionState } from "../../transactions.js"
|
|
5
6
|
import { GreenCheckAnimation } from "./GreenCheckAnimation.js"
|
|
7
|
+
import { YellowWarningAnimation } from "./YellowWarningAnimation.js"
|
|
6
8
|
import { getTxTimeDiff } from "../../transactions.js"
|
|
7
9
|
import { QuoteDetails } from "./QuoteDetails.js"
|
|
8
10
|
import type { PrepareSendQuote } from "../../prepareSend.js"
|
|
9
11
|
import { truncateAddress } from "../../address.js"
|
|
10
12
|
import { formatElapsed } from "../../utils.js"
|
|
13
|
+
import { ChainImage } from "./ChainImage.js"
|
|
11
14
|
|
|
12
15
|
interface ReceiptProps {
|
|
13
16
|
onSendAnother: () => void
|
|
@@ -55,8 +58,9 @@ function useTxTimeDiff(firstTx?: TransactionState, lastTx?: TransactionState) {
|
|
|
55
58
|
|
|
56
59
|
// Custom hook to compute finalExplorerUrl and completionTimeSeconds
|
|
57
60
|
function useReceipt(transactionStates?: TransactionState[]) {
|
|
58
|
-
const
|
|
59
|
-
|
|
61
|
+
const lastTx = transactionStates?.[transactionStates.length - 1]
|
|
62
|
+
const finalExplorerUrl = lastTx?.explorerUrl
|
|
63
|
+
const finalChainId = lastTx?.chainId
|
|
60
64
|
|
|
61
65
|
// Only consider confirmed transactions
|
|
62
66
|
const confirmedTxs = (transactionStates || []).filter(
|
|
@@ -67,10 +71,11 @@ function useReceipt(transactionStates?: TransactionState[]) {
|
|
|
67
71
|
const last = confirmedTxs[confirmedTxs.length - 1]
|
|
68
72
|
|
|
69
73
|
const completionTimeSeconds = useTxTimeDiff(first, last)
|
|
70
|
-
return { finalExplorerUrl, completionTimeSeconds }
|
|
74
|
+
return { finalExplorerUrl, completionTimeSeconds, finalChainId }
|
|
71
75
|
}
|
|
72
76
|
|
|
73
77
|
export const Receipt: React.FC<ReceiptProps> = ({
|
|
78
|
+
onSendAnother,
|
|
74
79
|
onClose,
|
|
75
80
|
renderInline = false,
|
|
76
81
|
transactionStates = [],
|
|
@@ -78,6 +83,8 @@ export const Receipt: React.FC<ReceiptProps> = ({
|
|
|
78
83
|
quote,
|
|
79
84
|
}) => {
|
|
80
85
|
const [showContent, setShowContent] = useState(false)
|
|
86
|
+
const [showRefundInfo, setShowRefundInfo] = useState(false)
|
|
87
|
+
const [refundMessage, setRefundMessage] = useState<string | null>(null)
|
|
81
88
|
|
|
82
89
|
useEffect(() => {
|
|
83
90
|
const timer = setTimeout(() => {
|
|
@@ -87,13 +94,155 @@ export const Receipt: React.FC<ReceiptProps> = ({
|
|
|
87
94
|
return () => clearTimeout(timer)
|
|
88
95
|
}, [])
|
|
89
96
|
|
|
90
|
-
|
|
91
|
-
|
|
97
|
+
// Helper function to check if a specific transaction has meta tx errors
|
|
98
|
+
const hasMetaTxError = useCallback((tx: TransactionState) => {
|
|
99
|
+
return tx?.decodedGuestModuleEvents?.some(
|
|
100
|
+
(event) => event.type === "CallFailed",
|
|
101
|
+
)
|
|
102
|
+
}, [])
|
|
103
|
+
|
|
104
|
+
const showMetaTxError = useMemo(() => {
|
|
105
|
+
return transactionStates.some((tx) => hasMetaTxError(tx))
|
|
106
|
+
}, [transactionStates, hasMetaTxError])
|
|
107
|
+
|
|
108
|
+
const {
|
|
109
|
+
finalExplorerUrl,
|
|
110
|
+
finalChainId,
|
|
111
|
+
completionTimeSeconds: calculatedCompletionTime,
|
|
112
|
+
} = useReceipt(transactionStates)
|
|
92
113
|
|
|
93
114
|
// Use provided totalCompletionSeconds if available, otherwise use calculated time
|
|
94
115
|
const completionTimeSeconds =
|
|
95
116
|
totalCompletionSeconds ?? calculatedCompletionTime
|
|
96
117
|
|
|
118
|
+
// Detect successful refund events on origin or sweep on destination
|
|
119
|
+
useEffect(() => {
|
|
120
|
+
if (!transactionStates || transactionStates.length === 0) return
|
|
121
|
+
|
|
122
|
+
const originTx = transactionStates[0]
|
|
123
|
+
const destinationTx = transactionStates[transactionStates.length - 1]
|
|
124
|
+
|
|
125
|
+
// Check if this is a same-chain transaction (all transactions on same chain)
|
|
126
|
+
const isSameChain =
|
|
127
|
+
transactionStates.length <= 2 &&
|
|
128
|
+
transactionStates.every((tx) => tx.chainId === originTx?.chainId)
|
|
129
|
+
|
|
130
|
+
const originRefund = originTx?.decodedTrailsTokenSweeperEvents?.find(
|
|
131
|
+
(e) => e.type === "Refund",
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
// Only check destination sweep for cross-chain transactions
|
|
135
|
+
const destinationSweep = !isSameChain
|
|
136
|
+
? destinationTx?.decodedTrailsTokenSweeperEvents?.find(
|
|
137
|
+
(e) => e.type === "Sweep",
|
|
138
|
+
)
|
|
139
|
+
: null
|
|
140
|
+
|
|
141
|
+
if (originRefund) {
|
|
142
|
+
setRefundMessage(
|
|
143
|
+
"The origin call failed, but your funds were successfully refunded on the origin chain.",
|
|
144
|
+
)
|
|
145
|
+
setShowRefundInfo(true)
|
|
146
|
+
return
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (destinationSweep) {
|
|
150
|
+
setRefundMessage(
|
|
151
|
+
"The destination call failed, but a refund was successfully handled on the destination chain.",
|
|
152
|
+
)
|
|
153
|
+
setShowRefundInfo(true)
|
|
154
|
+
return
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
setShowRefundInfo(false)
|
|
158
|
+
setRefundMessage(null)
|
|
159
|
+
}, [transactionStates])
|
|
160
|
+
|
|
161
|
+
// Extract QuoteDetails section to reuse in both success and failure states
|
|
162
|
+
const quoteDetailsSection = quote && (
|
|
163
|
+
<div className="mt-2">
|
|
164
|
+
<QuoteDetails quote={quote} showContent={true}>
|
|
165
|
+
{transactionStates.length > 0 && (
|
|
166
|
+
<>
|
|
167
|
+
<div className="font-medium text-gray-700 dark:text-gray-300">
|
|
168
|
+
Transactions:
|
|
169
|
+
</div>
|
|
170
|
+
<div className="space-y-2">
|
|
171
|
+
{transactionStates.map((state, i) => (
|
|
172
|
+
<div
|
|
173
|
+
key={`${state.transactionHash}-${i}`}
|
|
174
|
+
className="p-2 rounded bg-gray-100 dark:bg-gray-700/50"
|
|
175
|
+
>
|
|
176
|
+
<div className="flex justify-between items-center">
|
|
177
|
+
<span className="text-gray-600 dark:text-gray-400">
|
|
178
|
+
{state.label}:
|
|
179
|
+
</span>
|
|
180
|
+
<span
|
|
181
|
+
className={`px-2 py-0.5 rounded-full text-xs ${
|
|
182
|
+
state.state === "confirmed"
|
|
183
|
+
? "bg-green-100 text-green-700 dark:bg-green-900/50 dark:text-green-400"
|
|
184
|
+
: "bg-yellow-100 text-yellow-700 dark:bg-yellow-900/50 dark:text-yellow-400"
|
|
185
|
+
}`}
|
|
186
|
+
>
|
|
187
|
+
{state.state.charAt(0).toUpperCase() +
|
|
188
|
+
state.state.slice(1)}
|
|
189
|
+
</span>
|
|
190
|
+
</div>
|
|
191
|
+
<div className="mt-1 flex justify-between items-center">
|
|
192
|
+
<span className="text-gray-600 dark:text-gray-400">
|
|
193
|
+
Hash:
|
|
194
|
+
</span>
|
|
195
|
+
<a
|
|
196
|
+
href={state.explorerUrl}
|
|
197
|
+
target="_blank"
|
|
198
|
+
rel="noopener noreferrer"
|
|
199
|
+
className="flex items-center gap-1 hover:underline text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300"
|
|
200
|
+
>
|
|
201
|
+
{hasMetaTxError(state) && (
|
|
202
|
+
<svg
|
|
203
|
+
className="w-4 h-4 text-orange-500"
|
|
204
|
+
fill="none"
|
|
205
|
+
viewBox="0 0 24 24"
|
|
206
|
+
stroke="currentColor"
|
|
207
|
+
>
|
|
208
|
+
<title>
|
|
209
|
+
An internal meta transaction failure occurred
|
|
210
|
+
</title>
|
|
211
|
+
<path
|
|
212
|
+
strokeLinecap="round"
|
|
213
|
+
strokeLinejoin="round"
|
|
214
|
+
strokeWidth={2}
|
|
215
|
+
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"
|
|
216
|
+
/>
|
|
217
|
+
</svg>
|
|
218
|
+
)}
|
|
219
|
+
<ChainImage chainId={state.chainId} size={16} />
|
|
220
|
+
<span>{truncateAddress(state.transactionHash)}</span>
|
|
221
|
+
<svg
|
|
222
|
+
className="w-3 h-3"
|
|
223
|
+
fill="none"
|
|
224
|
+
viewBox="0 0 24 24"
|
|
225
|
+
stroke="currentColor"
|
|
226
|
+
>
|
|
227
|
+
<title>External Link</title>
|
|
228
|
+
<path
|
|
229
|
+
strokeLinecap="round"
|
|
230
|
+
strokeLinejoin="round"
|
|
231
|
+
strokeWidth={2}
|
|
232
|
+
d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
|
|
233
|
+
/>
|
|
234
|
+
</svg>
|
|
235
|
+
</a>
|
|
236
|
+
</div>
|
|
237
|
+
</div>
|
|
238
|
+
))}
|
|
239
|
+
</div>
|
|
240
|
+
</>
|
|
241
|
+
)}
|
|
242
|
+
</QuoteDetails>
|
|
243
|
+
</div>
|
|
244
|
+
)
|
|
245
|
+
|
|
97
246
|
if (!finalExplorerUrl) {
|
|
98
247
|
return (
|
|
99
248
|
<div className="flex flex-col justify-center min-h-full space-y-6 pt-8">
|
|
@@ -126,6 +275,21 @@ export const Receipt: React.FC<ReceiptProps> = ({
|
|
|
126
275
|
</p>
|
|
127
276
|
</div>
|
|
128
277
|
|
|
278
|
+
{onSendAnother && (
|
|
279
|
+
<div className="flex justify-center">
|
|
280
|
+
<button
|
|
281
|
+
type="button"
|
|
282
|
+
onClick={onSendAnother}
|
|
283
|
+
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"
|
|
284
|
+
>
|
|
285
|
+
Try Again
|
|
286
|
+
</button>
|
|
287
|
+
</div>
|
|
288
|
+
)}
|
|
289
|
+
|
|
290
|
+
{/* Quote Details - Show even in failed state */}
|
|
291
|
+
{quoteDetailsSection}
|
|
292
|
+
|
|
129
293
|
{!renderInline && (
|
|
130
294
|
<div className="text-center">
|
|
131
295
|
<button
|
|
@@ -145,15 +309,24 @@ export const Receipt: React.FC<ReceiptProps> = ({
|
|
|
145
309
|
<div className="flex flex-col justify-center min-h-full space-y-6 pt-8">
|
|
146
310
|
<div className="text-center mb-2">
|
|
147
311
|
<div className={`mx-auto flex items-center justify-center`}>
|
|
148
|
-
|
|
312
|
+
{showRefundInfo || showMetaTxError ? (
|
|
313
|
+
<YellowWarningAnimation />
|
|
314
|
+
) : (
|
|
315
|
+
<GreenCheckAnimation />
|
|
316
|
+
)}
|
|
149
317
|
</div>
|
|
150
318
|
|
|
151
319
|
<div
|
|
152
320
|
className={`transition-all duration-500 ease-out ${showContent ? "opacity-100 translate-y-0" : "opacity-0 translate-y-4"}`}
|
|
153
321
|
>
|
|
154
322
|
<h2 className="mt-4 text-2xl font-bold text-gray-900 dark:text-white">
|
|
155
|
-
|
|
323
|
+
{showRefundInfo ? "Unable to process." : "Completed"}
|
|
156
324
|
</h2>
|
|
325
|
+
{showRefundInfo && (
|
|
326
|
+
<div className="mt-1 text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-1 justify-center animate-fade-in-up">
|
|
327
|
+
Refunded.
|
|
328
|
+
</div>
|
|
329
|
+
)}
|
|
157
330
|
{completionTimeSeconds > 0 && (
|
|
158
331
|
<div
|
|
159
332
|
className="mt-1 text-sm text-gray-600 dark:text-gray-400 flex items-center gap-1 justify-center animate-fade-in-up"
|
|
@@ -162,28 +335,37 @@ export const Receipt: React.FC<ReceiptProps> = ({
|
|
|
162
335
|
animationFillMode: "both",
|
|
163
336
|
}}
|
|
164
337
|
>
|
|
165
|
-
<
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
338
|
+
<div className="inline-block animate-fade-in-up">
|
|
339
|
+
{showRefundInfo ? (
|
|
340
|
+
<span>Transaction confirmed</span>
|
|
341
|
+
) : (
|
|
342
|
+
<span>
|
|
343
|
+
Completed in{" "}
|
|
344
|
+
<strong>{formatElapsed(completionTimeSeconds)}</strong>
|
|
345
|
+
</span>
|
|
346
|
+
)}
|
|
347
|
+
</div>
|
|
348
|
+
{totalCompletionSeconds &&
|
|
349
|
+
totalCompletionSeconds < 15 &&
|
|
350
|
+
!showMetaTxError &&
|
|
351
|
+
!showRefundInfo && (
|
|
352
|
+
<svg
|
|
353
|
+
className="w-4 h-4 ml-1 text-yellow-400 inline"
|
|
354
|
+
fill="none"
|
|
355
|
+
viewBox="0 0 24 24"
|
|
356
|
+
stroke="currentColor"
|
|
357
|
+
aria-hidden="true"
|
|
358
|
+
>
|
|
359
|
+
<title>Lightning Fast</title>
|
|
360
|
+
<path
|
|
361
|
+
strokeLinecap="round"
|
|
362
|
+
strokeLinejoin="round"
|
|
363
|
+
strokeWidth={2}
|
|
364
|
+
d="M13 10V3L4 14h7v7l9-11h-7z"
|
|
365
|
+
fill="currentColor"
|
|
366
|
+
/>
|
|
367
|
+
</svg>
|
|
368
|
+
)}
|
|
187
369
|
<style>{`
|
|
188
370
|
@keyframes fadeInUp {
|
|
189
371
|
0% { opacity: 0; transform: translateY(16px); }
|
|
@@ -192,6 +374,33 @@ export const Receipt: React.FC<ReceiptProps> = ({
|
|
|
192
374
|
`}</style>
|
|
193
375
|
</div>
|
|
194
376
|
)}
|
|
377
|
+
|
|
378
|
+
{(showMetaTxError || showRefundInfo) && (
|
|
379
|
+
<div
|
|
380
|
+
className="mt-2 text-sm text-orange-600 dark:text-orange-400 flex items-center gap-2 justify-center animate-fade-in-up"
|
|
381
|
+
style={{
|
|
382
|
+
animation: "fadeInUp 0.7s cubic-bezier(0.23, 1, 0.32, 1)",
|
|
383
|
+
animationFillMode: "both",
|
|
384
|
+
}}
|
|
385
|
+
>
|
|
386
|
+
<svg
|
|
387
|
+
className="w-4 h-4 text-orange-500"
|
|
388
|
+
fill="none"
|
|
389
|
+
viewBox="0 0 24 24"
|
|
390
|
+
stroke="currentColor"
|
|
391
|
+
aria-hidden="true"
|
|
392
|
+
>
|
|
393
|
+
<title>Internal Meta Transaction Error</title>
|
|
394
|
+
<path
|
|
395
|
+
strokeLinecap="round"
|
|
396
|
+
strokeLinejoin="round"
|
|
397
|
+
strokeWidth={2}
|
|
398
|
+
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"
|
|
399
|
+
/>
|
|
400
|
+
</svg>
|
|
401
|
+
<span>Although one or more errors occurred</span>
|
|
402
|
+
</div>
|
|
403
|
+
)}
|
|
195
404
|
</div>
|
|
196
405
|
</div>
|
|
197
406
|
|
|
@@ -204,6 +413,7 @@ export const Receipt: React.FC<ReceiptProps> = ({
|
|
|
204
413
|
rel="noopener noreferrer"
|
|
205
414
|
className="inline-flex items-center gap-1 px-3 py-1.5 rounded-md font-medium transition-colors border border-solid text-sm bg-white border-gray-200 text-black hover:bg-gray-50 hover:text-gray-900 dark:bg-gray-900 dark:border-gray-700 dark:text-blue-300 dark:hover:bg-gray-800 dark:hover:text-blue-200"
|
|
206
415
|
>
|
|
416
|
+
{finalChainId && <ChainImage chainId={finalChainId} size={16} />}
|
|
207
417
|
View on Explorer
|
|
208
418
|
<svg
|
|
209
419
|
className="w-4 h-4 ml-1 text-black dark:text-blue-300"
|
|
@@ -222,9 +432,64 @@ export const Receipt: React.FC<ReceiptProps> = ({
|
|
|
222
432
|
</a>
|
|
223
433
|
</div>
|
|
224
434
|
|
|
435
|
+
{showRefundInfo && refundMessage && (
|
|
436
|
+
<div
|
|
437
|
+
className="mt-2 text-sm text-yellow-700 dark:text-yellow-400 flex items-center gap-2 justify-center animate-fade-in-up"
|
|
438
|
+
style={{
|
|
439
|
+
animation: "fadeInUp 0.7s cubic-bezier(0.23, 1, 0.32, 1)",
|
|
440
|
+
animationFillMode: "both",
|
|
441
|
+
}}
|
|
442
|
+
>
|
|
443
|
+
<div className="rounded-xl bg-warning">
|
|
444
|
+
<div className="flex bg-background-overlay rounded-xl p-4 w-full flex-col gap-3">
|
|
445
|
+
<div className="flex w-full gap-2 justify-between">
|
|
446
|
+
<div className="flex flex-col gap-1">
|
|
447
|
+
<div className="text-sm font-medium text-gray-900 dark:text-white text-left">
|
|
448
|
+
Refund Information
|
|
449
|
+
</div>
|
|
450
|
+
<div className="text-sm text-gray-700 dark:text-gray-300 text-left">
|
|
451
|
+
{refundMessage}
|
|
452
|
+
</div>
|
|
453
|
+
</div>
|
|
454
|
+
<div className="flex items-center">
|
|
455
|
+
<svg
|
|
456
|
+
className="w-5 h-5 text-yellow-600 dark:text-yellow-400"
|
|
457
|
+
fill="none"
|
|
458
|
+
viewBox="0 0 24 24"
|
|
459
|
+
stroke="currentColor"
|
|
460
|
+
aria-hidden="true"
|
|
461
|
+
>
|
|
462
|
+
<title>Information</title>
|
|
463
|
+
<path
|
|
464
|
+
strokeLinecap="round"
|
|
465
|
+
strokeLinejoin="round"
|
|
466
|
+
strokeWidth={2}
|
|
467
|
+
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"
|
|
468
|
+
/>
|
|
469
|
+
</svg>
|
|
470
|
+
</div>
|
|
471
|
+
</div>
|
|
472
|
+
</div>
|
|
473
|
+
</div>
|
|
474
|
+
</div>
|
|
475
|
+
)}
|
|
476
|
+
|
|
225
477
|
<div
|
|
226
478
|
className={`space-y-3 transition-all duration-500 ease-out delay-200 ${showContent ? "opacity-100 translate-y-0" : "opacity-0 translate-y-4"}`}
|
|
227
479
|
>
|
|
480
|
+
{onSendAnother && (
|
|
481
|
+
<div className="flex justify-center">
|
|
482
|
+
<button
|
|
483
|
+
type="button"
|
|
484
|
+
onClick={onSendAnother}
|
|
485
|
+
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"
|
|
486
|
+
>
|
|
487
|
+
Send Again
|
|
488
|
+
<ChevronRight className="w-4 h-4" />
|
|
489
|
+
</button>
|
|
490
|
+
</div>
|
|
491
|
+
)}
|
|
492
|
+
|
|
228
493
|
{!renderInline && (
|
|
229
494
|
<button
|
|
230
495
|
type="button"
|
|
@@ -236,79 +501,7 @@ export const Receipt: React.FC<ReceiptProps> = ({
|
|
|
236
501
|
)}
|
|
237
502
|
|
|
238
503
|
{/* Quote Details */}
|
|
239
|
-
{
|
|
240
|
-
<div className="mt-2">
|
|
241
|
-
<QuoteDetails quote={quote} showContent={true}>
|
|
242
|
-
{transactionStates.length > 0 && (
|
|
243
|
-
<>
|
|
244
|
-
<div className="font-medium text-gray-700 dark:text-gray-300">
|
|
245
|
-
Transactions:
|
|
246
|
-
</div>
|
|
247
|
-
<div className="space-y-2">
|
|
248
|
-
{transactionStates.map((state) => (
|
|
249
|
-
<div
|
|
250
|
-
key={state.transactionHash}
|
|
251
|
-
className="p-2 rounded bg-gray-100 dark:bg-gray-700/50"
|
|
252
|
-
>
|
|
253
|
-
<div className="flex justify-between items-center">
|
|
254
|
-
<span className="text-gray-600 dark:text-gray-400">
|
|
255
|
-
{state.label}:
|
|
256
|
-
</span>
|
|
257
|
-
<span
|
|
258
|
-
className={`px-2 py-0.5 rounded-full text-xs ${
|
|
259
|
-
state.state === "confirmed"
|
|
260
|
-
? "bg-green-100 text-green-700 dark:bg-green-900/50 dark:text-green-400"
|
|
261
|
-
: "bg-yellow-100 text-yellow-700 dark:bg-yellow-900/50 dark:text-yellow-400"
|
|
262
|
-
}`}
|
|
263
|
-
>
|
|
264
|
-
{state.state}
|
|
265
|
-
</span>
|
|
266
|
-
</div>
|
|
267
|
-
<div className="mt-1 flex justify-between items-center">
|
|
268
|
-
<span className="text-gray-600 dark:text-gray-400">
|
|
269
|
-
Chain ID:
|
|
270
|
-
</span>
|
|
271
|
-
<span className="text-gray-900 dark:text-white">
|
|
272
|
-
{state.chainId}
|
|
273
|
-
</span>
|
|
274
|
-
</div>
|
|
275
|
-
<div className="mt-1 flex justify-between items-center">
|
|
276
|
-
<span className="text-gray-600 dark:text-gray-400">
|
|
277
|
-
Hash:
|
|
278
|
-
</span>
|
|
279
|
-
<a
|
|
280
|
-
href={state.explorerUrl}
|
|
281
|
-
target="_blank"
|
|
282
|
-
rel="noopener noreferrer"
|
|
283
|
-
className="flex items-center gap-1 hover:underline text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300"
|
|
284
|
-
>
|
|
285
|
-
<span>
|
|
286
|
-
{truncateAddress(state.transactionHash)}
|
|
287
|
-
</span>
|
|
288
|
-
<svg
|
|
289
|
-
className="w-3 h-3"
|
|
290
|
-
fill="none"
|
|
291
|
-
viewBox="0 0 24 24"
|
|
292
|
-
stroke="currentColor"
|
|
293
|
-
>
|
|
294
|
-
<title>External Link</title>
|
|
295
|
-
<path
|
|
296
|
-
strokeLinecap="round"
|
|
297
|
-
strokeLinejoin="round"
|
|
298
|
-
strokeWidth={2}
|
|
299
|
-
d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
|
|
300
|
-
/>
|
|
301
|
-
</svg>
|
|
302
|
-
</a>
|
|
303
|
-
</div>
|
|
304
|
-
</div>
|
|
305
|
-
))}
|
|
306
|
-
</div>
|
|
307
|
-
</>
|
|
308
|
-
)}
|
|
309
|
-
</QuoteDetails>
|
|
310
|
-
</div>
|
|
311
|
-
)}
|
|
504
|
+
{quoteDetailsSection}
|
|
312
505
|
</div>
|
|
313
506
|
</div>
|
|
314
507
|
)
|