0xtrails 0.2.5 → 0.3.0

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 (267) hide show
  1. package/dist/aave.d.ts +2 -0
  2. package/dist/aave.d.ts.map +1 -1
  3. package/dist/abortController.d.ts +8 -0
  4. package/dist/abortController.d.ts.map +1 -0
  5. package/dist/{ccip-CXlshvBY.js → ccip-BMB3uDZt.js} +1 -1
  6. package/dist/config.d.ts +0 -5
  7. package/dist/config.d.ts.map +1 -1
  8. package/dist/constants.d.ts +4 -4
  9. package/dist/constants.d.ts.map +1 -1
  10. package/dist/error.d.ts +4 -1
  11. package/dist/error.d.ts.map +1 -1
  12. package/dist/fees.d.ts +19 -0
  13. package/dist/fees.d.ts.map +1 -0
  14. package/dist/{index-_QuyGrjU.js → index-QXPUrZVv.js} +48719 -50852
  15. package/dist/index.d.ts +9 -8
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +811 -784
  18. package/dist/intentReceiptMonitor.d.ts +24 -0
  19. package/dist/intentReceiptMonitor.d.ts.map +1 -0
  20. package/dist/intentReceiptPoller.d.ts +69 -0
  21. package/dist/intentReceiptPoller.d.ts.map +1 -0
  22. package/dist/intents.d.ts +15 -11
  23. package/dist/intents.d.ts.map +1 -1
  24. package/dist/morpho.d.ts +6 -5
  25. package/dist/morpho.d.ts.map +1 -1
  26. package/dist/mutations.d.ts +16 -0
  27. package/dist/mutations.d.ts.map +1 -0
  28. package/dist/preconditions.d.ts +5 -4
  29. package/dist/preconditions.d.ts.map +1 -1
  30. package/dist/prepareSend.d.ts +7 -258
  31. package/dist/prepareSend.d.ts.map +1 -1
  32. package/dist/prices.d.ts +9 -6
  33. package/dist/prices.d.ts.map +1 -1
  34. package/dist/sequenceWallet.d.ts +3 -16
  35. package/dist/sequenceWallet.d.ts.map +1 -1
  36. package/dist/tokenBalances.d.ts +17 -13
  37. package/dist/tokenBalances.d.ts.map +1 -1
  38. package/dist/trails.d.ts +24 -40
  39. package/dist/trails.d.ts.map +1 -1
  40. package/dist/transactionIntent/constants.d.ts +7 -0
  41. package/dist/transactionIntent/constants.d.ts.map +1 -0
  42. package/dist/transactionIntent/deposits/depositOrchestrator.d.ts +44 -0
  43. package/dist/transactionIntent/deposits/depositOrchestrator.d.ts.map +1 -0
  44. package/dist/transactionIntent/deposits/gaslessDeposit.d.ts +30 -0
  45. package/dist/transactionIntent/deposits/gaslessDeposit.d.ts.map +1 -0
  46. package/dist/transactionIntent/deposits/index.d.ts +4 -0
  47. package/dist/transactionIntent/deposits/index.d.ts.map +1 -0
  48. package/dist/transactionIntent/deposits/standardDeposit.d.ts +30 -0
  49. package/dist/transactionIntent/deposits/standardDeposit.d.ts.map +1 -0
  50. package/dist/transactionIntent/execution/index.d.ts +2 -0
  51. package/dist/transactionIntent/execution/index.d.ts.map +1 -0
  52. package/dist/transactionIntent/execution/transactionState.d.ts +5 -0
  53. package/dist/transactionIntent/execution/transactionState.d.ts.map +1 -0
  54. package/dist/transactionIntent/handlers/crossChain.d.ts +82 -0
  55. package/dist/transactionIntent/handlers/crossChain.d.ts.map +1 -0
  56. package/dist/transactionIntent/handlers/index.d.ts +4 -0
  57. package/dist/transactionIntent/handlers/index.d.ts.map +1 -0
  58. package/dist/transactionIntent/handlers/sameChainDifferentToken.d.ts +62 -0
  59. package/dist/transactionIntent/handlers/sameChainDifferentToken.d.ts.map +1 -0
  60. package/dist/transactionIntent/handlers/sameChainSameToken.d.ts +72 -0
  61. package/dist/transactionIntent/handlers/sameChainSameToken.d.ts.map +1 -0
  62. package/dist/transactionIntent/index.d.ts +9 -0
  63. package/dist/transactionIntent/index.d.ts.map +1 -0
  64. package/dist/transactionIntent/quote/feeExtractors.d.ts +17 -0
  65. package/dist/transactionIntent/quote/feeExtractors.d.ts.map +1 -0
  66. package/dist/transactionIntent/quote/index.d.ts +4 -0
  67. package/dist/transactionIntent/quote/index.d.ts.map +1 -0
  68. package/dist/transactionIntent/quote/normalizeQuote.d.ts +34 -0
  69. package/dist/transactionIntent/quote/normalizeQuote.d.ts.map +1 -0
  70. package/dist/transactionIntent/quote/quoteHelpers.d.ts +5 -0
  71. package/dist/transactionIntent/quote/quoteHelpers.d.ts.map +1 -0
  72. package/dist/transactionIntent/types.d.ts +131 -0
  73. package/dist/transactionIntent/types.d.ts.map +1 -0
  74. package/dist/transactionIntent/utils/balanceChecker.d.ts +18 -0
  75. package/dist/transactionIntent/utils/balanceChecker.d.ts.map +1 -0
  76. package/dist/transactionIntent/utils/index.d.ts +4 -0
  77. package/dist/transactionIntent/utils/index.d.ts.map +1 -0
  78. package/dist/transactionIntent/utils/lifiHelpers.d.ts +10 -0
  79. package/dist/transactionIntent/utils/lifiHelpers.d.ts.map +1 -0
  80. package/dist/transactionIntent/utils/testnetHelpers.d.ts +3 -0
  81. package/dist/transactionIntent/utils/testnetHelpers.d.ts.map +1 -0
  82. package/dist/transactionIntent/validators.d.ts +6 -0
  83. package/dist/transactionIntent/validators.d.ts.map +1 -0
  84. package/dist/transactions.d.ts +6 -3
  85. package/dist/transactions.d.ts.map +1 -1
  86. package/dist/widget/components/AccountIntentTransactionHistoryButton.d.ts +4 -0
  87. package/dist/widget/components/AccountIntentTransactionHistoryButton.d.ts.map +1 -0
  88. package/dist/widget/components/AccountSettings.d.ts.map +1 -1
  89. package/dist/widget/components/ChainFilterDropdown.d.ts.map +1 -1
  90. package/dist/widget/components/ClassicSwap.d.ts +2 -3
  91. package/dist/widget/components/ClassicSwap.d.ts.map +1 -1
  92. package/dist/widget/components/ConfigDisplay.d.ts.map +1 -1
  93. package/dist/widget/components/ConnectWallet.d.ts.map +1 -1
  94. package/dist/widget/components/ConnectedWallets.d.ts.map +1 -1
  95. package/dist/widget/components/DynamicInputStyles.d.ts +18 -0
  96. package/dist/widget/components/DynamicInputStyles.d.ts.map +1 -0
  97. package/dist/widget/components/DynamicSizeInputField.d.ts +13 -0
  98. package/dist/widget/components/DynamicSizeInputField.d.ts.map +1 -0
  99. package/dist/widget/components/Earn.d.ts +2 -3
  100. package/dist/widget/components/Earn.d.ts.map +1 -1
  101. package/dist/widget/components/ErrorAnimationIcon.d.ts +2 -0
  102. package/dist/widget/components/ErrorAnimationIcon.d.ts.map +1 -0
  103. package/dist/widget/components/FeeBreakdown.d.ts +9 -0
  104. package/dist/widget/components/FeeBreakdown.d.ts.map +1 -0
  105. package/dist/widget/components/FeeOptions.d.ts +5 -13
  106. package/dist/widget/components/FeeOptions.d.ts.map +1 -1
  107. package/dist/widget/components/Fund.d.ts +2 -3
  108. package/dist/widget/components/Fund.d.ts.map +1 -1
  109. package/dist/widget/components/FundMethods.d.ts.map +1 -1
  110. package/dist/widget/components/FundSwap.d.ts +2 -3
  111. package/dist/widget/components/FundSwap.d.ts.map +1 -1
  112. package/dist/widget/components/FundingMethodSelectorButton.d.ts.map +1 -1
  113. package/dist/widget/components/Identicon.d.ts.map +1 -1
  114. package/dist/widget/components/MeshConnectExchanges.d.ts +0 -3
  115. package/dist/widget/components/MeshConnectExchanges.d.ts.map +1 -1
  116. package/dist/widget/components/Modal.d.ts.map +1 -1
  117. package/dist/widget/components/Pay.d.ts +2 -3
  118. package/dist/widget/components/Pay.d.ts.map +1 -1
  119. package/dist/widget/components/PoolDeposit.d.ts +3 -3
  120. package/dist/widget/components/PoolDeposit.d.ts.map +1 -1
  121. package/dist/widget/components/PoolWithdraw.d.ts +3 -20
  122. package/dist/widget/components/PoolWithdraw.d.ts.map +1 -1
  123. package/dist/widget/components/QuoteDetails.d.ts +2 -0
  124. package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
  125. package/dist/widget/components/Receipt.d.ts.map +1 -1
  126. package/dist/widget/components/RecipientSelectorButton.d.ts.map +1 -1
  127. package/dist/widget/components/ScreenHeader.d.ts.map +1 -1
  128. package/dist/widget/components/Swap.d.ts +2 -3
  129. package/dist/widget/components/Swap.d.ts.map +1 -1
  130. package/dist/widget/components/ThemeProvider.d.ts.map +1 -1
  131. package/dist/widget/components/TokenDisplayNonSelectable.d.ts +11 -0
  132. package/dist/widget/components/TokenDisplayNonSelectable.d.ts.map +1 -0
  133. package/dist/widget/components/TokenSelector.d.ts.map +1 -1
  134. package/dist/widget/components/TokenSelectorButton.d.ts.map +1 -1
  135. package/dist/widget/components/Tooltip.d.ts +9 -0
  136. package/dist/widget/components/Tooltip.d.ts.map +1 -0
  137. package/dist/widget/components/TransferPendingVertical.d.ts.map +1 -1
  138. package/dist/widget/components/WaasFeeOptions.d.ts +1 -0
  139. package/dist/widget/components/WaasFeeOptions.d.ts.map +1 -1
  140. package/dist/widget/components/WalletConfirmation.d.ts.map +1 -1
  141. package/dist/widget/components/WalletConnect.d.ts.map +1 -1
  142. package/dist/widget/css/compiled.css +2 -2
  143. package/dist/widget/hooks/useCheckout.d.ts +17 -4
  144. package/dist/widget/hooks/useCheckout.d.ts.map +1 -1
  145. package/dist/widget/hooks/useDefaultTokenSelection.d.ts.map +1 -1
  146. package/dist/widget/hooks/useQuote.d.ts +82 -0
  147. package/dist/widget/hooks/useQuote.d.ts.map +1 -0
  148. package/dist/widget/hooks/useSelectedFeeToken.d.ts +1 -0
  149. package/dist/widget/hooks/useSelectedFeeToken.d.ts.map +1 -1
  150. package/dist/widget/hooks/useSendForm.d.ts +5 -6
  151. package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
  152. package/dist/widget/hooks/useTokenList.d.ts.map +1 -1
  153. package/dist/widget/hooks/useWalletConnectionContext.d.ts +25 -0
  154. package/dist/widget/hooks/useWalletConnectionContext.d.ts.map +1 -0
  155. package/dist/widget/index.js +2 -2
  156. package/dist/widget/widget.d.ts +17 -7
  157. package/dist/widget/widget.d.ts.map +1 -1
  158. package/package.json +19 -21
  159. package/src/aave.ts +54 -1
  160. package/src/abortController.ts +35 -0
  161. package/src/config.ts +57 -58
  162. package/src/constants.ts +11 -9
  163. package/src/error.ts +21 -3
  164. package/src/fees.ts +210 -0
  165. package/src/index.ts +35 -13
  166. package/src/intentReceiptMonitor.ts +102 -0
  167. package/src/intentReceiptPoller.ts +299 -0
  168. package/src/intents.ts +205 -171
  169. package/src/morpho.ts +58 -9
  170. package/src/mutations.ts +129 -0
  171. package/src/preconditions.ts +16 -21
  172. package/src/prepareSend.ts +92 -4699
  173. package/src/prices.ts +26 -22
  174. package/src/relaySdk.ts +2 -2
  175. package/src/sequenceWallet.ts +6 -73
  176. package/src/tokenBalances.ts +175 -69
  177. package/src/trails.ts +230 -722
  178. package/src/transactionIntent/constants.ts +11 -0
  179. package/src/transactionIntent/deposits/depositOrchestrator.ts +210 -0
  180. package/src/transactionIntent/deposits/gaslessDeposit.ts +588 -0
  181. package/src/transactionIntent/deposits/index.ts +3 -0
  182. package/src/transactionIntent/deposits/standardDeposit.ts +379 -0
  183. package/src/transactionIntent/execution/index.ts +1 -0
  184. package/src/transactionIntent/execution/transactionState.ts +35 -0
  185. package/src/transactionIntent/handlers/crossChain.ts +1707 -0
  186. package/src/transactionIntent/handlers/index.ts +3 -0
  187. package/src/transactionIntent/handlers/sameChainDifferentToken.ts +323 -0
  188. package/src/transactionIntent/handlers/sameChainSameToken.ts +712 -0
  189. package/src/transactionIntent/index.ts +9 -0
  190. package/src/transactionIntent/quote/feeExtractors.ts +81 -0
  191. package/src/transactionIntent/quote/index.ts +3 -0
  192. package/src/transactionIntent/quote/normalizeQuote.ts +367 -0
  193. package/src/transactionIntent/quote/quoteHelpers.ts +53 -0
  194. package/src/transactionIntent/types.ts +157 -0
  195. package/src/transactionIntent/utils/balanceChecker.ts +96 -0
  196. package/src/transactionIntent/utils/index.ts +3 -0
  197. package/src/transactionIntent/utils/lifiHelpers.ts +68 -0
  198. package/src/transactionIntent/utils/testnetHelpers.ts +10 -0
  199. package/src/transactionIntent/validators.ts +57 -0
  200. package/src/transactions.ts +98 -71
  201. package/src/widget/compiled.css +2 -2
  202. package/src/widget/components/AccountIntentTransactionHistory.tsx +36 -36
  203. package/src/widget/components/AccountIntentTransactionHistoryButton.tsx +22 -0
  204. package/src/widget/components/AccountSettings.tsx +70 -41
  205. package/src/widget/components/ChainFilterDropdown.tsx +24 -3
  206. package/src/widget/components/ClassicSwap.tsx +44 -107
  207. package/src/widget/components/ConfigDisplay.tsx +0 -11
  208. package/src/widget/components/ConnectWallet.tsx +4 -1
  209. package/src/widget/components/ConnectedWallets.tsx +51 -25
  210. package/src/widget/components/DynamicInputStyles.tsx +76 -0
  211. package/src/widget/components/DynamicSizeInputField.tsx +109 -0
  212. package/src/widget/components/Earn.tsx +34 -45
  213. package/src/widget/components/ErrorAnimationIcon.tsx +130 -0
  214. package/src/widget/components/FeeBreakdown.tsx +155 -0
  215. package/src/widget/components/FeeOption.tsx +2 -2
  216. package/src/widget/components/FeeOptions.tsx +151 -112
  217. package/src/widget/components/Fund.tsx +10 -29
  218. package/src/widget/components/FundMethods.tsx +4 -3
  219. package/src/widget/components/FundSwap.tsx +2 -3
  220. package/src/widget/components/FundingMethodSelectorButton.tsx +24 -14
  221. package/src/widget/components/Identicon.tsx +164 -95
  222. package/src/widget/components/MeshConnectExchanges.tsx +2 -15
  223. package/src/widget/components/Modal.tsx +0 -12
  224. package/src/widget/components/Pay.tsx +72 -75
  225. package/src/widget/components/PoolDeposit.tsx +221 -242
  226. package/src/widget/components/PoolWithdraw.tsx +347 -469
  227. package/src/widget/components/PriceImpactWarning.tsx +1 -1
  228. package/src/widget/components/QuoteDetails.tsx +906 -484
  229. package/src/widget/components/Receipt.tsx +16 -2
  230. package/src/widget/components/RecipientSelectorButton.tsx +7 -5
  231. package/src/widget/components/Recipients.tsx +1 -1
  232. package/src/widget/components/ScreenHeader.tsx +60 -36
  233. package/src/widget/components/Swap.tsx +2 -3
  234. package/src/widget/components/ThemeProvider.tsx +2 -1
  235. package/src/widget/components/TokenDisplayNonSelectable.tsx +40 -0
  236. package/src/widget/components/TokenImage.tsx +1 -1
  237. package/src/widget/components/TokenSelector.tsx +62 -53
  238. package/src/widget/components/TokenSelectorButton.tsx +38 -15
  239. package/src/widget/components/Tooltip.tsx +51 -0
  240. package/src/widget/components/TransferPendingVertical.tsx +12 -8
  241. package/src/widget/components/WaasFeeOptions.tsx +139 -4
  242. package/src/widget/components/WalletConfirmation.tsx +23 -13
  243. package/src/widget/components/WalletConnect.tsx +93 -29
  244. package/src/widget/hooks/useAmountUsd.ts +9 -9
  245. package/src/widget/hooks/useCheckout.ts +97 -9
  246. package/src/widget/hooks/useDefaultTokenSelection.tsx +27 -21
  247. package/src/widget/hooks/useQuote.ts +466 -0
  248. package/src/widget/hooks/useSelectedFeeToken.tsx +32 -37
  249. package/src/widget/hooks/useSendForm.ts +45 -51
  250. package/src/widget/hooks/useTokenList.ts +34 -26
  251. package/src/widget/hooks/useWalletConnectionContext.tsx +128 -0
  252. package/src/widget/widget.tsx +365 -390
  253. package/dist/apiClient.d.ts +0 -9
  254. package/dist/apiClient.d.ts.map +0 -1
  255. package/dist/intentEntrypoint.d.ts +0 -114
  256. package/dist/intentEntrypoint.d.ts.map +0 -1
  257. package/dist/metaTxnMonitor.d.ts +0 -15
  258. package/dist/metaTxnMonitor.d.ts.map +0 -1
  259. package/dist/metaTxns.d.ts +0 -11
  260. package/dist/metaTxns.d.ts.map +0 -1
  261. package/dist/relayer.d.ts +0 -43
  262. package/dist/relayer.d.ts.map +0 -1
  263. package/src/apiClient.ts +0 -35
  264. package/src/intentEntrypoint.ts +0 -203
  265. package/src/metaTxnMonitor.ts +0 -171
  266. package/src/metaTxns.ts +0 -45
  267. package/src/relayer.ts +0 -289
@@ -13,6 +13,7 @@ import { truncateAddress } from "../../utils.js"
13
13
  import { formatElapsed } from "../../utils.js"
14
14
  import { ChainImage } from "./ChainImage.js"
15
15
  import { getChainInfo } from "../../chains.js"
16
+ import { useMode } from "../hooks/useMode.js"
16
17
 
17
18
  interface ReceiptProps {
18
19
  onSendAnother: () => void
@@ -86,6 +87,7 @@ export const Receipt: React.FC<ReceiptProps> = ({
86
87
  quote,
87
88
  showCloseButton,
88
89
  }) => {
90
+ const { mode } = useMode()
89
91
  const [showContent, setShowContent] = useState(false)
90
92
  const [showRefundInfo, setShowRefundInfo] = useState(false)
91
93
  const [refundMessage, setRefundMessage] = useState<string | ReactNode | null>(
@@ -111,6 +113,18 @@ export const Receipt: React.FC<ReceiptProps> = ({
111
113
  return transactionStates.some((tx) => hasMetaTxError(tx))
112
114
  }, [transactionStates, hasMetaTxError])
113
115
 
116
+ const buttonText = useMemo(() => {
117
+ if (mode === "pay") {
118
+ return "Pay Again"
119
+ } else if (mode === "fund") {
120
+ return "Fund Again"
121
+ } else if (mode === "swap") {
122
+ return "Swap Again"
123
+ } else {
124
+ return "Send Again"
125
+ }
126
+ }, [mode])
127
+
114
128
  const {
115
129
  finalExplorerUrl,
116
130
  finalChainId,
@@ -154,7 +168,7 @@ export const Receipt: React.FC<ReceiptProps> = ({
154
168
  // Extract QuoteDetails section to reuse in both success and failure states
155
169
  const quoteDetailsSection = quote && (
156
170
  <div className="mt-2">
157
- <QuoteDetails quote={quote} showContent={true}>
171
+ <QuoteDetails quote={quote} showContent={true} compact={true}>
158
172
  {transactionStates.length > 0 && (
159
173
  <>
160
174
  <div className="font-medium text-gray-700 dark:text-gray-300">
@@ -477,7 +491,7 @@ export const Receipt: React.FC<ReceiptProps> = ({
477
491
  onClick={onSendAnother}
478
492
  className="inline-flex items-center gap-1 px-4 py-2 text-sm bg-gray-100 hover:bg-gray-200 dark:bg-gray-700 dark:hover:bg-gray-600 trails-border-radius-button transition-colors duration-200 text-gray-600 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 cursor-pointer font-medium"
479
493
  >
480
- Send Again
494
+ {buttonText}
481
495
  <ChevronRight className="w-4 h-4" />
482
496
  </button>
483
497
  </div>
@@ -26,15 +26,17 @@ export const RecipientSelectorButton: React.FC = () => {
26
26
  >
27
27
  {selectedRecipient ? (
28
28
  <>
29
- <Identicon value={selectedRecipient} size={16} />
30
- <span className="text-sm font-medium">
31
- {truncateAddress(selectedRecipient, 4, 2)}
29
+ <div className="flex items-center mr-1">
30
+ <Identicon value={selectedRecipient} size={16} />
31
+ </div>
32
+ <span className="text-sm font-medium m-0">
33
+ {truncateAddress(selectedRecipient, 4, 4)}
32
34
  </span>
33
35
  </>
34
36
  ) : (
35
- <span className="text-sm font-medium">Select Recipient</span>
37
+ <span className="text-sm font-medium m-0">Select Recipient</span>
36
38
  )}
37
- <ChevronRight className="w-4 h-4" />
39
+ <ChevronRight className="w-4 h-4 m-0" />
38
40
  </button>
39
41
  )
40
42
  }
@@ -233,7 +233,7 @@ export const Recipients: React.FC<RecipientsProps> = ({
233
233
  {/* Recent Recipients */}
234
234
  {recentRecipients.length > 0 && (
235
235
  <div className="space-y-2">
236
- <div className="text-sm font-medium text-gray-700 dark:text-gray-300 text-left">
236
+ <div className="text-sm font-medium text-gray-900 dark:text-gray-100 text-left">
237
237
  Recent wallets
238
238
  </div>
239
239
  <div className="trails-border-radius-container border trails-border-primary">
@@ -1,8 +1,10 @@
1
- import { ChevronLeft } from "lucide-react"
1
+ import { ChevronLeft, X } from "lucide-react"
2
2
  import type React from "react"
3
- import { useAccount } from "wagmi"
3
+ import { useConnections } from "wagmi"
4
4
  import AccountActionsDropdown from "./AccountActionsDropdown.js"
5
+ import AccountIntentTransactionHistoryButton from "./AccountIntentTransactionHistoryButton.js"
5
6
  import { useWidgetProps } from "../hooks/useWidgetProps.js"
7
+ import { useModal } from "../widget.js"
6
8
 
7
9
  interface ScreenHeaderProps {
8
10
  onBack?: () => void
@@ -20,45 +22,67 @@ export const ScreenHeader: React.FC<ScreenHeaderProps> = ({
20
22
  headerContentAlign = "left",
21
23
  showAccountActions = false,
22
24
  }) => {
23
- const { isConnected } = useAccount()
25
+ const connections = useConnections()
24
26
  const { renderInline } = useWidgetProps()
27
+ const { closeModal, isModalOpen } = useModal()
28
+
29
+ // Check if there are any connected accounts across all connectors
30
+ const isConnected = connections.length > 0
31
+
32
+ // Show close button when in modal mode (not renderInline) and modal is open
33
+ const showCloseButton = !renderInline && isModalOpen
25
34
  return (
26
- <div className="relative w-full mb-4">
27
- {/* Left side - Back button (absolute positioned) */}
28
- {onBack && (
29
- <button
30
- type="button"
31
- onClick={onBack}
32
- className="absolute -left-2 top-1/2 -translate-y-1/2 -translate-x-0 w-6 h-6 flex-shrink-0 rounded-full transition-colors cursor-pointer text-gray-400 z-10 flex items-center justify-center hover:bg-gray-100 dark:hover:bg-gray-800"
35
+ <div className="flex items-center justify-between w-full mb-4">
36
+ {/* Left side - Back button */}
37
+ <div className="flex items-center">
38
+ {onBack && (
39
+ <button
40
+ type="button"
41
+ onClick={onBack}
42
+ className="flex h-8 w-8 justify-center items-center rounded-full bg-gray-50 dark:bg-gray-700 cursor-pointer transition-colors text-gray-900 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-600 mr-2"
43
+ title="Back"
44
+ >
45
+ <ChevronLeft className="h-4 w-4" />
46
+ </button>
47
+ )}
48
+
49
+ {/* Header content */}
50
+ <h2
51
+ className={`text-lg font-semibold ${
52
+ headerContentAlign === "center" ? "text-center" : "text-left"
53
+ } text-gray-900 dark:text-white`}
33
54
  >
34
- <ChevronLeft className="h-4 w-4" />
35
- </button>
36
- )}
55
+ {headerContent}
56
+ </h2>
57
+ </div>
37
58
 
38
- {/* Center - Header content */}
39
- <h2
40
- className={`text-lg font-semibold ${
41
- headerContentAlign === "left"
42
- ? onBack
43
- ? "text-left ml-8" // Add margin when back button exists to prevent overlap
44
- : "text-left" // No margin when no back button
45
- : "text-center" // Perfect center when center-aligned
46
- } ${"text-gray-900 dark:text-white"}`}
47
- >
48
- {headerContent}
49
- </h2>
59
+ {/* Right side - Content, Account Actions, and Close button */}
60
+ <div className="flex items-center gap-2">
61
+ {/* Right side content and Account Actions */}
62
+ {rightSideContent && (
63
+ <div className="text-right max-w-[280px]">{rightSideContent}</div>
64
+ )}
65
+ {isConnected && showAccountActions && (
66
+ <>
67
+ <div className="m-0">
68
+ <AccountIntentTransactionHistoryButton />
69
+ </div>
70
+ <AccountActionsDropdown />
71
+ </>
72
+ )}
50
73
 
51
- {/* Right side - Optional content and Account Actions */}
52
- {(rightSideContent || (isConnected && showAccountActions)) && (
53
- <div
54
- className={`absolute ${renderInline ? "right-0" : "right-8"} top-1/2 -translate-y-1/2 -translate-x-0 flex items-center gap-2 z-10`}
55
- >
56
- {rightSideContent && (
57
- <div className="text-right max-w-[280px]">{rightSideContent}</div>
58
- )}
59
- {isConnected && showAccountActions && <AccountActionsDropdown />}
60
- </div>
61
- )}
74
+ {/* Close button (always rightmost) */}
75
+ {showCloseButton && (
76
+ <button
77
+ type="button"
78
+ onClick={closeModal}
79
+ className="flex h-8 w-8 justify-center items-center rounded-full bg-gray-50 dark:bg-gray-700 cursor-pointer transition-colors text-gray-900 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-600"
80
+ title="Close"
81
+ >
82
+ <X className="h-4 w-4" />
83
+ </button>
84
+ )}
85
+ </div>
62
86
  </div>
63
87
  )
64
88
  }
@@ -13,18 +13,17 @@ interface SwapProps {
13
13
  onBack?: () => void
14
14
  onConfirm: () => void
15
15
  onComplete: (result: OnCompleteProps) => void
16
- account: Account
16
+ account?: Account
17
17
  toRecipient?: string
18
18
  toAmount?: string
19
19
  toChainId?: number
20
20
  toToken?: string
21
21
  toCalldata?: string
22
- walletClient: WalletClient
22
+ walletClient?: WalletClient
23
23
  onTransactionStateChange: (transactionStates: TransactionState[]) => void
24
24
  onError: (error: Error | string | null) => void
25
25
  onWaitingForWalletConfirm: (props: PrepareSendQuote) => void
26
26
  paymasterUrls?: Array<{ chainId: number; url: string }>
27
- gasless?: boolean
28
27
  setWalletConfirmRetryHandler: (handler: () => Promise<void>) => void
29
28
  quoteProvider?: string
30
29
  fundMethod?: string
@@ -3,6 +3,7 @@ import { createContext, useContext, useEffect, useState } from "react"
3
3
  import type { Theme } from "../../theme.js"
4
4
  import { ThemeProvider as DesignSystemThemeProvider } from "@0xsequence/design-system"
5
5
  import { logger } from "../../logger.js"
6
+ import { DEFAULT_THEME } from "../../constants.js"
6
7
 
7
8
  interface ThemeContextType {
8
9
  theme: Theme
@@ -31,7 +32,7 @@ const getIsDark = (theme: Theme): boolean => {
31
32
 
32
33
  export const ThemeProvider: React.FC<ThemeProviderProps> = ({
33
34
  children,
34
- initialTheme = "auto",
35
+ initialTheme = DEFAULT_THEME,
35
36
  }) => {
36
37
  const [theme, setTheme] = useState<Theme>(initialTheme)
37
38
  const [isDark, setIsDark] = useState(getIsDark(initialTheme))
@@ -0,0 +1,40 @@
1
+ import type React from "react"
2
+ import { TokenImage } from "./TokenImage.js"
3
+
4
+ interface TokenDisplayNonSelectableProps {
5
+ symbol: string
6
+ imageUrl?: string
7
+ chainId: number
8
+ contractAddress: string
9
+ chainName?: string
10
+ }
11
+
12
+ export const TokenDisplayNonSelectable: React.FC<
13
+ TokenDisplayNonSelectableProps
14
+ > = ({ symbol, imageUrl, chainId, contractAddress, chainName }) => {
15
+ return (
16
+ <div className="relative max-w-[120px]">
17
+ <div className="flex items-center space-x-1.5 trails-bg-card trails-border-radius-input px-2.5 py-1.5 border trails-border-primary">
18
+ <div className="flex items-center flex-shrink-0">
19
+ <TokenImage
20
+ symbol={symbol}
21
+ imageUrl={imageUrl}
22
+ chainId={chainId}
23
+ contractAddress={contractAddress}
24
+ size={28}
25
+ />
26
+ </div>
27
+ <div className="flex flex-col items-start min-w-0 overflow-hidden">
28
+ <span className="font-bold trails-text-primary text-sm leading-tight truncate max-w-full text-left">
29
+ {symbol}
30
+ </span>
31
+ {chainName && (
32
+ <span className="text-xs trails-text-muted leading-tight truncate max-w-full text-left">
33
+ {chainName}
34
+ </span>
35
+ )}
36
+ </div>
37
+ </div>
38
+ </div>
39
+ )
40
+ }
@@ -64,7 +64,7 @@ export const TokenImage: React.FC<TokenImageProps> = ({
64
64
 
65
65
  return (
66
66
  <div
67
- className={`rounded-full flex items-center justify-center text-sm relative ${
67
+ className={`rounded-full flex items-center justify-center text-sm relative m-0 ${
68
68
  symbol !== "ETH" ? "bg-gray-400 dark:bg-gray-900" : ""
69
69
  }`}
70
70
  style={{
@@ -2,6 +2,7 @@ import { ChevronLeft, Copy } from "lucide-react"
2
2
  import type React from "react"
3
3
  import { useState, useMemo } from "react"
4
4
  import { AnimatePresence, motion } from "framer-motion"
5
+ import { zeroAddress } from "viem"
5
6
  import type { Token, TokenFormatted } from "../hooks/useTokenList.js"
6
7
  import { useTokenList } from "../hooks/useTokenList.js"
7
8
  import { useChainFilter } from "../hooks/useChainFilter.js"
@@ -14,6 +15,7 @@ import { ChainFilterDropdown } from "./ChainFilterDropdown.js"
14
15
  import { SearchInputField } from "./SearchInputField.js"
15
16
  import { truncateAddress } from "../../utils.js"
16
17
  import { logger } from "../../logger.js"
18
+ import { useAccount } from "wagmi"
17
19
 
18
20
  interface TokenSelectorProps {
19
21
  onTokenSelect: (selectedToken: Token) => void
@@ -55,6 +57,7 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
55
57
  }) => {
56
58
  const [copiedAddress, setCopiedAddress] = useState<string | null>(null)
57
59
  const { isBalanceVisible } = useBalanceVisible()
60
+ const { address } = useAccount()
58
61
 
59
62
  const {
60
63
  searchQuery,
@@ -224,7 +227,9 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
224
227
  ? "No tokens found matching your search."
225
228
  : fundMethod === "qr-code" || fundMethod === "exchange"
226
229
  ? ""
227
- : "No available tokens found"}
230
+ : address
231
+ ? "No available tokens found"
232
+ : ""}
228
233
  </p>
229
234
  </div>
230
235
  )}
@@ -330,7 +335,9 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
330
335
  {/* Default state: show symbol */}
331
336
  <div
332
337
  className={`flex items-center transition-all duration-300 ease-in-out ${
333
- contractAddress
338
+ contractAddress &&
339
+ contractAddress.toLowerCase() !==
340
+ zeroAddress.toLowerCase()
334
341
  ? "group-hover:opacity-0 group-hover:transform group-hover:-translate-x-2"
335
342
  : ""
336
343
  } ${
@@ -346,58 +353,60 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
346
353
  </span>
347
354
  </div>
348
355
 
349
- {/* Hover state: show address with copy button */}
350
- {contractAddress && (
351
- <div
352
- className={`absolute top-0 left-0 flex items-center transition-all duration-300 ease-in-out opacity-0 transform translate-x-2 ${
353
- !isSufficientBalance &&
354
- fundMethod !== "qr-code" &&
355
- fundMethod !== "exchange"
356
- ? "group-hover:opacity-70"
357
- : "group-hover:opacity-100"
358
- } group-hover:translate-x-0`}
359
- >
360
- <span className="text-xs text-gray-500 dark:text-gray-400 whitespace-nowrap">
361
- {truncateAddress(contractAddress)}
362
- </span>
363
- <button
364
- type="button"
365
- onClick={(e) =>
366
- handleCopyAddress(contractAddress, e)
367
- }
368
- className={`ml-1 p-0.5 rounded transition-all duration-200 cursor-pointer ${
369
- copiedAddress === contractAddress
370
- ? "bg-green-100 dark:bg-green-900/30"
371
- : "hover:bg-gray-200 dark:hover:bg-gray-600"
372
- }`}
373
- title={
374
- copiedAddress === contractAddress
375
- ? "Copied!"
376
- : "Copy full address"
377
- }
356
+ {/* Hover state: show address with copy button (only for non-zero addresses) */}
357
+ {contractAddress &&
358
+ contractAddress.toLowerCase() !==
359
+ zeroAddress.toLowerCase() && (
360
+ <div
361
+ className={`absolute top-0 left-0 flex items-center transition-all duration-300 ease-in-out opacity-0 transform translate-x-2 ${
362
+ !isSufficientBalance &&
363
+ fundMethod !== "qr-code" &&
364
+ fundMethod !== "exchange"
365
+ ? "group-hover:opacity-70"
366
+ : "group-hover:opacity-100"
367
+ } group-hover:translate-x-0`}
378
368
  >
379
- {copiedAddress === contractAddress ? (
380
- <svg
381
- className="w-3 h-3 text-green-600 dark:text-green-400"
382
- fill="none"
383
- viewBox="0 0 24 24"
384
- stroke="currentColor"
385
- aria-label="Copied"
386
- >
387
- <title>Copied</title>
388
- <path
389
- strokeLinecap="round"
390
- strokeLinejoin="round"
391
- strokeWidth={2}
392
- d="M5 13l4 4L19 7"
393
- />
394
- </svg>
395
- ) : (
396
- <Copy className="w-3 h-3 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300" />
397
- )}
398
- </button>
399
- </div>
400
- )}
369
+ <span className="text-xs text-gray-500 dark:text-gray-400 whitespace-nowrap">
370
+ {truncateAddress(contractAddress)}
371
+ </span>
372
+ <button
373
+ type="button"
374
+ onClick={(e) =>
375
+ handleCopyAddress(contractAddress, e)
376
+ }
377
+ className={`ml-1 p-0.5 rounded transition-all duration-200 cursor-pointer ${
378
+ copiedAddress === contractAddress
379
+ ? "bg-green-100 dark:bg-green-900/30"
380
+ : "hover:bg-gray-200 dark:hover:bg-gray-600"
381
+ }`}
382
+ title={
383
+ copiedAddress === contractAddress
384
+ ? "Copied!"
385
+ : "Copy full address"
386
+ }
387
+ >
388
+ {copiedAddress === contractAddress ? (
389
+ <svg
390
+ className="w-3 h-3 text-green-600 dark:text-green-400"
391
+ fill="none"
392
+ viewBox="0 0 24 24"
393
+ stroke="currentColor"
394
+ aria-label="Copied"
395
+ >
396
+ <title>Copied</title>
397
+ <path
398
+ strokeLinecap="round"
399
+ strokeLinejoin="round"
400
+ strokeWidth={2}
401
+ d="M5 13l4 4L19 7"
402
+ />
403
+ </svg>
404
+ ) : (
405
+ <Copy className="w-3 h-3 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300" />
406
+ )}
407
+ </button>
408
+ </div>
409
+ )}
401
410
  </div>
402
411
  </div>
403
412
 
@@ -1,8 +1,11 @@
1
1
  import { ChevronRight } from "lucide-react"
2
2
  import type React from "react"
3
3
  import { useMemo } from "react"
4
+ import { useConnections } from "wagmi"
4
5
  import { TokenImage } from "./TokenImage.js"
5
6
  import { getChainInfo } from "../../chains.js"
7
+ import { useCurrentScreen } from "../hooks/useCurrentScreen.js"
8
+ import { useSelectedFundMethod } from "../hooks/useSelectedFundMethod.js"
6
9
 
7
10
  interface TokenSelectorButtonProps {
8
11
  token?: {
@@ -21,47 +24,67 @@ export const TokenSelectorButton: React.FC<TokenSelectorButtonProps> = ({
21
24
  token,
22
25
  chainId,
23
26
  onSelect,
24
- className = "flex items-center space-x-2 trails-border-radius-input px-2.5 py-1.5 border transition-colors",
27
+ className = "flex items-center space-x-1.5 trails-border-radius-input px-2.5 py-1.5 border transition-all duration-200",
25
28
  unselectable = false,
26
29
  }) => {
30
+ const connections = useConnections()
31
+ const { setCurrentScreen } = useCurrentScreen()
32
+ const { selectedFundMethod } = useSelectedFundMethod()
27
33
  const displayChainId = token?.chainId || chainId
28
34
 
35
+ // Check if there are any connected accounts across all connectors
36
+ const isConnected = connections.length > 0
37
+
29
38
  const chainInfo = useMemo(() => {
30
39
  return displayChainId ? getChainInfo(displayChainId) : null
31
40
  }, [displayChainId])
32
41
 
42
+ const handleClick = () => {
43
+ if (unselectable) return
44
+
45
+ // If no wallet connected and fund method is "wallet", redirect to connect screen
46
+ if (!isConnected && selectedFundMethod === "wallet") {
47
+ setCurrentScreen("connect")
48
+ return
49
+ }
50
+
51
+ onSelect()
52
+ }
53
+
33
54
  return (
34
55
  <button
35
56
  type="button"
36
- onClick={unselectable ? undefined : onSelect}
57
+ onClick={handleClick}
37
58
  disabled={unselectable}
38
- className={`${className} ${
59
+ className={`${className} ${token ? "max-w-[120px]" : ""} ${
39
60
  token
40
- ? "trails-bg-card hover:trails-hover-bg trails-border-primary"
61
+ ? "bg-white dark:bg-gray-900 border-gray-200 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-800 hover:border-gray-300 dark:hover:border-gray-600"
41
62
  : "bg-blue-500 hover:bg-blue-600 border-blue-500 text-white"
42
63
  } ${unselectable ? "cursor-default" : "cursor-pointer"}`}
43
64
  >
44
65
  {token ? (
45
66
  <>
46
- <TokenImage
47
- symbol={token.symbol}
48
- imageUrl={token.imageUrl}
49
- chainId={displayChainId}
50
- contractAddress={token.contractAddress}
51
- size={28}
52
- />
53
- <div className="flex flex-col items-start">
54
- <span className="font-bold trails-text-primary text-sm">
67
+ <div className="flex items-center flex-shrink-0">
68
+ <TokenImage
69
+ symbol={token.symbol}
70
+ imageUrl={token.imageUrl}
71
+ chainId={displayChainId}
72
+ contractAddress={token.contractAddress}
73
+ size={28}
74
+ />
75
+ </div>
76
+ <div className="flex flex-col items-start min-w-0 overflow-hidden">
77
+ <span className="font-bold trails-text-primary text-sm leading-tight truncate max-w-full text-left">
55
78
  {token.symbol}
56
79
  </span>
57
80
  {chainInfo && (
58
- <span className="text-xs trails-text-muted">
81
+ <span className="text-xs trails-text-muted leading-tight truncate max-w-full text-left">
59
82
  {chainInfo.name}
60
83
  </span>
61
84
  )}
62
85
  </div>
63
86
  {!unselectable && (
64
- <ChevronRight className="w-3.5 h-3.5 trails-text-muted" />
87
+ <ChevronRight className="w-3.5 h-3.5 trails-text-muted flex-shrink-0" />
65
88
  )}
66
89
  </>
67
90
  ) : (
@@ -0,0 +1,51 @@
1
+ import type React from "react"
2
+ import { TooltipPrimitive } from "@0xsequence/design-system"
3
+ import { useTheme } from "./ThemeProvider.js"
4
+
5
+ interface TooltipProps {
6
+ message: string
7
+ children: React.ReactNode
8
+ className?: string
9
+ }
10
+
11
+ export const Tooltip: React.FC<TooltipProps> = ({
12
+ message,
13
+ children,
14
+ className = "",
15
+ }) => {
16
+ const { isDark } = useTheme()
17
+
18
+ return (
19
+ <TooltipPrimitive.Provider>
20
+ <TooltipPrimitive.Root delayDuration={0}>
21
+ <TooltipPrimitive.Trigger asChild>
22
+ <div className={className}>{children}</div>
23
+ </TooltipPrimitive.Trigger>
24
+ <TooltipPrimitive.Portal>
25
+ <TooltipPrimitive.Content
26
+ className="trails-border-radius-container px-3 py-2 text-xs font-medium shadow-lg z-50 animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2"
27
+ style={{
28
+ maxWidth: "400px",
29
+ wordWrap: "break-word",
30
+ whiteSpace: "normal",
31
+ overflowWrap: "break-word",
32
+ backgroundColor: isDark ? "#111827" : "#ffffff", // gray-900 or white
33
+ color: isDark ? "#ffffff" : "#000000", // white or black
34
+ }}
35
+ side="top"
36
+ align="center"
37
+ sideOffset={4}
38
+ alignOffset={0}
39
+ >
40
+ {message}
41
+ <TooltipPrimitive.Arrow
42
+ style={{ fill: isDark ? "#111827" : "#ffffff" }} // gray-900 or white
43
+ />
44
+ </TooltipPrimitive.Content>
45
+ </TooltipPrimitive.Portal>
46
+ </TooltipPrimitive.Root>
47
+ </TooltipPrimitive.Provider>
48
+ )
49
+ }
50
+
51
+ export default Tooltip
@@ -477,15 +477,19 @@ export const TransferPending: React.FC<TransferPendingProps> = ({
477
477
  )}
478
478
 
479
479
  {/* Details Section */}
480
- <div
481
- className={`w-full max-w-sm transition-all duration-500 ease-out delay-200 ${
482
- showContent ? "opacity-100 translate-y-0" : "opacity-0 translate-y-4"
483
- }`}
484
- >
485
- <div className="mt-4">
486
- <QuoteDetails quote={quote} showContent={true} />
480
+ {quote && (
481
+ <div
482
+ className={`w-full max-w-sm transition-all duration-500 ease-out delay-200 ${
483
+ showContent
484
+ ? "opacity-100 translate-y-0"
485
+ : "opacity-0 translate-y-4"
486
+ }`}
487
+ >
488
+ <div className="mt-4">
489
+ <QuoteDetails quote={quote} showContent={true} compact={true} />
490
+ </div>
487
491
  </div>
488
- </div>
492
+ )}
489
493
 
490
494
  {/* Timeout Warning */}
491
495
  {showTimeoutWarning && !showContinueButton && (