0xtrails 0.12.2 → 0.13.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 (243) hide show
  1. package/dist/abis/trailsHydrate.d.ts.map +1 -1
  2. package/dist/analytics.d.ts +41 -0
  3. package/dist/analytics.d.ts.map +1 -1
  4. package/dist/{ccip-62W6LwH2.js → ccip-Cg9-lJ6K.js} +16 -16
  5. package/dist/chainSwitch.d.ts.map +1 -1
  6. package/dist/chains.d.ts +9 -3
  7. package/dist/chains.d.ts.map +1 -1
  8. package/dist/error.d.ts +1 -0
  9. package/dist/error.d.ts.map +1 -1
  10. package/dist/{index-C0QTNYIA.js → index-DEojZg7b.js} +50431 -50424
  11. package/dist/index.d.ts +1 -3
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +377 -421
  14. package/dist/intentReceiptPoller.d.ts.map +1 -1
  15. package/dist/intents.d.ts +1 -3
  16. package/dist/intents.d.ts.map +1 -1
  17. package/dist/mutations.d.ts +1 -4
  18. package/dist/mutations.d.ts.map +1 -1
  19. package/dist/prepareSend.d.ts.map +1 -1
  20. package/dist/query/balance.hooks.d.ts.map +1 -1
  21. package/dist/query/chains.hooks.d.ts.map +1 -1
  22. package/dist/query/chains.queries.d.ts +4 -1
  23. package/dist/query/chains.queries.d.ts.map +1 -1
  24. package/dist/queryParams.d.ts.map +1 -1
  25. package/dist/recover.d.ts.map +1 -1
  26. package/dist/tokens.d.ts.map +1 -1
  27. package/dist/transactionIntent/deposits/depositOrchestrator.d.ts.map +1 -1
  28. package/dist/transactionIntent/deposits/gaslessDeposit.d.ts.map +1 -1
  29. package/dist/transactionIntent/deposits/standardDeposit.d.ts +1 -7
  30. package/dist/transactionIntent/deposits/standardDeposit.d.ts.map +1 -1
  31. package/dist/transactionIntent/handlers/intentHandler.d.ts.map +1 -1
  32. package/dist/transactionIntent/helpers/transactionStateHelpers.d.ts +10 -1
  33. package/dist/transactionIntent/helpers/transactionStateHelpers.d.ts.map +1 -1
  34. package/dist/transactionIntent/types.d.ts +3 -6
  35. package/dist/transactionIntent/types.d.ts.map +1 -1
  36. package/dist/transactionIntent/utils/resilientDepositTracker.d.ts +3 -3
  37. package/dist/transactionIntent/utils/resilientDepositTracker.d.ts.map +1 -1
  38. package/dist/transactions.d.ts +2 -0
  39. package/dist/transactions.d.ts.map +1 -1
  40. package/dist/umd/trails.min.js +200 -200
  41. package/dist/walletUtils.d.ts +4 -0
  42. package/dist/walletUtils.d.ts.map +1 -1
  43. package/dist/wallets.d.ts +2 -1
  44. package/dist/wallets.d.ts.map +1 -1
  45. package/dist/widget/components/AccountActionsDropdown.d.ts.map +1 -1
  46. package/dist/widget/components/AccountIntentTransactionHistoryButton.d.ts.map +1 -1
  47. package/dist/widget/components/AccountSettings.d.ts.map +1 -1
  48. package/dist/widget/components/ClassicSwap.d.ts.map +1 -1
  49. package/dist/widget/components/ConnectWallet.d.ts.map +1 -1
  50. package/dist/widget/components/ConnectedWallets.d.ts +5 -1
  51. package/dist/widget/components/ConnectedWallets.d.ts.map +1 -1
  52. package/dist/widget/components/DepositTracker.d.ts +1 -1
  53. package/dist/widget/components/DepositTracker.d.ts.map +1 -1
  54. package/dist/widget/components/DirectTransfer.d.ts +0 -8
  55. package/dist/widget/components/DirectTransfer.d.ts.map +1 -1
  56. package/dist/widget/components/Fund.d.ts +1 -1
  57. package/dist/widget/components/Fund.d.ts.map +1 -1
  58. package/dist/widget/components/FundMethods.d.ts.map +1 -1
  59. package/dist/widget/components/FundWalletSelection.d.ts +0 -8
  60. package/dist/widget/components/FundWalletSelection.d.ts.map +1 -1
  61. package/dist/widget/components/FundingMethodSelectorButton.d.ts +1 -1
  62. package/dist/widget/components/FundingMethodSelectorButton.d.ts.map +1 -1
  63. package/dist/widget/components/MeldStepsFlow.d.ts.map +1 -1
  64. package/dist/widget/components/OnrampErrorScreen.d.ts.map +1 -1
  65. package/dist/widget/components/OnrampPaymentMethods.d.ts.map +1 -1
  66. package/dist/widget/components/OnrampProviderConfirmation.d.ts +0 -6
  67. package/dist/widget/components/OnrampProviderConfirmation.d.ts.map +1 -1
  68. package/dist/widget/components/Pay.d.ts.map +1 -1
  69. package/dist/widget/components/QrCode.d.ts.map +1 -1
  70. package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
  71. package/dist/widget/components/Receipt.d.ts.map +1 -1
  72. package/dist/widget/components/ReceiptRecoverableFunds.d.ts +25 -0
  73. package/dist/widget/components/ReceiptRecoverableFunds.d.ts.map +1 -0
  74. package/dist/widget/components/RecipientSelectorButton.d.ts +3 -1
  75. package/dist/widget/components/RecipientSelectorButton.d.ts.map +1 -1
  76. package/dist/widget/components/Recipients.d.ts.map +1 -1
  77. package/dist/widget/components/Swap.d.ts +2 -16
  78. package/dist/widget/components/Swap.d.ts.map +1 -1
  79. package/dist/widget/components/TokenSelector.d.ts.map +1 -1
  80. package/dist/widget/components/TransactionDetails.d.ts.map +1 -1
  81. package/dist/widget/components/TransactionHistoryItem.d.ts.map +1 -1
  82. package/dist/widget/components/TransferPendingVertical.d.ts.map +1 -1
  83. package/dist/widget/components/TruncatedTransactionHash.d.ts.map +1 -1
  84. package/dist/widget/components/WalletConfirmation.d.ts.map +1 -1
  85. package/dist/widget/components/WalletConnect.d.ts.map +1 -1
  86. package/dist/widget/components/WidgetProviders.d.ts.map +1 -1
  87. package/dist/widget/components/Withdraw.d.ts.map +1 -1
  88. package/dist/widget/css/compiled.css +1 -1
  89. package/dist/widget/hooks/useClickTracking.d.ts.map +1 -1
  90. package/dist/widget/hooks/useDebugScreens.d.ts +1 -10
  91. package/dist/widget/hooks/useDebugScreens.d.ts.map +1 -1
  92. package/dist/widget/hooks/useDepositMonitor.d.ts +2 -4
  93. package/dist/widget/hooks/useDepositMonitor.d.ts.map +1 -1
  94. package/dist/widget/hooks/useExternalFundingReceiptSync.d.ts +11 -0
  95. package/dist/widget/hooks/useExternalFundingReceiptSync.d.ts.map +1 -0
  96. package/dist/widget/hooks/useIntentReceiptBalances.d.ts +16 -0
  97. package/dist/widget/hooks/useIntentReceiptBalances.d.ts.map +1 -0
  98. package/dist/widget/hooks/useQuote.d.ts +0 -4
  99. package/dist/widget/hooks/useQuote.d.ts.map +1 -1
  100. package/dist/widget/hooks/useScreenTracking.d.ts +2 -0
  101. package/dist/widget/hooks/useScreenTracking.d.ts.map +1 -0
  102. package/dist/widget/hooks/useSelectedFundMethod.d.ts +0 -2
  103. package/dist/widget/hooks/useSelectedFundMethod.d.ts.map +1 -1
  104. package/dist/widget/hooks/useSendForm.d.ts +0 -4
  105. package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
  106. package/dist/widget/hooks/useTokenList.d.ts.map +1 -1
  107. package/dist/widget/hooks/useTrailsSendTransaction.d.ts.map +1 -1
  108. package/dist/widget/hooks/useViewManager.d.ts +89 -0
  109. package/dist/widget/hooks/useViewManager.d.ts.map +1 -0
  110. package/dist/widget/hooks/useWalletConnectUri.d.ts.map +1 -1
  111. package/dist/widget/hooks/useWalletConnectionContext.d.ts +1 -1
  112. package/dist/widget/hooks/useWalletConnectionContext.d.ts.map +1 -1
  113. package/dist/widget/index.d.ts +1 -1
  114. package/dist/widget/index.d.ts.map +1 -1
  115. package/dist/widget/index.js +7 -6
  116. package/dist/widget/providers/TrailsProvider.d.ts.map +1 -1
  117. package/dist/widget/types/commonProps.d.ts +1 -6
  118. package/dist/widget/types/commonProps.d.ts.map +1 -1
  119. package/dist/widget/utils/forexRateStore.d.ts.map +1 -1
  120. package/dist/widget/utils/fundMethodSwitchState.d.ts +10 -0
  121. package/dist/widget/utils/fundMethodSwitchState.d.ts.map +1 -0
  122. package/dist/widget/utils/localeStore.d.ts.map +1 -1
  123. package/dist/widget/utils/viewManagerGuards.d.ts +5 -0
  124. package/dist/widget/utils/viewManagerGuards.d.ts.map +1 -0
  125. package/dist/widget/widget.d.ts +23 -2
  126. package/dist/widget/widget.d.ts.map +1 -1
  127. package/package.json +2 -2
  128. package/src/abis/trailsHydrate.ts +2 -1
  129. package/src/analytics.ts +60 -0
  130. package/src/chainSwitch.ts +11 -8
  131. package/src/chains.ts +82 -37
  132. package/src/constants.ts +2 -2
  133. package/src/error.ts +8 -0
  134. package/src/index.ts +1 -12
  135. package/src/intentReceiptPoller.ts +27 -0
  136. package/src/intents.ts +36 -87
  137. package/src/mutations.ts +11 -102
  138. package/src/onramp-client/index.ts +3 -3
  139. package/src/prepareSend.ts +6 -2
  140. package/src/query/balance.hooks.ts +31 -10
  141. package/src/query/chains.hooks.ts +7 -1
  142. package/src/query/chains.queries.ts +8 -5
  143. package/src/queryParams.ts +8 -6
  144. package/src/recover.ts +9 -9
  145. package/src/tokens.ts +4 -2
  146. package/src/transactionIntent/deposits/depositOrchestrator.ts +0 -2
  147. package/src/transactionIntent/deposits/gaslessDeposit.ts +8 -0
  148. package/src/transactionIntent/deposits/standardDeposit.ts +25 -35
  149. package/src/transactionIntent/handlers/intentHandler.ts +234 -138
  150. package/src/transactionIntent/helpers/transactionStateHelpers.ts +108 -1
  151. package/src/transactionIntent/types.ts +14 -8
  152. package/src/transactionIntent/utils/resilientDepositTracker.ts +72 -183
  153. package/src/transactions.ts +16 -0
  154. package/src/walletUtils.ts +188 -1
  155. package/src/wallets.ts +50 -15
  156. package/src/widget/compiled.css +1 -1
  157. package/src/widget/components/AccountActionsDropdown.tsx +4 -6
  158. package/src/widget/components/AccountIntentTransactionHistoryButton.tsx +4 -6
  159. package/src/widget/components/AccountSettings.tsx +36 -22
  160. package/src/widget/components/ClassicSwap.tsx +67 -9
  161. package/src/widget/components/ConnectWallet.tsx +5 -7
  162. package/src/widget/components/ConnectedWallets.tsx +143 -82
  163. package/src/widget/components/DepositTracker.tsx +4 -5
  164. package/src/widget/components/DirectTransfer.tsx +85 -84
  165. package/src/widget/components/Earn.tsx +3 -3
  166. package/src/widget/components/Fund.tsx +90 -17
  167. package/src/widget/components/FundMethods.tsx +77 -43
  168. package/src/widget/components/FundWalletSelection.tsx +13 -397
  169. package/src/widget/components/FundingMethodSelectorButton.tsx +11 -10
  170. package/src/widget/components/MeldStepsFlow.tsx +64 -30
  171. package/src/widget/components/OnrampErrorScreen.tsx +2 -18
  172. package/src/widget/components/OnrampPaymentMethods.tsx +4 -6
  173. package/src/widget/components/OnrampProviderConfirmation.tsx +91 -110
  174. package/src/widget/components/OriginTransferInformation.tsx +2 -2
  175. package/src/widget/components/Pay.tsx +27 -7
  176. package/src/widget/components/PaymentMethods.tsx +10 -10
  177. package/src/widget/components/PoolDeposit.tsx +2 -2
  178. package/src/widget/components/QrCode.tsx +13 -11
  179. package/src/widget/components/QuoteDetails.tsx +16 -6
  180. package/src/widget/components/Receipt.tsx +66 -6
  181. package/src/widget/components/ReceiptRecoverableFunds.tsx +135 -0
  182. package/src/widget/components/RecipientSelectorButton.tsx +6 -17
  183. package/src/widget/components/Recipients.tsx +38 -29
  184. package/src/widget/components/Swap.tsx +2 -25
  185. package/src/widget/components/TokenList.tsx +2 -2
  186. package/src/widget/components/TokenSelector.tsx +11 -11
  187. package/src/widget/components/TokenSelectorButton.tsx +3 -3
  188. package/src/widget/components/TrailsHookModal.tsx +1 -1
  189. package/src/widget/components/TransactionDetails.tsx +43 -37
  190. package/src/widget/components/TransactionHistoryItem.tsx +1 -42
  191. package/src/widget/components/TransferPendingVertical.tsx +11 -4
  192. package/src/widget/components/TruncatedTransactionHash.tsx +5 -0
  193. package/src/widget/components/WalletConfirmation.tsx +5 -8
  194. package/src/widget/components/WalletConnect.tsx +6 -2
  195. package/src/widget/components/WidgetProviders.tsx +34 -43
  196. package/src/widget/components/Withdraw.tsx +25 -11
  197. package/src/widget/hooks/useClickTracking.ts +5 -0
  198. package/src/widget/hooks/useDebugScreens.ts +40 -86
  199. package/src/widget/hooks/useDepositMonitor.ts +14 -149
  200. package/src/widget/hooks/useExternalFundingReceiptSync.ts +79 -0
  201. package/src/widget/hooks/useIntentReceiptBalances.ts +141 -0
  202. package/src/widget/hooks/useQuote.ts +7 -16
  203. package/src/widget/hooks/useScreenTracking.ts +14 -0
  204. package/src/widget/hooks/useSelectedFundMethod.tsx +0 -5
  205. package/src/widget/hooks/useSendForm.ts +5 -14
  206. package/src/widget/hooks/useTokenList.ts +3 -16
  207. package/src/widget/hooks/useTrailsSendTransaction.ts +1 -5
  208. package/src/widget/hooks/useViewManager.tsx +505 -0
  209. package/src/widget/hooks/useWalletConnectUri.tsx +77 -18
  210. package/src/widget/hooks/useWalletConnectionContext.tsx +1 -1
  211. package/src/widget/index.tsx +1 -0
  212. package/src/widget/providers/TrailsProvider.tsx +0 -41
  213. package/src/widget/styles.ts +1 -1
  214. package/src/widget/types/commonProps.ts +0 -8
  215. package/src/widget/utils/forexRateStore.ts +0 -2
  216. package/src/widget/utils/fundMethodSwitchState.ts +25 -0
  217. package/src/widget/utils/localeStore.ts +0 -1
  218. package/src/widget/utils/viewManagerGuards.ts +49 -0
  219. package/src/widget/widget.tsx +405 -316
  220. package/dist/intentStorage.d.ts +0 -24
  221. package/dist/intentStorage.d.ts.map +0 -1
  222. package/dist/mode.d.ts +0 -2
  223. package/dist/mode.d.ts.map +0 -1
  224. package/dist/widget/hooks/useBack.d.ts +0 -22
  225. package/dist/widget/hooks/useBack.d.ts.map +0 -1
  226. package/dist/widget/hooks/useCurrentScreen.d.ts +0 -13
  227. package/dist/widget/hooks/useCurrentScreen.d.ts.map +0 -1
  228. package/dist/widget/hooks/useInitialRedirect.d.ts +0 -7
  229. package/dist/widget/hooks/useInitialRedirect.d.ts.map +0 -1
  230. package/dist/widget/hooks/useMode.d.ts +0 -20
  231. package/dist/widget/hooks/useMode.d.ts.map +0 -1
  232. package/dist/widget/hooks/usePreviousScreen.d.ts +0 -12
  233. package/dist/widget/hooks/usePreviousScreen.d.ts.map +0 -1
  234. package/dist/widget/workers/intentExecutionWorker.d.ts +0 -73
  235. package/dist/widget/workers/intentExecutionWorker.d.ts.map +0 -1
  236. package/src/intentStorage.ts +0 -106
  237. package/src/mode.ts +0 -1
  238. package/src/widget/hooks/useBack.tsx +0 -210
  239. package/src/widget/hooks/useCurrentScreen.tsx +0 -73
  240. package/src/widget/hooks/useInitialRedirect.tsx +0 -70
  241. package/src/widget/hooks/useMode.tsx +0 -51
  242. package/src/widget/hooks/usePreviousScreen.ts +0 -36
  243. package/src/widget/workers/intentExecutionWorker.ts +0 -502
@@ -1,15 +1,17 @@
1
1
  import { Plus, X } from "lucide-react"
2
2
  import type React from "react"
3
- import { useCallback, useEffect, useRef, useState } from "react"
3
+ import { useCallback, useEffect, useState } from "react"
4
4
  import { isAddress } from "viem"
5
5
  import { useAccount, useConnections } from "wagmi"
6
6
  import { useResolveEnsAddress, useResolveEnsName } from "../../ens.js"
7
7
  import { logger } from "../../logger.js"
8
8
  import { addressEqual, truncateAddress } from "../../utils/address.js"
9
9
  import { useWallets, wagmiConnectorToWalletId } from "../../wallets.js"
10
- import { useBack } from "../hooks/useBack.js"
11
- import { useCurrentScreen } from "../hooks/useCurrentScreen.js"
12
- import { useMode } from "../hooks/useMode.js"
10
+ import {
11
+ useViewManager,
12
+ type Mode,
13
+ type Screen,
14
+ } from "../hooks/useViewManager.js"
13
15
  import { useRecipients, type RecentRecipient } from "../hooks/useRecipients.js"
14
16
  import { useSelectedRecipient } from "../hooks/useSelectedRecipient.js"
15
17
  import { AddressOrEnsName } from "./AddressOrEnsName.js"
@@ -47,15 +49,33 @@ interface RecipientsProps {
47
49
  onRecipientSelect?: (address: string) => void
48
50
  }
49
51
 
52
+ type RecipientReturnScreen = Exclude<Screen, "recipients">
53
+ type RecipientFallbackScreen = Extract<
54
+ RecipientReturnScreen,
55
+ "send-form" | "fund-form" | "earn" | "swap" | "withdraw"
56
+ >
57
+
58
+ const isRecipientReturnScreen = (
59
+ screen: Screen | null,
60
+ ): screen is RecipientReturnScreen => {
61
+ return screen !== null && screen !== "recipients"
62
+ }
63
+
64
+ const fallbackRecipientTargetByMode = {
65
+ pay: "send-form",
66
+ fund: "fund-form",
67
+ earn: "earn",
68
+ swap: "swap",
69
+ withdraw: "withdraw",
70
+ } satisfies Record<Mode, RecipientFallbackScreen>
71
+
50
72
  export const Recipients: React.FC<RecipientsProps> = ({
51
73
  onBack,
52
74
  selectedRecipient = "",
53
75
  onRecipientSelect,
54
76
  }) => {
55
- const { setCurrentScreen } = useCurrentScreen()
56
- const { mode } = useMode()
77
+ const { navigate, mode, backScreen } = useViewManager()
57
78
  const { setSelectedRecipient } = useSelectedRecipient()
58
- const { getPreviousScreen } = useBack()
59
79
  const { recentRecipients, addRecentRecipient, clearRecentRecipients } =
60
80
  useRecipients()
61
81
  const [recipientInput, setRecipientInput] = useState(selectedRecipient)
@@ -65,7 +85,7 @@ export const Recipients: React.FC<RecipientsProps> = ({
65
85
  const { address } = useAccount()
66
86
  const connections = useConnections()
67
87
  const { wallets: allWallets } = useWallets()
68
- const isWithdrawBack = useRef(getPreviousScreen() === "withdraw").current
88
+ const isWithdrawBack = backScreen === "withdraw"
69
89
 
70
90
  // Use wagmi ENS resolution for both directions
71
91
  const trimmedInput = recipientInput.trim()
@@ -166,13 +186,12 @@ export const Recipients: React.FC<RecipientsProps> = ({
166
186
 
167
187
  // Determine the screen to navigate to after selection
168
188
  const getTargetScreen = useCallback(() => {
169
- if (mode === "fund") {
170
- return "fund-form"
171
- } else if (mode === "withdraw") {
172
- return "withdraw"
189
+ if (isRecipientReturnScreen(backScreen)) {
190
+ return backScreen
173
191
  }
174
- return "home"
175
- }, [mode])
192
+
193
+ return fallbackRecipientTargetByMode[mode]
194
+ }, [mode, backScreen])
176
195
 
177
196
  // Handle recent recipient selection
178
197
  const handleRecentRecipientSelect = useCallback(
@@ -180,14 +199,9 @@ export const Recipients: React.FC<RecipientsProps> = ({
180
199
  logger.console.log("[trails-sdk] Selected recent recipient:", recipient)
181
200
  setSelectedRecipient(recipient.address)
182
201
  onRecipientSelect?.(recipient.address)
183
- setCurrentScreen(getTargetScreen())
202
+ navigate(getTargetScreen())
184
203
  },
185
- [
186
- setSelectedRecipient,
187
- onRecipientSelect,
188
- setCurrentScreen,
189
- getTargetScreen,
190
- ],
204
+ [setSelectedRecipient, onRecipientSelect, navigate, getTargetScreen],
191
205
  )
192
206
 
193
207
  // Handle connected wallet selection
@@ -199,14 +213,9 @@ export const Recipients: React.FC<RecipientsProps> = ({
199
213
  )
200
214
  setSelectedRecipient(walletAddress)
201
215
  onRecipientSelect?.(walletAddress)
202
- setCurrentScreen(getTargetScreen())
216
+ navigate(getTargetScreen())
203
217
  },
204
- [
205
- setSelectedRecipient,
206
- onRecipientSelect,
207
- setCurrentScreen,
208
- getTargetScreen,
209
- ],
218
+ [setSelectedRecipient, onRecipientSelect, navigate, getTargetScreen],
210
219
  )
211
220
 
212
221
  const getValidationMessage = () => {
@@ -277,7 +286,7 @@ export const Recipients: React.FC<RecipientsProps> = ({
277
286
  ))}
278
287
  <button
279
288
  type="button"
280
- onClick={() => setCurrentScreen("connect")}
289
+ onClick={() => navigate("connect")}
281
290
  className="w-full text-left px-4 py-2 text-sm flex items-center justify-between cursor-pointer transition-colors rounded-xl trails-text-primary trails-hover-bg"
282
291
  >
283
292
  <div className="flex items-center gap-3">
@@ -6,8 +6,8 @@ import type { Token } from "../../tokens.js"
6
6
  import type { CheckoutOnHandlers } from "../hooks/useCheckout.js"
7
7
  import type { PrepareSendQuote } from "../../prepareSend.js"
8
8
  import { ClassicSwap } from "./ClassicSwap.js"
9
- import type { OnrampQuote } from "../hooks/useOnRampQuote.js"
10
9
  import type { FundMethod } from "../../transactionIntent/types.js"
10
+ import type { OnrampConfirmCallback } from "../types/commonProps.js"
11
11
 
12
12
  interface SwapProps {
13
13
  selectedToken: Token | null
@@ -25,30 +25,7 @@ interface SwapProps {
25
25
  onTransactionStateChange: (transactionStates: TransactionState[]) => void
26
26
  onError: (error: Error | string | null) => void
27
27
  onWaitingForWalletConfirm: (props: PrepareSendQuote) => void
28
- onWaitingForOnrampConfirm?: (
29
- props: PrepareSendQuote,
30
- onrampProviderQuote?: OnrampQuote | null,
31
- widgetParams?: {
32
- depositAddress: string
33
- userAddress: string
34
- countryCode: string
35
- sourceCurrencyCode: string
36
- sourceAmount: string
37
- destinationCurrencyCode: string
38
- serviceProvider: string
39
- paymentMethodType?: string
40
- },
41
- sessionId?: string,
42
- sendFn?:
43
- | ((options?: {
44
- selectedFeeOption?: any | null
45
- onOriginSend?: () => void
46
- depositTransactionHash?: string
47
- skipCommit?: boolean
48
- }) => Promise<any>)
49
- | null,
50
- popupWindowRef?: Window | null,
51
- ) => void
28
+ onWaitingForOnrampConfirm?: OnrampConfirmCallback
52
29
  paymasterUrls?: Array<{ chainId: number; url: string }>
53
30
  setWalletConfirmRetryHandler: (handler: () => Promise<void>) => void
54
31
  swapProvider?: string
@@ -5,7 +5,7 @@ import { ScreenHeader } from "./ScreenHeader.js"
5
5
  import { TokenSelector } from "./TokenSelector.js"
6
6
  import { ChainList } from "./ChainList.js"
7
7
  import { useTokenList } from "../hooks/useTokenList.js"
8
- import { useMode } from "../hooks/useMode.js"
8
+ import { useViewManager } from "../hooks/useViewManager.js"
9
9
  import { useOriginSelectedToken } from "../hooks/useOriginSelectedToken.js"
10
10
  import type { FundMethod } from "../../transactionIntent/types.js"
11
11
 
@@ -35,7 +35,7 @@ export const TokenList: React.FC<TokenListProps> = ({
35
35
  onNavigateToFundMethods,
36
36
  onShowChainList,
37
37
  }) => {
38
- const { mode } = useMode()
38
+ const { mode } = useViewManager()
39
39
  const { setSelectedToken } = useOriginSelectedToken()
40
40
  const [showChainListInternal, setShowChainListInternal] = useState(false)
41
41
 
@@ -26,6 +26,7 @@ import { useBalanceVisible } from "../hooks/useBalanceVisible.js"
26
26
  import { useChainFilter } from "../hooks/useChainFilter.js"
27
27
  import { useCustomTokenSearch } from "../hooks/useCustomTokenSearch.js"
28
28
  import { useTokenList } from "../hooks/useTokenList.js"
29
+ import { useSupportedChains } from "../../query/chains.hooks.js"
29
30
  import { ChainFilterDropdown } from "./ChainFilterDropdown.js"
30
31
  import { CopyButton } from "./CopyButton.js"
31
32
  import { RecentTokens } from "./RecentTokens.js"
@@ -425,6 +426,7 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
425
426
  selectedChainId: filterByChainId,
426
427
  setSelectedChainId: setFilterByChainId,
427
428
  } = useChainFilter()
429
+ const { data: supportedChains = [] } = useSupportedChains()
428
430
 
429
431
  // Handle custom token search and integration
430
432
  // Only enable custom token search after initial load is complete
@@ -452,22 +454,20 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
452
454
  !hasInitiallyLoaded &&
453
455
  (isLoadingTokens || rawChainFilteredTokens.length === 0)
454
456
 
455
- // Get unique chains from all tokens (not filtered by chain)
457
+ // Chain selector should show all supported chains, not just chains present in
458
+ // currently filtered token results.
456
459
  const uniqueChains = useMemo(() => {
457
- const chainIds = new Set(
458
- filteredTokensFormatted.map((token) => token.chainId || 0),
459
- )
460
- return Array.from(chainIds)
461
- .map((chainId) => {
462
- const chainInfo = getChainInfo(chainId)
460
+ return supportedChains
461
+ .map((chain) => {
462
+ const chainInfo = getChainInfo(chain.id)
463
463
  return {
464
- chainId,
465
- name: chainInfo?.name || `Chain ${chainId}`,
464
+ chainId: chain.id,
465
+ name: chainInfo?.name || chain.name || `Chain ${chain.id}`,
466
466
  imageUrl: "", // We'll use TokenImage component for chain icons
467
467
  }
468
468
  })
469
469
  .sort((a, b) => a.name.localeCompare(b.name))
470
- }, [filteredTokensFormatted])
470
+ }, [supportedChains])
471
471
 
472
472
  // Filter recent tokens to only show ones that exist in the current token list and match search
473
473
  const filteredRecentTokens = recentTokens.filter((recentToken) => {
@@ -714,7 +714,7 @@ export const TokenSelector: React.FC<TokenSelectorProps> = ({
714
714
  <div className="text-center pt-2 pb-1">
715
715
  <p className="text-sm font-medium text-gray-600 dark:text-gray-400">
716
716
  {fundMethod === "direct-transfer"
717
- ? "Paying with Direct Transfer"
717
+ ? "Paying with Crypto Transfer"
718
718
  : "Paying with Exchange Deposit"}
719
719
  </p>
720
720
  </div>
@@ -4,7 +4,7 @@ import { useMemo } from "react"
4
4
  import { useConnections } from "wagmi"
5
5
  import { getChainInfo } from "../../chains.js"
6
6
  import { useClickTracking } from "../hooks/useClickTracking.js"
7
- import { useCurrentScreen } from "../hooks/useCurrentScreen.js"
7
+ import { useViewManager } from "../hooks/useViewManager.js"
8
8
  import { useSelectedFundMethod } from "../hooks/useSelectedFundMethod.js"
9
9
  import { TokenImage } from "./TokenImage.js"
10
10
 
@@ -31,7 +31,7 @@ export const TokenSelectorButton: React.FC<TokenSelectorButtonProps> = ({
31
31
  fullWidth = false,
32
32
  }) => {
33
33
  const connections = useConnections()
34
- const { setCurrentScreen } = useCurrentScreen()
34
+ const { navigate } = useViewManager()
35
35
  const { selectedFundMethod } = useSelectedFundMethod()
36
36
  const displayChainId = token?.chainId || chainId
37
37
 
@@ -61,7 +61,7 @@ export const TokenSelectorButton: React.FC<TokenSelectorButtonProps> = ({
61
61
 
62
62
  // If no wallet connected and fund method is "wallet", redirect to connect screen
63
63
  if (!isConnected && selectedFundMethod === "wallet") {
64
- setCurrentScreen("connect")
64
+ navigate("connect")
65
65
  return
66
66
  }
67
67
 
@@ -82,7 +82,7 @@ export function TrailsHookModal() {
82
82
  return createWagmiConfig({
83
83
  apiKey,
84
84
  nodeGatewayUrl: trailsContext?.sequenceNodeGatewayUrl,
85
- connectors: getConnectorsInternal(apiKey),
85
+ connectors: getConnectorsInternal(apiKey, trailsContext?.trailsApiUrl),
86
86
  storage: createStorage({
87
87
  storage: localStorage,
88
88
  key: "trails-hook-modal-wagmi",
@@ -1,5 +1,8 @@
1
1
  import type React from "react"
2
- import type { IntentTransaction } from "../../transactions.js"
2
+ import {
3
+ type IntentTransaction,
4
+ isDisplayableTransactionHash,
5
+ } from "../../transactions.js"
3
6
  import { TokenImage } from "./TokenImage.js"
4
7
  import { ChainImage } from "./ChainImage.js"
5
8
  import { getExplorerUrlForAddress, getExplorerUrl } from "../../explorer.js"
@@ -57,39 +60,40 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
57
60
  )}
58
61
 
59
62
  {/* Deposit Transaction Hash */}
60
- {transaction.depositTransactionHash && transaction.originChainId && (
61
- <div className="flex justify-between items-center">
62
- <span className="text-xs text-gray-600 dark:text-gray-400">
63
- Deposit Tx:
64
- </span>
65
- <a
66
- href={getExplorerUrl({
67
- txHash: transaction.depositTransactionHash,
68
- chainId: transaction.originChainId,
69
- })}
70
- target="_blank"
71
- rel="noopener noreferrer"
72
- className="text-xs font-mono hover:underline flex items-center gap-1 text-gray-900 dark:text-gray-100"
73
- >
74
- <ChainImage chainId={transaction.originChainId} size={16} />
75
- {truncateAddress(transaction.depositTransactionHash)}
76
- <svg
77
- aria-hidden="true"
78
- className="w-3 h-3"
79
- fill="none"
80
- stroke="currentColor"
81
- viewBox="0 0 24 24"
63
+ {isDisplayableTransactionHash(transaction.depositTransactionHash) &&
64
+ transaction.originChainId && (
65
+ <div className="flex justify-between items-center">
66
+ <span className="text-xs text-gray-600 dark:text-gray-400">
67
+ Deposit Tx:
68
+ </span>
69
+ <a
70
+ href={getExplorerUrl({
71
+ txHash: transaction.depositTransactionHash,
72
+ chainId: transaction.originChainId,
73
+ })}
74
+ target="_blank"
75
+ rel="noopener noreferrer"
76
+ className="text-xs font-mono hover:underline flex items-center gap-1 text-gray-900 dark:text-gray-100"
82
77
  >
83
- <path
84
- strokeLinecap="round"
85
- strokeLinejoin="round"
86
- strokeWidth={2}
87
- d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
88
- />
89
- </svg>
90
- </a>
91
- </div>
92
- )}
78
+ <ChainImage chainId={transaction.originChainId} size={16} />
79
+ {truncateAddress(transaction.depositTransactionHash)}
80
+ <svg
81
+ aria-hidden="true"
82
+ className="w-3 h-3"
83
+ fill="none"
84
+ stroke="currentColor"
85
+ viewBox="0 0 24 24"
86
+ >
87
+ <path
88
+ strokeLinecap="round"
89
+ strokeLinejoin="round"
90
+ strokeWidth={2}
91
+ d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
92
+ />
93
+ </svg>
94
+ </a>
95
+ </div>
96
+ )}
93
97
 
94
98
  {/* Origin Token - Moved before Origin Intent */}
95
99
  {transaction.originToken && (
@@ -159,7 +163,7 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
159
163
  )}
160
164
 
161
165
  {/* Origin Intent Deposit Tx Hash */}
162
- {transaction.originIntentDepositTxHash &&
166
+ {isDisplayableTransactionHash(transaction.originIntentDepositTxHash) &&
163
167
  transaction.originIntentDepositTxExplorerUrl &&
164
168
  transaction.originChainId && (
165
169
  <div className="flex justify-between items-center">
@@ -193,7 +197,9 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
193
197
  )}
194
198
 
195
199
  {/* Destination Intent Deposit Tx Hash */}
196
- {transaction.destinationIntentDepositTxHash &&
200
+ {isDisplayableTransactionHash(
201
+ transaction.destinationIntentDepositTxHash,
202
+ ) &&
197
203
  transaction.destinationIntentDepositTxExplorerUrl &&
198
204
  transaction.destinationChainId && (
199
205
  <div className="flex justify-between items-center">
@@ -267,7 +273,7 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
267
273
  )}
268
274
 
269
275
  {/* Origin Intent Action Tx Hash */}
270
- {transaction.originIntentTxHash &&
276
+ {isDisplayableTransactionHash(transaction.originIntentTxHash) &&
271
277
  transaction.originIntentTxExplorerUrl &&
272
278
  transaction.originChainId && (
273
279
  <div className="flex justify-between items-center">
@@ -445,7 +451,7 @@ export const TransactionDetails: React.FC<TransactionDetailsProps> = ({
445
451
  )}
446
452
 
447
453
  {/* Destination Intent Action Tx Hash */}
448
- {transaction.destinationIntentTxHash &&
454
+ {isDisplayableTransactionHash(transaction.destinationIntentTxHash) &&
449
455
  transaction.destinationIntentTxExplorerUrl &&
450
456
  transaction.destinationChainId && (
451
457
  <div className="flex justify-between items-center">
@@ -148,8 +148,6 @@ const TransactionHistoryItem: React.FC<{
148
148
  const [commitError, setCommitError] = useState<string | null>(null)
149
149
  const [isExecuting, setIsExecuting] = useState(false)
150
150
  const [executeError, setExecuteError] = useState<string | null>(null)
151
- const [manualDepositTxHash, setManualDepositTxHash] = useState<string>("")
152
- const [showDepositHashInput, setShowDepositHashInput] = useState(false)
153
151
 
154
152
  // Execute intent mutation
155
153
  const executeIntentMutation = useExecuteIntent()
@@ -251,8 +249,7 @@ const TransactionHistoryItem: React.FC<{
251
249
  setIsExecuting(true)
252
250
  setExecuteError(null)
253
251
 
254
- // For committed intents, we need to provide a depositTransactionHash
255
- // First try the provided hash, then try to use any available transaction hash from the history
252
+ // Deposit tx hash is optional. If available, include it for backend correlation.
256
253
  const depositTxHash =
257
254
  providedDepositTxHash ||
258
255
  transaction.originTransactionHash ||
@@ -261,19 +258,8 @@ const TransactionHistoryItem: React.FC<{
261
258
  transaction.txnHash ||
262
259
  getQueryParam("depositTransactionHash")
263
260
 
264
- if (!depositTxHash) {
265
- // Show the input field for manual entry
266
- setShowDepositHashInput(true)
267
- setExecuteError(
268
- "No deposit transaction hash found. Please enter the deposit transaction hash manually.",
269
- )
270
- setIsExecuting(false)
271
- return
272
- }
273
-
274
261
  await executeIntentMutation.mutateAsync({
275
262
  intentId: transaction.intentId,
276
- depositTransactionHash: depositTxHash,
277
263
  })
278
264
 
279
265
  logger.console.log(
@@ -284,10 +270,6 @@ const TransactionHistoryItem: React.FC<{
284
270
  },
285
271
  )
286
272
 
287
- // Reset manual input fields on success
288
- setManualDepositTxHash("")
289
- setShowDepositHashInput(false)
290
-
291
273
  // Call success callback to refresh the list
292
274
  if (onCommitSuccess) {
293
275
  onCommitSuccess()
@@ -590,29 +572,6 @@ const TransactionHistoryItem: React.FC<{
590
572
  {executeError && (
591
573
  <div className="w-full">
592
574
  <ErrorDisplay error={executeError} severity="error" />
593
- {showDepositHashInput && (
594
- <div className="mt-2 flex gap-1.5">
595
- <input
596
- type="text"
597
- value={manualDepositTxHash}
598
- onChange={(e) => setManualDepositTxHash(e.target.value)}
599
- placeholder="Enter deposit tx hash (0x...)"
600
- className="flex-1 px-2 py-1 text-xs border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-transparent"
601
- />
602
- <button
603
- type="button"
604
- onClick={() => {
605
- if (manualDepositTxHash.trim()) {
606
- handleExecute(manualDepositTxHash.trim())
607
- }
608
- }}
609
- disabled={!manualDepositTxHash.trim() || isExecuting}
610
- className="px-2 py-1 text-xs bg-blue-600 hover:bg-blue-700 disabled:bg-gray-400 text-white rounded transition-colors disabled:cursor-not-allowed whitespace-nowrap"
611
- >
612
- {isExecuting ? "Executing..." : "Execute"}
613
- </button>
614
- </div>
615
- )}
616
575
  </div>
617
576
  )}
618
577
  {recoverError && (
@@ -6,7 +6,7 @@ import type { PrepareSendQuote } from "../../prepareSend.js"
6
6
  import type { TransactionState } from "../../transactions.js"
7
7
  import { formatDuration, MINUTE_MS } from "../../utils/time.js"
8
8
  import { hasMetaTxError } from "../../utils/passthrough.js"
9
- import { useMode } from "../hooks/useMode.js"
9
+ import { useViewManager } from "../hooks/useViewManager.js"
10
10
  import type { OnrampQuote } from "../hooks/useOnRampQuote.js"
11
11
  import {
12
12
  hasAnyFailedOrAbortedTransactions,
@@ -28,6 +28,8 @@ const isOFTRoute = (routeProviders?: { id: string }[]): boolean => {
28
28
  // Timeout constants
29
29
  const OFT_TIMEOUT_MS = 60 * MINUTE_MS // 1 hour for OFT routes
30
30
  const DEFAULT_TIMEOUT_MS = MINUTE_MS // 1 minute for normal routes
31
+ const MAINNET_TIMEOUT_MS = 2 * MINUTE_MS // 2 minutes for Ethereum mainnet routes
32
+ const ETHEREUM_MAINNET_CHAIN_ID = 1
31
33
 
32
34
  // Checkmark icon for completed steps
33
35
  const CheckmarkIcon = () => (
@@ -116,7 +118,7 @@ export const TransferPending: React.FC<TransferPendingProps> = ({
116
118
  timestamp,
117
119
  onContinue,
118
120
  }) => {
119
- const { mode } = useMode()
121
+ const { mode } = useViewManager()
120
122
  const [showContent, setShowContent] = useState(false)
121
123
  const [activePendingIndex, setActivePendingIndex] = useState(-1)
122
124
  const [showDots, setShowDots] = useState(false)
@@ -127,20 +129,25 @@ export const TransferPending: React.FC<TransferPendingProps> = ({
127
129
  null,
128
130
  )
129
131
  const isOFT = isOFTRoute(quote?.routeProviders)
132
+ const isMainnetOrigin = quote?.originChain?.id === ETHEREUM_MAINNET_CHAIN_ID
130
133
 
131
134
  const showContinueButton =
132
135
  hasAnyFailedOrAbortedTransactions(transactionStates) && onContinue
133
136
 
134
137
  // Timeout warning: OFT routes can take significantly longer than standard routes.
135
138
  useEffect(() => {
136
- const timeoutMs = isOFT ? OFT_TIMEOUT_MS : DEFAULT_TIMEOUT_MS
139
+ const timeoutMs = isOFT
140
+ ? OFT_TIMEOUT_MS
141
+ : isMainnetOrigin
142
+ ? MAINNET_TIMEOUT_MS
143
+ : DEFAULT_TIMEOUT_MS
137
144
 
138
145
  const timeoutTimer = setTimeout(() => {
139
146
  setShowTimeoutWarning(true)
140
147
  }, timeoutMs)
141
148
 
142
149
  return () => clearTimeout(timeoutTimer)
143
- }, [isOFT])
150
+ }, [isOFT, isMainnetOrigin])
144
151
  useEffect(() => {
145
152
  const depositConfirmed = transactionStates?.[0]?.state === "confirmed"
146
153
 
@@ -1,6 +1,7 @@
1
1
  import type React from "react"
2
2
  import { useState } from "react"
3
3
  import { getExplorerUrl } from "../../explorer.js"
4
+ import { isDisplayableTransactionHash } from "../../transactions.js"
4
5
 
5
6
  interface TruncatedTransactionHashProps {
6
7
  txHash: string
@@ -23,6 +24,10 @@ export const TruncatedTransactionHash: React.FC<
23
24
  }) => {
24
25
  const [isHovered, setIsHovered] = useState(false)
25
26
 
27
+ if (!isDisplayableTransactionHash(txHash)) {
28
+ return null
29
+ }
30
+
26
31
  const truncatedHash = `${txHash.slice(0, sliceStart)}…${txHash.slice(-sliceEnd)}`
27
32
  const explorerUrl = getExplorerUrl({ txHash, chainId })
28
33
 
@@ -10,7 +10,6 @@ import { ErrorAnimationIcon } from "./ErrorAnimationIcon.js"
10
10
  import { QuoteDetails } from "./QuoteDetails.js"
11
11
  import { TokenImage } from "./TokenImage.js"
12
12
  import { WaasFeeOptions } from "./WaasFeeOptions.js"
13
- import { removeStoredIntent } from "../../intentStorage.js"
14
13
 
15
14
  interface WalletConfirmationProps {
16
15
  onBack?: () => void
@@ -69,17 +68,15 @@ export const WalletConfirmation: React.FC<WalletConfirmationProps> = ({
69
68
  return isSequenceWaas
70
69
  }, [connector])
71
70
 
71
+ const hasOriginTokenVisual =
72
+ !!quote?.originToken?.symbol || !!quote?.originToken?.imageUrl
73
+
72
74
  return (
73
75
  <div className="space-y-6">
74
76
  <div className="flex items-center relative">
75
77
  <button
76
78
  type="button"
77
- onClick={() => {
78
- if (quote?.intentId) {
79
- removeStoredIntent(quote.intentId)
80
- }
81
- onBack?.()
82
- }}
79
+ onClick={onBack}
83
80
  className="absolute left-0 top-0 p-2 rounded-full transition-colors cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800 hover:trails-hover-bg text-gray-600 dark:text-gray-400"
84
81
  >
85
82
  <ChevronLeft className="h-6 w-6" />
@@ -99,7 +96,7 @@ export const WalletConfirmation: React.FC<WalletConfirmationProps> = ({
99
96
  <div className="animate-spin rounded-full h-24 w-24 border-solid border-b-2 border-blue-500 dark:border-blue-400" />
100
97
  )}
101
98
 
102
- {!feeOptionsError && (
99
+ {!feeOptionsError && hasOriginTokenVisual && (
103
100
  <div className="absolute">
104
101
  <TokenImage
105
102
  imageUrl={quote?.originToken.imageUrl}
@@ -1,6 +1,7 @@
1
1
  import { type FC, useEffect, useMemo, useState } from "react"
2
2
  import { useAccount, useConnect, useDisconnect } from "wagmi"
3
3
  import { logger } from "../../logger.js"
4
+ import { isWalletConnectConnector as checkIsWalletConnectConnector } from "../../walletUtils.js"
4
5
  import {
5
6
  getWalletIcon,
6
7
  getWalletName,
@@ -49,7 +50,7 @@ export const WalletConnectScreen: FC<WalletConnectProps> = ({
49
50
  )
50
51
 
51
52
  const isWalletConnectConnector =
52
- connector?.name === "WalletConnect" && isConnected
53
+ checkIsWalletConnectConnector(connector) && isConnected
53
54
 
54
55
  // Track if we've already processed the initial disconnect
55
56
  const [hasDisconnected, setHasDisconnected] = useState(false)
@@ -60,7 +61,10 @@ export const WalletConnectScreen: FC<WalletConnectProps> = ({
60
61
  useEffect(() => {
61
62
  const resetWalletConnect = async () => {
62
63
  // Check if we're connected via WalletConnect
63
- if (isWalletConnectConnector || connector?.id === "walletConnect") {
64
+ if (
65
+ isWalletConnectConnector ||
66
+ checkIsWalletConnectConnector(connector)
67
+ ) {
64
68
  setIsResetting(true)
65
69
  logger.console.log(
66
70
  "[trails-sdk] [WalletConnect] Resetting WalletConnect connection to show fresh QR code",