0xtrails 0.2.2 → 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-ConT1gDe.js → ccip-CXlshvBY.js} +1 -1
- package/dist/chains.d.ts +5 -1
- package/dist/chains.d.ts.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/constants.d.ts +5 -4
- 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-CMh8uEbV.js → index-_QuyGrjU.js} +86304 -83380
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/intentEntrypoint.d.ts +0 -8
- package/dist/intentEntrypoint.d.ts.map +1 -1
- package/dist/intents.d.ts +40 -0
- package/dist/intents.d.ts.map +1 -1
- package/dist/metaTxnMonitor.d.ts +5 -4
- 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 +10 -7
- package/dist/relayer.d.ts.map +1 -1
- package/dist/sequenceWallet.d.ts +3 -2
- package/dist/sequenceWallet.d.ts.map +1 -1
- package/dist/tokenBalances.d.ts +7 -0
- 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 +2 -2
- package/dist/trails.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/EarnPools.d.ts.map +1 -1
- package/dist/widget/components/Fund.d.ts +1 -0
- 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 +1 -0
- 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/RefundWarning.d.ts +1 -0
- package/dist/widget/components/RefundWarning.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 +6 -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/useInitialRedirect.d.ts +7 -0
- package/dist/widget/hooks/useInitialRedirect.d.ts.map +1 -0
- package/dist/widget/hooks/usePayMessage.d.ts.map +1 -1
- package/dist/widget/hooks/useSelectedFeeToken.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 +30 -23
- package/src/aave.ts +32 -0
- package/src/chains.ts +23 -3
- package/src/config.ts +12 -4
- package/src/constants.ts +11 -16
- package/src/error.ts +20 -2
- package/src/estimate.ts +416 -5
- package/src/index.ts +8 -3
- package/src/intentEntrypoint.ts +0 -15
- package/src/intents.ts +161 -11
- package/src/metaTxnMonitor.ts +28 -22
- package/src/metaTxns.ts +3 -3
- package/src/morpho.ts +32 -0
- package/src/prepareSend.ts +710 -458
- package/src/queryParams.ts +2 -1
- package/src/relayer.ts +15 -16
- package/src/sequenceWallet.ts +7 -3
- package/src/tokenBalances.ts +47 -0
- package/src/tokens.ts +17 -1
- package/src/trails.ts +2 -2
- package/src/wallets.ts +8 -0
- package/src/widget/compiled.css +2 -2
- package/src/widget/components/AccountActionsDropdown.tsx +9 -15
- package/src/widget/components/AccountIntentTransactionHistory.tsx +1 -1
- package/src/widget/components/AccountSettings.tsx +10 -27
- package/src/widget/components/ChainFilterDropdown.tsx +1 -1
- package/src/widget/components/ChainList.tsx +1 -1
- package/src/widget/components/ClassicSwap.tsx +111 -155
- package/src/widget/components/ConnectWallet.tsx +10 -39
- package/src/widget/components/ConnectedWallets.tsx +113 -58
- package/src/widget/components/Earn.tsx +73 -589
- package/src/widget/components/EarnPools.tsx +2 -1
- package/src/widget/components/Fund.tsx +81 -109
- 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 +198 -200
- 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 +1 -3
- package/src/widget/components/RecipientSelectorButton.tsx +42 -0
- package/src/widget/components/Recipients.tsx +64 -156
- package/src/widget/components/RefundWarning.tsx +5 -1
- 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 +3 -15
- package/src/widget/components/TokenImage.tsx +21 -4
- package/src/widget/components/TokenList.tsx +0 -1
- package/src/widget/components/TokenSelector.tsx +2 -1
- 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 +7 -5
- package/src/widget/hooks/useBack.tsx +113 -9
- 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/useInitialRedirect.tsx +70 -0
- package/src/widget/hooks/usePayMessage.tsx +86 -11
- package/src/widget/hooks/useSelectedFeeToken.tsx +10 -16
- package/src/widget/hooks/useSelectedFundMethod.tsx +41 -0
- package/src/widget/hooks/useSelectedRecipient.tsx +10 -0
- package/src/widget/hooks/useSendForm.ts +34 -12
- package/src/widget/hooks/useTokenList.ts +1 -1
- package/src/widget/index.css +27 -0
- package/src/widget/widget.tsx +245 -208
- 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
- /package/dist/{style.css → 0xtrails.css} +0 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { ChevronRight, QrCode, Send } from "lucide-react"
|
|
2
|
+
import type React from "react"
|
|
3
|
+
import { truncateAddress } from "../../utils.js"
|
|
4
|
+
import { useAccount } from "wagmi"
|
|
5
|
+
import { Identicon } from "./Identicon.js"
|
|
6
|
+
import { useBack } from "../hooks/useBack.js"
|
|
7
|
+
import { useSelectedFundMethod } from "../hooks/useSelectedFundMethod.js"
|
|
8
|
+
|
|
9
|
+
export const FundingMethodSelectorButton: React.FC = () => {
|
|
10
|
+
const { address, isConnected } = useAccount()
|
|
11
|
+
const { setCurrentScreenWithBack } = useBack()
|
|
12
|
+
const { selectedFundMethod } = useSelectedFundMethod()
|
|
13
|
+
|
|
14
|
+
const handleClick = () => {
|
|
15
|
+
if (isConnected && address) {
|
|
16
|
+
// If wallet is connected, go to fund methods
|
|
17
|
+
setCurrentScreenWithBack("fund-methods")
|
|
18
|
+
} else {
|
|
19
|
+
// If no wallet connected, go to connect wallet
|
|
20
|
+
setCurrentScreenWithBack("connect")
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<button
|
|
26
|
+
type="button"
|
|
27
|
+
onClick={handleClick}
|
|
28
|
+
className="flex items-center space-x-2 text-blue-500 hover:text-blue-600 transition-colors cursor-pointer bg-transparent border-none p-0"
|
|
29
|
+
title={
|
|
30
|
+
isConnected && address ? "Select funding method" : "Connect wallet"
|
|
31
|
+
}
|
|
32
|
+
>
|
|
33
|
+
{isConnected && address ? (
|
|
34
|
+
selectedFundMethod === "qr-code" ? (
|
|
35
|
+
<>
|
|
36
|
+
<QrCode className="w-4 h-4" />
|
|
37
|
+
<span className="text-sm font-medium">QR Code</span>
|
|
38
|
+
</>
|
|
39
|
+
) : selectedFundMethod === "exchange" ? (
|
|
40
|
+
<>
|
|
41
|
+
<Send className="w-4 h-4" />
|
|
42
|
+
<span className="text-sm font-medium">Exchange</span>
|
|
43
|
+
</>
|
|
44
|
+
) : (
|
|
45
|
+
<>
|
|
46
|
+
<Identicon value={address} size={16} />
|
|
47
|
+
<span className="text-sm font-medium">
|
|
48
|
+
{truncateAddress(address, 4, 2)}
|
|
49
|
+
</span>
|
|
50
|
+
</>
|
|
51
|
+
)
|
|
52
|
+
) : (
|
|
53
|
+
<span className="text-sm font-medium">Connect Wallet</span>
|
|
54
|
+
)}
|
|
55
|
+
<ChevronRight className="w-4 h-4" />
|
|
56
|
+
</button>
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export default FundingMethodSelectorButton
|
|
@@ -73,9 +73,13 @@ const Modal: React.FC<ModalProps> = ({ isOpen, onClose, children }) => {
|
|
|
73
73
|
<button
|
|
74
74
|
type="button"
|
|
75
75
|
onClick={onClose}
|
|
76
|
-
className="absolute right-
|
|
76
|
+
className="absolute right-4 top-6 flex h-8 w-8 justify-center items-center rounded-full bg-gray-50 dark:bg-gray-700 cursor-pointer transition-colors text-gray-900 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-600 z-20"
|
|
77
|
+
title="Close"
|
|
77
78
|
>
|
|
78
|
-
<X
|
|
79
|
+
<X
|
|
80
|
+
className="h-4 w-4"
|
|
81
|
+
style={{ transform: "translate(0, -2px)" }}
|
|
82
|
+
/>
|
|
79
83
|
</button>
|
|
80
84
|
{children}
|
|
81
85
|
</motion.div>
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Search, Loader2, ChevronRight } from "lucide-react"
|
|
2
2
|
import { useEffect, useState, useMemo, useRef, useCallback } from "react"
|
|
3
3
|
import type React from "react"
|
|
4
4
|
import type { Account, WalletClient } from "viem"
|
|
5
|
+
import { zeroAddress } from "viem"
|
|
5
6
|
import type { TransactionState } from "../../transactions.js"
|
|
6
7
|
import type { OnCompleteProps } from "../hooks/useSendForm.js"
|
|
7
8
|
import type { CheckoutOnHandlers } from "../hooks/useCheckout.js"
|
|
@@ -31,6 +32,10 @@ import type { PrepareSendQuote } from "../../prepareSend.js"
|
|
|
31
32
|
import type { SupportedToken } from "../../tokens.js"
|
|
32
33
|
import { logger } from "../../logger.js"
|
|
33
34
|
import { RefundWarning } from "./RefundWarning.js"
|
|
35
|
+
import { TokenSelectorButton } from "./TokenSelectorButton.js"
|
|
36
|
+
import { RequiredPropsError } from "./RequiredPropsError.js"
|
|
37
|
+
import { FundingMethodSelectorButton } from "./FundingMethodSelectorButton.js"
|
|
38
|
+
import { PercentageMaxButtons } from "./PercentageMaxButtons.js"
|
|
34
39
|
|
|
35
40
|
interface PayProps {
|
|
36
41
|
selectedToken?: any // Origin token (optional - user can select)
|
|
@@ -45,6 +50,7 @@ interface PayProps {
|
|
|
45
50
|
onSend: (amount: string, recipient: string) => void
|
|
46
51
|
paymasterUrls?: Array<{ chainId: number; url: string }>
|
|
47
52
|
gasless?: boolean
|
|
53
|
+
isSequenceWallet?: boolean
|
|
48
54
|
setWalletConfirmRetryHandler: (handler: () => Promise<void>) => void
|
|
49
55
|
quoteProvider?: string
|
|
50
56
|
fundMethod?: string
|
|
@@ -82,6 +88,7 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
82
88
|
onSend,
|
|
83
89
|
paymasterUrls,
|
|
84
90
|
gasless,
|
|
91
|
+
isSequenceWallet = false,
|
|
85
92
|
setWalletConfirmRetryHandler,
|
|
86
93
|
quoteProvider,
|
|
87
94
|
fundMethod,
|
|
@@ -143,6 +150,18 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
143
150
|
allSupportedTokens: true, // Show all tokens for destination selection
|
|
144
151
|
})
|
|
145
152
|
|
|
153
|
+
// Get origin token balance for display
|
|
154
|
+
const originTokenBalance = useMemo(() => {
|
|
155
|
+
if (!originToken || !filteredTokensFormatted) return null
|
|
156
|
+
|
|
157
|
+
return filteredTokensFormatted.find(
|
|
158
|
+
(token) =>
|
|
159
|
+
token.contractAddress?.toLowerCase() ===
|
|
160
|
+
originToken.contractAddress?.toLowerCase() &&
|
|
161
|
+
token.chainId === originToken.chainId,
|
|
162
|
+
)
|
|
163
|
+
}, [originToken, filteredTokensFormatted])
|
|
164
|
+
|
|
146
165
|
// Use useSendForm for quote functionality with EXACT_OUTPUT trade type
|
|
147
166
|
const {
|
|
148
167
|
amountUsdDisplay,
|
|
@@ -314,10 +333,12 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
314
333
|
const destTokenToUse = globalDestinationToken || defaultDestinationToken
|
|
315
334
|
|
|
316
335
|
if (destTokenToUse && !isLoadingDefaults) {
|
|
317
|
-
logger.console.log(
|
|
318
|
-
|
|
319
|
-
destTokenToUse,
|
|
320
|
-
|
|
336
|
+
logger.console.log("[trails-sdk] Initializing destination token:", {
|
|
337
|
+
symbol: destTokenToUse.symbol,
|
|
338
|
+
chainId: destTokenToUse.chainId,
|
|
339
|
+
name: destTokenToUse.name,
|
|
340
|
+
contractAddress: destTokenToUse.contractAddress,
|
|
341
|
+
})
|
|
321
342
|
|
|
322
343
|
// Set destination token if not already set by global state
|
|
323
344
|
if (!globalDestinationToken && defaultDestinationToken) {
|
|
@@ -403,21 +424,21 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
403
424
|
return inputDisplayValue
|
|
404
425
|
}, [inputDisplayValue])
|
|
405
426
|
|
|
406
|
-
// Dynamic font size based on input length
|
|
427
|
+
// Dynamic font size based on input length for destination amount
|
|
407
428
|
const inputStyles = useMemo(() => {
|
|
408
429
|
const inputLength = displayAmount.length
|
|
409
430
|
let fontSize: string
|
|
410
431
|
|
|
411
432
|
if (inputLength > 12) {
|
|
412
|
-
fontSize = "0.875rem"
|
|
413
|
-
} else if (inputLength > 9) {
|
|
414
433
|
fontSize = "1rem"
|
|
434
|
+
} else if (inputLength > 9) {
|
|
435
|
+
fontSize = "1.25rem"
|
|
415
436
|
} else if (inputLength > 6) {
|
|
416
|
-
fontSize = "1.
|
|
437
|
+
fontSize = "1.5rem"
|
|
417
438
|
} else if (inputLength > 3) {
|
|
418
|
-
fontSize = "1.
|
|
439
|
+
fontSize = "1.75rem"
|
|
419
440
|
} else {
|
|
420
|
-
fontSize = "
|
|
441
|
+
fontSize = "2rem"
|
|
421
442
|
}
|
|
422
443
|
|
|
423
444
|
return {
|
|
@@ -426,6 +447,29 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
426
447
|
}
|
|
427
448
|
}, [displayAmount.length])
|
|
428
449
|
|
|
450
|
+
// Dynamic font size based on input length for origin amount (Pay with section)
|
|
451
|
+
const originInputStyles = useMemo(() => {
|
|
452
|
+
const inputLength = (prepareSendQuote?.originAmountFormatted || "").length
|
|
453
|
+
let fontSize: string
|
|
454
|
+
|
|
455
|
+
if (inputLength > 12) {
|
|
456
|
+
fontSize = "1rem"
|
|
457
|
+
} else if (inputLength > 9) {
|
|
458
|
+
fontSize = "1.25rem"
|
|
459
|
+
} else if (inputLength > 6) {
|
|
460
|
+
fontSize = "1.5rem"
|
|
461
|
+
} else if (inputLength > 3) {
|
|
462
|
+
fontSize = "1.75rem"
|
|
463
|
+
} else {
|
|
464
|
+
fontSize = "2rem"
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
return {
|
|
468
|
+
fontSize,
|
|
469
|
+
transition: "all 0.1s ease-in-out",
|
|
470
|
+
}
|
|
471
|
+
}, [prepareSendQuote?.originAmountFormatted])
|
|
472
|
+
|
|
429
473
|
const handleOriginTokenSelect = useCallback(
|
|
430
474
|
(token: any) => {
|
|
431
475
|
const formattedToken = {
|
|
@@ -519,7 +563,6 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
519
563
|
onBack={() => setShowOriginTokenSelector(false)}
|
|
520
564
|
headerContent="Select Token"
|
|
521
565
|
headerContentAlign="left"
|
|
522
|
-
showAccountActions={true}
|
|
523
566
|
/>
|
|
524
567
|
<TokenSelector
|
|
525
568
|
onTokenSelect={handleOriginTokenSelect}
|
|
@@ -566,7 +609,6 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
566
609
|
onBack={() => setShowDestinationTokenSelector(false)}
|
|
567
610
|
headerContent="Select Token"
|
|
568
611
|
headerContentAlign="left"
|
|
569
|
-
showAccountActions={true}
|
|
570
612
|
/>
|
|
571
613
|
<TokenSelector
|
|
572
614
|
onTokenSelect={handleDestinationTokenSelect}
|
|
@@ -603,11 +645,35 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
603
645
|
)
|
|
604
646
|
}
|
|
605
647
|
|
|
648
|
+
// Check for required props
|
|
649
|
+
const missingRequiredProps = []
|
|
650
|
+
if (!toAmount) missingRequiredProps.push("toAmount")
|
|
651
|
+
if (!toToken) missingRequiredProps.push("toToken")
|
|
652
|
+
if (!toRecipient) missingRequiredProps.push("toRecipient")
|
|
653
|
+
|
|
606
654
|
// Check if this is a payment request (all required props are set)
|
|
607
655
|
const isPaymentRequest = !!(toToken && toAmount && toChainId && toRecipient)
|
|
608
656
|
|
|
657
|
+
// If required props are missing, only show the error
|
|
658
|
+
if (missingRequiredProps.length > 0) {
|
|
659
|
+
return (
|
|
660
|
+
<div className="space-y-4">
|
|
661
|
+
<ScreenHeader
|
|
662
|
+
onBack={onBack}
|
|
663
|
+
headerContent="Pay"
|
|
664
|
+
headerContentAlign="left"
|
|
665
|
+
showAccountActions={true}
|
|
666
|
+
/>
|
|
667
|
+
<RequiredPropsError
|
|
668
|
+
missingProps={missingRequiredProps}
|
|
669
|
+
componentName="Pay"
|
|
670
|
+
/>
|
|
671
|
+
</div>
|
|
672
|
+
)
|
|
673
|
+
}
|
|
674
|
+
|
|
609
675
|
return (
|
|
610
|
-
<div className="space-y-
|
|
676
|
+
<div className="space-y-2">
|
|
611
677
|
<ScreenHeader
|
|
612
678
|
onBack={onBack}
|
|
613
679
|
headerContent="Pay"
|
|
@@ -621,7 +687,7 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
621
687
|
{/* Payment Request Header */}
|
|
622
688
|
<div className="space-y-1 trails-bg-secondary trails-border-radius-container p-3">
|
|
623
689
|
<div className="flex justify-start">
|
|
624
|
-
<div className="flex items-center font-medium trails-text-primary text-sm whitespace-nowrap overflow-hidden">
|
|
690
|
+
<div className="flex items-center font-medium trails-text-primary text-sm whitespace-nowrap overflow-hidden min-w-full">
|
|
625
691
|
{payMessage}
|
|
626
692
|
</div>
|
|
627
693
|
</div>
|
|
@@ -629,10 +695,10 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
629
695
|
|
|
630
696
|
{/* Origin Token Selection for Payment Request */}
|
|
631
697
|
<div className="space-y-1">
|
|
632
|
-
<div className="trails-bg-secondary trails-bg-secondary-hover trails-border-radius-container p-3 group transition-all duration-200 border border-transparent focus-within:!bg-white dark:focus-within:!bg-gray-800 trails-focus-border-secondary">
|
|
698
|
+
<div className="trails-bg-secondary trails-bg-secondary-hover trails-border-radius-container p-3 group transition-all duration-200 border border-transparent focus-within:!bg-white dark:focus-within:!bg-gray-800 trails-focus-border-secondary min-h-[120px] flex flex-col">
|
|
633
699
|
{/* Amount to Pay Label */}
|
|
634
700
|
<div className="flex justify-between items-center mb-2">
|
|
635
|
-
<div className="text-sm font-
|
|
701
|
+
<div className="text-sm font-medium trails-text-secondary text-left">
|
|
636
702
|
Pay with
|
|
637
703
|
{fundMethod === "qr-code"
|
|
638
704
|
? " QR Code"
|
|
@@ -640,82 +706,38 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
640
706
|
? " Exchange"
|
|
641
707
|
: ""}
|
|
642
708
|
</div>
|
|
709
|
+
<FundingMethodSelectorButton />
|
|
643
710
|
</div>
|
|
644
711
|
|
|
645
|
-
<div className="flex items-center space-x-2">
|
|
712
|
+
<div className="flex items-center space-x-2 flex-1">
|
|
646
713
|
{/* Amount Display - Non-editable */}
|
|
647
714
|
<div className="flex-1">
|
|
648
|
-
<div
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
width: prepareSendQuote?.originAmountFormatted
|
|
664
|
-
? `${Math.max(prepareSendQuote.originAmountFormatted.length - 1 + 0.5, 1)}ch`
|
|
665
|
-
: "1ch",
|
|
666
|
-
minWidth: "1ch",
|
|
667
|
-
maxWidth: "200px",
|
|
668
|
-
padding: "0",
|
|
669
|
-
margin: "0",
|
|
670
|
-
transition: "all 0.1s ease-in-out",
|
|
671
|
-
}}
|
|
672
|
-
/>
|
|
673
|
-
<span
|
|
674
|
-
className="font-bold text-gray-400 dark:text-gray-500"
|
|
675
|
-
style={{
|
|
676
|
-
fontSize: inputStyles.fontSize,
|
|
677
|
-
marginLeft: "0.1em",
|
|
678
|
-
padding: "0",
|
|
679
|
-
transition: "all 0.2s ease-in-out",
|
|
680
|
-
}}
|
|
681
|
-
>
|
|
682
|
-
{originToken?.symbol || "TOKEN"}
|
|
683
|
-
</span>
|
|
684
|
-
{isLoadingQuote && (
|
|
685
|
-
<div className="ml-2 animate-spin rounded-full h-4 w-4 border-solid border-b-2 trails-primary" />
|
|
686
|
-
)}
|
|
687
|
-
</div>
|
|
715
|
+
<div className="flex items-center space-x-2">
|
|
716
|
+
<input
|
|
717
|
+
ref={paymentRequestInputRef}
|
|
718
|
+
type="text"
|
|
719
|
+
value={prepareSendQuote?.originAmountFormatted || ""}
|
|
720
|
+
placeholder={`0 ${originToken?.symbol || ""}`.trim()}
|
|
721
|
+
readOnly={true}
|
|
722
|
+
className={`w-full bg-transparent font-bold trails-text-primary border-none outline-none ${
|
|
723
|
+
isLoadingQuote ? "animate-pulse" : ""
|
|
724
|
+
}`}
|
|
725
|
+
style={originInputStyles}
|
|
726
|
+
/>
|
|
727
|
+
{isLoadingQuote && (
|
|
728
|
+
<div className="animate-spin rounded-full h-4 w-4 border-solid border-b-2 trails-primary" />
|
|
729
|
+
)}
|
|
688
730
|
</div>
|
|
689
731
|
</div>
|
|
690
732
|
|
|
691
|
-
{/* Origin Token Selection
|
|
692
|
-
<
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
<TokenImage
|
|
700
|
-
symbol={originToken.symbol}
|
|
701
|
-
imageUrl={originToken.imageUrl}
|
|
702
|
-
chainId={originToken.chainId}
|
|
703
|
-
size={20}
|
|
704
|
-
/>
|
|
705
|
-
<span className="font-medium trails-text-primary text-sm">
|
|
706
|
-
{originToken.symbol}
|
|
707
|
-
</span>
|
|
708
|
-
<ChevronDown className="w-3.5 h-3.5 trails-text-muted" />
|
|
709
|
-
</>
|
|
710
|
-
) : (
|
|
711
|
-
<>
|
|
712
|
-
<span className="font-medium trails-text-muted text-sm">
|
|
713
|
-
Select Token
|
|
714
|
-
</span>
|
|
715
|
-
<ChevronDown className="w-3.5 h-3.5 trails-text-muted" />
|
|
716
|
-
</>
|
|
717
|
-
)}
|
|
718
|
-
</button>
|
|
733
|
+
{/* Origin Token Selection */}
|
|
734
|
+
<div className="relative">
|
|
735
|
+
<TokenSelectorButton
|
|
736
|
+
token={originToken}
|
|
737
|
+
chainId={originToken?.chainId}
|
|
738
|
+
onSelect={() => setShowOriginTokenSelector(true)}
|
|
739
|
+
/>
|
|
740
|
+
</div>
|
|
719
741
|
</div>
|
|
720
742
|
|
|
721
743
|
{/* Bottom Info Row */}
|
|
@@ -729,9 +751,59 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
729
751
|
<span> </span>
|
|
730
752
|
)}
|
|
731
753
|
</div>
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
754
|
+
|
|
755
|
+
{/* Origin Token Balance and Percentage Buttons */}
|
|
756
|
+
{originToken && originTokenBalance?.balanceFormatted && (
|
|
757
|
+
<div className="flex items-center space-x-2">
|
|
758
|
+
<button
|
|
759
|
+
type="button"
|
|
760
|
+
className="text-xs trails-text-muted cursor-pointer hover:trails-hover-text transition-colors bg-transparent border-none p-0"
|
|
761
|
+
onClick={() => {
|
|
762
|
+
if (originTokenBalance.balanceFormatted) {
|
|
763
|
+
const balance = parseFloat(
|
|
764
|
+
originTokenBalance.balanceFormatted,
|
|
765
|
+
)
|
|
766
|
+
if (!Number.isNaN(balance)) {
|
|
767
|
+
setTokenAmountForBackend(balance.toFixed(6))
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
}}
|
|
771
|
+
onKeyDown={(e) => {
|
|
772
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
773
|
+
e.preventDefault()
|
|
774
|
+
if (originTokenBalance.balanceFormatted) {
|
|
775
|
+
const balance = parseFloat(
|
|
776
|
+
originTokenBalance.balanceFormatted,
|
|
777
|
+
)
|
|
778
|
+
if (!Number.isNaN(balance)) {
|
|
779
|
+
setTokenAmountForBackend(balance.toFixed(6))
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
}}
|
|
784
|
+
title="Click to use full balance"
|
|
785
|
+
>
|
|
786
|
+
Balance: {originTokenBalance.balanceFormatted}
|
|
787
|
+
</button>
|
|
788
|
+
|
|
789
|
+
{/* Percentage Buttons - Only show if toAmount is not set */}
|
|
790
|
+
{!toAmount && (
|
|
791
|
+
<PercentageMaxButtons
|
|
792
|
+
userBalance={originTokenBalance.balanceFormatted}
|
|
793
|
+
isNativeToken={
|
|
794
|
+
originToken.contractAddress === zeroAddress ||
|
|
795
|
+
originToken.contractAddress === undefined
|
|
796
|
+
}
|
|
797
|
+
gasCostFormatted={prepareSendQuote?.gasCostFormatted}
|
|
798
|
+
chainId={originToken.chainId}
|
|
799
|
+
onAmountSelect={(amount) => {
|
|
800
|
+
setTokenAmountForBackend(amount)
|
|
801
|
+
}}
|
|
802
|
+
className="opacity-100"
|
|
803
|
+
/>
|
|
804
|
+
)}
|
|
805
|
+
</div>
|
|
806
|
+
)}
|
|
735
807
|
</div>
|
|
736
808
|
</div>
|
|
737
809
|
</div>
|
|
@@ -817,12 +889,7 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
817
889
|
>
|
|
818
890
|
<div className="text-left">
|
|
819
891
|
<div className="font-medium trails-text-primary text-sm">
|
|
820
|
-
|
|
821
|
-
{fundMethod === "qr-code"
|
|
822
|
-
? " QR Code"
|
|
823
|
-
: fundMethod === "exchange"
|
|
824
|
-
? " Exchange"
|
|
825
|
-
: ""}
|
|
892
|
+
Payment method
|
|
826
893
|
</div>
|
|
827
894
|
</div>
|
|
828
895
|
|
|
@@ -866,113 +933,46 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
866
933
|
|
|
867
934
|
<div className="space-y-1">
|
|
868
935
|
{/* Destination Amount Input Section - Like Fund.tsx but for destination token */}
|
|
869
|
-
<div className="trails-bg-secondary trails-bg-secondary-hover trails-border-radius-container p-3 group transition-all duration-200 border border-transparent focus-within:!bg-white dark:focus-within:!bg-gray-800 trails-focus-border-secondary">
|
|
936
|
+
<div className="trails-bg-secondary trails-bg-secondary-hover trails-border-radius-container p-3 group transition-all duration-200 border border-transparent focus-within:!bg-white dark:focus-within:!bg-gray-800 trails-focus-border-secondary min-h-[120px] flex flex-col">
|
|
870
937
|
{/* Amount to Pay Label */}
|
|
871
938
|
<div className="flex justify-between items-center mb-2">
|
|
872
939
|
<div className="text-sm font-medium trails-text-secondary text-left">
|
|
873
940
|
Recipient receives
|
|
874
941
|
</div>
|
|
942
|
+
<FundingMethodSelectorButton />
|
|
875
943
|
</div>
|
|
876
944
|
|
|
877
|
-
<div className="flex items-center space-x-2">
|
|
945
|
+
<div className="flex items-center space-x-2 flex-1">
|
|
878
946
|
{/* Amount Input */}
|
|
879
947
|
<div className="flex-1">
|
|
880
|
-
<div
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
fontSize: inputStyles.fontSize,
|
|
897
|
-
width: `${Math.max((displayAmount || "0").length - 1 + 0.5, 1)}ch`,
|
|
898
|
-
minWidth: "1ch",
|
|
899
|
-
maxWidth: "270px",
|
|
900
|
-
padding: "0",
|
|
901
|
-
margin: "0",
|
|
902
|
-
transition: "all 0.1s ease-in-out",
|
|
903
|
-
}}
|
|
904
|
-
inputMode="decimal"
|
|
905
|
-
/>
|
|
906
|
-
<span
|
|
907
|
-
className="font-bold text-gray-400 dark:text-gray-500"
|
|
908
|
-
style={{
|
|
909
|
-
fontSize: inputStyles.fontSize,
|
|
910
|
-
marginLeft: "0.1em",
|
|
911
|
-
padding: "0",
|
|
912
|
-
transition: "all 0.2s ease-in-out",
|
|
913
|
-
}}
|
|
914
|
-
>
|
|
915
|
-
{selectedDestToken?.symbol?.slice(0, 4) || "TOKEN"}
|
|
916
|
-
</span>
|
|
917
|
-
{isLoadingQuote && (
|
|
918
|
-
<div className="ml-2 animate-spin rounded-full h-4 w-4 border-solid border-b-2 trails-primary" />
|
|
919
|
-
)}
|
|
920
|
-
</div>
|
|
948
|
+
<div className="flex items-center space-x-2">
|
|
949
|
+
<input
|
|
950
|
+
ref={inputRef}
|
|
951
|
+
type="text"
|
|
952
|
+
value={displayAmount}
|
|
953
|
+
onChange={(e) => handleAmountChange(e.target.value)}
|
|
954
|
+
placeholder={`0 ${selectedDestToken?.symbol || ""}`}
|
|
955
|
+
readOnly={!!toAmount}
|
|
956
|
+
className={`w-full bg-transparent font-bold trails-text-primary placeholder:trails-text-muted border-none outline-none ${
|
|
957
|
+
isLoadingQuote ? "animate-pulse" : ""
|
|
958
|
+
}`}
|
|
959
|
+
style={inputStyles}
|
|
960
|
+
/>
|
|
961
|
+
{isLoadingQuote && (
|
|
962
|
+
<div className="animate-spin rounded-full h-4 w-4 border-solid border-b-2 trails-primary" />
|
|
963
|
+
)}
|
|
921
964
|
</div>
|
|
922
965
|
</div>
|
|
923
966
|
|
|
924
|
-
{/* Destination Token Selection
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
{
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
chainId={globalDestinationToken?.chainId || toChainId}
|
|
934
|
-
size={20}
|
|
935
|
-
/>
|
|
936
|
-
<span className="font-medium trails-text-primary text-sm">
|
|
937
|
-
{selectedDestToken.symbol}
|
|
938
|
-
</span>
|
|
939
|
-
</>
|
|
940
|
-
) : (
|
|
941
|
-
<span className="font-medium trails-text-muted text-sm">
|
|
942
|
-
Select Token
|
|
943
|
-
</span>
|
|
944
|
-
)}
|
|
945
|
-
</div>
|
|
946
|
-
) : (
|
|
947
|
-
/* Clickable button when toToken is not provided */
|
|
948
|
-
<button
|
|
949
|
-
type="button"
|
|
950
|
-
onClick={() => setShowDestinationTokenSelector(true)}
|
|
951
|
-
className="flex items-center space-x-2 trails-bg-card hover:trails-hover-bg trails-border-radius-input px-2.5 py-1.5 border trails-border-primary transition-colors cursor-pointer"
|
|
952
|
-
>
|
|
953
|
-
{selectedDestToken ? (
|
|
954
|
-
<>
|
|
955
|
-
<TokenImage
|
|
956
|
-
symbol={selectedDestToken.symbol}
|
|
957
|
-
imageUrl={selectedDestToken.imageUrl}
|
|
958
|
-
chainId={globalDestinationToken?.chainId || toChainId}
|
|
959
|
-
size={20}
|
|
960
|
-
/>
|
|
961
|
-
<span className="font-medium trails-text-primary text-sm">
|
|
962
|
-
{selectedDestToken.symbol}
|
|
963
|
-
</span>
|
|
964
|
-
<ChevronDown className="w-3.5 h-3.5 trails-text-muted" />
|
|
965
|
-
</>
|
|
966
|
-
) : (
|
|
967
|
-
<>
|
|
968
|
-
<span className="font-medium trails-text-muted text-sm">
|
|
969
|
-
Select Token
|
|
970
|
-
</span>
|
|
971
|
-
<ChevronDown className="w-3.5 h-3.5 trails-text-muted" />
|
|
972
|
-
</>
|
|
973
|
-
)}
|
|
974
|
-
</button>
|
|
975
|
-
)}
|
|
967
|
+
{/* Destination Token Selection */}
|
|
968
|
+
<div className="relative">
|
|
969
|
+
<TokenSelectorButton
|
|
970
|
+
token={selectedDestToken}
|
|
971
|
+
chainId={globalDestinationToken?.chainId || toChainId}
|
|
972
|
+
onSelect={() => setShowDestinationTokenSelector(true)}
|
|
973
|
+
unselectable={!!toToken}
|
|
974
|
+
/>
|
|
975
|
+
</div>
|
|
976
976
|
</div>
|
|
977
977
|
|
|
978
978
|
{/* Bottom Info Row */}
|
|
@@ -985,9 +985,6 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
985
985
|
<span> </span>
|
|
986
986
|
)}
|
|
987
987
|
</div>
|
|
988
|
-
<div className="text-xs trails-text-muted">
|
|
989
|
-
<span> </span>
|
|
990
|
-
</div>
|
|
991
988
|
</div>
|
|
992
989
|
</div>
|
|
993
990
|
</div>
|
|
@@ -999,6 +996,7 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
999
996
|
fundMethod={fundMethod}
|
|
1000
997
|
isSenderContractOnOrigin={isSenderContractOnOrigin}
|
|
1001
998
|
isSenderContractOnDestination={isSenderContractOnDestination}
|
|
999
|
+
isSequenceWallet={isSequenceWallet}
|
|
1002
1000
|
/>
|
|
1003
1001
|
|
|
1004
1002
|
{/* Error Display */}
|
|
@@ -1040,6 +1038,13 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
1040
1038
|
chainId={originToken?.chainId}
|
|
1041
1039
|
/>
|
|
1042
1040
|
|
|
1041
|
+
{/* Quote Details */}
|
|
1042
|
+
{prepareSendQuote && (
|
|
1043
|
+
<div className="space-y-2">
|
|
1044
|
+
<QuoteDetails quote={prepareSendQuote} showContent={true} />
|
|
1045
|
+
</div>
|
|
1046
|
+
)}
|
|
1047
|
+
|
|
1043
1048
|
{/* Pay Button */}
|
|
1044
1049
|
<form onSubmit={handleSubmit}>
|
|
1045
1050
|
<button
|
|
@@ -1078,13 +1083,6 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
1078
1083
|
)}
|
|
1079
1084
|
</button>
|
|
1080
1085
|
</form>
|
|
1081
|
-
|
|
1082
|
-
{/* Quote Details */}
|
|
1083
|
-
{prepareSendQuote && (
|
|
1084
|
-
<div className="space-y-2">
|
|
1085
|
-
<QuoteDetails quote={prepareSendQuote} showContent={true} />
|
|
1086
|
-
</div>
|
|
1087
|
-
)}
|
|
1088
1086
|
</div>
|
|
1089
1087
|
)
|
|
1090
1088
|
}
|