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.
Files changed (194) hide show
  1. package/dist/aave.d.ts +8 -0
  2. package/dist/aave.d.ts.map +1 -1
  3. package/dist/{ccip-ConT1gDe.js → ccip-CXlshvBY.js} +1 -1
  4. package/dist/chains.d.ts +5 -1
  5. package/dist/chains.d.ts.map +1 -1
  6. package/dist/config.d.ts +1 -1
  7. package/dist/config.d.ts.map +1 -1
  8. package/dist/constants.d.ts +5 -4
  9. package/dist/constants.d.ts.map +1 -1
  10. package/dist/error.d.ts +1 -0
  11. package/dist/error.d.ts.map +1 -1
  12. package/dist/estimate.d.ts +52 -0
  13. package/dist/estimate.d.ts.map +1 -1
  14. package/dist/{index-CMh8uEbV.js → index-_QuyGrjU.js} +86304 -83380
  15. package/dist/index.d.ts +4 -3
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +2 -2
  18. package/dist/intentEntrypoint.d.ts +0 -8
  19. package/dist/intentEntrypoint.d.ts.map +1 -1
  20. package/dist/intents.d.ts +40 -0
  21. package/dist/intents.d.ts.map +1 -1
  22. package/dist/metaTxnMonitor.d.ts +5 -4
  23. package/dist/metaTxnMonitor.d.ts.map +1 -1
  24. package/dist/metaTxns.d.ts +3 -3
  25. package/dist/metaTxns.d.ts.map +1 -1
  26. package/dist/morpho.d.ts +8 -0
  27. package/dist/morpho.d.ts.map +1 -1
  28. package/dist/prepareSend.d.ts +16 -6
  29. package/dist/prepareSend.d.ts.map +1 -1
  30. package/dist/queryParams.d.ts.map +1 -1
  31. package/dist/relayer.d.ts +10 -7
  32. package/dist/relayer.d.ts.map +1 -1
  33. package/dist/sequenceWallet.d.ts +3 -2
  34. package/dist/sequenceWallet.d.ts.map +1 -1
  35. package/dist/tokenBalances.d.ts +7 -0
  36. package/dist/tokenBalances.d.ts.map +1 -1
  37. package/dist/tokens.d.ts +2 -1
  38. package/dist/tokens.d.ts.map +1 -1
  39. package/dist/trails.d.ts +2 -2
  40. package/dist/trails.d.ts.map +1 -1
  41. package/dist/wallets.d.ts.map +1 -1
  42. package/dist/widget/components/AccountActionsDropdown.d.ts.map +1 -1
  43. package/dist/widget/components/AccountSettings.d.ts.map +1 -1
  44. package/dist/widget/components/ClassicSwap.d.ts +2 -0
  45. package/dist/widget/components/ClassicSwap.d.ts.map +1 -1
  46. package/dist/widget/components/ConnectWallet.d.ts.map +1 -1
  47. package/dist/widget/components/ConnectedWallets.d.ts +4 -0
  48. package/dist/widget/components/ConnectedWallets.d.ts.map +1 -1
  49. package/dist/widget/components/Earn.d.ts.map +1 -1
  50. package/dist/widget/components/EarnPools.d.ts.map +1 -1
  51. package/dist/widget/components/Fund.d.ts +1 -0
  52. package/dist/widget/components/Fund.d.ts.map +1 -1
  53. package/dist/widget/components/FundMethods.d.ts.map +1 -1
  54. package/dist/widget/components/{FundSendForm.d.ts → FundSwap.d.ts} +11 -5
  55. package/dist/widget/components/FundSwap.d.ts.map +1 -0
  56. package/dist/widget/components/FundingMethodSelectorButton.d.ts +4 -0
  57. package/dist/widget/components/FundingMethodSelectorButton.d.ts.map +1 -0
  58. package/dist/widget/components/Modal.d.ts.map +1 -1
  59. package/dist/widget/components/Pay.d.ts +1 -0
  60. package/dist/widget/components/Pay.d.ts.map +1 -1
  61. package/dist/widget/components/PercentageMaxButtons.d.ts +12 -0
  62. package/dist/widget/components/PercentageMaxButtons.d.ts.map +1 -0
  63. package/dist/widget/components/{PaySendForm.d.ts → PoolDeposit.d.ts} +11 -34
  64. package/dist/widget/components/PoolDeposit.d.ts.map +1 -0
  65. package/dist/widget/components/{SimpleSwap.d.ts → PoolWithdraw.d.ts} +16 -8
  66. package/dist/widget/components/PoolWithdraw.d.ts.map +1 -0
  67. package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
  68. package/dist/widget/components/Receive.d.ts.map +1 -1
  69. package/dist/widget/components/RecipientSelectorButton.d.ts +4 -0
  70. package/dist/widget/components/RecipientSelectorButton.d.ts.map +1 -0
  71. package/dist/widget/components/Recipients.d.ts.map +1 -1
  72. package/dist/widget/components/RefundWarning.d.ts +1 -0
  73. package/dist/widget/components/RefundWarning.d.ts.map +1 -1
  74. package/dist/widget/components/RequiredPropsError.d.ts +8 -0
  75. package/dist/widget/components/RequiredPropsError.d.ts.map +1 -0
  76. package/dist/widget/components/ScreenHeader.d.ts.map +1 -1
  77. package/dist/widget/components/SlippageToleranceSettings.d.ts.map +1 -1
  78. package/dist/widget/components/Swap.d.ts +1 -0
  79. package/dist/widget/components/Swap.d.ts.map +1 -1
  80. package/dist/widget/components/SwapSettings.d.ts.map +1 -1
  81. package/dist/widget/components/TokenImage.d.ts +1 -0
  82. package/dist/widget/components/TokenImage.d.ts.map +1 -1
  83. package/dist/widget/components/TokenList.d.ts.map +1 -1
  84. package/dist/widget/components/TokenSelector.d.ts.map +1 -1
  85. package/dist/widget/components/TokenSelectorButton.d.ts +16 -0
  86. package/dist/widget/components/TokenSelectorButton.d.ts.map +1 -0
  87. package/dist/widget/components/UserPreferences.d.ts.map +1 -1
  88. package/dist/widget/components/WaasFeeOptions.d.ts +8 -0
  89. package/dist/widget/components/WaasFeeOptions.d.ts.map +1 -0
  90. package/dist/widget/components/WalletConfirmation.d.ts.map +1 -1
  91. package/dist/widget/components/WalletList.d.ts.map +1 -1
  92. package/dist/widget/css/compiled.css +2 -0
  93. package/dist/widget/css/index.css +554 -0
  94. package/dist/widget/hooks/useBack.d.ts +6 -0
  95. package/dist/widget/hooks/useBack.d.ts.map +1 -1
  96. package/dist/widget/hooks/useCheckout.d.ts +1 -1
  97. package/dist/widget/hooks/useCheckout.d.ts.map +1 -1
  98. package/dist/widget/hooks/useCurrentScreen.d.ts +1 -1
  99. package/dist/widget/hooks/useCurrentScreen.d.ts.map +1 -1
  100. package/dist/widget/hooks/useDefaultTokenSelection.d.ts +3 -3
  101. package/dist/widget/hooks/useDefaultTokenSelection.d.ts.map +1 -1
  102. package/dist/widget/hooks/useInitialRedirect.d.ts +7 -0
  103. package/dist/widget/hooks/useInitialRedirect.d.ts.map +1 -0
  104. package/dist/widget/hooks/usePayMessage.d.ts.map +1 -1
  105. package/dist/widget/hooks/useSelectedFeeToken.d.ts.map +1 -1
  106. package/dist/widget/hooks/useSelectedFundMethod.d.ts +12 -0
  107. package/dist/widget/hooks/useSelectedFundMethod.d.ts.map +1 -0
  108. package/dist/widget/hooks/useSelectedRecipient.d.ts.map +1 -1
  109. package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
  110. package/dist/widget/index.js +1 -1
  111. package/dist/widget/widget.d.ts +4 -4
  112. package/dist/widget/widget.d.ts.map +1 -1
  113. package/package.json +30 -23
  114. package/src/aave.ts +32 -0
  115. package/src/chains.ts +23 -3
  116. package/src/config.ts +12 -4
  117. package/src/constants.ts +11 -16
  118. package/src/error.ts +20 -2
  119. package/src/estimate.ts +416 -5
  120. package/src/index.ts +8 -3
  121. package/src/intentEntrypoint.ts +0 -15
  122. package/src/intents.ts +161 -11
  123. package/src/metaTxnMonitor.ts +28 -22
  124. package/src/metaTxns.ts +3 -3
  125. package/src/morpho.ts +32 -0
  126. package/src/prepareSend.ts +710 -458
  127. package/src/queryParams.ts +2 -1
  128. package/src/relayer.ts +15 -16
  129. package/src/sequenceWallet.ts +7 -3
  130. package/src/tokenBalances.ts +47 -0
  131. package/src/tokens.ts +17 -1
  132. package/src/trails.ts +2 -2
  133. package/src/wallets.ts +8 -0
  134. package/src/widget/compiled.css +2 -2
  135. package/src/widget/components/AccountActionsDropdown.tsx +9 -15
  136. package/src/widget/components/AccountIntentTransactionHistory.tsx +1 -1
  137. package/src/widget/components/AccountSettings.tsx +10 -27
  138. package/src/widget/components/ChainFilterDropdown.tsx +1 -1
  139. package/src/widget/components/ChainList.tsx +1 -1
  140. package/src/widget/components/ClassicSwap.tsx +111 -155
  141. package/src/widget/components/ConnectWallet.tsx +10 -39
  142. package/src/widget/components/ConnectedWallets.tsx +113 -58
  143. package/src/widget/components/Earn.tsx +73 -589
  144. package/src/widget/components/EarnPools.tsx +2 -1
  145. package/src/widget/components/Fund.tsx +81 -109
  146. package/src/widget/components/FundMethods.tsx +82 -159
  147. package/src/widget/components/FundSwap.tsx +52 -0
  148. package/src/widget/components/FundingMethodSelectorButton.tsx +60 -0
  149. package/src/widget/components/Modal.tsx +6 -2
  150. package/src/widget/components/Pay.tsx +198 -200
  151. package/src/widget/components/PercentageMaxButtons.tsx +77 -0
  152. package/src/widget/components/PoolDeposit.tsx +593 -0
  153. package/src/widget/components/PoolWithdraw.tsx +903 -0
  154. package/src/widget/components/QuoteDetails.tsx +22 -8
  155. package/src/widget/components/Receive.tsx +1 -3
  156. package/src/widget/components/RecipientSelectorButton.tsx +42 -0
  157. package/src/widget/components/Recipients.tsx +64 -156
  158. package/src/widget/components/RefundWarning.tsx +5 -1
  159. package/src/widget/components/RequiredPropsError.tsx +33 -0
  160. package/src/widget/components/ScreenHeader.tsx +5 -1
  161. package/src/widget/components/SlippageToleranceSettings.tsx +2 -1
  162. package/src/widget/components/Swap.tsx +2 -43
  163. package/src/widget/components/SwapSettings.tsx +3 -15
  164. package/src/widget/components/TokenImage.tsx +21 -4
  165. package/src/widget/components/TokenList.tsx +0 -1
  166. package/src/widget/components/TokenSelector.tsx +2 -1
  167. package/src/widget/components/TokenSelectorButton.tsx +75 -0
  168. package/src/widget/components/UserPreferences.tsx +6 -24
  169. package/src/widget/components/WaasFeeOptions.tsx +331 -0
  170. package/src/widget/components/WalletConfirmation.tsx +55 -3
  171. package/src/widget/components/WalletList.tsx +7 -5
  172. package/src/widget/hooks/useBack.tsx +113 -9
  173. package/src/widget/hooks/useCheckout.ts +36 -20
  174. package/src/widget/hooks/useCurrentScreen.tsx +1 -0
  175. package/src/widget/hooks/useDefaultTokenSelection.tsx +104 -28
  176. package/src/widget/hooks/useInitialRedirect.tsx +70 -0
  177. package/src/widget/hooks/usePayMessage.tsx +86 -11
  178. package/src/widget/hooks/useSelectedFeeToken.tsx +10 -16
  179. package/src/widget/hooks/useSelectedFundMethod.tsx +41 -0
  180. package/src/widget/hooks/useSelectedRecipient.tsx +10 -0
  181. package/src/widget/hooks/useSendForm.ts +34 -12
  182. package/src/widget/hooks/useTokenList.ts +1 -1
  183. package/src/widget/index.css +27 -0
  184. package/src/widget/widget.tsx +245 -208
  185. package/dist/widget/components/FundSendForm.d.ts.map +0 -1
  186. package/dist/widget/components/PaySendForm.d.ts.map +0 -1
  187. package/dist/widget/components/SimpleSwap.d.ts.map +0 -1
  188. package/dist/widget/hooks/useSwapSettings.d.ts +0 -16
  189. package/dist/widget/hooks/useSwapSettings.d.ts.map +0 -1
  190. package/src/widget/components/FundSendForm.tsx +0 -903
  191. package/src/widget/components/PaySendForm.tsx +0 -869
  192. package/src/widget/components/SimpleSwap.tsx +0 -983
  193. package/src/widget/hooks/useSwapSettings.tsx +0 -100
  194. /package/dist/{style.css → 0xtrails.css} +0 -0
@@ -109,11 +109,12 @@ export const EarnPools: React.FC<EarnPoolsProps> = ({
109
109
 
110
110
  // Search filter - split by spaces to allow "usdc base" type searches
111
111
  const searchTerms = searchFilter
112
+ .trim()
112
113
  .toLowerCase()
113
114
  .split(/\s+/)
114
115
  .filter((term) => term.length > 0)
115
116
  const searchMatch =
116
- !searchFilter ||
117
+ !searchFilter.trim() ||
117
118
  searchTerms.every(
118
119
  (term) =>
119
120
  pool.token?.symbol?.toLowerCase().includes(term) ||
@@ -1,13 +1,8 @@
1
- import {
2
- ChevronRight,
3
- Search,
4
- Loader2,
5
- ChevronDown,
6
- ArrowDown,
7
- } from "lucide-react"
1
+ import { ChevronRight, Search, Loader2, ArrowDown } from "lucide-react"
8
2
  import { useEffect, useState, useMemo, useRef, useCallback } from "react"
9
3
  import type React from "react"
10
4
  import type { Account, WalletClient } from "viem"
5
+ import { zeroAddress } from "viem"
11
6
  import type { TransactionState } from "../../transactions.js"
12
7
  import type { OnCompleteProps } from "../hooks/useSendForm.js"
13
8
  import type { CheckoutOnHandlers } from "../hooks/useCheckout.js"
@@ -35,6 +30,8 @@ import type { PrepareSendQuote } from "../../prepareSend.js"
35
30
  import type { SupportedToken } from "../../tokens.js"
36
31
  import { logger } from "../../logger.js"
37
32
  import { RefundWarning } from "./RefundWarning.js"
33
+ import { PercentageMaxButtons } from "./PercentageMaxButtons.js"
34
+ import { TokenSelectorButton } from "./TokenSelectorButton.js"
38
35
 
39
36
  interface FundProps {
40
37
  onBack?: () => void
@@ -48,6 +45,7 @@ interface FundProps {
48
45
  onSend: (amount: string, recipient: string) => void
49
46
  paymasterUrls?: Array<{ chainId: number; url: string }>
50
47
  gasless?: boolean
48
+ isSequenceWallet?: boolean
51
49
  setWalletConfirmRetryHandler: (handler: () => Promise<void>) => void
52
50
  quoteProvider?: string
53
51
  fundMethod?: string
@@ -83,6 +81,7 @@ export const Fund: React.FC<FundProps> = ({
83
81
  onSend,
84
82
  paymasterUrls,
85
83
  gasless,
84
+ isSequenceWallet = false,
86
85
  setWalletConfirmRetryHandler,
87
86
  quoteProvider,
88
87
  fundMethod,
@@ -635,7 +634,6 @@ export const Fund: React.FC<FundProps> = ({
635
634
  onBack={() => setShowOriginTokenSelector(false)}
636
635
  headerContent="Select From Token"
637
636
  headerContentAlign="left"
638
- showAccountActions={true}
639
637
  />
640
638
  <TokenSelector
641
639
  onTokenSelect={handleOriginTokenSelect}
@@ -682,7 +680,6 @@ export const Fund: React.FC<FundProps> = ({
682
680
  onBack={() => setShowDestinationTokenSelector(false)}
683
681
  headerContent="Select To Token"
684
682
  headerContentAlign="left"
685
- showAccountActions={true}
686
683
  />
687
684
  <TokenSelector
688
685
  onTokenSelect={handleDestinationTokenSelect}
@@ -726,7 +723,6 @@ export const Fund: React.FC<FundProps> = ({
726
723
  onBack={onBack}
727
724
  headerContent="Fund"
728
725
  headerContentAlign="left"
729
- showAccountActions={true}
730
726
  />
731
727
 
732
728
  <div className="space-y-2">
@@ -768,7 +764,7 @@ export const Fund: React.FC<FundProps> = ({
768
764
  <div className="space-y-1">
769
765
  {/* Origin Amount Input Section */}
770
766
  <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 focus-within:border-gray-400 dark:focus-within:border-gray-500">
771
- {/* Deposit Label and Percentage Buttons */}
767
+ {/* Deposit Label */}
772
768
  <div className="flex justify-between items-center mb-2">
773
769
  <div className="text-sm font-medium trails-text-secondary text-left">
774
770
  Deposit
@@ -780,48 +776,16 @@ export const Fund: React.FC<FundProps> = ({
780
776
  ""
781
777
  )}
782
778
  </div>
783
-
784
- {/* Percentage Buttons */}
785
- {originToken && (
786
- <div className="flex space-x-1 opacity-0 group-hover:opacity-100 transition-opacity duration-200">
787
- <button
788
- type="button"
789
- onClick={() => handlePercentageClick(25)}
790
- 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"
791
- >
792
- 25%
793
- </button>
794
- <button
795
- type="button"
796
- onClick={() => handlePercentageClick(50)}
797
- 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"
798
- >
799
- 50%
800
- </button>
801
- <button
802
- type="button"
803
- onClick={() => handlePercentageClick(75)}
804
- 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"
805
- >
806
- 75%
807
- </button>
808
- <button
809
- type="button"
810
- onClick={() => handlePercentageClick(100)}
811
- 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"
812
- >
813
- Max
814
- </button>
815
- </div>
816
- )}
817
779
  </div>
818
780
 
819
781
  <div className="flex items-center space-x-2">
820
782
  {/* Amount Input */}
821
783
  <div className="flex-1">
822
- <div
823
- className="flex items-center justify-start cursor-text"
784
+ <button
785
+ type="button"
786
+ className="flex items-center justify-start cursor-text bg-transparent border-none p-0 w-full"
824
787
  onClick={() => inputRef.current?.focus()}
788
+ aria-label="Focus amount input"
825
789
  >
826
790
  <div className="flex items-center">
827
791
  <input
@@ -861,37 +825,15 @@ export const Fund: React.FC<FundProps> = ({
861
825
  <div className="ml-2 animate-spin rounded-full h-4 w-4 border-solid border-b-2 trails-primary" />
862
826
  )}
863
827
  </div>
864
- </div>
828
+ </button>
865
829
  </div>
866
830
 
867
831
  {/* Token Selection Button */}
868
- <button
869
- type="button"
870
- onClick={() => setShowOriginTokenSelector(true)}
871
- 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"
872
- >
873
- {originToken ? (
874
- <>
875
- <TokenImage
876
- symbol={originToken.symbol}
877
- imageUrl={originToken.imageUrl}
878
- chainId={originToken.chainId}
879
- size={20}
880
- />
881
- <span className="font-medium trails-text-primary text-sm">
882
- {originToken.symbol}
883
- </span>
884
- <ChevronDown className="w-3.5 h-3.5 trails-text-muted" />
885
- </>
886
- ) : (
887
- <>
888
- <span className="font-medium trails-text-muted text-sm">
889
- Select Token
890
- </span>
891
- <ChevronDown className="w-3.5 h-3.5 trails-text-muted" />
892
- </>
893
- )}
894
- </button>
832
+ <TokenSelectorButton
833
+ token={originToken}
834
+ chainId={originToken?.chainId}
835
+ onSelect={() => setShowOriginTokenSelector(true)}
836
+ />
895
837
  </div>
896
838
 
897
839
  {/* Bottom Info Row */}
@@ -905,9 +847,9 @@ export const Fund: React.FC<FundProps> = ({
905
847
  )}
906
848
  </div>
907
849
 
908
- {/* Origin Token Balance */}
909
- <div className="text-xs trails-text-muted text-right">
910
- {originToken ? (
850
+ {/* Origin Token Balance and Percentage Buttons */}
851
+ {originToken && balanceFormatted && (
852
+ <div className="flex items-center space-x-2">
911
853
  <button
912
854
  type="button"
913
855
  className="text-xs trails-text-muted cursor-pointer hover:trails-hover-text transition-colors bg-transparent border-none p-0"
@@ -921,14 +863,25 @@ export const Fund: React.FC<FundProps> = ({
921
863
  title="Click to use full balance"
922
864
  >
923
865
  Balance:{" "}
924
- {isBalanceVisible
925
- ? `${balanceFormatted || "0.00"} ${originToken.symbol}`
926
- : "••••••"}
866
+ {isBalanceVisible ? balanceFormatted || "0.00" : "••••••"}
927
867
  </button>
928
- ) : (
929
- <span>&nbsp;</span>
930
- )}
931
- </div>
868
+
869
+ {/* Percentage Buttons */}
870
+ <PercentageMaxButtons
871
+ userBalance={balanceFormatted}
872
+ isNativeToken={originToken.contractAddress === zeroAddress}
873
+ gasCostFormatted={prepareSendQuote?.gasCostFormatted}
874
+ chainId={originToken.chainId}
875
+ onAmountSelect={(amount) => {
876
+ setTokenAmountForBackend(amount)
877
+ setSendFormAmount(amount)
878
+ setGlobalAmount(amount)
879
+ setInputDisplayValue(amount)
880
+ }}
881
+ className="opacity-100"
882
+ />
883
+ </div>
884
+ )}
932
885
  </div>
933
886
  </div>
934
887
 
@@ -1050,7 +1003,7 @@ export const Fund: React.FC<FundProps> = ({
1050
1003
  <div className="relative">
1051
1004
  {toToken ? (
1052
1005
  /* Display only - destination token is fixed */
1053
- <div className="w-full flex items-center justify-between space-x-3 trails-bg-secondary trails-border-radius-list-button px-4 py-2">
1006
+ <div className="w-full flex items-center justify-between space-x-3 trails-bg-secondary trails-border-radius-list-button px-4 py-2 pb-6">
1054
1007
  <div className="text-left">
1055
1008
  <div className="font-medium trails-text-primary text-sm whitespace-nowrap">
1056
1009
  Receiving amount
@@ -1059,17 +1012,26 @@ export const Fund: React.FC<FundProps> = ({
1059
1012
  <div className="flex items-center space-x-2">
1060
1013
  {selectedDestToken ? (
1061
1014
  <>
1062
- <div className="font-medium trails-text-primary text-sm">
1063
- {isLoadingQuote ? (
1064
- <div className="h-4 w-20 bg-gray-200 dark:bg-gray-700 rounded animate-pulse"></div>
1065
- ) : prepareSendQuote?.destinationAmountFormatted ? (
1066
- <span className="whitespace-nowrap">
1067
- {prepareSendQuote.destinationAmountFormatted}{" "}
1068
- {selectedDestToken.symbol}
1069
- </span>
1070
- ) : (
1071
- ""
1072
- )}
1015
+ <div className="relative">
1016
+ <div className="font-medium trails-text-primary text-sm">
1017
+ {isLoadingQuote ? (
1018
+ <div className="h-4 w-20 bg-gray-200 dark:bg-gray-700 rounded animate-pulse"></div>
1019
+ ) : prepareSendQuote?.destinationAmountFormatted ? (
1020
+ <span className="whitespace-nowrap">
1021
+ {prepareSendQuote.destinationAmountFormatted}{" "}
1022
+ {selectedDestToken.symbol}
1023
+ </span>
1024
+ ) : (
1025
+ ""
1026
+ )}
1027
+ </div>
1028
+ {/* USD Display - Hidden during loading, absolutely positioned */}
1029
+ {!isLoadingQuote &&
1030
+ prepareSendQuote?.destinationAmountUsdDisplay && (
1031
+ <div className="absolute top-full right-0 text-xs trails-text-muted mt-0.5">
1032
+ ≈ {prepareSendQuote.destinationAmountUsdDisplay}
1033
+ </div>
1034
+ )}
1073
1035
  </div>
1074
1036
  <TokenImage
1075
1037
  symbol={selectedDestToken.symbol}
@@ -1095,7 +1057,7 @@ export const Fund: React.FC<FundProps> = ({
1095
1057
  <button
1096
1058
  type="button"
1097
1059
  onClick={() => setShowDestinationTokenSelector(true)}
1098
- className="w-full flex items-center justify-between space-x-3 hover:trails-hover-bg hover:bg-gray-50 dark:hover:bg-gray-700 trails-border-radius-list-button px-4 py-2 transition-all duration-200 cursor-pointer"
1060
+ className="w-full flex items-center justify-between space-x-3 hover:trails-hover-bg hover:bg-gray-50 dark:hover:bg-gray-700 trails-border-radius-list-button px-4 py-2 pb-6 transition-all duration-200 cursor-pointer"
1099
1061
  >
1100
1062
  <div className="text-left">
1101
1063
  <div className="font-medium trails-text-primary text-sm whitespace-nowrap">
@@ -1106,17 +1068,26 @@ export const Fund: React.FC<FundProps> = ({
1106
1068
  <div className="flex items-center space-x-2">
1107
1069
  {selectedDestToken ? (
1108
1070
  <>
1109
- <div className="font-medium trails-text-primary text-sm">
1110
- {isLoadingQuote ? (
1111
- <div className="h-4 w-20 bg-gray-200 dark:bg-gray-700 rounded animate-pulse"></div>
1112
- ) : prepareSendQuote?.destinationAmountFormatted ? (
1113
- <span className="whitespace-nowrap">
1114
- {prepareSendQuote.destinationAmountFormatted}{" "}
1115
- {selectedDestToken.symbol}
1116
- </span>
1117
- ) : (
1118
- ""
1119
- )}
1071
+ <div className="relative">
1072
+ <div className="font-medium trails-text-primary text-sm">
1073
+ {isLoadingQuote ? (
1074
+ <div className="h-4 w-20 bg-gray-200 dark:bg-gray-700 rounded animate-pulse"></div>
1075
+ ) : prepareSendQuote?.destinationAmountFormatted ? (
1076
+ <span className="whitespace-nowrap">
1077
+ {prepareSendQuote.destinationAmountFormatted}{" "}
1078
+ {selectedDestToken.symbol}
1079
+ </span>
1080
+ ) : (
1081
+ ""
1082
+ )}
1083
+ </div>
1084
+ {/* USD Display - Hidden during loading, absolutely positioned */}
1085
+ {!isLoadingQuote &&
1086
+ prepareSendQuote?.destinationAmountUsdDisplay && (
1087
+ <div className="absolute top-full right-0 text-xs trails-text-muted mt-0.5">
1088
+ ≈ {prepareSendQuote.destinationAmountUsdDisplay}
1089
+ </div>
1090
+ )}
1120
1091
  </div>
1121
1092
  <TokenImage
1122
1093
  symbol={selectedDestToken.symbol}
@@ -1149,6 +1120,7 @@ export const Fund: React.FC<FundProps> = ({
1149
1120
  fundMethod={fundMethod}
1150
1121
  isSenderContractOnOrigin={isSenderContractOnOrigin}
1151
1122
  isSenderContractOnDestination={isSenderContractOnDestination}
1123
+ isSequenceWallet={isSequenceWallet}
1152
1124
  />
1153
1125
 
1154
1126
  {/* Error Display */}
@@ -1,11 +1,12 @@
1
1
  import type React from "react"
2
- import { Wallet, QrCode, Building2 } from "lucide-react"
3
- import { useAccount } from "wagmi"
4
- import { truncateAddress } from "../../utils.js"
5
- import { useTheme } from "../components/ThemeProvider.js"
6
- import WalletConnectLogoWhite from "../assets/WalletConnect-logo-white.svg"
7
- import WalletConnectLogoBlack from "../assets/WalletConnect-logo-black.svg"
2
+ import { QrCode, Send, ChevronRight } from "lucide-react"
3
+ import { useSwitchAccount } from "wagmi"
8
4
  import { ScreenHeader } from "./ScreenHeader.js"
5
+ import { ConnectedWallets } from "./ConnectedWallets.js"
6
+ import { useCurrentScreen } from "../hooks/useCurrentScreen.js"
7
+ import { useConnections } from "wagmi"
8
+ import { logger } from "../../logger.js"
9
+ import { useSelectedFundMethod } from "../hooks/useSelectedFundMethod.js"
9
10
 
10
11
  export interface FundMethodsProps {
11
12
  onBack?: () => void
@@ -17,178 +18,100 @@ export interface FundMethodsProps {
17
18
 
18
19
  const FundMethods: React.FC<FundMethodsProps> = ({
19
20
  onBack,
20
- onSelectWalletConnect,
21
21
  onSelectExchangeList,
22
- onSelectConnectedAccount,
23
22
  onSelectQrCode,
24
23
  }) => {
25
- const { address, isConnected, connector } = useAccount()
26
- const { getActiveTheme } = useTheme()
24
+ const { switchAccount } = useSwitchAccount()
25
+ const connections = useConnections()
26
+ const { setCurrentScreen } = useCurrentScreen()
27
+ const { setSelectedFundMethod } = useSelectedFundMethod()
27
28
 
28
- const activeTheme = getActiveTheme()
29
+ // Handle wallet selection - switch to the selected wallet and go to home
30
+ const handleWalletSelect = async (
31
+ walletAddress: string,
32
+ walletConnector: unknown,
33
+ ) => {
34
+ try {
35
+ // Find the connection for this wallet
36
+ const connection = connections.find(
37
+ (conn) =>
38
+ conn.accounts.includes(walletAddress as `0x${string}`) &&
39
+ conn.connector.id === (walletConnector as { id: string }).id,
40
+ )
41
+
42
+ if (connection) {
43
+ await switchAccount({
44
+ connector: connection.connector,
45
+ })
46
+ logger.console.log(`[trails-sdk] Switched to wallet: ${walletAddress}`)
47
+
48
+ // Set funding method to "wallet" since user selected a wallet
49
+ setSelectedFundMethod("wallet")
50
+
51
+ // Navigate to home screen which will redirect to the appropriate mode screen
52
+ setCurrentScreen("home")
53
+ }
54
+ } catch (error) {
55
+ logger.console.error("[trails-sdk] Failed to switch wallet:", error)
56
+ }
57
+ }
29
58
 
30
59
  return (
31
60
  <div className="flex flex-col h-full">
32
61
  <ScreenHeader
33
62
  onBack={onBack}
34
- headerContent="Funding Method"
63
+ headerContent="Payment methods"
35
64
  headerContentAlign="left"
36
65
  rightSideContent={<div className="w-9" />}
37
- showAccountActions={true}
38
66
  />
39
67
 
40
68
  <div className="flex-1">
41
- <div className="space-y-3">
42
- <button
43
- type="button"
44
- onClick={onSelectConnectedAccount}
45
- className="w-full flex items-center justify-between cursor-pointer font-semibold py-4 px-6 trails-border-radius-large-button transition-all duration-200 trails-bg-secondary trails-hover-bg trails-text-primary"
46
- >
47
- <div className="flex items-center space-x-3 flex-1">
48
- <Wallet className="h-6 w-6 text-gray-600 dark:text-gray-400" />
49
- <div className="flex-1 text-left">
50
- <h4 className="font-semibold text-gray-900 dark:text-gray-100">
51
- Connected Account
52
- </h4>
53
- <p className="text-sm text-gray-600 dark:text-gray-400">
54
- Use your connected wallet to fund directly.
55
- </p>
56
- <p className="text-xs font-mono text-gray-600 dark:text-gray-300">
57
- {isConnected && address
58
- ? `${connector?.name || "Connected"}: ${truncateAddress(address)}`
59
- : "No wallet connected"}
60
- </p>
61
- </div>
62
- </div>
63
- <div className="text-gray-400">
64
- <svg
65
- className="w-5 h-5"
66
- fill="none"
67
- stroke="currentColor"
68
- viewBox="0 0 24 24"
69
- aria-label="Chevron right"
70
- >
71
- <path
72
- strokeLinecap="round"
73
- strokeLinejoin="round"
74
- strokeWidth={2}
75
- d="M9 5l7 7-7 7"
76
- />
77
- </svg>
78
- </div>
79
- </button>
69
+ <div className="space-y-4">
70
+ {/* Connected Wallets Section */}
71
+ <ConnectedWallets
72
+ showConnectNewWallet={true}
73
+ onWalletSelect={handleWalletSelect}
74
+ backScreen="fund-methods"
75
+ />
80
76
 
81
- <button
82
- type="button"
83
- onClick={onSelectWalletConnect}
84
- className="w-full flex items-center justify-between cursor-pointer font-semibold py-4 px-6 trails-border-radius-large-button transition-all duration-200 trails-bg-secondary trails-hover-bg trails-text-primary"
85
- >
86
- <div className="flex items-center space-x-3 flex-1">
87
- <div className="h-6 w-6 rounded flex items-center justify-center">
88
- <img
89
- src={
90
- activeTheme === "dark"
91
- ? WalletConnectLogoWhite
92
- : WalletConnectLogoBlack
93
- }
94
- alt="WalletConnect"
95
- className="h-4 w-4"
96
- />
97
- </div>
98
- <div className="flex-1 text-left">
99
- <h4 className="font-semibold text-gray-900 dark:text-gray-100">
100
- WalletConnect
101
- </h4>
102
- <p className="text-sm text-gray-600 dark:text-gray-400">
103
- Connect another wallet.
104
- </p>
105
- </div>
106
- </div>
107
- <div className="text-gray-400">
108
- <svg
109
- className="w-5 h-5"
110
- fill="none"
111
- stroke="currentColor"
112
- viewBox="0 0 24 24"
113
- aria-label="Chevron right"
114
- >
115
- <path
116
- strokeLinecap="round"
117
- strokeLinejoin="round"
118
- strokeWidth={2}
119
- d="M9 5l7 7-7 7"
120
- />
121
- </svg>
122
- </div>
123
- </button>
77
+ {/* Divider */}
78
+ <div className="relative flex items-center justify-center">
79
+ <div className="flex-1 border-t border-gray-200 dark:border-gray-700"></div>
80
+ <span className="px-4 text-sm text-gray-500 dark:text-gray-400 bg-white dark:bg-gray-900">
81
+ or
82
+ </span>
83
+ <div className="flex-1 border-t border-gray-200 dark:border-gray-700"></div>
84
+ </div>
124
85
 
125
- <button
126
- type="button"
127
- onClick={onSelectQrCode}
128
- className="w-full flex items-center justify-between cursor-pointer font-semibold py-4 px-6 trails-border-radius-large-button transition-all duration-200 trails-bg-secondary trails-hover-bg trails-text-primary"
129
- >
130
- <div className="flex items-center space-x-3 flex-1">
131
- <QrCode className="h-6 w-6 text-gray-600 dark:text-gray-400" />
132
- <div className="flex-1 text-left">
133
- <h4 className="font-semibold text-gray-900 dark:text-gray-100">
134
- Pay with QR Code
135
- </h4>
136
- <p className="text-sm text-gray-600 dark:text-gray-400">
137
- Scan a QR code to deposit funds.
138
- </p>
86
+ {/* Additional Funding Options */}
87
+ <div className="trails-border-radius-container border trails-border-primary">
88
+ <button
89
+ type="button"
90
+ onClick={onSelectQrCode}
91
+ className="w-full text-left px-3 py-4 text-sm flex items-center justify-between cursor-pointer transition-colors trails-text-primary trails-hover-bg"
92
+ >
93
+ <div className="flex items-center gap-3">
94
+ <QrCode className="w-4 h-4" />
95
+ <span className="text-sm font-bold">Pay with QR Code</span>
139
96
  </div>
140
- </div>
141
- <div className="text-gray-400">
142
- <svg
143
- className="w-5 h-5"
144
- fill="none"
145
- stroke="currentColor"
146
- viewBox="0 0 24 24"
147
- aria-label="Chevron right"
148
- >
149
- <path
150
- strokeLinecap="round"
151
- strokeLinejoin="round"
152
- strokeWidth={2}
153
- d="M9 5l7 7-7 7"
154
- />
155
- </svg>
156
- </div>
157
- </button>
97
+ <ChevronRight className="w-5 h-5 text-gray-400" />
98
+ </button>
99
+
100
+ {/* Divider between buttons */}
101
+ <div className="border-b border-gray-200 dark:border-gray-700"></div>
158
102
 
159
- <button
160
- type="button"
161
- onClick={onSelectExchangeList}
162
- className="w-full flex items-center justify-between cursor-pointer font-semibold py-4 px-6 trails-border-radius-large-button transition-all duration-200 trails-bg-secondary trails-hover-bg trails-text-primary"
163
- >
164
- <div className="flex items-center space-x-3 flex-1">
165
- <Building2 className="h-6 w-6 text-gray-600 dark:text-gray-400" />
166
- <div className="flex-1 text-left">
167
- <h4 className="font-semibold text-gray-900 dark:text-gray-100">
168
- Send from Exchange
169
- </h4>
170
- <p className="text-sm text-gray-600 dark:text-gray-400">
171
- Transfer from Coinbase, Binance, etc.
172
- </p>
103
+ <button
104
+ type="button"
105
+ onClick={onSelectExchangeList}
106
+ className="w-full text-left px-3 py-4 text-sm flex items-center justify-between cursor-pointer transition-colors trails-text-primary trails-hover-bg"
107
+ >
108
+ <div className="flex items-center gap-3">
109
+ <Send className="w-4 h-4" />
110
+ <span className="text-sm font-bold">Send from Exchange</span>
173
111
  </div>
174
- </div>
175
- <div className="text-gray-400">
176
- <svg
177
- className="w-5 h-5"
178
- fill="none"
179
- stroke="currentColor"
180
- viewBox="0 0 24 24"
181
- aria-label="Chevron right"
182
- >
183
- <path
184
- strokeLinecap="round"
185
- strokeLinejoin="round"
186
- strokeWidth={2}
187
- d="M9 5l7 7-7 7"
188
- />
189
- </svg>
190
- </div>
191
- </button>
112
+ <ChevronRight className="w-5 h-5 text-gray-400" />
113
+ </button>
114
+ </div>
192
115
  </div>
193
116
  </div>
194
117
  </div>
@@ -0,0 +1,52 @@
1
+ import type React from "react"
2
+ import type { Account, WalletClient } from "viem"
3
+ import type { TransactionState } from "../../transactions.js"
4
+ import type { OnCompleteProps, Token } from "../hooks/useSendForm.js"
5
+ import type { SupportedToken } from "../../tokens.js"
6
+ import type { CheckoutOnHandlers } from "../hooks/useCheckout.js"
7
+ import type { PrepareSendQuote } from "../../prepareSend.js"
8
+ import { ClassicSwap } from "./ClassicSwap.js"
9
+
10
+ interface FundProps {
11
+ selectedToken: Token | null
12
+ onSend: (amount: string, recipient: string) => void
13
+ onBack?: () => void
14
+ onConfirm: () => void
15
+ onComplete: (result: OnCompleteProps) => void
16
+ account: Account
17
+ toRecipient?: string
18
+ toAmount?: string
19
+ toChainId?: number
20
+ toToken?: string
21
+ toCalldata?: string
22
+ walletClient: WalletClient
23
+ onTransactionStateChange: (transactionStates: TransactionState[]) => void
24
+ onError: (error: Error | string | null) => void
25
+ onWaitingForWalletConfirm: (props: PrepareSendQuote) => void
26
+ paymasterUrls?: Array<{ chainId: number; url: string }>
27
+ gasless?: boolean
28
+ setWalletConfirmRetryHandler: (handler: () => Promise<void>) => void
29
+ quoteProvider?: string
30
+ fundMethod?: string
31
+ onNavigateToMeshConnect?: (
32
+ props: {
33
+ toTokenSymbol: string
34
+ toTokenAmount: string
35
+ toChainId: number
36
+ toRecipientAddress: string
37
+ },
38
+ quote?: PrepareSendQuote | null,
39
+ ) => void
40
+ onAmountUpdate?: (amount: string) => void
41
+ checkoutOnHandlers?: CheckoutOnHandlers
42
+ recentTokens?: SupportedToken[]
43
+ onRecentTokenSelect?: (token: SupportedToken) => void
44
+ onTrackToken?: (token: any) => void
45
+ isSequenceWallet?: boolean
46
+ }
47
+
48
+ export const Fund: React.FC<FundProps> = (props) => {
49
+ return <ClassicSwap {...props} title="Fund" />
50
+ }
51
+
52
+ export default Fund