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,51 +0,0 @@
1
- import { createContext, useContext, useEffect, useState } from "react"
2
- import type { ReactNode } from "react"
3
- import type { Mode } from "../../mode.js"
4
-
5
- interface ModeContextType {
6
- /** The effective mode — use this for all UI decisions */
7
- mode: Mode
8
- /** The mode from the widget prop (source of truth) */
9
- configuredMode: Mode
10
- /** Temporarily override the mode (e.g. "Buy Crypto" from settings) */
11
- setMode: (mode: Mode) => void
12
- /** Clear any override, reverting to configuredMode */
13
- resetMode: () => void
14
- }
15
-
16
- const ModeContext = createContext<ModeContextType | null>(null)
17
-
18
- interface ModeProviderProps {
19
- children: ReactNode
20
- configuredMode: Mode
21
- }
22
-
23
- export function ModeProvider({ children, configuredMode }: ModeProviderProps) {
24
- const [overrideMode, setOverrideMode] = useState<Mode | null>(null)
25
-
26
- // biome-ignore lint/correctness/useExhaustiveDependencies: intentionally reacts to configuredMode changes to clear internal overrides
27
- useEffect(() => {
28
- setOverrideMode(null)
29
- }, [configuredMode])
30
-
31
- return (
32
- <ModeContext.Provider
33
- value={{
34
- mode: overrideMode ?? configuredMode,
35
- configuredMode,
36
- setMode: (m: Mode) => setOverrideMode(m),
37
- resetMode: () => setOverrideMode(null),
38
- }}
39
- >
40
- {children}
41
- </ModeContext.Provider>
42
- )
43
- }
44
-
45
- export function useMode(): ModeContextType {
46
- const context = useContext(ModeContext)
47
- if (!context) {
48
- throw new Error("useMode must be used within a ModeProvider")
49
- }
50
- return context
51
- }
@@ -1,36 +0,0 @@
1
- import React, {
2
- createContext,
3
- useContext,
4
- useState,
5
- type ReactNode,
6
- } from "react"
7
- import type { Screen } from "./useCurrentScreen.js"
8
-
9
- interface PreviousScreenContextType {
10
- previousScreen: Screen | null
11
- setPreviousScreen: (screen: Screen | null) => void
12
- }
13
-
14
- const PreviousScreenContext = createContext<PreviousScreenContextType | null>(
15
- null,
16
- )
17
-
18
- export function PreviousScreenProvider({ children }: { children: ReactNode }) {
19
- const [previousScreen, setPreviousScreen] = useState<Screen | null>(null)
20
-
21
- return React.createElement(
22
- PreviousScreenContext.Provider,
23
- { value: { previousScreen, setPreviousScreen } },
24
- children,
25
- )
26
- }
27
-
28
- export function usePreviousScreen(): PreviousScreenContextType {
29
- const context = useContext(PreviousScreenContext)
30
- if (!context) {
31
- throw new Error(
32
- "usePreviousScreen must be used within a PreviousScreenProvider",
33
- )
34
- }
35
- return context
36
- }
@@ -1,502 +0,0 @@
1
- import { logger } from "../../logger.js"
2
- import { getIntent, executeIntent } from "../../intents.js"
3
- import { trackDepositResilient } from "../../transactionIntent/utils/resilientDepositTracker.js"
4
- import type { TrailsClient } from "../../trailsClient.js"
5
- import { getChainRpcClient } from "../../chains.js"
6
- import { IntentStatus } from "@0xtrails/api"
7
- import { SECOND_MS, HOUR_MS } from "../../utils/time.js"
8
-
9
- const INTENT_STORAGE_KEY = "trails_pending_intents"
10
- const WORKER_INTERVAL = 30 * SECOND_MS // Check every 30 seconds (reduced from 10s to avoid excessive API calls)
11
- const INTENT_EXPIRY_TIME = HOUR_MS // 1 hour in milliseconds
12
-
13
- interface StoredIntent {
14
- intentId: string
15
- timestamp: number
16
- lastCheckTime?: number
17
- }
18
-
19
- interface IntentExecutionWorkerOptions {
20
- trailsClient: TrailsClient
21
- trailsApiKey: string
22
- sequenceIndexerUrl: string
23
- enabled?: boolean
24
- }
25
-
26
- // @preserve - Prevent tree-shaking of this class
27
- export class IntentExecutionWorker {
28
- // biome-ignore lint/correctness/noUnusedPrivateClassMembers: Used in getInstance() and storeIntentForMonitoring()
29
- private static instance: IntentExecutionWorker | null = null
30
- private intervalId: NodeJS.Timeout | null = null
31
- private isRunning = false
32
- private trailsClient: TrailsClient
33
- private trailsApiKey: string
34
- private sequenceIndexerUrl: string
35
- private enabled: boolean
36
- private abortController: AbortController | null = null
37
-
38
- private constructor(options: IntentExecutionWorkerOptions) {
39
- this.trailsClient = options.trailsClient
40
- this.trailsApiKey = options.trailsApiKey
41
- this.sequenceIndexerUrl = options.sequenceIndexerUrl
42
- this.enabled = options.enabled !== false
43
- }
44
-
45
- /**
46
- * Get or create the singleton instance of IntentExecutionWorker
47
- */
48
- static getInstance(
49
- options?: IntentExecutionWorkerOptions,
50
- ): IntentExecutionWorker {
51
- if (!IntentExecutionWorker.instance) {
52
- if (!options) {
53
- throw new Error(
54
- "[trails-sdk][intent-worker] Options required for first initialization",
55
- )
56
- }
57
- logger.console.log(
58
- "[trails-sdk][intent-worker] Creating singleton instance",
59
- )
60
- IntentExecutionWorker.instance = new IntentExecutionWorker(options)
61
- } else if (options) {
62
- // Update the existing instance with new options if provided
63
- logger.console.log(
64
- "[trails-sdk][intent-worker] Updating existing singleton instance",
65
- )
66
- IntentExecutionWorker.instance.updateOptions(options)
67
- }
68
- return IntentExecutionWorker.instance
69
- }
70
-
71
- /**
72
- * Update the worker options (used when re-initializing with new config)
73
- */
74
- // biome-ignore lint/correctness/noUnusedPrivateClassMembers: Used in getInstance() method when updating existing instance
75
- private updateOptions(options: IntentExecutionWorkerOptions): void {
76
- const wasRunning = this.isRunning
77
-
78
- // Stop if running
79
- if (wasRunning) {
80
- this.stop()
81
- }
82
-
83
- // Update options
84
- this.trailsClient = options.trailsClient
85
- this.trailsApiKey = options.trailsApiKey
86
- this.sequenceIndexerUrl = options.sequenceIndexerUrl
87
- this.enabled = options.enabled !== false
88
-
89
- // Restart if was running
90
- if (wasRunning && this.enabled) {
91
- this.start()
92
- }
93
- }
94
-
95
- /**
96
- * Destroy the singleton instance (useful for cleanup/testing)
97
- */
98
- static destroyInstance(): void {
99
- if (IntentExecutionWorker.instance) {
100
- logger.console.log(
101
- "[trails-sdk][intent-worker] Destroying singleton instance",
102
- )
103
- IntentExecutionWorker.instance.stop()
104
- IntentExecutionWorker.instance = null
105
- }
106
- }
107
-
108
- /**
109
- * Start the worker to monitor pending intents
110
- */
111
- start(): void {
112
- if (!this.enabled) {
113
- logger.console.log("[trails-sdk][intent-worker] Worker is disabled")
114
- return
115
- }
116
-
117
- if (this.isRunning) {
118
- logger.console.log(
119
- "[trails-sdk][intent-worker] Worker is already running",
120
- )
121
- return
122
- }
123
-
124
- logger.console.log(
125
- "[trails-sdk][intent-worker] Starting intent execution worker",
126
- )
127
- this.isRunning = true
128
- this.abortController = new AbortController()
129
-
130
- // Run immediately on start
131
- this.checkPendingIntents()
132
-
133
- // Then run periodically
134
- this.intervalId = setInterval(() => {
135
- this.checkPendingIntents()
136
- }, WORKER_INTERVAL)
137
- }
138
-
139
- /**
140
- * Stop the worker
141
- */
142
- stop(): void {
143
- logger.console.log(
144
- "[trails-sdk][intent-worker] Stopping intent execution worker",
145
- )
146
- this.isRunning = false
147
-
148
- if (this.abortController) {
149
- this.abortController.abort()
150
- this.abortController = null
151
- }
152
-
153
- if (this.intervalId) {
154
- clearInterval(this.intervalId)
155
- this.intervalId = null
156
- }
157
- }
158
-
159
- /**
160
- * Check all pending intents and process them if needed
161
- */
162
- private async checkPendingIntents(): Promise<void> {
163
- if (!this.isRunning) return
164
-
165
- try {
166
- const storedIntents = this.getStoredIntents()
167
-
168
- if (storedIntents.length === 0) {
169
- return
170
- }
171
-
172
- logger.console.log(
173
- `[trails-sdk][intent-worker] Checking ${storedIntents.length} pending intents`,
174
- )
175
-
176
- for (const storedIntent of storedIntents) {
177
- if (!this.isRunning || this.abortController?.signal.aborted) break
178
-
179
- try {
180
- await this.processIntent(storedIntent)
181
- } catch (error) {
182
- logger.console.error(
183
- `[trails-sdk][intent-worker] Error processing intent ${storedIntent.intentId}:`,
184
- error,
185
- )
186
- }
187
- }
188
- } catch (error) {
189
- logger.console.error(
190
- "[trails-sdk][intent-worker] Error in checkPendingIntents:",
191
- error,
192
- )
193
- }
194
- }
195
-
196
- /**
197
- * Process a single intent
198
- */
199
- private async processIntent(storedIntent: StoredIntent): Promise<void> {
200
- const now = Date.now()
201
-
202
- // Check if intent has expired
203
- if (now - storedIntent.timestamp > INTENT_EXPIRY_TIME) {
204
- logger.console.log(
205
- `[trails-sdk][intent-worker] Removing expired intent ${storedIntent.intentId}`,
206
- )
207
- this.removeStoredIntent(storedIntent.intentId)
208
- return
209
- }
210
-
211
- // Rate limit checking to avoid too many API calls
212
- if (
213
- storedIntent.lastCheckTime &&
214
- now - storedIntent.lastCheckTime < 5 * SECOND_MS
215
- ) {
216
- return // Skip if checked within last 5 seconds
217
- }
218
-
219
- logger.console.log(
220
- `[trails-sdk][intent-worker] Checking intent ${storedIntent.intentId}`,
221
- )
222
-
223
- try {
224
- // Get current intent status from API
225
- const intentResponse = await getIntent(
226
- this.trailsClient,
227
- storedIntent.intentId,
228
- )
229
-
230
- if (!intentResponse || !intentResponse.intent) {
231
- logger.console.warn(
232
- `[trails-sdk][intent-worker] No intent found for ${storedIntent.intentId}`,
233
- )
234
- this.updateStoredIntent(storedIntent.intentId, { lastCheckTime: now })
235
- return
236
- }
237
-
238
- const intent = intentResponse.intent
239
- const status = intent.status
240
-
241
- logger.console.log(
242
- `[trails-sdk][intent-worker] Intent ${storedIntent.intentId} status: ${status}`,
243
- )
244
-
245
- // Update last check time
246
- this.updateStoredIntent(storedIntent.intentId, {
247
- lastCheckTime: now,
248
- })
249
-
250
- // If not in committed state, check if we should remove it
251
- if (status !== IntentStatus.COMMITTED) {
252
- if (
253
- status === IntentStatus.SUCCEEDED ||
254
- status === IntentStatus.FAILED ||
255
- status === IntentStatus.REFUNDED ||
256
- status === IntentStatus.ABORTED ||
257
- status === IntentStatus.INVALID ||
258
- status === IntentStatus.EXECUTING
259
- ) {
260
- logger.console.log(
261
- `[trails-sdk][intent-worker] Removing intent ${storedIntent.intentId} with final status: ${status}`,
262
- )
263
- this.removeStoredIntent(storedIntent.intentId)
264
- }
265
- return
266
- }
267
-
268
- // Intent is in committed state - check for deposit transaction
269
- logger.console.log(
270
- `[trails-sdk][intent-worker] Checking for deposit transaction for intent ${storedIntent.intentId}`,
271
- )
272
-
273
- // Get the intent details we need for tracking
274
- const originChainId = Number(intent.quoteRequest.originChainId)
275
- const originIntentAddress = intent.originIntentAddress
276
- const originTokenAddress = intent.quoteRequest.originTokenAddress
277
- const depositAmount =
278
- intent.quoteRequest.originTokenAmount?.toString() || "0"
279
-
280
- const publicClient = getChainRpcClient(originChainId)
281
-
282
- // Track deposit using resilient tracker
283
- const depositReceipt = await trackDepositResilient({
284
- publicClient,
285
- originChainId,
286
- originIntentAddress,
287
- originTokenAddress,
288
- depositAmount,
289
- abortSignal: this.abortController?.signal,
290
- sequenceProjectAccessKey: this.trailsApiKey,
291
- sequenceIndexerUrl: this.sequenceIndexerUrl,
292
- maxRetries: 1, // Just check once, don't wait
293
- })
294
-
295
- if (depositReceipt) {
296
- logger.console.log(
297
- `[trails-sdk][intent-worker] Found deposit transaction for intent ${storedIntent.intentId}:`,
298
- depositReceipt.transactionHash,
299
- )
300
-
301
- // Execute the intent with the deposit transaction hash
302
- try {
303
- const executeResponse = await executeIntent(
304
- this.trailsClient,
305
- storedIntent.intentId,
306
- depositReceipt.transactionHash,
307
- )
308
-
309
- logger.console.log(
310
- `[trails-sdk][intent-worker] Successfully executed intent ${storedIntent.intentId}:`,
311
- executeResponse,
312
- )
313
-
314
- // Remove from storage after successful execution
315
- this.removeStoredIntent(storedIntent.intentId)
316
- } catch (executeError) {
317
- logger.console.error(
318
- `[trails-sdk][intent-worker] Failed to execute intent ${storedIntent.intentId}:`,
319
- executeError,
320
- )
321
- // Keep in storage to retry later
322
- this.updateStoredIntent(storedIntent.intentId, { lastCheckTime: now })
323
- }
324
- } else {
325
- // No deposit found yet, update check time
326
- this.updateStoredIntent(storedIntent.intentId, { lastCheckTime: now })
327
- }
328
- } catch (error) {
329
- logger.console.error(
330
- `[trails-sdk][intent-worker] Error processing intent ${storedIntent.intentId}:`,
331
- error,
332
- )
333
- this.updateStoredIntent(storedIntent.intentId, { lastCheckTime: now })
334
- }
335
- }
336
-
337
- /**
338
- * Store an intent ID for monitoring
339
- * @preserve
340
- */
341
- static storeIntentForMonitoring(intentId: string): void {
342
- try {
343
- logger.console.log(
344
- `[trails-sdk][intent-worker] storeIntentForMonitoring called with intentId: ${intentId}`,
345
- )
346
-
347
- const storedIntent: StoredIntent = {
348
- intentId,
349
- timestamp: Date.now(),
350
- }
351
-
352
- const existingIntents = IntentExecutionWorker.getStoredIntentsStatic()
353
-
354
- logger.console.log(
355
- `[trails-sdk][intent-worker] Current stored intents:`,
356
- existingIntents,
357
- )
358
-
359
- // Check if intent already exists
360
- const existingIndex = existingIntents.findIndex(
361
- (i) => i.intentId === intentId,
362
- )
363
- if (existingIndex >= 0) {
364
- // Update existing intent
365
- logger.console.log(
366
- `[trails-sdk][intent-worker] Updating existing intent at index ${existingIndex}`,
367
- )
368
- existingIntents[existingIndex] = storedIntent
369
- } else {
370
- // Add new intent
371
- logger.console.log(
372
- `[trails-sdk][intent-worker] Adding new intent to storage`,
373
- )
374
- existingIntents.push(storedIntent)
375
- }
376
-
377
- localStorage.setItem(INTENT_STORAGE_KEY, JSON.stringify(existingIntents))
378
-
379
- // Verify it was actually stored
380
- const verifyStored = localStorage.getItem(INTENT_STORAGE_KEY)
381
- logger.console.log(
382
- `[trails-sdk][intent-worker] Verification - localStorage content after storing:`,
383
- verifyStored,
384
- )
385
-
386
- logger.console.log(
387
- `[trails-sdk][intent-worker] Successfully stored intent ${intentId} for monitoring. Total intents: ${existingIntents.length}`,
388
- )
389
-
390
- // Check if the singleton worker exists and is running
391
- // This ensures the worker is available to process stored intents
392
- if (!IntentExecutionWorker.instance) {
393
- logger.console.warn(
394
- "[trails-sdk][intent-worker] Worker singleton not initialized. Intent stored but won't be processed until TrailsProvider initializes the worker.",
395
- )
396
- } else if (!IntentExecutionWorker.instance.isRunning) {
397
- logger.console.log(
398
- "[trails-sdk][intent-worker] Starting worker to process stored intent",
399
- )
400
- IntentExecutionWorker.instance.start()
401
- }
402
- } catch (error) {
403
- logger.console.error(
404
- "[trails-sdk][intent-worker] Failed to store intent for monitoring:",
405
- error,
406
- )
407
- }
408
- }
409
-
410
- /**
411
- * Get stored intents (static version for external use)
412
- */
413
- // biome-ignore lint/correctness/noUnusedPrivateClassMembers: Used in storeIntentForMonitoring() and getStoredIntents() methods
414
- private static getStoredIntentsStatic(): StoredIntent[] {
415
- try {
416
- const stored = localStorage.getItem(INTENT_STORAGE_KEY)
417
- if (!stored) return []
418
-
419
- const intents = JSON.parse(stored) as StoredIntent[]
420
- return Array.isArray(intents) ? intents : []
421
- } catch (error) {
422
- logger.console.error(
423
- "[trails-sdk][intent-worker] Failed to retrieve stored intents:",
424
- error,
425
- )
426
- return []
427
- }
428
- }
429
-
430
- /**
431
- * Get stored intents
432
- */
433
- private getStoredIntents(): StoredIntent[] {
434
- return IntentExecutionWorker.getStoredIntentsStatic()
435
- }
436
-
437
- /**
438
- * Update a stored intent
439
- */
440
- private updateStoredIntent(
441
- intentId: string,
442
- updates: Partial<Omit<StoredIntent, "intentId">>,
443
- ): void {
444
- try {
445
- const intents = this.getStoredIntents()
446
- const index = intents.findIndex((i) => i.intentId === intentId)
447
-
448
- if (index >= 0 && intents[index]) {
449
- const existingIntent = intents[index]
450
- intents[index] = {
451
- ...existingIntent,
452
- ...updates,
453
- intentId: existingIntent.intentId,
454
- timestamp: existingIntent.timestamp,
455
- }
456
- localStorage.setItem(INTENT_STORAGE_KEY, JSON.stringify(intents))
457
- }
458
- } catch (error) {
459
- logger.console.error(
460
- `[trails-sdk][intent-worker] Failed to update intent ${intentId}:`,
461
- error,
462
- )
463
- }
464
- }
465
-
466
- /**
467
- * Remove a stored intent
468
- */
469
- private removeStoredIntent(intentId: string): void {
470
- try {
471
- const intents = this.getStoredIntents()
472
- const filtered = intents.filter((i) => i.intentId !== intentId)
473
- localStorage.setItem(INTENT_STORAGE_KEY, JSON.stringify(filtered))
474
-
475
- logger.console.log(
476
- `[trails-sdk][intent-worker] Removed intent ${intentId} from monitoring`,
477
- )
478
- } catch (error) {
479
- logger.console.error(
480
- `[trails-sdk][intent-worker] Failed to remove intent ${intentId}:`,
481
- error,
482
- )
483
- }
484
- }
485
-
486
- /**
487
- * Clear all stored intents (useful for cleanup/testing)
488
- */
489
- static clearAllStoredIntents(): void {
490
- try {
491
- localStorage.removeItem(INTENT_STORAGE_KEY)
492
- logger.console.log(
493
- "[trails-sdk][intent-worker] Cleared all stored intents",
494
- )
495
- } catch (error) {
496
- logger.console.error(
497
- "[trails-sdk][intent-worker] Failed to clear stored intents:",
498
- error,
499
- )
500
- }
501
- }
502
- }