0xtrails 0.2.4 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/dist/aave.d.ts +8 -0
  2. package/dist/aave.d.ts.map +1 -1
  3. package/dist/{ccip-BlV1Mry3.js → ccip-CXlshvBY.js} +1 -1
  4. package/dist/config.d.ts +1 -1
  5. package/dist/config.d.ts.map +1 -1
  6. package/dist/constants.d.ts +1 -0
  7. package/dist/constants.d.ts.map +1 -1
  8. package/dist/error.d.ts +1 -0
  9. package/dist/error.d.ts.map +1 -1
  10. package/dist/estimate.d.ts +52 -0
  11. package/dist/estimate.d.ts.map +1 -1
  12. package/dist/{index-BNWCIGfQ.js → index-_QuyGrjU.js} +72332 -72246
  13. package/dist/index.js +2 -2
  14. package/dist/intents.d.ts +40 -0
  15. package/dist/intents.d.ts.map +1 -1
  16. package/dist/metaTxnMonitor.d.ts +3 -3
  17. package/dist/metaTxnMonitor.d.ts.map +1 -1
  18. package/dist/metaTxns.d.ts +3 -3
  19. package/dist/metaTxns.d.ts.map +1 -1
  20. package/dist/morpho.d.ts +8 -0
  21. package/dist/morpho.d.ts.map +1 -1
  22. package/dist/prepareSend.d.ts +16 -6
  23. package/dist/prepareSend.d.ts.map +1 -1
  24. package/dist/queryParams.d.ts.map +1 -1
  25. package/dist/relayer.d.ts +6 -6
  26. package/dist/relayer.d.ts.map +1 -1
  27. package/dist/sequenceWallet.d.ts +2 -2
  28. package/dist/sequenceWallet.d.ts.map +1 -1
  29. package/dist/tokens.d.ts.map +1 -1
  30. package/dist/wallets.d.ts.map +1 -1
  31. package/dist/widget/components/AccountActionsDropdown.d.ts.map +1 -1
  32. package/dist/widget/components/AccountSettings.d.ts.map +1 -1
  33. package/dist/widget/components/ClassicSwap.d.ts +2 -0
  34. package/dist/widget/components/ClassicSwap.d.ts.map +1 -1
  35. package/dist/widget/components/ConnectWallet.d.ts.map +1 -1
  36. package/dist/widget/components/ConnectedWallets.d.ts +4 -0
  37. package/dist/widget/components/ConnectedWallets.d.ts.map +1 -1
  38. package/dist/widget/components/Earn.d.ts.map +1 -1
  39. package/dist/widget/components/Fund.d.ts.map +1 -1
  40. package/dist/widget/components/FundMethods.d.ts.map +1 -1
  41. package/dist/widget/components/{FundSendForm.d.ts → FundSwap.d.ts} +11 -5
  42. package/dist/widget/components/FundSwap.d.ts.map +1 -0
  43. package/dist/widget/components/FundingMethodSelectorButton.d.ts +4 -0
  44. package/dist/widget/components/FundingMethodSelectorButton.d.ts.map +1 -0
  45. package/dist/widget/components/Modal.d.ts.map +1 -1
  46. package/dist/widget/components/Pay.d.ts.map +1 -1
  47. package/dist/widget/components/PercentageMaxButtons.d.ts +12 -0
  48. package/dist/widget/components/PercentageMaxButtons.d.ts.map +1 -0
  49. package/dist/widget/components/{PaySendForm.d.ts → PoolDeposit.d.ts} +11 -34
  50. package/dist/widget/components/PoolDeposit.d.ts.map +1 -0
  51. package/dist/widget/components/{SimpleSwap.d.ts → PoolWithdraw.d.ts} +16 -8
  52. package/dist/widget/components/PoolWithdraw.d.ts.map +1 -0
  53. package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
  54. package/dist/widget/components/Receive.d.ts.map +1 -1
  55. package/dist/widget/components/RecipientSelectorButton.d.ts +4 -0
  56. package/dist/widget/components/RecipientSelectorButton.d.ts.map +1 -0
  57. package/dist/widget/components/Recipients.d.ts.map +1 -1
  58. package/dist/widget/components/RequiredPropsError.d.ts +8 -0
  59. package/dist/widget/components/RequiredPropsError.d.ts.map +1 -0
  60. package/dist/widget/components/ScreenHeader.d.ts.map +1 -1
  61. package/dist/widget/components/SlippageToleranceSettings.d.ts.map +1 -1
  62. package/dist/widget/components/Swap.d.ts +1 -0
  63. package/dist/widget/components/Swap.d.ts.map +1 -1
  64. package/dist/widget/components/SwapSettings.d.ts.map +1 -1
  65. package/dist/widget/components/TokenImage.d.ts +1 -0
  66. package/dist/widget/components/TokenImage.d.ts.map +1 -1
  67. package/dist/widget/components/TokenList.d.ts.map +1 -1
  68. package/dist/widget/components/TokenSelector.d.ts.map +1 -1
  69. package/dist/widget/components/TokenSelectorButton.d.ts +16 -0
  70. package/dist/widget/components/TokenSelectorButton.d.ts.map +1 -0
  71. package/dist/widget/components/UserPreferences.d.ts.map +1 -1
  72. package/dist/widget/components/WaasFeeOptions.d.ts +8 -0
  73. package/dist/widget/components/WaasFeeOptions.d.ts.map +1 -0
  74. package/dist/widget/components/WalletConfirmation.d.ts.map +1 -1
  75. package/dist/widget/components/WalletList.d.ts.map +1 -1
  76. package/dist/widget/css/compiled.css +2 -0
  77. package/dist/widget/css/index.css +554 -0
  78. package/dist/widget/hooks/useBack.d.ts +1 -0
  79. package/dist/widget/hooks/useBack.d.ts.map +1 -1
  80. package/dist/widget/hooks/useCheckout.d.ts +1 -1
  81. package/dist/widget/hooks/useCheckout.d.ts.map +1 -1
  82. package/dist/widget/hooks/useCurrentScreen.d.ts +1 -1
  83. package/dist/widget/hooks/useCurrentScreen.d.ts.map +1 -1
  84. package/dist/widget/hooks/useDefaultTokenSelection.d.ts +3 -3
  85. package/dist/widget/hooks/useDefaultTokenSelection.d.ts.map +1 -1
  86. package/dist/widget/hooks/usePayMessage.d.ts.map +1 -1
  87. package/dist/widget/hooks/useSelectedFundMethod.d.ts +12 -0
  88. package/dist/widget/hooks/useSelectedFundMethod.d.ts.map +1 -0
  89. package/dist/widget/hooks/useSelectedRecipient.d.ts.map +1 -1
  90. package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
  91. package/dist/widget/index.js +1 -1
  92. package/dist/widget/widget.d.ts +4 -4
  93. package/dist/widget/widget.d.ts.map +1 -1
  94. package/package.json +18 -12
  95. package/src/aave.ts +32 -0
  96. package/src/config.ts +12 -4
  97. package/src/constants.ts +2 -0
  98. package/src/error.ts +19 -1
  99. package/src/estimate.ts +416 -5
  100. package/src/intents.ts +161 -11
  101. package/src/metaTxnMonitor.ts +3 -3
  102. package/src/metaTxns.ts +3 -5
  103. package/src/morpho.ts +32 -0
  104. package/src/prepareSend.ts +503 -166
  105. package/src/queryParams.ts +2 -1
  106. package/src/relayer.ts +11 -11
  107. package/src/sequenceWallet.ts +2 -2
  108. package/src/tokens.ts +7 -1
  109. package/src/wallets.ts +8 -0
  110. package/src/widget/compiled.css +2 -2
  111. package/src/widget/components/AccountActionsDropdown.tsx +3 -13
  112. package/src/widget/components/AccountSettings.tsx +6 -24
  113. package/src/widget/components/ClassicSwap.tsx +111 -155
  114. package/src/widget/components/ConnectWallet.tsx +4 -37
  115. package/src/widget/components/ConnectedWallets.tsx +113 -58
  116. package/src/widget/components/Earn.tsx +73 -589
  117. package/src/widget/components/Fund.tsx +31 -82
  118. package/src/widget/components/FundMethods.tsx +82 -159
  119. package/src/widget/components/FundSwap.tsx +52 -0
  120. package/src/widget/components/FundingMethodSelectorButton.tsx +60 -0
  121. package/src/widget/components/Modal.tsx +6 -2
  122. package/src/widget/components/Pay.tsx +183 -208
  123. package/src/widget/components/PercentageMaxButtons.tsx +77 -0
  124. package/src/widget/components/PoolDeposit.tsx +593 -0
  125. package/src/widget/components/PoolWithdraw.tsx +903 -0
  126. package/src/widget/components/QuoteDetails.tsx +22 -8
  127. package/src/widget/components/Receive.tsx +0 -2
  128. package/src/widget/components/RecipientSelectorButton.tsx +42 -0
  129. package/src/widget/components/Recipients.tsx +62 -156
  130. package/src/widget/components/RequiredPropsError.tsx +33 -0
  131. package/src/widget/components/ScreenHeader.tsx +5 -1
  132. package/src/widget/components/SlippageToleranceSettings.tsx +2 -1
  133. package/src/widget/components/Swap.tsx +2 -43
  134. package/src/widget/components/SwapSettings.tsx +2 -14
  135. package/src/widget/components/TokenImage.tsx +21 -4
  136. package/src/widget/components/TokenList.tsx +0 -1
  137. package/src/widget/components/TokenSelector.tsx +1 -0
  138. package/src/widget/components/TokenSelectorButton.tsx +75 -0
  139. package/src/widget/components/UserPreferences.tsx +6 -24
  140. package/src/widget/components/WaasFeeOptions.tsx +331 -0
  141. package/src/widget/components/WalletConfirmation.tsx +55 -3
  142. package/src/widget/components/WalletList.tsx +4 -2
  143. package/src/widget/hooks/useBack.tsx +2 -0
  144. package/src/widget/hooks/useCheckout.ts +36 -20
  145. package/src/widget/hooks/useCurrentScreen.tsx +1 -0
  146. package/src/widget/hooks/useDefaultTokenSelection.tsx +104 -28
  147. package/src/widget/hooks/usePayMessage.tsx +86 -11
  148. package/src/widget/hooks/useSelectedFundMethod.tsx +41 -0
  149. package/src/widget/hooks/useSelectedRecipient.tsx +10 -0
  150. package/src/widget/hooks/useSendForm.ts +24 -2
  151. package/src/widget/index.css +27 -0
  152. package/src/widget/widget.tsx +169 -111
  153. package/dist/widget/components/FundSendForm.d.ts.map +0 -1
  154. package/dist/widget/components/PaySendForm.d.ts.map +0 -1
  155. package/dist/widget/components/SimpleSwap.d.ts.map +0 -1
  156. package/dist/widget/hooks/useSwapSettings.d.ts +0 -16
  157. package/dist/widget/hooks/useSwapSettings.d.ts.map +0 -1
  158. package/src/widget/components/FundSendForm.tsx +0 -903
  159. package/src/widget/components/PaySendForm.tsx +0 -869
  160. package/src/widget/components/SimpleSwap.tsx +0 -983
  161. package/src/widget/hooks/useSwapSettings.tsx +0 -100
@@ -1,13 +1,13 @@
1
- import { ChevronDown, Loader2, ArrowDown } from "lucide-react"
1
+ import { Loader2, ArrowDown } from "lucide-react"
2
2
  import type React from "react"
3
3
  import { useCallback, useEffect, useRef, useState, useMemo } 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, Token } from "../hooks/useSendForm.js"
7
8
  import type { SupportedToken } from "../../tokens.js"
8
9
  import { useSendForm } from "../hooks/useSendForm.js"
9
10
  import type { CheckoutOnHandlers } from "../hooks/useCheckout.js"
10
- import { TokenImage } from "./TokenImage.js"
11
11
  import { QuoteDetails } from "./QuoteDetails.js"
12
12
  import { type PrepareSendQuote, TradeType } from "../../prepareSend.js"
13
13
  import { getChainInfo } from "../../chains.js"
@@ -16,12 +16,18 @@ import { TokenSelector } from "./TokenSelector.js"
16
16
  import { ErrorDisplay } from "./ErrorDisplay.js"
17
17
  import { useMode } from "../hooks/useMode.js"
18
18
  import { logger } from "../../logger.js"
19
- import { SwapSettings } from "./SwapSettings.js"
20
19
  import { useOriginSelectedToken } from "../hooks/useOriginSelectedToken.js"
21
20
  import { useDestinationSelectedToken } from "../hooks/useDestinationSelectedToken.js"
22
21
  import { useBalanceVisible } from "../hooks/useBalanceVisible.js"
23
22
  import { useDefaultTokenSelection } from "../hooks/useDefaultTokenSelection.js"
24
23
  import { ChainList } from "./ChainList.js"
24
+ import { PercentageMaxButtons } from "./PercentageMaxButtons.js"
25
+ import { TokenSelectorButton } from "./TokenSelectorButton.js"
26
+ import { FundingMethodSelectorButton } from "./FundingMethodSelectorButton.js"
27
+ import { RecipientSelectorButton } from "./RecipientSelectorButton.js"
28
+ import { RefundWarning } from "./RefundWarning.js"
29
+ import { Identicon } from "./Identicon.js"
30
+ import { truncateAddress } from "../../utils.js"
25
31
 
26
32
  interface ClassicSwapProps {
27
33
  selectedToken: Token | null
@@ -58,6 +64,8 @@ interface ClassicSwapProps {
58
64
  recentTokens?: SupportedToken[]
59
65
  onRecentTokenSelect?: (token: SupportedToken) => void
60
66
  onTrackToken?: (token: any) => void
67
+ title?: string
68
+ isSequenceWallet?: boolean
61
69
  }
62
70
 
63
71
  export const ClassicSwap: React.FC<ClassicSwapProps> = ({
@@ -67,6 +75,7 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
67
75
  onConfirm,
68
76
  onComplete,
69
77
  account,
78
+ toRecipient,
70
79
  toAmount,
71
80
  toChainId,
72
81
  toToken,
@@ -85,6 +94,8 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
85
94
  checkoutOnHandlers,
86
95
  recentTokens,
87
96
  onTrackToken,
97
+ title = "Swap",
98
+ isSequenceWallet = false,
88
99
  }) => {
89
100
  const { mode } = useMode()
90
101
  const { isBalanceVisible } = useBalanceVisible()
@@ -135,7 +146,7 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
135
146
  } = useSendForm({
136
147
  account,
137
148
  toAmount: tradeType === TradeType.EXACT_OUTPUT ? buyAmount : toAmount,
138
- toRecipient: account.address,
149
+ toRecipient: toRecipient || account.address,
139
150
  toChainId,
140
151
  toToken,
141
152
  toCalldata,
@@ -230,24 +241,6 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
230
241
  }
231
242
  }, [prepareSendQuote, tradeType])
232
243
 
233
- // Handle percentage button clicks
234
- const handlePercentageClick = useCallback(
235
- (percentage: number) => {
236
- if (!originToken || !balanceFormatted) return
237
-
238
- // Parse the balance and calculate percentage
239
- const balance = parseFloat(balanceFormatted)
240
- if (Number.isNaN(balance)) return
241
-
242
- const amount = (balance * percentage) / 100
243
- setTradeType(TradeType.EXACT_INPUT)
244
- setSellAmount(amount.toFixed(6))
245
- setBuyAmount("")
246
- setLastInputType("sell")
247
- },
248
- [originToken, balanceFormatted],
249
- )
250
-
251
244
  // Call onAmountUpdate when amountRaw changes
252
245
  useEffect(() => {
253
246
  if (onAmountUpdate) {
@@ -369,7 +362,7 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
369
362
  }
370
363
  }
371
364
 
372
- // Dynamic font size based on input length - matching SimpleSwap.tsx
365
+ // Dynamic font size based on input length
373
366
  const sellInputStyles = useMemo(() => {
374
367
  const inputLength = sellAmount.length
375
368
  let fontSize: string
@@ -429,13 +422,25 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
429
422
  name: token.name,
430
423
  },
431
424
  }
425
+
426
+ // Only reset input fields if the token symbol is different
427
+ const isDifferentToken =
428
+ !originToken || originToken.symbol !== token.symbol
429
+ if (isDifferentToken) {
430
+ setSellAmount("")
431
+ setBuyAmount("")
432
+ setTradeType(TradeType.EXACT_INPUT)
433
+ setLastInputType("sell")
434
+ }
435
+
432
436
  setOriginToken(formattedToken as any)
433
437
  setOriginChainId(token.chainId)
434
438
  setShowSourceTokenSelector(false)
439
+
435
440
  onTrackToken?.(token)
436
441
  logger.console.log("[trails-sdk] selected origin token", token)
437
442
  },
438
- [setOriginToken, onTrackToken],
443
+ [setOriginToken, onTrackToken, originToken],
439
444
  )
440
445
 
441
446
  // Handle destination token selection from full-screen selector
@@ -573,54 +578,20 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
573
578
  <div className="space-y-2">
574
579
  <ScreenHeader
575
580
  onBack={onBack}
576
- headerContent="Swap"
581
+ headerContent={title}
577
582
  headerContentAlign="left"
578
583
  showAccountActions={true}
579
- rightSideContent={<SwapSettings />}
580
584
  />
581
585
 
582
586
  <form onSubmit={handleSubmit} className="space-y-1">
583
587
  {/* Input Section - Amount + Token Selection */}
584
588
  <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">
585
- {/* Sell Label and Percentage Buttons */}
589
+ {/* Sell Label */}
586
590
  <div className="flex justify-between items-center mb-2">
587
591
  <div className="text-sm font-medium trails-text-secondary text-left">
588
- Sell
592
+ {mode === "fund" ? "Payment method" : "Sell"}
589
593
  </div>
590
-
591
- {/* Percentage Buttons */}
592
- {originToken && (
593
- <div className="flex space-x-1 opacity-0 group-hover:opacity-100 transition-opacity duration-200">
594
- <button
595
- type="button"
596
- onClick={() => handlePercentageClick(25)}
597
- className="py-1 px-2 text-xs font-medium trails-border-radius-container border border-solid transition-colors cursor-pointer border-gray-300 text-gray-600 dark:border-gray-600 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 hover:trails-hover-bg hover:border-gray-400 dark:hover:border-gray-500"
598
- >
599
- 25%
600
- </button>
601
- <button
602
- type="button"
603
- onClick={() => handlePercentageClick(50)}
604
- className="py-1 px-2 text-xs font-medium trails-border-radius-container border border-solid transition-colors cursor-pointer border-gray-300 text-gray-600 dark:border-gray-600 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 hover:trails-hover-bg hover:border-gray-400 dark:hover:border-gray-500"
605
- >
606
- 50%
607
- </button>
608
- <button
609
- type="button"
610
- onClick={() => handlePercentageClick(75)}
611
- className="py-1 px-2 text-xs font-medium trails-border-radius-container border border-solid transition-colors cursor-pointer border-gray-300 text-gray-600 dark:border-gray-600 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 hover:trails-hover-bg hover:border-gray-400 dark:hover:border-gray-500"
612
- >
613
- 75%
614
- </button>
615
- <button
616
- type="button"
617
- onClick={() => handlePercentageClick(100)}
618
- className="py-1 px-2 text-xs font-medium trails-border-radius-container border border-solid transition-colors cursor-pointer border-gray-300 text-gray-600 dark:border-gray-600 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 hover:trails-hover-bg hover:border-gray-400 dark:hover:border-gray-500"
619
- >
620
- Max
621
- </button>
622
- </div>
623
- )}
594
+ <FundingMethodSelectorButton />
624
595
  </div>
625
596
 
626
597
  <div className="flex items-center space-x-2 flex-1">
@@ -652,37 +623,11 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
652
623
 
653
624
  {/* Token Selection Button */}
654
625
  <div className="relative">
655
- <button
656
- type="button"
657
- onClick={() => setShowSourceTokenSelector(true)}
658
- className={`flex items-center space-x-2 trails-border-radius-input px-2.5 py-1.5 border transition-colors cursor-pointer ${
659
- originToken
660
- ? "trails-bg-card hover:trails-hover-bg trails-border-primary"
661
- : "bg-blue-500 hover:bg-blue-600 border-blue-500 text-white"
662
- }`}
663
- >
664
- {originToken ? (
665
- <>
666
- <TokenImage
667
- symbol={originToken.symbol}
668
- imageUrl={originToken.imageUrl}
669
- chainId={originChainId}
670
- size={20}
671
- />
672
- <span className="font-medium trails-text-primary text-sm">
673
- {originToken.symbol}
674
- </span>
675
- <ChevronDown className="w-3.5 h-3.5 trails-text-muted" />
676
- </>
677
- ) : (
678
- <>
679
- <span className="font-medium text-sm text-white">
680
- Select Token
681
- </span>
682
- <ChevronDown className="w-3.5 h-3.5 text-white" />
683
- </>
684
- )}
685
- </button>
626
+ <TokenSelectorButton
627
+ token={originToken}
628
+ chainId={originChainId}
629
+ onSelect={() => setShowSourceTokenSelector(true)}
630
+ />
686
631
  </div>
687
632
  </div>
688
633
 
@@ -700,25 +645,13 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
700
645
  </div>
701
646
  )}
702
647
 
703
- {/* Origin Token Balance */}
704
- {originToken && (
705
- <button
706
- type="button"
707
- className="text-xs trails-text-muted cursor-pointer hover:trails-hover-text transition-colors bg-transparent border-none p-0"
708
- onClick={() => {
709
- if (balanceFormatted) {
710
- const balance = parseFloat(balanceFormatted)
711
- if (!Number.isNaN(balance)) {
712
- setTradeType(TradeType.EXACT_INPUT)
713
- setSellAmount(balance.toFixed(6))
714
- setBuyAmount("")
715
- setLastInputType("sell")
716
- }
717
- }
718
- }}
719
- onKeyDown={(e) => {
720
- if (e.key === "Enter" || e.key === " ") {
721
- e.preventDefault()
648
+ {/* Origin Token Balance and Percentage Buttons */}
649
+ {originToken && balanceFormatted && (
650
+ <div className="flex items-center space-x-2">
651
+ <button
652
+ type="button"
653
+ className="text-xs trails-text-muted cursor-pointer hover:trails-hover-text transition-colors bg-transparent border-none p-0"
654
+ onClick={() => {
722
655
  if (balanceFormatted) {
723
656
  const balance = parseFloat(balanceFormatted)
724
657
  if (!Number.isNaN(balance)) {
@@ -728,15 +661,42 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
728
661
  setLastInputType("sell")
729
662
  }
730
663
  }
731
- }
732
- }}
733
- title="Click to use full balance"
734
- >
735
- Balance:{" "}
736
- {isBalanceVisible
737
- ? `${balanceFormatted || "0.00"} ${originToken.symbol}`
738
- : "••••••"}
739
- </button>
664
+ }}
665
+ onKeyDown={(e) => {
666
+ if (e.key === "Enter" || e.key === " ") {
667
+ e.preventDefault()
668
+ if (balanceFormatted) {
669
+ const balance = parseFloat(balanceFormatted)
670
+ if (!Number.isNaN(balance)) {
671
+ setTradeType(TradeType.EXACT_INPUT)
672
+ setSellAmount(balance.toFixed(6))
673
+ setBuyAmount("")
674
+ setLastInputType("sell")
675
+ }
676
+ }
677
+ }
678
+ }}
679
+ title="Click to use full balance"
680
+ >
681
+ Balance:{" "}
682
+ {isBalanceVisible ? balanceFormatted || "0.00" : "••••••"}
683
+ </button>
684
+
685
+ {/* Percentage Buttons */}
686
+ <PercentageMaxButtons
687
+ userBalance={balanceFormatted}
688
+ isNativeToken={originToken.contractAddress === zeroAddress}
689
+ gasCostFormatted={prepareSendQuote?.gasCostFormatted}
690
+ chainId={originChainId || undefined}
691
+ onAmountSelect={(amount) => {
692
+ setTradeType(TradeType.EXACT_INPUT)
693
+ setSellAmount(amount)
694
+ setBuyAmount("")
695
+ setLastInputType("sell")
696
+ }}
697
+ className="opacity-100"
698
+ />
699
+ </div>
740
700
  )}
741
701
  </div>
742
702
  </div>
@@ -758,8 +718,20 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
758
718
  {/* Output Section - Amount + Token Selection */}
759
719
  <div className="trails-bg-secondary trails-bg-secondary-hover trails-border-radius-container p-3 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">
760
720
  {/* Buy Label */}
761
- <div className="text-sm font-medium trails-text-secondary mb-2 text-left">
762
- Buy
721
+ <div className="flex justify-between items-center mb-2">
722
+ <div className="text-sm font-medium trails-text-secondary text-left">
723
+ {mode === "fund" ? "Recipient" : "Buy"}
724
+ </div>
725
+ {toRecipient ? (
726
+ <div className="flex items-center space-x-2 text-black dark:text-white">
727
+ <Identicon value={toRecipient} size={16} />
728
+ <span className="text-sm font-medium">
729
+ {truncateAddress(toRecipient, 4, 2)}
730
+ </span>
731
+ </div>
732
+ ) : (
733
+ <RecipientSelectorButton />
734
+ )}
763
735
  </div>
764
736
 
765
737
  <div className="flex items-center space-x-2 flex-1">
@@ -783,7 +755,8 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
783
755
  } ${isLoadingQuote && tradeType === TradeType.EXACT_INPUT ? "animate-pulse" : ""}`}
784
756
  style={buyInputStyles}
785
757
  readOnly={
786
- tradeType === TradeType.EXACT_INPUT && isLoadingQuote
758
+ (tradeType === TradeType.EXACT_INPUT && isLoadingQuote) ||
759
+ !!toAmount
787
760
  }
788
761
  />
789
762
  {isLoadingQuote && tradeType === TradeType.EXACT_INPUT && (
@@ -794,37 +767,12 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
794
767
 
795
768
  {/* Destination Token Selection */}
796
769
  <div className="relative">
797
- <button
798
- type="button"
799
- onClick={() => setShowDestinationTokenSelector(true)}
800
- className={`flex items-center space-x-2 trails-border-radius-input px-2.5 py-1.5 border transition-colors cursor-pointer ${
801
- selectedDestToken
802
- ? "trails-bg-card hover:trails-hover-bg trails-border-primary"
803
- : "bg-blue-500 hover:bg-blue-600 border-blue-500 text-white"
804
- }`}
805
- >
806
- {selectedDestToken ? (
807
- <>
808
- <TokenImage
809
- symbol={selectedDestToken.symbol}
810
- imageUrl={selectedDestToken.imageUrl}
811
- chainId={(selectedDestToken as any)?.chainId}
812
- size={20}
813
- />
814
- <span className="font-medium trails-text-primary text-sm">
815
- {selectedDestToken.symbol}
816
- </span>
817
- <ChevronDown className="w-3.5 h-3.5 trails-text-muted" />
818
- </>
819
- ) : (
820
- <>
821
- <span className="font-medium text-sm text-white">
822
- Select Token
823
- </span>
824
- <ChevronDown className="w-3.5 h-3.5 text-white" />
825
- </>
826
- )}
827
- </button>
770
+ <TokenSelectorButton
771
+ token={selectedDestToken}
772
+ chainId={(selectedDestToken as any)?.chainId}
773
+ onSelect={() => setShowDestinationTokenSelector(true)}
774
+ unselectable={!!toToken}
775
+ />
828
776
  </div>
829
777
  </div>
830
778
 
@@ -850,6 +798,14 @@ export const ClassicSwap: React.FC<ClassicSwapProps> = ({
850
798
  severity="warning"
851
799
  />
852
800
 
801
+ {/* Exchange/Contract Warning */}
802
+ <RefundWarning
803
+ fundMethod={fundMethod}
804
+ isSenderContractOnOrigin={false}
805
+ isSenderContractOnDestination={false}
806
+ isSequenceWallet={isSequenceWallet}
807
+ />
808
+
853
809
  {prepareSendQuote?.noSufficientBalance ? (
854
810
  <div className="px-2 py-3 rounded-lg bg-amber-500/10 border border-solid border-amber-500/30">
855
811
  <div className="flex items-center space-x-2">
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useState } from "react"
1
+ import React, { useEffect, useMemo, useState } from "react"
2
2
  import { ChevronRight, LogOut } from "lucide-react"
3
3
  import {
4
4
  useAccount,
@@ -105,13 +105,7 @@ export const ConnectWallet: React.FC<ConnectWalletProps> = ({
105
105
  const connectedWallets = getConnectedWallets()
106
106
 
107
107
  // Get available browser wallets using EIP-6963 and injected providers
108
- const getAvailableBrowserWallets = (): Array<{
109
- connector: any
110
- walletId: string
111
- walletConfig: any
112
- name: string
113
- icon?: string
114
- }> => {
108
+ const allAvailableBrowserWallets = useMemo(() => {
115
109
  const filteredConnectors = connectors
116
110
  .filter((connector) => {
117
111
  // EIP-6963 compliant wallets will have type "injected" and be ready when installed
@@ -130,27 +124,6 @@ export const ConnectWallet: React.FC<ConnectWalletProps> = ({
130
124
  (conn) => conn.connector.id === connector.id,
131
125
  )
132
126
 
133
- // Log for debugging EIP-6963 detection
134
- if (isInjected && isNotWalletConnect) {
135
- logger.console.log(
136
- "[trails-sdk] Detected browser wallet via EIP-6963:",
137
- {
138
- id: connector.id,
139
- name: connector.name,
140
- type: connector.type,
141
- uid: connector.uid,
142
- hasIcon: !!connector.icon,
143
- },
144
- )
145
- }
146
-
147
- // Log all connectors for debugging
148
- logger.console.log("[trails-sdk] All connector:", {
149
- id: connector.id,
150
- name: connector.name,
151
- type: connector.type,
152
- })
153
-
154
127
  return (
155
128
  isInjected &&
156
129
  isNotWalletConnect &&
@@ -181,9 +154,7 @@ export const ConnectWallet: React.FC<ConnectWalletProps> = ({
181
154
  seenWalletIds.add(wallet.walletId)
182
155
  return true
183
156
  })
184
- }
185
-
186
- const allAvailableBrowserWallets = getAvailableBrowserWallets()
157
+ }, [connectors, allWallets, connections])
187
158
 
188
159
  // Handle switching to a different connected wallet
189
160
  const handleWalletSwitch = async (
@@ -259,11 +230,7 @@ export const ConnectWallet: React.FC<ConnectWalletProps> = ({
259
230
 
260
231
  return (
261
232
  <div className="space-y-6">
262
- <ScreenHeader
263
- headerContent="Connect Wallet"
264
- headerContentAlign="left"
265
- showAccountActions={true}
266
- />
233
+ <ScreenHeader headerContent="Connect Wallet" headerContentAlign="left" />
267
234
 
268
235
  {isConnected ? (
269
236
  <div className="space-y-4">