0xtrails 0.2.4 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/aave.d.ts +8 -0
- package/dist/aave.d.ts.map +1 -1
- package/dist/abortController.d.ts +8 -0
- package/dist/abortController.d.ts.map +1 -0
- package/dist/{ccip-BlV1Mry3.js → ccip-Xjh9d1gb.js} +7 -7
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/constants.d.ts +3 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/error.d.ts +1 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/estimate.d.ts +52 -0
- package/dist/estimate.d.ts.map +1 -1
- package/dist/fees.d.ts +19 -0
- package/dist/fees.d.ts.map +1 -0
- package/dist/{index-BNWCIGfQ.js → index-BnhdZ8Ho.js} +76406 -75798
- package/dist/index.js +726 -520
- package/dist/intents.d.ts +40 -0
- package/dist/intents.d.ts.map +1 -1
- package/dist/metaTxnMonitor.d.ts +3 -3
- package/dist/metaTxnMonitor.d.ts.map +1 -1
- package/dist/metaTxns.d.ts +3 -3
- package/dist/metaTxns.d.ts.map +1 -1
- package/dist/morpho.d.ts +8 -0
- package/dist/morpho.d.ts.map +1 -1
- package/dist/prepareSend.d.ts +19 -75
- package/dist/prepareSend.d.ts.map +1 -1
- package/dist/queryParams.d.ts.map +1 -1
- package/dist/relayer.d.ts +6 -6
- package/dist/relayer.d.ts.map +1 -1
- package/dist/sequenceWallet.d.ts +2 -2
- package/dist/sequenceWallet.d.ts.map +1 -1
- package/dist/tokens.d.ts.map +1 -1
- package/dist/transactions.d.ts +4 -2
- package/dist/transactions.d.ts.map +1 -1
- package/dist/wallets.d.ts.map +1 -1
- package/dist/widget/components/AccountActionsDropdown.d.ts.map +1 -1
- package/dist/widget/components/AccountIntentTransactionHistoryButton.d.ts +4 -0
- package/dist/widget/components/AccountIntentTransactionHistoryButton.d.ts.map +1 -0
- package/dist/widget/components/AccountSettings.d.ts.map +1 -1
- package/dist/widget/components/ChainFilterDropdown.d.ts.map +1 -1
- package/dist/widget/components/ClassicSwap.d.ts +4 -2
- package/dist/widget/components/ClassicSwap.d.ts.map +1 -1
- package/dist/widget/components/ConnectWallet.d.ts.map +1 -1
- package/dist/widget/components/ConnectedWallets.d.ts +4 -0
- package/dist/widget/components/ConnectedWallets.d.ts.map +1 -1
- package/dist/widget/components/DynamicInputStyles.d.ts +18 -0
- package/dist/widget/components/DynamicInputStyles.d.ts.map +1 -0
- package/dist/widget/components/Earn.d.ts +2 -2
- package/dist/widget/components/Earn.d.ts.map +1 -1
- package/dist/widget/components/ErrorAnimationIcon.d.ts +2 -0
- package/dist/widget/components/ErrorAnimationIcon.d.ts.map +1 -0
- package/dist/widget/components/FeeBreakdown.d.ts +9 -0
- package/dist/widget/components/FeeBreakdown.d.ts.map +1 -0
- package/dist/widget/components/Fund.d.ts +2 -2
- package/dist/widget/components/Fund.d.ts.map +1 -1
- package/dist/widget/components/FundMethods.d.ts.map +1 -1
- package/dist/widget/components/{FundSendForm.d.ts → FundSwap.d.ts} +13 -7
- package/dist/widget/components/FundSwap.d.ts.map +1 -0
- package/dist/widget/components/FundingMethodSelectorButton.d.ts +4 -0
- package/dist/widget/components/FundingMethodSelectorButton.d.ts.map +1 -0
- package/dist/widget/components/Identicon.d.ts.map +1 -1
- package/dist/widget/components/MeshConnectExchanges.d.ts +0 -3
- package/dist/widget/components/MeshConnectExchanges.d.ts.map +1 -1
- package/dist/widget/components/Modal.d.ts.map +1 -1
- package/dist/widget/components/Pay.d.ts +2 -2
- package/dist/widget/components/Pay.d.ts.map +1 -1
- package/dist/widget/components/PercentageMaxButtons.d.ts +12 -0
- package/dist/widget/components/PercentageMaxButtons.d.ts.map +1 -0
- package/dist/widget/components/{PaySendForm.d.ts → PoolDeposit.d.ts} +14 -36
- package/dist/widget/components/PoolDeposit.d.ts.map +1 -0
- package/dist/widget/components/{SimpleSwap.d.ts → PoolWithdraw.d.ts} +19 -10
- package/dist/widget/components/PoolWithdraw.d.ts.map +1 -0
- package/dist/widget/components/QuoteDetails.d.ts +1 -0
- package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
- package/dist/widget/components/Receipt.d.ts.map +1 -1
- package/dist/widget/components/Receive.d.ts.map +1 -1
- package/dist/widget/components/RecipientSelectorButton.d.ts +4 -0
- package/dist/widget/components/RecipientSelectorButton.d.ts.map +1 -0
- package/dist/widget/components/Recipients.d.ts.map +1 -1
- package/dist/widget/components/RequiredPropsError.d.ts +8 -0
- package/dist/widget/components/RequiredPropsError.d.ts.map +1 -0
- package/dist/widget/components/ScreenHeader.d.ts.map +1 -1
- package/dist/widget/components/SlippageToleranceSettings.d.ts.map +1 -1
- package/dist/widget/components/Swap.d.ts +3 -2
- package/dist/widget/components/Swap.d.ts.map +1 -1
- package/dist/widget/components/SwapSettings.d.ts.map +1 -1
- package/dist/widget/components/ThemeProvider.d.ts.map +1 -1
- package/dist/widget/components/TokenDisplayNonSelectable.d.ts +11 -0
- package/dist/widget/components/TokenDisplayNonSelectable.d.ts.map +1 -0
- package/dist/widget/components/TokenImage.d.ts +1 -0
- package/dist/widget/components/TokenImage.d.ts.map +1 -1
- package/dist/widget/components/TokenList.d.ts.map +1 -1
- package/dist/widget/components/TokenSelector.d.ts.map +1 -1
- package/dist/widget/components/TokenSelectorButton.d.ts +16 -0
- package/dist/widget/components/TokenSelectorButton.d.ts.map +1 -0
- package/dist/widget/components/Tooltip.d.ts +9 -0
- package/dist/widget/components/Tooltip.d.ts.map +1 -0
- package/dist/widget/components/UserPreferences.d.ts.map +1 -1
- package/dist/widget/components/WaasFeeOptions.d.ts +9 -0
- package/dist/widget/components/WaasFeeOptions.d.ts.map +1 -0
- package/dist/widget/components/WalletConfirmation.d.ts.map +1 -1
- package/dist/widget/components/WalletConnect.d.ts.map +1 -1
- package/dist/widget/components/WalletList.d.ts.map +1 -1
- package/dist/widget/css/compiled.css +2 -0
- package/dist/widget/css/index.css +554 -0
- package/dist/widget/hooks/useBack.d.ts +1 -0
- package/dist/widget/hooks/useBack.d.ts.map +1 -1
- package/dist/widget/hooks/useCheckout.d.ts +1 -1
- package/dist/widget/hooks/useCheckout.d.ts.map +1 -1
- package/dist/widget/hooks/useCurrentScreen.d.ts +1 -1
- package/dist/widget/hooks/useCurrentScreen.d.ts.map +1 -1
- package/dist/widget/hooks/useDefaultTokenSelection.d.ts +3 -3
- package/dist/widget/hooks/useDefaultTokenSelection.d.ts.map +1 -1
- package/dist/widget/hooks/usePayMessage.d.ts.map +1 -1
- package/dist/widget/hooks/useQuote.d.ts +83 -0
- package/dist/widget/hooks/useQuote.d.ts.map +1 -0
- package/dist/widget/hooks/useSelectedFundMethod.d.ts +12 -0
- package/dist/widget/hooks/useSelectedFundMethod.d.ts.map +1 -0
- package/dist/widget/hooks/useSelectedRecipient.d.ts.map +1 -1
- package/dist/widget/hooks/useSendForm.d.ts +2 -2
- package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
- package/dist/widget/index.js +2 -2
- package/dist/widget/widget.d.ts +9 -4
- package/dist/widget/widget.d.ts.map +1 -1
- package/package.json +18 -12
- package/src/aave.ts +32 -0
- package/src/abortController.ts +35 -0
- package/src/config.ts +12 -4
- package/src/constants.ts +5 -0
- package/src/error.ts +19 -1
- package/src/estimate.ts +416 -5
- package/src/fees.ts +199 -0
- package/src/intents.ts +161 -11
- package/src/metaTxnMonitor.ts +3 -3
- package/src/metaTxns.ts +3 -5
- package/src/morpho.ts +32 -0
- package/src/prepareSend.ts +714 -550
- package/src/queryParams.ts +2 -1
- package/src/relayer.ts +11 -11
- package/src/sequenceWallet.ts +2 -2
- package/src/tokens.ts +7 -1
- package/src/trails.ts +3 -3
- package/src/transactions.ts +62 -18
- package/src/wallets.ts +8 -0
- package/src/widget/compiled.css +2 -2
- package/src/widget/components/AccountActionsDropdown.tsx +3 -13
- package/src/widget/components/AccountIntentTransactionHistoryButton.tsx +22 -0
- package/src/widget/components/AccountSettings.tsx +48 -54
- package/src/widget/components/ChainFilterDropdown.tsx +24 -3
- package/src/widget/components/ClassicSwap.tsx +131 -213
- package/src/widget/components/ConnectWallet.tsx +8 -38
- package/src/widget/components/ConnectedWallets.tsx +132 -77
- package/src/widget/components/DynamicInputStyles.tsx +76 -0
- package/src/widget/components/Earn.tsx +82 -593
- package/src/widget/components/ErrorAnimationIcon.tsx +130 -0
- package/src/widget/components/FeeBreakdown.tsx +155 -0
- package/src/widget/components/Fund.tsx +41 -108
- package/src/widget/components/FundMethods.tsx +82 -159
- package/src/widget/components/FundSwap.tsx +52 -0
- package/src/widget/components/FundingMethodSelectorButton.tsx +70 -0
- package/src/widget/components/Identicon.tsx +164 -95
- package/src/widget/components/MeshConnectExchanges.tsx +2 -15
- package/src/widget/components/Modal.tsx +0 -8
- package/src/widget/components/Pay.tsx +214 -237
- package/src/widget/components/PercentageMaxButtons.tsx +77 -0
- package/src/widget/components/PoolDeposit.tsx +569 -0
- package/src/widget/components/PoolWithdraw.tsx +884 -0
- package/src/widget/components/PriceImpactWarning.tsx +1 -1
- package/src/widget/components/QuoteDetails.tsx +43 -12
- package/src/widget/components/Receipt.tsx +16 -2
- package/src/widget/components/Receive.tsx +0 -2
- package/src/widget/components/RecipientSelectorButton.tsx +44 -0
- package/src/widget/components/Recipients.tsx +63 -157
- package/src/widget/components/RequiredPropsError.tsx +33 -0
- package/src/widget/components/ScreenHeader.tsx +62 -34
- package/src/widget/components/SlippageToleranceSettings.tsx +2 -1
- package/src/widget/components/Swap.tsx +4 -45
- package/src/widget/components/SwapSettings.tsx +2 -14
- package/src/widget/components/ThemeProvider.tsx +2 -1
- package/src/widget/components/TokenDisplayNonSelectable.tsx +40 -0
- package/src/widget/components/TokenImage.tsx +22 -5
- package/src/widget/components/TokenList.tsx +0 -1
- package/src/widget/components/TokenSelector.tsx +63 -53
- package/src/widget/components/TokenSelectorButton.tsx +98 -0
- package/src/widget/components/Tooltip.tsx +51 -0
- package/src/widget/components/TransferPendingVertical.tsx +1 -1
- package/src/widget/components/UserPreferences.tsx +6 -24
- package/src/widget/components/WaasFeeOptions.tsx +450 -0
- package/src/widget/components/WalletConfirmation.tsx +76 -14
- package/src/widget/components/WalletConnect.tsx +93 -29
- package/src/widget/components/WalletList.tsx +4 -2
- package/src/widget/hooks/useBack.tsx +2 -0
- package/src/widget/hooks/useCheckout.ts +36 -20
- package/src/widget/hooks/useCurrentScreen.tsx +1 -0
- package/src/widget/hooks/useDefaultTokenSelection.tsx +104 -28
- package/src/widget/hooks/usePayMessage.tsx +86 -11
- package/src/widget/hooks/useQuote.ts +413 -0
- package/src/widget/hooks/useSelectedFundMethod.tsx +41 -0
- package/src/widget/hooks/useSelectedRecipient.tsx +10 -0
- package/src/widget/hooks/useSendForm.ts +32 -6
- package/src/widget/index.css +27 -0
- package/src/widget/widget.tsx +326 -283
- package/dist/widget/components/FundSendForm.d.ts.map +0 -1
- package/dist/widget/components/PaySendForm.d.ts.map +0 -1
- package/dist/widget/components/SimpleSwap.d.ts.map +0 -1
- package/dist/widget/hooks/useSwapSettings.d.ts +0 -16
- package/dist/widget/hooks/useSwapSettings.d.ts.map +0 -1
- package/src/widget/components/FundSendForm.tsx +0 -903
- package/src/widget/components/PaySendForm.tsx +0 -869
- package/src/widget/components/SimpleSwap.tsx +0 -983
- package/src/widget/hooks/useSwapSettings.tsx +0 -100
|
@@ -1,7 +1,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,12 +32,17 @@ 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"
|
|
39
|
+
import { useDynamicInputStyles } from "./DynamicInputStyles.js"
|
|
34
40
|
|
|
35
41
|
interface PayProps {
|
|
36
42
|
selectedToken?: any // Origin token (optional - user can select)
|
|
37
43
|
onBack?: () => void
|
|
38
|
-
account
|
|
39
|
-
walletClient
|
|
44
|
+
account?: Account
|
|
45
|
+
walletClient?: WalletClient
|
|
40
46
|
onTransactionStateChange: (transactionStates: TransactionState[]) => void
|
|
41
47
|
onError: (error: Error | string | null) => void
|
|
42
48
|
onWaitingForWalletConfirm: (props: PrepareSendQuote) => void
|
|
@@ -157,6 +163,19 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
157
163
|
)
|
|
158
164
|
}, [originToken, filteredTokensFormatted])
|
|
159
165
|
|
|
166
|
+
// Calculate effective recipient for useSendForm
|
|
167
|
+
const effectiveRecipient = useMemo(() => {
|
|
168
|
+
const recipient = selectedRecipient || toRecipient || account?.address
|
|
169
|
+
logger.console.log("[trails-sdk] Effective recipient calculated:", {
|
|
170
|
+
selectedRecipient,
|
|
171
|
+
toRecipient,
|
|
172
|
+
accountAddress: account?.address,
|
|
173
|
+
effectiveRecipient: recipient,
|
|
174
|
+
willPassToUseSendForm: recipient,
|
|
175
|
+
})
|
|
176
|
+
return recipient
|
|
177
|
+
}, [selectedRecipient, toRecipient, account?.address])
|
|
178
|
+
|
|
160
179
|
// Use useSendForm for quote functionality with EXACT_OUTPUT trade type
|
|
161
180
|
const {
|
|
162
181
|
amountUsdDisplay,
|
|
@@ -182,7 +201,7 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
182
201
|
} = useSendForm({
|
|
183
202
|
account,
|
|
184
203
|
toAmount: tokenAmountForBackend || toAmount, // Use the input amount as target amount for EXACT_OUTPUT
|
|
185
|
-
toRecipient:
|
|
204
|
+
toRecipient: effectiveRecipient,
|
|
186
205
|
toChainId,
|
|
187
206
|
toToken,
|
|
188
207
|
toCalldata,
|
|
@@ -283,15 +302,31 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
283
302
|
setSelectedDestinationChain,
|
|
284
303
|
])
|
|
285
304
|
|
|
286
|
-
// Initialize selected recipient from toRecipient prop or default to connected wallet
|
|
305
|
+
// Initialize and update selected recipient from toRecipient prop or default to connected wallet
|
|
306
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: selectedRecipient is intentionally excluded to avoid infinite loops
|
|
287
307
|
useEffect(() => {
|
|
288
|
-
|
|
308
|
+
logger.console.log("[trails-sdk] toRecipient prop effect:", {
|
|
309
|
+
toRecipient,
|
|
310
|
+
selectedRecipient,
|
|
311
|
+
accountAddress: account?.address,
|
|
312
|
+
})
|
|
313
|
+
|
|
314
|
+
if (toRecipient) {
|
|
315
|
+
// Always sync with toRecipient prop when it changes
|
|
316
|
+
logger.console.log(
|
|
317
|
+
"[trails-sdk] Setting selectedRecipient to toRecipient:",
|
|
318
|
+
toRecipient,
|
|
319
|
+
)
|
|
289
320
|
setSelectedRecipient(toRecipient)
|
|
290
321
|
} else if (!selectedRecipient && account?.address) {
|
|
291
322
|
// Default to connected wallet address if no recipient is set
|
|
323
|
+
logger.console.log(
|
|
324
|
+
"[trails-sdk] Setting selectedRecipient to account address:",
|
|
325
|
+
account.address,
|
|
326
|
+
)
|
|
292
327
|
setSelectedRecipient(account.address)
|
|
293
328
|
}
|
|
294
|
-
}, [toRecipient,
|
|
329
|
+
}, [toRecipient, setSelectedRecipient, account?.address])
|
|
295
330
|
|
|
296
331
|
// Initialize and update amount from toAmount prop
|
|
297
332
|
useEffect(() => {
|
|
@@ -328,10 +363,12 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
328
363
|
const destTokenToUse = globalDestinationToken || defaultDestinationToken
|
|
329
364
|
|
|
330
365
|
if (destTokenToUse && !isLoadingDefaults) {
|
|
331
|
-
logger.console.log(
|
|
332
|
-
|
|
333
|
-
destTokenToUse,
|
|
334
|
-
|
|
366
|
+
logger.console.log("[trails-sdk] Initializing destination token:", {
|
|
367
|
+
symbol: destTokenToUse.symbol,
|
|
368
|
+
chainId: destTokenToUse.chainId,
|
|
369
|
+
name: destTokenToUse.name,
|
|
370
|
+
contractAddress: destTokenToUse.contractAddress,
|
|
371
|
+
})
|
|
335
372
|
|
|
336
373
|
// Set destination token if not already set by global state
|
|
337
374
|
if (!globalDestinationToken && defaultDestinationToken) {
|
|
@@ -417,28 +454,13 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
417
454
|
return inputDisplayValue
|
|
418
455
|
}, [inputDisplayValue])
|
|
419
456
|
|
|
420
|
-
// Dynamic font size based on input length
|
|
421
|
-
const inputStyles =
|
|
422
|
-
const inputLength = displayAmount.length
|
|
423
|
-
let fontSize: string
|
|
424
|
-
|
|
425
|
-
if (inputLength > 12) {
|
|
426
|
-
fontSize = "0.875rem"
|
|
427
|
-
} else if (inputLength > 9) {
|
|
428
|
-
fontSize = "1rem"
|
|
429
|
-
} else if (inputLength > 6) {
|
|
430
|
-
fontSize = "1.125rem"
|
|
431
|
-
} else if (inputLength > 3) {
|
|
432
|
-
fontSize = "1.25rem"
|
|
433
|
-
} else {
|
|
434
|
-
fontSize = "1.5rem"
|
|
435
|
-
}
|
|
457
|
+
// Dynamic font size based on input length for destination amount
|
|
458
|
+
const inputStyles = useDynamicInputStyles({ inputValue: displayAmount })
|
|
436
459
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
}, [displayAmount.length])
|
|
460
|
+
// Dynamic font size based on input length for origin amount (Pay with section)
|
|
461
|
+
const originInputStyles = useDynamicInputStyles({
|
|
462
|
+
inputValue: prepareSendQuote?.originAmountFormatted || "",
|
|
463
|
+
})
|
|
442
464
|
|
|
443
465
|
const handleOriginTokenSelect = useCallback(
|
|
444
466
|
(token: any) => {
|
|
@@ -533,7 +555,6 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
533
555
|
onBack={() => setShowOriginTokenSelector(false)}
|
|
534
556
|
headerContent="Select Token"
|
|
535
557
|
headerContentAlign="left"
|
|
536
|
-
showAccountActions={true}
|
|
537
558
|
/>
|
|
538
559
|
<TokenSelector
|
|
539
560
|
onTokenSelect={handleOriginTokenSelect}
|
|
@@ -580,7 +601,6 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
580
601
|
onBack={() => setShowDestinationTokenSelector(false)}
|
|
581
602
|
headerContent="Select Token"
|
|
582
603
|
headerContentAlign="left"
|
|
583
|
-
showAccountActions={true}
|
|
584
604
|
/>
|
|
585
605
|
<TokenSelector
|
|
586
606
|
onTokenSelect={handleDestinationTokenSelect}
|
|
@@ -617,11 +637,35 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
617
637
|
)
|
|
618
638
|
}
|
|
619
639
|
|
|
640
|
+
// Check for required props
|
|
641
|
+
const missingRequiredProps = []
|
|
642
|
+
if (!toAmount) missingRequiredProps.push("toAmount")
|
|
643
|
+
if (!toToken) missingRequiredProps.push("toToken")
|
|
644
|
+
if (!toRecipient) missingRequiredProps.push("toAddress")
|
|
645
|
+
|
|
620
646
|
// Check if this is a payment request (all required props are set)
|
|
621
647
|
const isPaymentRequest = !!(toToken && toAmount && toChainId && toRecipient)
|
|
622
648
|
|
|
649
|
+
// If required props are missing, only show the error
|
|
650
|
+
if (missingRequiredProps.length > 0) {
|
|
651
|
+
return (
|
|
652
|
+
<div className="space-y-4">
|
|
653
|
+
<ScreenHeader
|
|
654
|
+
onBack={onBack}
|
|
655
|
+
headerContent="Pay"
|
|
656
|
+
headerContentAlign="left"
|
|
657
|
+
showAccountActions={true}
|
|
658
|
+
/>
|
|
659
|
+
<RequiredPropsError
|
|
660
|
+
missingProps={missingRequiredProps}
|
|
661
|
+
componentName="Pay"
|
|
662
|
+
/>
|
|
663
|
+
</div>
|
|
664
|
+
)
|
|
665
|
+
}
|
|
666
|
+
|
|
623
667
|
return (
|
|
624
|
-
<div className="space-y-
|
|
668
|
+
<div className="space-y-2">
|
|
625
669
|
<ScreenHeader
|
|
626
670
|
onBack={onBack}
|
|
627
671
|
headerContent="Pay"
|
|
@@ -635,18 +679,18 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
635
679
|
{/* Payment Request Header */}
|
|
636
680
|
<div className="space-y-1 trails-bg-secondary trails-border-radius-container p-3">
|
|
637
681
|
<div className="flex justify-start">
|
|
638
|
-
<div className="flex items-center font-medium trails-text-primary text-sm whitespace-nowrap overflow-hidden">
|
|
682
|
+
<div className="flex items-center font-medium trails-text-primary text-sm whitespace-nowrap overflow-hidden min-w-full">
|
|
639
683
|
{payMessage}
|
|
640
684
|
</div>
|
|
641
685
|
</div>
|
|
642
686
|
</div>
|
|
643
687
|
|
|
644
688
|
{/* Origin Token Selection for Payment Request */}
|
|
645
|
-
<div className="
|
|
646
|
-
<div className="
|
|
689
|
+
<div className="mb-4">
|
|
690
|
+
<div className="pt-4 pb-4 trails-bg-secondary trails-border-radius-container p-3 group transition-all duration-200 border border-transparent min-h-[120px] flex flex-col">
|
|
647
691
|
{/* Amount to Pay Label */}
|
|
648
|
-
<div className="flex justify-between items-center
|
|
649
|
-
<div className="text-sm font-
|
|
692
|
+
<div className="mb-4 flex justify-between items-center">
|
|
693
|
+
<div className="text-sm font-medium trails-text-secondary text-left m-0">
|
|
650
694
|
Pay with
|
|
651
695
|
{fundMethod === "qr-code"
|
|
652
696
|
? " QR Code"
|
|
@@ -654,88 +698,44 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
654
698
|
? " Exchange"
|
|
655
699
|
: ""}
|
|
656
700
|
</div>
|
|
701
|
+
<FundingMethodSelectorButton />
|
|
657
702
|
</div>
|
|
658
703
|
|
|
659
|
-
<div className="flex items-center space-x-2">
|
|
704
|
+
<div className="flex items-center space-x-2 flex-1">
|
|
660
705
|
{/* Amount Display - Non-editable */}
|
|
661
706
|
<div className="flex-1">
|
|
662
|
-
<div
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
width: prepareSendQuote?.originAmountFormatted
|
|
678
|
-
? `${Math.max(prepareSendQuote.originAmountFormatted.length - 1 + 0.5, 1)}ch`
|
|
679
|
-
: "1ch",
|
|
680
|
-
minWidth: "1ch",
|
|
681
|
-
maxWidth: "200px",
|
|
682
|
-
padding: "0",
|
|
683
|
-
margin: "0",
|
|
684
|
-
transition: "all 0.1s ease-in-out",
|
|
685
|
-
}}
|
|
686
|
-
/>
|
|
687
|
-
<span
|
|
688
|
-
className="font-bold text-gray-400 dark:text-gray-500"
|
|
689
|
-
style={{
|
|
690
|
-
fontSize: inputStyles.fontSize,
|
|
691
|
-
marginLeft: "0.1em",
|
|
692
|
-
padding: "0",
|
|
693
|
-
transition: "all 0.2s ease-in-out",
|
|
694
|
-
}}
|
|
695
|
-
>
|
|
696
|
-
{originToken?.symbol || "TOKEN"}
|
|
697
|
-
</span>
|
|
698
|
-
{isLoadingQuote && (
|
|
699
|
-
<div className="ml-2 animate-spin rounded-full h-4 w-4 border-solid border-b-2 trails-primary" />
|
|
700
|
-
)}
|
|
701
|
-
</div>
|
|
707
|
+
<div className="flex items-center space-x-2">
|
|
708
|
+
<input
|
|
709
|
+
ref={paymentRequestInputRef}
|
|
710
|
+
type="text"
|
|
711
|
+
value={prepareSendQuote?.originAmountFormatted || ""}
|
|
712
|
+
placeholder={"0"}
|
|
713
|
+
readOnly={true}
|
|
714
|
+
className={`w-full bg-transparent font-bold trails-text-primary border-none outline-none ${
|
|
715
|
+
isLoadingQuote ? "animate-pulse" : ""
|
|
716
|
+
}`}
|
|
717
|
+
style={originInputStyles}
|
|
718
|
+
/>
|
|
719
|
+
{isLoadingQuote && (
|
|
720
|
+
<div className="animate-spin rounded-full h-4 w-4 border-solid border-b-2 trails-primary" />
|
|
721
|
+
)}
|
|
702
722
|
</div>
|
|
703
723
|
</div>
|
|
704
724
|
|
|
705
|
-
{/* Origin Token Selection
|
|
706
|
-
<
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
<TokenImage
|
|
714
|
-
symbol={originToken.symbol}
|
|
715
|
-
imageUrl={originToken.imageUrl}
|
|
716
|
-
chainId={originToken.chainId}
|
|
717
|
-
size={20}
|
|
718
|
-
/>
|
|
719
|
-
<span className="font-medium trails-text-primary text-sm">
|
|
720
|
-
{originToken.symbol}
|
|
721
|
-
</span>
|
|
722
|
-
<ChevronDown className="w-3.5 h-3.5 trails-text-muted" />
|
|
723
|
-
</>
|
|
724
|
-
) : (
|
|
725
|
-
<>
|
|
726
|
-
<span className="font-medium trails-text-muted text-sm">
|
|
727
|
-
Select Token
|
|
728
|
-
</span>
|
|
729
|
-
<ChevronDown className="w-3.5 h-3.5 trails-text-muted" />
|
|
730
|
-
</>
|
|
731
|
-
)}
|
|
732
|
-
</button>
|
|
725
|
+
{/* Origin Token Selection */}
|
|
726
|
+
<div className="relative">
|
|
727
|
+
<TokenSelectorButton
|
|
728
|
+
token={originToken}
|
|
729
|
+
chainId={originToken?.chainId}
|
|
730
|
+
onSelect={() => setShowOriginTokenSelector(true)}
|
|
731
|
+
/>
|
|
732
|
+
</div>
|
|
733
733
|
</div>
|
|
734
734
|
|
|
735
735
|
{/* Bottom Info Row */}
|
|
736
|
-
<div className="mt-
|
|
736
|
+
<div className="mt-4 flex justify-between items-center">
|
|
737
737
|
{/* USD Amount */}
|
|
738
|
-
<div className="text-xs
|
|
738
|
+
<div className="text-xs text-gray-500 dark:text-gray-400">
|
|
739
739
|
{originToken?.symbol &&
|
|
740
740
|
prepareSendQuote?.originAmountFormatted ? (
|
|
741
741
|
<>≈ {prepareSendQuote?.originAmountUsdDisplay || "$0.00"}</>
|
|
@@ -743,17 +743,59 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
743
743
|
<span> </span>
|
|
744
744
|
)}
|
|
745
745
|
</div>
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
746
|
+
|
|
747
|
+
{/* Origin Token Balance and Percentage Buttons */}
|
|
748
|
+
{originToken && originTokenBalance?.balanceFormatted && (
|
|
749
|
+
<div className="flex items-center space-x-2">
|
|
750
|
+
<button
|
|
751
|
+
type="button"
|
|
752
|
+
className="text-xs text-gray-500 dark:text-gray-400 cursor-pointer hover:text-gray-700 dark:hover:text-gray-200 transition-colors bg-transparent border-none p-0"
|
|
753
|
+
onClick={() => {
|
|
754
|
+
if (originTokenBalance.balanceFormatted) {
|
|
755
|
+
const balance = parseFloat(
|
|
756
|
+
originTokenBalance.balanceFormatted,
|
|
757
|
+
)
|
|
758
|
+
if (!Number.isNaN(balance)) {
|
|
759
|
+
setTokenAmountForBackend(balance.toFixed(6))
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
}}
|
|
763
|
+
onKeyDown={(e) => {
|
|
764
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
765
|
+
e.preventDefault()
|
|
766
|
+
if (originTokenBalance.balanceFormatted) {
|
|
767
|
+
const balance = parseFloat(
|
|
768
|
+
originTokenBalance.balanceFormatted,
|
|
769
|
+
)
|
|
770
|
+
if (!Number.isNaN(balance)) {
|
|
771
|
+
setTokenAmountForBackend(balance.toFixed(6))
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
}}
|
|
776
|
+
title="Click to use full balance"
|
|
777
|
+
>
|
|
778
|
+
Balance: {originTokenBalance.balanceFormatted}
|
|
779
|
+
</button>
|
|
780
|
+
|
|
781
|
+
{/* Percentage Buttons - Only show if toAmount is not set */}
|
|
782
|
+
{!toAmount && (
|
|
783
|
+
<PercentageMaxButtons
|
|
784
|
+
userBalance={originTokenBalance.balanceFormatted}
|
|
785
|
+
isNativeToken={
|
|
786
|
+
originToken.contractAddress === zeroAddress ||
|
|
787
|
+
originToken.contractAddress === undefined
|
|
788
|
+
}
|
|
789
|
+
gasCostFormatted={prepareSendQuote?.gasCostFormatted}
|
|
790
|
+
chainId={originToken.chainId}
|
|
791
|
+
onAmountSelect={(amount) => {
|
|
792
|
+
setTokenAmountForBackend(amount)
|
|
793
|
+
}}
|
|
794
|
+
className="opacity-100"
|
|
795
|
+
/>
|
|
796
|
+
)}
|
|
797
|
+
</div>
|
|
798
|
+
)}
|
|
757
799
|
</div>
|
|
758
800
|
</div>
|
|
759
801
|
</div>
|
|
@@ -839,12 +881,7 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
839
881
|
>
|
|
840
882
|
<div className="text-left">
|
|
841
883
|
<div className="font-medium trails-text-primary text-sm">
|
|
842
|
-
|
|
843
|
-
{fundMethod === "qr-code"
|
|
844
|
-
? " QR Code"
|
|
845
|
-
: fundMethod === "exchange"
|
|
846
|
-
? " Exchange"
|
|
847
|
-
: ""}
|
|
884
|
+
Payment method
|
|
848
885
|
</div>
|
|
849
886
|
</div>
|
|
850
887
|
|
|
@@ -888,128 +925,64 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
888
925
|
|
|
889
926
|
<div className="space-y-1">
|
|
890
927
|
{/* Destination Amount Input Section - Like Fund.tsx but for destination token */}
|
|
891
|
-
<div
|
|
928
|
+
<div
|
|
929
|
+
className={`pt-4 pb-4 trails-bg-secondary trails-border-radius-container p-3 group transition-all duration-200 border border-transparent min-h-[120px] flex flex-col ${
|
|
930
|
+
!toAmount
|
|
931
|
+
? "trails-bg-secondary-hover focus-within:!bg-white dark:focus-within:!bg-gray-800 trails-focus-border-secondary"
|
|
932
|
+
: ""
|
|
933
|
+
}`}
|
|
934
|
+
>
|
|
892
935
|
{/* Amount to Pay Label */}
|
|
893
|
-
<div className="flex justify-between items-center
|
|
894
|
-
<div className="text-sm font-medium trails-text-secondary text-left">
|
|
936
|
+
<div className="mb-4 flex justify-between items-center">
|
|
937
|
+
<div className="text-sm font-medium trails-text-secondary text-left m-0">
|
|
895
938
|
Recipient receives
|
|
896
939
|
</div>
|
|
940
|
+
<FundingMethodSelectorButton />
|
|
897
941
|
</div>
|
|
898
942
|
|
|
899
|
-
<div className="flex items-center space-x-2">
|
|
943
|
+
<div className="flex items-center space-x-2 flex-1">
|
|
900
944
|
{/* Amount Input */}
|
|
901
945
|
<div className="flex-1">
|
|
902
|
-
<div
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
fontSize: inputStyles.fontSize,
|
|
919
|
-
width: `${Math.max((displayAmount || "0").length - 1 + 0.5, 1)}ch`,
|
|
920
|
-
minWidth: "1ch",
|
|
921
|
-
maxWidth: "270px",
|
|
922
|
-
padding: "0",
|
|
923
|
-
margin: "0",
|
|
924
|
-
transition: "all 0.1s ease-in-out",
|
|
925
|
-
}}
|
|
926
|
-
inputMode="decimal"
|
|
927
|
-
/>
|
|
928
|
-
<span
|
|
929
|
-
className="font-bold text-gray-400 dark:text-gray-500"
|
|
930
|
-
style={{
|
|
931
|
-
fontSize: inputStyles.fontSize,
|
|
932
|
-
marginLeft: "0.1em",
|
|
933
|
-
padding: "0",
|
|
934
|
-
transition: "all 0.2s ease-in-out",
|
|
935
|
-
}}
|
|
936
|
-
>
|
|
937
|
-
{selectedDestToken?.symbol?.slice(0, 4) || "TOKEN"}
|
|
938
|
-
</span>
|
|
939
|
-
{isLoadingQuote && (
|
|
940
|
-
<div className="ml-2 animate-spin rounded-full h-4 w-4 border-solid border-b-2 trails-primary" />
|
|
941
|
-
)}
|
|
942
|
-
</div>
|
|
946
|
+
<div className="flex items-center space-x-2">
|
|
947
|
+
<input
|
|
948
|
+
ref={inputRef}
|
|
949
|
+
type="text"
|
|
950
|
+
value={displayAmount}
|
|
951
|
+
onChange={(e) => handleAmountChange(e.target.value)}
|
|
952
|
+
placeholder={`0 ${selectedDestToken?.symbol || ""}`}
|
|
953
|
+
readOnly={!!toAmount}
|
|
954
|
+
className={`w-full bg-transparent font-bold trails-text-primary placeholder:trails-text-muted border-none outline-none ${
|
|
955
|
+
isLoadingQuote ? "animate-pulse" : ""
|
|
956
|
+
}`}
|
|
957
|
+
style={inputStyles}
|
|
958
|
+
/>
|
|
959
|
+
{isLoadingQuote && (
|
|
960
|
+
<div className="animate-spin rounded-full h-4 w-4 border-solid border-b-2 trails-primary" />
|
|
961
|
+
)}
|
|
943
962
|
</div>
|
|
944
963
|
</div>
|
|
945
964
|
|
|
946
|
-
{/* Destination Token Selection
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
{
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
chainId={globalDestinationToken?.chainId || toChainId}
|
|
956
|
-
size={20}
|
|
957
|
-
/>
|
|
958
|
-
<span className="font-medium trails-text-primary text-sm">
|
|
959
|
-
{selectedDestToken.symbol}
|
|
960
|
-
</span>
|
|
961
|
-
</>
|
|
962
|
-
) : (
|
|
963
|
-
<span className="font-medium trails-text-muted text-sm">
|
|
964
|
-
Select Token
|
|
965
|
-
</span>
|
|
966
|
-
)}
|
|
967
|
-
</div>
|
|
968
|
-
) : (
|
|
969
|
-
/* Clickable button when toToken is not provided */
|
|
970
|
-
<button
|
|
971
|
-
type="button"
|
|
972
|
-
onClick={() => setShowDestinationTokenSelector(true)}
|
|
973
|
-
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"
|
|
974
|
-
>
|
|
975
|
-
{selectedDestToken ? (
|
|
976
|
-
<>
|
|
977
|
-
<TokenImage
|
|
978
|
-
symbol={selectedDestToken.symbol}
|
|
979
|
-
imageUrl={selectedDestToken.imageUrl}
|
|
980
|
-
chainId={globalDestinationToken?.chainId || toChainId}
|
|
981
|
-
size={20}
|
|
982
|
-
/>
|
|
983
|
-
<span className="font-medium trails-text-primary text-sm">
|
|
984
|
-
{selectedDestToken.symbol}
|
|
985
|
-
</span>
|
|
986
|
-
<ChevronDown className="w-3.5 h-3.5 trails-text-muted" />
|
|
987
|
-
</>
|
|
988
|
-
) : (
|
|
989
|
-
<>
|
|
990
|
-
<span className="font-medium trails-text-muted text-sm">
|
|
991
|
-
Select Token
|
|
992
|
-
</span>
|
|
993
|
-
<ChevronDown className="w-3.5 h-3.5 trails-text-muted" />
|
|
994
|
-
</>
|
|
995
|
-
)}
|
|
996
|
-
</button>
|
|
997
|
-
)}
|
|
965
|
+
{/* Destination Token Selection */}
|
|
966
|
+
<div className="relative">
|
|
967
|
+
<TokenSelectorButton
|
|
968
|
+
token={selectedDestToken}
|
|
969
|
+
chainId={globalDestinationToken?.chainId || toChainId}
|
|
970
|
+
onSelect={() => setShowDestinationTokenSelector(true)}
|
|
971
|
+
unselectable={!!toToken}
|
|
972
|
+
/>
|
|
973
|
+
</div>
|
|
998
974
|
</div>
|
|
999
975
|
|
|
1000
976
|
{/* Bottom Info Row */}
|
|
1001
|
-
<div className="mt-
|
|
977
|
+
<div className="mt-4 flex justify-between items-center">
|
|
1002
978
|
{/* USD Amount */}
|
|
1003
|
-
<div className="text-xs
|
|
979
|
+
<div className="text-xs text-gray-500 dark:text-gray-400">
|
|
1004
980
|
{selectedDestToken?.symbol && displayAmount ? (
|
|
1005
981
|
<>≈ {amountUsdDisplay || "$0.00"}</>
|
|
1006
982
|
) : (
|
|
1007
983
|
<span> </span>
|
|
1008
984
|
)}
|
|
1009
985
|
</div>
|
|
1010
|
-
<div className="text-xs trails-text-muted">
|
|
1011
|
-
<span> </span>
|
|
1012
|
-
</div>
|
|
1013
986
|
</div>
|
|
1014
987
|
</div>
|
|
1015
988
|
</div>
|
|
@@ -1063,6 +1036,13 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
1063
1036
|
chainId={originToken?.chainId}
|
|
1064
1037
|
/>
|
|
1065
1038
|
|
|
1039
|
+
{/* Quote Details */}
|
|
1040
|
+
{prepareSendQuote && (
|
|
1041
|
+
<div className="mb-4">
|
|
1042
|
+
<QuoteDetails quote={prepareSendQuote} showContent={true} />
|
|
1043
|
+
</div>
|
|
1044
|
+
)}
|
|
1045
|
+
|
|
1066
1046
|
{/* Pay Button */}
|
|
1067
1047
|
<form onSubmit={handleSubmit}>
|
|
1068
1048
|
<button
|
|
@@ -1085,10 +1065,14 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
1085
1065
|
<Loader2 className="w-5 h-5 animate-spin mr-2" />
|
|
1086
1066
|
<span>{buttonText}</span>
|
|
1087
1067
|
</div>
|
|
1068
|
+
) : !account?.address ? (
|
|
1069
|
+
"Connect your wallet"
|
|
1088
1070
|
) : prepareSendQuote?.noSufficientBalance ? (
|
|
1089
1071
|
"Insufficient Balance"
|
|
1090
1072
|
) : !selectedRecipient ? (
|
|
1091
1073
|
"Select recipient address"
|
|
1074
|
+
) : !originToken ? (
|
|
1075
|
+
"Select payment token"
|
|
1092
1076
|
) : !selectedDestToken ? (
|
|
1093
1077
|
"Select destination token"
|
|
1094
1078
|
) : !tokenAmountForBackend ||
|
|
@@ -1101,13 +1085,6 @@ export const Pay: React.FC<PayProps> = ({
|
|
|
1101
1085
|
)}
|
|
1102
1086
|
</button>
|
|
1103
1087
|
</form>
|
|
1104
|
-
|
|
1105
|
-
{/* Quote Details */}
|
|
1106
|
-
{prepareSendQuote && (
|
|
1107
|
-
<div className="space-y-2">
|
|
1108
|
-
<QuoteDetails quote={prepareSendQuote} showContent={true} />
|
|
1109
|
-
</div>
|
|
1110
|
-
)}
|
|
1111
1088
|
</div>
|
|
1112
1089
|
)
|
|
1113
1090
|
}
|