Skip to content

Latest commit

 

History

History
478 lines (352 loc) · 15.5 KB

File metadata and controls

478 lines (352 loc) · 15.5 KB

OperationTracker Class

Table of Contents


Overview

OperationTracker allows monitoring the lifecycle of cross-chain transactions between TON and TAC.
It queries multiple Lite Sequencer endpoints for status updates, execution breakdowns, and operation IDs associated with TON transactions, providing automatic failover if one endpoint fails.


How Tracking Works

After calling TacSdk.sendCrossChainTransaction(...), a TransactionLinker object is returned.
This linker allows tracking status of the operation through these steps:

  1. Use getOperationId(linker) to fetch the cross-chain operation ID.
  2. Use getOperationStatus(...) or getSimplifiedOperationStatus(...) to get the current state.
  3. For debugging or performance profiling, use getStageProfiling(...).

For automated polling, use startTracking() which handles all the above and prints status updates.


Getting Started

Constructor

new OperationTracker(
  network: Network,
  customLiteSequencerEndpoints?: string[],
  logger?: ILogger,
  clientFactory?: ILiteSequencerClientFactory
)

Creates a new OperationTracker instance.

Parameters:

  • network: Network type (TESTNET or MAINNET)
  • customLiteSequencerEndpoints (optional): Custom sequencer endpoints. If not provided, uses default endpoints for the network
  • logger (optional): Logger implementation (defaults to NoopLogger)
  • clientFactory (optional): Factory for creating sequencer clients (defaults to DefaultLiteSequencerClientFactory)

Example Usage

import { OperationTracker, Network } from "@tonappchain/sdk";
import { ConsoleLogger } from "@tonappchain/sdk";

// Basic usage with defaults
const tracker = new OperationTracker(Network.TESTNET);

// With custom endpoints and logging
const trackerWithOptions = new OperationTracker(
  Network.TESTNET,
  ["https://your-sequencer.com"], // customLiteSequencerEndpoints
  new ConsoleLogger(), // logger
  // clientFactory (optional)
);

Architecture

OperationTracker implements the IOperationTracker interface and uses multiple ILiteSequencerClient instances internally to provide high availability and automatic failover.

Key Components

ILiteSequencerClientFactory

Factory interface for creating sequencer clients. The default implementation (DefaultLiteSequencerClientFactory) creates LiteSequencerClient instances.

ILiteSequencerClient

Interface that defines the operations supported by sequencer clients:

  • getOperationType(operationId: string): Promise<OperationType>
  • getOperationId(transactionLinker: TransactionLinker): Promise<string>
  • getOperationIdByTransactionHash(transactionHash: string): Promise<string>
  • getOperationIdsByShardsKeys(shardsKeys: string[], caller: string, chunkSize?: number): Promise<OperationIdsByShardsKey>
  • getStageProfilings(operationIds: string[], chunkSize?: number): Promise<ExecutionStagesByOperationId>
  • getOperationStatuses(operationIds: string[], chunkSize?: number): Promise<StatusInfosByOperationId>

Failover Strategy

  1. Each endpoint is wrapped in its own ILiteSequencerClient implementation
  2. Requests are tried on each client in sequence until one succeeds
  3. If all clients fail, an AllEndpointsFailedError is thrown

This architecture provides:

  • High Availability: Automatic failover if an endpoint is down
  • Load Distribution: Requests spread across multiple endpoints
  • Testability: Interface-based design allows for easy mocking and testing
  • Consistent Interface: Same API regardless of endpoint availability

For more details about the underlying client, see LiteSequencerClient.


Waiting for Results

All methods in OperationTracker support an optional waitOptions parameter that enables automatic retrying and waiting for successful results:

interface WaitOptions<T = unknown, TContext = unknown> {
    /**
     * Timeout in milliseconds
     * @default 300000 (5 minutes)
     */
    timeout?: number;
    /**
     * Maximum number of attempts
     * @default 30
     */
    maxAttempts?: number;
    /**
     * Delay between attempts in milliseconds
     * @default 10000 (10 seconds)
     */
    delay?: number;
    /**
     * Logger
     */
    logger?: ILogger;
    /**
     * Optional context object to pass additional parameters to callbacks
     * This allows passing custom data like OperationTracker instances, configurations, etc.
     */
    context?: TContext;
    /**
     * Function to check if the result is successful
     * If not provided, any non-error result is considered successful
     */
    successCheck?: (result: T, context?: TContext) => boolean;
    /**
     * Custom callback function that executes when operation is successful
     * Receives both the result and optional context with additional parameters
     * Can be used for additional processing like profiling data retrieval
     */
    onSuccess?: (result: T, context?: TContext) => Promise<void> | void;
    /**
     * Include underlying stack trace in FetchError.innerStack when all endpoints fail
     * @default false
     */
    includeErrorTrace?: boolean;
}

Default Retry Behavior

When waitOptions is not specified (undefined): All OperationTracker methods automatically use default retry settings:

  • timeout: 300000ms (5 minutes) - from DEFAULT_WAIT_TIMEOUT_MS
  • maxAttempts: 30 - from DEFAULT_WAIT_MAX_ATTEMPTS
  • delay: 10000ms (10 seconds) - from DEFAULT_WAIT_DELAY_MS
  • Logger from the OperationTracker instance is automatically passed

This ensures resilient behavior against rate limits and temporary network issues.

Disabling Retries

To disable retry behavior and use a single attempt, explicitly pass null:

// Single attempt, no retries
await tracker.getOperationId(linker, null);

Custom Retry Configuration

To customize retry behavior, pass a WaitOptions object:

// Custom retry settings
await tracker.getOperationId(linker, {
    maxAttempts: 5,
    delay: 2000,
    timeout: 60000
});

Usage Examples

For comprehensive examples and usage patterns, including detailed context parameter usage, see the Enhanced WaitOptions Examples documentation.


Tracking by Transaction Link

getOperationId

getOperationId(
    transactionLinker: TransactionLinker,
    waitOptions?: WaitOptions<string> | null
): Promise<string>

Fetches the cross-chain operationId based on a transaction linker. Tries each endpoint in sequence until successful.

Parameters:

  • transactionLinker: Transaction linker object containing sharding information
  • waitOptions (optional):
    • undefined (default): Uses default retry settings (30 attempts, 10s delay, 5min timeout)
    • null: Single attempt, no retries
    • WaitOptions object: Custom retry configuration

Returns: Operation ID string (empty string if not found)

Note: Returns an empty string if the operation ID has not been assigned yet. Use waitOptions with a custom successCheck to wait for a non-empty result.


getOperationIdByTransactionHash

getOperationIdByTransactionHash(
    transactionHash: string,
    waitOptions?: WaitOptions<string>
): Promise<string>

Fetches the cross-chain operationId by a transaction hash. The hash can be either an ETH-style hash (0x... 32 bytes) or a TON hash. The tracker automatically routes the request to the correct underlying API.

Parameters:

  • transactionHash: TAC (EVM) or TON transaction hash
  • waitOptions (optional): Wait configuration for automatic retrying

Returns: Operation ID string (empty string if not found)

Note: Returns an empty string if the operation ID has not been assigned yet. Use waitOptions with a custom successCheck to wait for a non-empty result.


getSimplifiedOperationStatus

getSimplifiedOperationStatus(transactionLinker: TransactionLinker): Promise<SimplifiedStatuses>

Gets a simplified status for an operation based on its transaction linker. This method combines multiple queries internally to determine the overall operation state.

Parameters:

  • transactionLinker: Transaction linker object containing sharding information

Returns: SimplifiedStatuses

Status Logic:

  • OPERATION_ID_NOT_FOUND: Operation ID not yet assigned
  • PENDING: Operation type is PENDING or UNKNOWN
  • FAILED: Operation type is ROLLBACK
  • SUCCESSFUL: Operation completed successfully

Internal Process:

  1. Fetches operation ID using the transaction linker
  2. If no operation ID, returns OPERATION_ID_NOT_FOUND
  3. Fetches operation type
  4. Maps operation type to simplified status

Detailed Operation Info

getOperationStatus

getOperationStatus(
    operationId: string,
    waitOptions?: WaitOptions<StatusInfo>
): Promise<StatusInfo>

Retrieves detailed status information for a single operation.

Parameters:

  • operationId: The operation ID to query
  • waitOptions (optional): Wait configuration for automatic retrying

Returns: StatusInfo

Note: This method internally calls getOperationStatuses with a single operation ID and extracts the result.

getOperationStatuses

getOperationStatuses(
    operationIds: string[],
    waitOptions?: WaitOptions<StatusInfosByOperationId>,
    chunkSize?: number
): Promise<StatusInfosByOperationId>

Retrieves status information for multiple operations in a single call. Processes requests in chunks for better performance.

Parameters:

  • operationIds: Array of operation IDs to query
  • waitOptions (optional): Wait configuration for automatic retrying
  • chunkSize (optional): Number of items to process per request (default: 100)

Returns: StatusInfosByOperationId


Execution Profiling

getStageProfiling

getStageProfiling(
    operationId: string,
    waitOptions?: WaitOptions<ExecutionStages>
): Promise<ExecutionStages>

Retrieves detailed execution stage information for a single operation. Useful for debugging or understanding delays in cross-chain flow.

Parameters:

  • operationId: The operation ID to query
  • waitOptions (optional): Wait configuration for automatic retrying

Returns: ExecutionStages

Note: This method internally calls getStageProfilings with a single operation ID and extracts the result.


getStageProfilings

getStageProfilings(
    operationIds: string[],
    waitOptions?: WaitOptions<ExecutionStagesByOperationId>,
    chunkSize?: number
): Promise<ExecutionStagesByOperationId>

Retrieves execution stage profiling information for multiple operations. Processes requests in chunks for better performance.

Parameters:

  • operationIds: Array of operation IDs to query
  • waitOptions (optional): Wait configuration for automatic retrying
  • chunkSize (optional): Number of items to process per request (default: 100)

Returns: ExecutionStagesByOperationId


Other Metadata

getOperationType

getOperationType(
    operationId: string,
    waitOptions?: WaitOptions<OperationType>
): Promise<OperationType>

Retrieves the operation type classification for a given operation ID.

Parameters:

  • operationId: The operation ID to query
  • waitOptions (optional): Wait configuration for automatic retrying

Returns: OperationType


getOperationIdsByShardsKeys

getOperationIdsByShardsKeys(
    shardsKeys: string[],
    caller: string,
    waitOptions?: WaitOptions<OperationIdsByShardsKey>,
    chunkSize?: number
): Promise<OperationIdsByShardsKey>

Maps TON shard keys (with caller address) to operation IDs. Processes requests in chunks for better performance.

Parameters:

  • shardsKeys: Array of shard keys to query
  • caller: Caller's address
  • waitOptions (optional): Wait configuration for automatic retrying
  • chunkSize (optional): Number of items to process per request (default: 100)

Returns: OperationIdsByShardsKey


convertCurrency

convertCurrency(
    params: ConvertCurrencyParams,
    waitOptions?: WaitOptions<ConvertedCurrencyResult>
): Promise<ConvertedCurrencyResult>

Converts currency amount using the tracker service with automatic failover across multiple sequencer endpoints.

Parameters:

  • params: ConvertCurrencyParams - Parameters for currency conversion
  • waitOptions (optional): Wait configuration for automatic retrying

Returns: ConvertedCurrencyResult


simulateTACMessage

simulateTACMessage(
    params: TACSimulationParams,
    waitOptions?: WaitOptions<TACSimulationResult>
): Promise<TACSimulationResult>

Simulates TAC message execution without broadcasting it on-chain. Useful for estimating fees and validating transaction inputs before sending real transactions.

Parameters:

  • params: TACSimulationParams - Simulation request with encoded message and context
  • waitOptions (optional): Wait configuration for automatic retrying

Returns: TACSimulationResult


getTVMExecutorFee

getTVMExecutorFee(
    params: GetTVMExecutorFeeParams,
    waitOptions?: WaitOptions<SuggestedTVMExecutorFee>
): Promise<SuggestedTVMExecutorFee>

Calculates suggested TVM executor fee for cross-chain operations with automatic failover across multiple sequencer endpoints.

Parameters:

  • params: GetTVMExecutorFeeParams - Parameters for fee calculation
  • waitOptions (optional): Wait configuration for automatic retrying

Returns: SuggestedTVMExecutorFee