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
@@ -83,7 +83,7 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
83
83
 
84
84
  {/* More Details Button - only visible when collapsed */}
85
85
  {!isExpanded && (
86
- <div className={`flex justify-center ${swapMode ? "" : "mb-4"}`}>
86
+ <div className={`flex justify-center`}>
87
87
  {swapMode ? (
88
88
  <button
89
89
  type="button"
@@ -161,10 +161,10 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
161
161
  <button
162
162
  type="button"
163
163
  onClick={() => setIsExpanded(true)}
164
- className="w-full flex items-center justify-center gap-2 py-1 px-4 trails-border-radius-button transition-colors cursor-pointer text-xs text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300"
165
- aria-label="Show more details"
164
+ className="w-full max-w-md flex items-center justify-between gap-2 py-1 px-1 trails-border-radius-button transition-colors cursor-pointer text-xs text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300"
165
+ aria-label="Show transaction details"
166
166
  >
167
- <span>More Details</span>
167
+ <span>Transaction details</span>
168
168
  <svg
169
169
  className="w-3 h-3 transition-transform duration-300 ease-out"
170
170
  fill="none"
@@ -191,9 +191,13 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
191
191
  isExpanded ? "max-h-[250px] opacity-100" : "max-h-0 opacity-0"
192
192
  }`}
193
193
  >
194
- <div className="p-4 rounded-lg text-sm space-y-4 trails-bg-secondary">
194
+ <div
195
+ className={`text-sm ${swapMode ? "p-2 space-y-2" : "p-4 rounded-lg space-y-4 trails-bg-secondary"}`}
196
+ >
195
197
  {/* Close Button - only visible when expanded, at top center */}
196
- <div className="flex justify-center mb-4 -mt-2">
198
+ <div
199
+ className={`flex justify-center ${swapMode ? "mb-2 -mt-1" : "mb-4 -mt-2"}`}
200
+ >
197
201
  {swapMode ? (
198
202
  <button
199
203
  type="button"
@@ -367,6 +371,7 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
367
371
  imageUrl={quote.originToken.imageUrl}
368
372
  symbol={quote.originToken.symbol}
369
373
  chainId={quote.originChain.id}
374
+ contractAddress={quote.originToken.contractAddress}
370
375
  size={16}
371
376
  />
372
377
  {quote.originAmountDisplay} {quote.originToken.symbol}
@@ -393,6 +398,9 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
393
398
  imageUrl={quote.originToken.imageUrl}
394
399
  symbol={quote.originToken.symbol}
395
400
  chainId={quote.originChain.id}
401
+ contractAddress={
402
+ quote.originToken.contractAddress
403
+ }
396
404
  size={16}
397
405
  />
398
406
  {quote.originAmountDisplay}{" "}
@@ -430,6 +438,9 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
430
438
  imageUrl={quote.destinationToken.imageUrl}
431
439
  symbol={quote.destinationToken.symbol}
432
440
  chainId={quote.destinationChain.id}
441
+ contractAddress={
442
+ quote.destinationToken.contractAddress
443
+ }
433
444
  size={16}
434
445
  />
435
446
  {quote.destinationAmountDisplay}{" "}
@@ -457,6 +468,9 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
457
468
  imageUrl={quote.destinationToken.imageUrl}
458
469
  symbol={quote.destinationToken.symbol}
459
470
  chainId={quote.destinationChain.id}
471
+ contractAddress={
472
+ quote.destinationToken.contractAddress
473
+ }
460
474
  size={16}
461
475
  />
462
476
  {quote.destinationAmountDisplay}{" "}
@@ -665,7 +679,7 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
665
679
  </div>
666
680
  )}
667
681
 
668
- {quote?.quoteProvider && (
682
+ {quote?.quoteProvider?.name && (
669
683
  <div className="flex justify-between items-center">
670
684
  <span className="text-xs text-gray-600 dark:text-gray-400 flex items-center gap-1">
671
685
  {quote.originChain.id === quote.destinationChain.id
@@ -766,7 +780,7 @@ export const QuoteDetails: React.FC<QuoteDetailsProps> = ({
766
780
  )}
767
781
 
768
782
  {/* Children content */}
769
- {children && <div className="space-y-2">{children}</div>}
783
+ {children && <div className="mb-0">{children}</div>}
770
784
  </div>
771
785
  </div>
772
786
  </div>
@@ -60,7 +60,6 @@ export const Receive: React.FC<ReceiveProps> = ({
60
60
  onBack={onBack}
61
61
  headerContent="Receive"
62
62
  headerContentAlign="left"
63
- showAccountActions={true}
64
63
  />
65
64
 
66
65
  <div className="flex flex-col justify-center min-h-full space-y-6 pt-8">
@@ -97,14 +96,13 @@ export const Receive: React.FC<ReceiveProps> = ({
97
96
  onBack={onBack}
98
97
  headerContent={`Pay ${ensName ? ensName : truncateAddress(resolvedAddress)}`}
99
98
  headerContentAlign="left"
100
- showAccountActions={true}
101
99
  />
102
100
 
103
101
  <div className="flex flex-col justify-center min-h-full space-y-6 pt-2">
104
102
  {/* QR Code Section */}
105
103
  <div className="space-y-3 p-4 bg-gray-50 dark:bg-gray-800 rounded-lg">
106
104
  <div className="flex justify-center">
107
- <div className="flex flex-col items-center">
105
+ <div className="flex flex-col items-center" title={qrCodeUrl}>
108
106
  <QrCode url={qrCodeUrl} size={300} />
109
107
  </div>
110
108
  </div>
@@ -0,0 +1,42 @@
1
+ import { ChevronRight } from "lucide-react"
2
+ import type React from "react"
3
+ import { truncateAddress } from "../../utils.js"
4
+ import { Identicon } from "./Identicon.js"
5
+ import { useBack } from "../hooks/useBack.js"
6
+ import { useSelectedRecipient } from "../hooks/useSelectedRecipient.js"
7
+
8
+ export const RecipientSelectorButton: React.FC = () => {
9
+ const { setCurrentScreenWithBack } = useBack()
10
+ const { selectedRecipient } = useSelectedRecipient()
11
+
12
+ const handleClick = () => {
13
+ setCurrentScreenWithBack("recipients")
14
+ }
15
+
16
+ return (
17
+ <button
18
+ type="button"
19
+ onClick={handleClick}
20
+ className="flex items-center space-x-2 text-blue-500 hover:text-blue-600 transition-colors cursor-pointer bg-transparent border-none p-0"
21
+ title={
22
+ selectedRecipient
23
+ ? `Selected: ${selectedRecipient}`
24
+ : "Select recipient"
25
+ }
26
+ >
27
+ {selectedRecipient ? (
28
+ <>
29
+ <Identicon value={selectedRecipient} size={16} />
30
+ <span className="text-sm font-medium">
31
+ {truncateAddress(selectedRecipient, 4, 2)}
32
+ </span>
33
+ </>
34
+ ) : (
35
+ <span className="text-sm font-medium">Select Recipient</span>
36
+ )}
37
+ <ChevronRight className="w-4 h-4" />
38
+ </button>
39
+ )
40
+ }
41
+
42
+ export default RecipientSelectorButton
@@ -1,7 +1,7 @@
1
1
  import { useEffect, useState, useCallback } from "react"
2
2
  import type React from "react"
3
3
  import { isAddress } from "viem"
4
- import { Copy, RotateCcw } from "lucide-react"
4
+ import { Copy, RotateCcw, ChevronRight } from "lucide-react"
5
5
  import { useAccount, useConnections } from "wagmi"
6
6
  import { ScreenHeader } from "./ScreenHeader.js"
7
7
  import { SearchInputField } from "./SearchInputField.js"
@@ -12,8 +12,8 @@ import { useRecipients, type RecentRecipient } from "../hooks/useRecipients.js"
12
12
  import { useResolveEnsAddress, useResolveEnsName } from "../../ens.js"
13
13
  import { truncateAddress } from "../../utils.js"
14
14
  import { logger } from "../../logger.js"
15
- import { useMode } from "../hooks/useMode.js"
16
15
  import { useWallets, wagmiConnectorToWalletId } from "../../wallets.js"
16
+ import { ConnectedWallets } from "./ConnectedWallets.js"
17
17
 
18
18
  interface RecipientsProps {
19
19
  onBack?: () => void
@@ -26,7 +26,6 @@ export const Recipients: React.FC<RecipientsProps> = ({
26
26
  selectedRecipient = "",
27
27
  onRecipientSelect,
28
28
  }) => {
29
- const { mode } = useMode()
30
29
  const { setCurrentScreen } = useCurrentScreen()
31
30
  const { setSelectedRecipient } = useSelectedRecipient()
32
31
  const { recentRecipients, addRecentRecipient, clearRecentRecipients } =
@@ -136,9 +135,9 @@ export const Recipients: React.FC<RecipientsProps> = ({
136
135
  logger.console.log("[trails-sdk] Selected recent recipient:", recipient)
137
136
  setSelectedRecipient(recipient.address)
138
137
  onRecipientSelect?.(recipient.address)
139
- setCurrentScreen(mode === "pay" ? "send-form" : "fund-form")
138
+ setCurrentScreen("home")
140
139
  },
141
- [setSelectedRecipient, onRecipientSelect, setCurrentScreen, mode],
140
+ [setSelectedRecipient, onRecipientSelect, setCurrentScreen],
142
141
  )
143
142
 
144
143
  // Handle connected wallet selection
@@ -150,9 +149,9 @@ export const Recipients: React.FC<RecipientsProps> = ({
150
149
  )
151
150
  setSelectedRecipient(walletAddress)
152
151
  onRecipientSelect?.(walletAddress)
153
- setCurrentScreen(mode === "pay" ? "send-form" : "fund-form")
152
+ setCurrentScreen("home")
154
153
  },
155
- [setSelectedRecipient, onRecipientSelect, setCurrentScreen, mode],
154
+ [setSelectedRecipient, onRecipientSelect, setCurrentScreen],
156
155
  )
157
156
 
158
157
  // Handle copy to clipboard with success indication
@@ -202,7 +201,6 @@ export const Recipients: React.FC<RecipientsProps> = ({
202
201
  onBack={onBack}
203
202
  headerContent="Recipient address"
204
203
  headerContentAlign="left"
205
- showAccountActions={true}
206
204
  />
207
205
 
208
206
  <div className="space-y-4">
@@ -223,69 +221,77 @@ export const Recipients: React.FC<RecipientsProps> = ({
223
221
  )}
224
222
  </div>
225
223
 
224
+ {/* Connected Wallets - only show when no input */}
225
+ {connectedWallets.length > 0 && !recipientInput.trim() && (
226
+ <ConnectedWallets
227
+ showConnectNewWallet={true}
228
+ onWalletSelect={handleConnectedWalletSelect}
229
+ backScreen="recipients"
230
+ />
231
+ )}
232
+
226
233
  {/* Recent Recipients */}
227
234
  {recentRecipients.length > 0 && (
228
235
  <div className="space-y-2">
229
236
  <div className="text-sm font-medium text-gray-700 dark:text-gray-300 text-left">
230
- Recents
237
+ Recent wallets
231
238
  </div>
232
- <div className="space-y-1 max-h-48 overflow-y-auto trails-scrollbar">
233
- {recentRecipients.map((recipient) => {
239
+ <div className="trails-border-radius-container border trails-border-primary">
240
+ {recentRecipients.map((recipient, index) => {
234
241
  // Only highlight if search field contains a valid address that matches this recipient
235
242
  const searchQuery = recipientInput.trim()
236
243
  const isHighlighted =
237
244
  searchQuery &&
238
245
  isAddress(searchQuery) &&
239
- recipient.address.toLowerCase() === searchQuery.toLowerCase()
246
+ recipient.address.toLowerCase() ===
247
+ searchQuery.trim().toLowerCase()
240
248
 
241
249
  return (
242
- <button
243
- key={recipient.address}
244
- type="button"
245
- className={`w-full py-2 px-4 flex items-center space-x-3 transition-all duration-200 trails-border-radius-list-button cursor-pointer group ${
246
- isHighlighted
247
- ? "trails-list-item-selected border border-blue-200 dark:border-blue-800"
248
- : "trails-list-item"
249
- }`}
250
- onClick={() => handleRecentRecipientSelect(recipient)}
251
- onKeyDown={(e) => {
252
- if (e.key === "Enter" || e.key === " ") {
253
- e.preventDefault()
254
- handleRecentRecipientSelect(recipient)
255
- }
256
- }}
257
- aria-label={`Select recipient ${recipient.ensName || recipient.address}`}
258
- >
259
- {/* Identicon */}
260
- <div className="relative flex-shrink-0 mr-2">
261
- <Identicon
262
- value={recipient.address}
263
- size={32}
264
- className="flex-shrink-0"
265
- />
266
- </div>
267
-
268
- <div className="flex-1 min-w-0 text-left">
269
- <div className="flex items-start">
270
- <div className="flex-1">
271
- <div className="flex items-center">
272
- <span className="text-sm font-medium text-gray-900 dark:text-white">
250
+ <div key={recipient.address}>
251
+ <button
252
+ type="button"
253
+ className={`w-full text-left px-3 py-4 text-sm flex items-center justify-between cursor-pointer transition-colors ${
254
+ isHighlighted
255
+ ? "trails-list-item-selected border border-blue-200 dark:border-blue-800"
256
+ : "trails-text-primary trails-hover-bg"
257
+ }`}
258
+ onClick={() => handleRecentRecipientSelect(recipient)}
259
+ onKeyDown={(e) => {
260
+ if (e.key === "Enter" || e.key === " ") {
261
+ e.preventDefault()
262
+ handleRecentRecipientSelect(recipient)
263
+ }
264
+ }}
265
+ aria-label={`Select recipient ${recipient.ensName || recipient.address}`}
266
+ >
267
+ <div className="flex items-center gap-3">
268
+ <Identicon
269
+ value={recipient.address}
270
+ size={32}
271
+ className="flex-shrink-0"
272
+ />
273
+ <div className="text-left">
274
+ <div className="flex items-center space-x-1">
275
+ <span className="text-sm font-bold">
273
276
  {truncateAddress(recipient.address, 8, 4)}
274
277
  </span>
275
- <button
276
- type="button"
277
- onClick={(e) =>
278
+ <div
279
+ onClick={(e) => {
280
+ e.preventDefault()
281
+ e.stopPropagation()
278
282
  handleCopyAddress(recipient.address, e)
279
- }
280
- className={`ml-1 p-0.5 rounded opacity-0 group-hover:opacity-100 transition-all duration-200 cursor-pointer ${
283
+ }}
284
+ onMouseDown={(e) => e.stopPropagation()}
285
+ onMouseUp={(e) => e.stopPropagation()}
286
+ className={`p-0.5 rounded transition-all duration-200 cursor-pointer z-10 relative ${
281
287
  copiedAddress === recipient.address
282
- ? "bg-green-100 dark:bg-green-900/30 opacity-100"
288
+ ? "bg-green-100 dark:bg-green-900/30"
283
289
  : "hover:bg-gray-200 dark:hover:bg-gray-600"
284
290
  }`}
285
291
  title={
286
292
  copiedAddress === recipient.address
287
293
  ? "Copied!"
288
- : "Copy address"
294
+ : "Copy full address"
289
295
  }
290
296
  >
291
297
  {copiedAddress === recipient.address ? (
@@ -307,7 +313,7 @@ export const Recipients: React.FC<RecipientsProps> = ({
307
313
  ) : (
308
314
  <Copy className="w-3 h-3 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300" />
309
315
  )}
310
- </button>
316
+ </div>
311
317
  </div>
312
318
  {recipient.ensName && (
313
319
  <div className="text-xs text-gray-500 dark:text-gray-400">
@@ -316,111 +322,13 @@ export const Recipients: React.FC<RecipientsProps> = ({
316
322
  )}
317
323
  </div>
318
324
  </div>
319
- </div>
320
- </button>
321
- )
322
- })}
323
- </div>
324
- </div>
325
- )}
326
-
327
- {/* Connected Wallets - only show when no input */}
328
- {connectedWallets.length > 0 && !recipientInput.trim() && (
329
- <div className="space-y-2">
330
- <div className="flex items-center gap-2">
331
- <div className="text-sm font-medium text-gray-700 dark:text-gray-300 text-left">
332
- Connected Wallets
333
- </div>
334
- </div>
335
- <div className="space-y-1 max-h-48 overflow-y-auto trails-scrollbar">
336
- {connectedWallets.map((wallet) => {
337
- // Only highlight if search field contains a valid address that matches this wallet
338
- const searchQuery = recipientInput.trim()
339
- const isHighlighted =
340
- searchQuery &&
341
- isAddress(searchQuery) &&
342
- wallet.address.toLowerCase() === searchQuery.toLowerCase()
343
-
344
- return (
345
- <button
346
- key={wallet.address}
347
- type="button"
348
- className={`w-full py-2 px-4 flex items-center space-x-3 transition-all duration-200 trails-border-radius-list-button cursor-pointer group ${
349
- isHighlighted
350
- ? "trails-list-item-selected border border-blue-200 dark:border-blue-800"
351
- : "trails-list-item"
352
- }`}
353
- onClick={() => handleConnectedWalletSelect(wallet.address)}
354
- onKeyDown={(e) => {
355
- if (e.key === "Enter" || e.key === " ") {
356
- e.preventDefault()
357
- handleConnectedWalletSelect(wallet.address)
358
- }
359
- }}
360
- aria-label={`Select wallet ${wallet.walletConfig?.name || "Wallet"} - ${wallet.address}`}
361
- >
362
- {/* Identicon */}
363
- <div className="relative flex-shrink-0 mr-2">
364
- <Identicon
365
- value={wallet.address}
366
- size={32}
367
- className="flex-shrink-0"
368
- />
369
- </div>
370
-
371
- <div className="flex-1 min-w-0 text-left">
372
- <div className="flex items-start">
373
- <div className="flex-1">
374
- <div className="flex items-center">
375
- <span className="text-sm font-medium text-gray-900 dark:text-white">
376
- {truncateAddress(wallet.address, 8, 4)}
377
- </span>
378
- <button
379
- type="button"
380
- onClick={(e) =>
381
- handleCopyAddress(wallet.address, e)
382
- }
383
- className={`ml-1 p-0.5 rounded opacity-0 group-hover:opacity-100 transition-all duration-200 cursor-pointer ${
384
- copiedAddress === wallet.address
385
- ? "bg-green-100 dark:bg-green-900/30 opacity-100"
386
- : "hover:bg-gray-200 dark:hover:bg-gray-600"
387
- }`}
388
- title={
389
- copiedAddress === wallet.address
390
- ? "Copied!"
391
- : "Copy address"
392
- }
393
- >
394
- {copiedAddress === wallet.address ? (
395
- <svg
396
- className="w-3 h-3 text-green-600 dark:text-green-400"
397
- fill="none"
398
- viewBox="0 0 24 24"
399
- stroke="currentColor"
400
- aria-label="Copied"
401
- >
402
- <title>Copied</title>
403
- <path
404
- strokeLinecap="round"
405
- strokeLinejoin="round"
406
- strokeWidth={2}
407
- d="M5 13l4 4L19 7"
408
- />
409
- </svg>
410
- ) : (
411
- <Copy className="w-3 h-3 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300" />
412
- )}
413
- </button>
414
- </div>
415
- <div className="text-xs text-gray-500 dark:text-gray-400">
416
- {wallet.walletConfig?.name ||
417
- wallet.connector?.name ||
418
- "Wallet"}
419
- </div>
420
- </div>
421
- </div>
422
- </div>
423
- </button>
325
+ <ChevronRight className="w-5 h-5 text-gray-400" />
326
+ </button>
327
+ {/* Add divider between items */}
328
+ {index < recentRecipients.length - 1 && (
329
+ <div className="border-b border-gray-200 dark:border-gray-700"></div>
330
+ )}
331
+ </div>
424
332
  )
425
333
  })}
426
334
  </div>
@@ -4,17 +4,21 @@ interface RefundWarningProps {
4
4
  fundMethod?: string
5
5
  isSenderContractOnOrigin?: boolean
6
6
  isSenderContractOnDestination?: boolean
7
+ isSequenceWallet?: boolean
7
8
  }
8
9
 
9
10
  export const RefundWarning: React.FC<RefundWarningProps> = ({
10
11
  fundMethod,
11
12
  isSenderContractOnOrigin,
12
13
  isSenderContractOnDestination,
14
+ isSequenceWallet = false,
13
15
  }) => {
14
16
  // Determine if we should show the warning
15
17
  const shouldShowWarning =
16
18
  fundMethod === "exchange" ||
17
- (isSenderContractOnOrigin && !isSenderContractOnDestination)
19
+ (isSenderContractOnOrigin &&
20
+ !isSenderContractOnDestination &&
21
+ !isSequenceWallet)
18
22
 
19
23
  if (!shouldShowWarning) {
20
24
  return null
@@ -0,0 +1,33 @@
1
+ import type React from "react"
2
+ import { ErrorDisplay } from "./ErrorDisplay.js"
3
+
4
+ interface RequiredPropsErrorProps {
5
+ missingProps: string[]
6
+ componentName: string
7
+ }
8
+
9
+ export const RequiredPropsError: React.FC<RequiredPropsErrorProps> = ({
10
+ missingProps,
11
+ componentName,
12
+ }) => {
13
+ if (missingProps.length === 0) {
14
+ return null
15
+ }
16
+
17
+ const isMultiple = missingProps.length > 1
18
+
19
+ const prettifiedMessage = `Missing required ${componentName} prop${isMultiple ? "s" : ""}`
20
+
21
+ const detailedMessage = `The following required props are missing for the ${componentName} component:
22
+ ${missingProps.map((prop) => `- ${prop}`).join("\n")}
23
+
24
+ Please ensure all required props are provided when rendering the ${componentName} component.`
25
+
26
+ return (
27
+ <ErrorDisplay
28
+ errorPrettified={prettifiedMessage}
29
+ error={detailedMessage}
30
+ severity="error"
31
+ />
32
+ )
33
+ }
@@ -2,6 +2,7 @@ import { ChevronLeft } from "lucide-react"
2
2
  import type React from "react"
3
3
  import { useAccount } from "wagmi"
4
4
  import AccountActionsDropdown from "./AccountActionsDropdown.js"
5
+ import { useWidgetProps } from "../hooks/useWidgetProps.js"
5
6
 
6
7
  interface ScreenHeaderProps {
7
8
  onBack?: () => void
@@ -20,6 +21,7 @@ export const ScreenHeader: React.FC<ScreenHeaderProps> = ({
20
21
  showAccountActions = false,
21
22
  }) => {
22
23
  const { isConnected } = useAccount()
24
+ const { renderInline } = useWidgetProps()
23
25
  return (
24
26
  <div className="relative w-full mb-4">
25
27
  {/* Left side - Back button (absolute positioned) */}
@@ -48,7 +50,9 @@ export const ScreenHeader: React.FC<ScreenHeaderProps> = ({
48
50
 
49
51
  {/* Right side - Optional content and Account Actions */}
50
52
  {(rightSideContent || (isConnected && showAccountActions)) && (
51
- <div className="absolute right-0 top-1/2 -translate-y-1/2 -translate-x-0 flex items-center gap-2 z-10">
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
+ >
52
56
  {rightSideContent && (
53
57
  <div className="text-right max-w-[280px]">{rightSideContent}</div>
54
58
  )}
@@ -142,7 +142,8 @@ export const SlippageToleranceSettings: React.FC<
142
142
  onBlur={handleInputBlur}
143
143
  onKeyDown={handleKeyDown}
144
144
  placeholder="5"
145
- className="w-full px-2 py-1.5 text-sm border border-solid border-gray-200 dark:border-gray-700 trails-border-radius-input focus:ring-2 focus:ring-blue-500 focus:border-blue-500 trails-input pr-6"
145
+ className="w-full px-2 py-1.5 text-sm border border-solid border-gray-200 dark:border-gray-700 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 trails-input pr-6"
146
+ style={{ borderRadius: "10px" }}
146
147
  />
147
148
  <div className="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
148
149
  <span className="text-xs text-gray-500 dark:text-gray-400">%</span>
@@ -1,15 +1,11 @@
1
1
  import type React from "react"
2
- import { useEffect } from "react"
3
2
  import type { Account, WalletClient } from "viem"
4
3
  import type { TransactionState } from "../../transactions.js"
5
4
  import type { OnCompleteProps, Token } from "../hooks/useSendForm.js"
6
5
  import type { SupportedToken } from "../../tokens.js"
7
6
  import type { CheckoutOnHandlers } from "../hooks/useCheckout.js"
8
7
  import type { PrepareSendQuote } from "../../prepareSend.js"
9
- import { SimpleSwap } from "./SimpleSwap.js"
10
8
  import { ClassicSwap } from "./ClassicSwap.js"
11
- import { useSwapSettings } from "../hooks/useSwapSettings.js"
12
- import { useWidgetProps } from "../hooks/useWidgetProps.js"
13
9
 
14
10
  interface SwapProps {
15
11
  selectedToken: Token | null
@@ -46,48 +42,11 @@ interface SwapProps {
46
42
  recentTokens?: SupportedToken[]
47
43
  onRecentTokenSelect?: (token: SupportedToken) => void
48
44
  onTrackToken?: (token: any) => void
45
+ isSequenceWallet?: boolean
49
46
  }
50
47
 
51
48
  export const Swap: React.FC<SwapProps> = (props) => {
52
- const { swapMode } = useWidgetProps()
53
- const {
54
- isSimpleSwapMode: isSimpleMode,
55
- setIsSimpleSwapMode: setIsSimpleMode,
56
- } = useSwapSettings()
57
-
58
- // Update isSimpleMode when swapMode changes
59
- useEffect(() => {
60
- if (swapMode === "simple") {
61
- setIsSimpleMode(true)
62
- }
63
- }, [swapMode, setIsSimpleMode])
64
-
65
- // Render SimpleSwap or ClassicSwap based on mode
66
- if (isSimpleMode) {
67
- return (
68
- <SimpleSwap
69
- onBack={props.onBack}
70
- account={props.account}
71
- walletClient={props.walletClient}
72
- onTransactionStateChange={props.onTransactionStateChange}
73
- onError={props.onError}
74
- onWaitingForWalletConfirm={props.onWaitingForWalletConfirm}
75
- onConfirm={props.onConfirm}
76
- onComplete={props.onComplete}
77
- onSend={props.onSend}
78
- paymasterUrls={props.paymasterUrls}
79
- gasless={props.gasless}
80
- setWalletConfirmRetryHandler={props.setWalletConfirmRetryHandler}
81
- quoteProvider={props.quoteProvider}
82
- fundMethod={props.fundMethod}
83
- checkoutOnHandlers={props.checkoutOnHandlers}
84
- showHeader={true}
85
- onTokenSelectorVisibilityChange={() => {}}
86
- />
87
- )
88
- }
89
-
90
- // Default to ClassicSwap
49
+ // Always render ClassicSwap
91
50
  return <ClassicSwap {...props} />
92
51
  }
93
52