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.
- package/dist/abis/trailsHydrate.d.ts.map +1 -1
- package/dist/analytics.d.ts +41 -0
- package/dist/analytics.d.ts.map +1 -1
- package/dist/{ccip-62W6LwH2.js → ccip-Cg9-lJ6K.js} +16 -16
- package/dist/chainSwitch.d.ts.map +1 -1
- package/dist/chains.d.ts +9 -3
- package/dist/chains.d.ts.map +1 -1
- package/dist/error.d.ts +1 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/{index-C0QTNYIA.js → index-DEojZg7b.js} +50431 -50424
- package/dist/index.d.ts +1 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +377 -421
- package/dist/intentReceiptPoller.d.ts.map +1 -1
- package/dist/intents.d.ts +1 -3
- package/dist/intents.d.ts.map +1 -1
- package/dist/mutations.d.ts +1 -4
- package/dist/mutations.d.ts.map +1 -1
- package/dist/prepareSend.d.ts.map +1 -1
- package/dist/query/balance.hooks.d.ts.map +1 -1
- package/dist/query/chains.hooks.d.ts.map +1 -1
- package/dist/query/chains.queries.d.ts +4 -1
- package/dist/query/chains.queries.d.ts.map +1 -1
- package/dist/queryParams.d.ts.map +1 -1
- package/dist/recover.d.ts.map +1 -1
- package/dist/tokens.d.ts.map +1 -1
- package/dist/transactionIntent/deposits/depositOrchestrator.d.ts.map +1 -1
- package/dist/transactionIntent/deposits/gaslessDeposit.d.ts.map +1 -1
- package/dist/transactionIntent/deposits/standardDeposit.d.ts +1 -7
- package/dist/transactionIntent/deposits/standardDeposit.d.ts.map +1 -1
- package/dist/transactionIntent/handlers/intentHandler.d.ts.map +1 -1
- package/dist/transactionIntent/helpers/transactionStateHelpers.d.ts +10 -1
- package/dist/transactionIntent/helpers/transactionStateHelpers.d.ts.map +1 -1
- package/dist/transactionIntent/types.d.ts +3 -6
- package/dist/transactionIntent/types.d.ts.map +1 -1
- package/dist/transactionIntent/utils/resilientDepositTracker.d.ts +3 -3
- package/dist/transactionIntent/utils/resilientDepositTracker.d.ts.map +1 -1
- package/dist/transactions.d.ts +2 -0
- package/dist/transactions.d.ts.map +1 -1
- package/dist/umd/trails.min.js +200 -200
- package/dist/walletUtils.d.ts +4 -0
- package/dist/walletUtils.d.ts.map +1 -1
- package/dist/wallets.d.ts +2 -1
- package/dist/wallets.d.ts.map +1 -1
- package/dist/widget/components/AccountActionsDropdown.d.ts.map +1 -1
- package/dist/widget/components/AccountIntentTransactionHistoryButton.d.ts.map +1 -1
- package/dist/widget/components/AccountSettings.d.ts.map +1 -1
- package/dist/widget/components/ClassicSwap.d.ts.map +1 -1
- package/dist/widget/components/ConnectWallet.d.ts.map +1 -1
- package/dist/widget/components/ConnectedWallets.d.ts +5 -1
- package/dist/widget/components/ConnectedWallets.d.ts.map +1 -1
- package/dist/widget/components/DepositTracker.d.ts +1 -1
- package/dist/widget/components/DepositTracker.d.ts.map +1 -1
- package/dist/widget/components/DirectTransfer.d.ts +0 -8
- package/dist/widget/components/DirectTransfer.d.ts.map +1 -1
- package/dist/widget/components/Fund.d.ts +1 -1
- package/dist/widget/components/Fund.d.ts.map +1 -1
- package/dist/widget/components/FundMethods.d.ts.map +1 -1
- package/dist/widget/components/FundWalletSelection.d.ts +0 -8
- package/dist/widget/components/FundWalletSelection.d.ts.map +1 -1
- package/dist/widget/components/FundingMethodSelectorButton.d.ts +1 -1
- package/dist/widget/components/FundingMethodSelectorButton.d.ts.map +1 -1
- package/dist/widget/components/MeldStepsFlow.d.ts.map +1 -1
- package/dist/widget/components/OnrampErrorScreen.d.ts.map +1 -1
- package/dist/widget/components/OnrampPaymentMethods.d.ts.map +1 -1
- package/dist/widget/components/OnrampProviderConfirmation.d.ts +0 -6
- package/dist/widget/components/OnrampProviderConfirmation.d.ts.map +1 -1
- package/dist/widget/components/Pay.d.ts.map +1 -1
- package/dist/widget/components/QrCode.d.ts.map +1 -1
- package/dist/widget/components/QuoteDetails.d.ts.map +1 -1
- package/dist/widget/components/Receipt.d.ts.map +1 -1
- package/dist/widget/components/ReceiptRecoverableFunds.d.ts +25 -0
- package/dist/widget/components/ReceiptRecoverableFunds.d.ts.map +1 -0
- package/dist/widget/components/RecipientSelectorButton.d.ts +3 -1
- package/dist/widget/components/RecipientSelectorButton.d.ts.map +1 -1
- package/dist/widget/components/Recipients.d.ts.map +1 -1
- package/dist/widget/components/Swap.d.ts +2 -16
- package/dist/widget/components/Swap.d.ts.map +1 -1
- package/dist/widget/components/TokenSelector.d.ts.map +1 -1
- package/dist/widget/components/TransactionDetails.d.ts.map +1 -1
- package/dist/widget/components/TransactionHistoryItem.d.ts.map +1 -1
- package/dist/widget/components/TransferPendingVertical.d.ts.map +1 -1
- package/dist/widget/components/TruncatedTransactionHash.d.ts.map +1 -1
- package/dist/widget/components/WalletConfirmation.d.ts.map +1 -1
- package/dist/widget/components/WalletConnect.d.ts.map +1 -1
- package/dist/widget/components/WidgetProviders.d.ts.map +1 -1
- package/dist/widget/components/Withdraw.d.ts.map +1 -1
- package/dist/widget/css/compiled.css +1 -1
- package/dist/widget/hooks/useClickTracking.d.ts.map +1 -1
- package/dist/widget/hooks/useDebugScreens.d.ts +1 -10
- package/dist/widget/hooks/useDebugScreens.d.ts.map +1 -1
- package/dist/widget/hooks/useDepositMonitor.d.ts +2 -4
- package/dist/widget/hooks/useDepositMonitor.d.ts.map +1 -1
- package/dist/widget/hooks/useExternalFundingReceiptSync.d.ts +11 -0
- package/dist/widget/hooks/useExternalFundingReceiptSync.d.ts.map +1 -0
- package/dist/widget/hooks/useIntentReceiptBalances.d.ts +16 -0
- package/dist/widget/hooks/useIntentReceiptBalances.d.ts.map +1 -0
- package/dist/widget/hooks/useQuote.d.ts +0 -4
- package/dist/widget/hooks/useQuote.d.ts.map +1 -1
- package/dist/widget/hooks/useScreenTracking.d.ts +2 -0
- package/dist/widget/hooks/useScreenTracking.d.ts.map +1 -0
- package/dist/widget/hooks/useSelectedFundMethod.d.ts +0 -2
- package/dist/widget/hooks/useSelectedFundMethod.d.ts.map +1 -1
- package/dist/widget/hooks/useSendForm.d.ts +0 -4
- package/dist/widget/hooks/useSendForm.d.ts.map +1 -1
- package/dist/widget/hooks/useTokenList.d.ts.map +1 -1
- package/dist/widget/hooks/useTrailsSendTransaction.d.ts.map +1 -1
- package/dist/widget/hooks/useViewManager.d.ts +89 -0
- package/dist/widget/hooks/useViewManager.d.ts.map +1 -0
- package/dist/widget/hooks/useWalletConnectUri.d.ts.map +1 -1
- package/dist/widget/hooks/useWalletConnectionContext.d.ts +1 -1
- package/dist/widget/hooks/useWalletConnectionContext.d.ts.map +1 -1
- package/dist/widget/index.d.ts +1 -1
- package/dist/widget/index.d.ts.map +1 -1
- package/dist/widget/index.js +7 -6
- package/dist/widget/providers/TrailsProvider.d.ts.map +1 -1
- package/dist/widget/types/commonProps.d.ts +1 -6
- package/dist/widget/types/commonProps.d.ts.map +1 -1
- package/dist/widget/utils/forexRateStore.d.ts.map +1 -1
- package/dist/widget/utils/fundMethodSwitchState.d.ts +10 -0
- package/dist/widget/utils/fundMethodSwitchState.d.ts.map +1 -0
- package/dist/widget/utils/localeStore.d.ts.map +1 -1
- package/dist/widget/utils/viewManagerGuards.d.ts +5 -0
- package/dist/widget/utils/viewManagerGuards.d.ts.map +1 -0
- package/dist/widget/widget.d.ts +23 -2
- package/dist/widget/widget.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/abis/trailsHydrate.ts +2 -1
- package/src/analytics.ts +60 -0
- package/src/chainSwitch.ts +11 -8
- package/src/chains.ts +82 -37
- package/src/constants.ts +2 -2
- package/src/error.ts +8 -0
- package/src/index.ts +1 -12
- package/src/intentReceiptPoller.ts +27 -0
- package/src/intents.ts +36 -87
- package/src/mutations.ts +11 -102
- package/src/onramp-client/index.ts +3 -3
- package/src/prepareSend.ts +6 -2
- package/src/query/balance.hooks.ts +31 -10
- package/src/query/chains.hooks.ts +7 -1
- package/src/query/chains.queries.ts +8 -5
- package/src/queryParams.ts +8 -6
- package/src/recover.ts +9 -9
- package/src/tokens.ts +4 -2
- package/src/transactionIntent/deposits/depositOrchestrator.ts +0 -2
- package/src/transactionIntent/deposits/gaslessDeposit.ts +8 -0
- package/src/transactionIntent/deposits/standardDeposit.ts +25 -35
- package/src/transactionIntent/handlers/intentHandler.ts +234 -138
- package/src/transactionIntent/helpers/transactionStateHelpers.ts +108 -1
- package/src/transactionIntent/types.ts +14 -8
- package/src/transactionIntent/utils/resilientDepositTracker.ts +72 -183
- package/src/transactions.ts +16 -0
- package/src/walletUtils.ts +188 -1
- package/src/wallets.ts +50 -15
- package/src/widget/compiled.css +1 -1
- package/src/widget/components/AccountActionsDropdown.tsx +4 -6
- package/src/widget/components/AccountIntentTransactionHistoryButton.tsx +4 -6
- package/src/widget/components/AccountSettings.tsx +36 -22
- package/src/widget/components/ClassicSwap.tsx +67 -9
- package/src/widget/components/ConnectWallet.tsx +5 -7
- package/src/widget/components/ConnectedWallets.tsx +143 -82
- package/src/widget/components/DepositTracker.tsx +4 -5
- package/src/widget/components/DirectTransfer.tsx +85 -84
- package/src/widget/components/Earn.tsx +3 -3
- package/src/widget/components/Fund.tsx +90 -17
- package/src/widget/components/FundMethods.tsx +77 -43
- package/src/widget/components/FundWalletSelection.tsx +13 -397
- package/src/widget/components/FundingMethodSelectorButton.tsx +11 -10
- package/src/widget/components/MeldStepsFlow.tsx +64 -30
- package/src/widget/components/OnrampErrorScreen.tsx +2 -18
- package/src/widget/components/OnrampPaymentMethods.tsx +4 -6
- package/src/widget/components/OnrampProviderConfirmation.tsx +91 -110
- package/src/widget/components/OriginTransferInformation.tsx +2 -2
- package/src/widget/components/Pay.tsx +27 -7
- package/src/widget/components/PaymentMethods.tsx +10 -10
- package/src/widget/components/PoolDeposit.tsx +2 -2
- package/src/widget/components/QrCode.tsx +13 -11
- package/src/widget/components/QuoteDetails.tsx +16 -6
- package/src/widget/components/Receipt.tsx +66 -6
- package/src/widget/components/ReceiptRecoverableFunds.tsx +135 -0
- package/src/widget/components/RecipientSelectorButton.tsx +6 -17
- package/src/widget/components/Recipients.tsx +38 -29
- package/src/widget/components/Swap.tsx +2 -25
- package/src/widget/components/TokenList.tsx +2 -2
- package/src/widget/components/TokenSelector.tsx +11 -11
- package/src/widget/components/TokenSelectorButton.tsx +3 -3
- package/src/widget/components/TrailsHookModal.tsx +1 -1
- package/src/widget/components/TransactionDetails.tsx +43 -37
- package/src/widget/components/TransactionHistoryItem.tsx +1 -42
- package/src/widget/components/TransferPendingVertical.tsx +11 -4
- package/src/widget/components/TruncatedTransactionHash.tsx +5 -0
- package/src/widget/components/WalletConfirmation.tsx +5 -8
- package/src/widget/components/WalletConnect.tsx +6 -2
- package/src/widget/components/WidgetProviders.tsx +34 -43
- package/src/widget/components/Withdraw.tsx +25 -11
- package/src/widget/hooks/useClickTracking.ts +5 -0
- package/src/widget/hooks/useDebugScreens.ts +40 -86
- package/src/widget/hooks/useDepositMonitor.ts +14 -149
- package/src/widget/hooks/useExternalFundingReceiptSync.ts +79 -0
- package/src/widget/hooks/useIntentReceiptBalances.ts +141 -0
- package/src/widget/hooks/useQuote.ts +7 -16
- package/src/widget/hooks/useScreenTracking.ts +14 -0
- package/src/widget/hooks/useSelectedFundMethod.tsx +0 -5
- package/src/widget/hooks/useSendForm.ts +5 -14
- package/src/widget/hooks/useTokenList.ts +3 -16
- package/src/widget/hooks/useTrailsSendTransaction.ts +1 -5
- package/src/widget/hooks/useViewManager.tsx +505 -0
- package/src/widget/hooks/useWalletConnectUri.tsx +77 -18
- package/src/widget/hooks/useWalletConnectionContext.tsx +1 -1
- package/src/widget/index.tsx +1 -0
- package/src/widget/providers/TrailsProvider.tsx +0 -41
- package/src/widget/styles.ts +1 -1
- package/src/widget/types/commonProps.ts +0 -8
- package/src/widget/utils/forexRateStore.ts +0 -2
- package/src/widget/utils/fundMethodSwitchState.ts +25 -0
- package/src/widget/utils/localeStore.ts +0 -1
- package/src/widget/utils/viewManagerGuards.ts +49 -0
- package/src/widget/widget.tsx +405 -316
- package/dist/intentStorage.d.ts +0 -24
- package/dist/intentStorage.d.ts.map +0 -1
- package/dist/mode.d.ts +0 -2
- package/dist/mode.d.ts.map +0 -1
- package/dist/widget/hooks/useBack.d.ts +0 -22
- package/dist/widget/hooks/useBack.d.ts.map +0 -1
- package/dist/widget/hooks/useCurrentScreen.d.ts +0 -13
- package/dist/widget/hooks/useCurrentScreen.d.ts.map +0 -1
- package/dist/widget/hooks/useInitialRedirect.d.ts +0 -7
- package/dist/widget/hooks/useInitialRedirect.d.ts.map +0 -1
- package/dist/widget/hooks/useMode.d.ts +0 -20
- package/dist/widget/hooks/useMode.d.ts.map +0 -1
- package/dist/widget/hooks/usePreviousScreen.d.ts +0 -12
- package/dist/widget/hooks/usePreviousScreen.d.ts.map +0 -1
- package/dist/widget/workers/intentExecutionWorker.d.ts +0 -73
- package/dist/widget/workers/intentExecutionWorker.d.ts.map +0 -1
- package/src/intentStorage.ts +0 -106
- package/src/mode.ts +0 -1
- package/src/widget/hooks/useBack.tsx +0 -210
- package/src/widget/hooks/useCurrentScreen.tsx +0 -73
- package/src/widget/hooks/useInitialRedirect.tsx +0 -70
- package/src/widget/hooks/useMode.tsx +0 -51
- package/src/widget/hooks/usePreviousScreen.ts +0 -36
- 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
|
-
}
|