@tonappchain/sdk 0.7.2-alpha-20 → 0.7.2-alpha-22

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.
@@ -62,9 +62,9 @@ export declare abstract class BaseContractOpener implements ContractOpener {
62
62
  */
63
63
  private findTransactionByHashType;
64
64
  /**
65
- * Retry lookup for root transaction because it may appear in indexers with a delay.
65
+ * Find transaction with retry logic
66
66
  */
67
- private findRootTransactionWithRetry;
67
+ private findTransactionWithRetry;
68
68
  /**
69
69
  * Track transaction tree and validate all transactions
70
70
  */
@@ -293,46 +293,31 @@ class BaseContractOpener {
293
293
  }
294
294
  }
295
295
  /**
296
- * Retry lookup for root transaction because it may appear in indexers with a delay.
296
+ * Find transaction with retry logic
297
297
  */
298
- async findRootTransactionWithRetry(address, hash, hashType, limit, maxScannedTransactions, waitForRootTransaction) {
299
- if (!waitForRootTransaction) {
300
- return this.findTransactionByHashType(address, hash, hashType, {
301
- limit,
302
- archival: true,
303
- maxScannedTransactions,
304
- });
305
- }
306
- const attempts = Math.ceil(Consts_1.DEFAULT_WAIT_FOR_ROOT_TRANSACTION_TIMEOUT_MS / Consts_1.DEFAULT_WAIT_FOR_ROOT_TRANSACTION_RETRY_DELAY_MS);
307
- const broadSearchOpts = { limit, archival: true, maxScannedTransactions };
308
- const baselineInfo = await this.getAddressInformation(address);
309
- let seenLt = baselineInfo.lastTransaction.lt || undefined;
310
- // Capture baseline before first search.
311
- const firstTx = await this.findTransactionByHashType(address, hash, hashType, broadSearchOpts);
312
- if (firstTx) {
313
- this.logger?.debug(`Root transaction found on attempt 1/${attempts}`);
314
- return firstTx;
315
- }
316
- this.logger?.debug(`Root transaction not found yet (attempt 1/${attempts}), retrying in ${Consts_1.DEFAULT_WAIT_FOR_ROOT_TRANSACTION_RETRY_DELAY_MS}ms`);
317
- await (0, Utils_1.sleep)(Consts_1.DEFAULT_WAIT_FOR_ROOT_TRANSACTION_RETRY_DELAY_MS);
318
- for (let attempt = 2; attempt <= attempts; attempt++) {
319
- const info = await this.getAddressInformation(address);
320
- const currentLt = info.lastTransaction.lt || undefined;
321
- if (!currentLt || currentLt === seenLt) {
322
- this.logger?.debug(`Root transaction not found yet (attempt ${attempt}/${attempts}), lastTx unchanged, retrying in ${Consts_1.DEFAULT_WAIT_FOR_ROOT_TRANSACTION_RETRY_DELAY_MS}ms`);
323
- await (0, Utils_1.sleep)(Consts_1.DEFAULT_WAIT_FOR_ROOT_TRANSACTION_RETRY_DELAY_MS);
324
- continue;
298
+ async findTransactionWithRetry(address, hash, hashType, opts, depth) {
299
+ const retryDelayMs = opts.retryDelayMs ?? Consts_1.DEFAULT_RETRY_ON_NOT_FOUND_DELAY_MS;
300
+ const maxRetries = opts.retries ?? Consts_1.DEFAULT_RETRY_ON_NOT_FOUND_RETRIES;
301
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
302
+ let errorMsg;
303
+ try {
304
+ const tx = await this.findTransactionByHashType(address, hash, hashType, opts);
305
+ if (tx) {
306
+ return tx;
307
+ }
308
+ }
309
+ catch (error) {
310
+ errorMsg = error instanceof Error ? error.message : String(error);
325
311
  }
326
- seenLt = currentLt;
327
- const tx = await this.findTransactionByHashType(address, hash, hashType, broadSearchOpts);
328
- if (tx) {
329
- this.logger?.debug(`Root transaction found on attempt ${attempt}/${attempts}`);
330
- return tx;
312
+ const isLastAttempt = attempt >= maxRetries;
313
+ const reason = errorMsg ?? 'not found';
314
+ const retryInfo = isLastAttempt ? '' : `, retrying in ${retryDelayMs}ms`;
315
+ this.logger?.debug(`Transaction not found at depth ${depth} (attempt ${attempt + 1}/${maxRetries + 1}): ${reason}${retryInfo}`);
316
+ if (isLastAttempt) {
317
+ return null;
331
318
  }
332
- this.logger?.debug(`Root transaction not found yet (attempt ${attempt}/${attempts}), retrying in ${Consts_1.DEFAULT_WAIT_FOR_ROOT_TRANSACTION_RETRY_DELAY_MS}ms`);
333
- await (0, Utils_1.sleep)(Consts_1.DEFAULT_WAIT_FOR_ROOT_TRANSACTION_RETRY_DELAY_MS);
319
+ await (0, Utils_1.sleep)(retryDelayMs);
334
320
  }
335
- this.logger?.debug(`Root transaction not found after ${attempts} attempts`);
336
321
  return null;
337
322
  }
338
323
  /**
@@ -343,7 +328,7 @@ class BaseContractOpener {
343
328
  ignoreOpcodeList: Consts_1.IGNORE_OPCODE,
344
329
  limit: Consts_1.DEFAULT_FIND_TX_LIMIT,
345
330
  direction: 'both',
346
- waitForRootTransaction: Consts_1.DEFAULT_WAIT_FOR_ROOT_TRANSACTION,
331
+ retryOnNotFound: Consts_1.DEFAULT_RETRY_ON_NOT_FOUND,
347
332
  }) {
348
333
  const result = await this.trackTransactionTreeWithResult(address, hash, params);
349
334
  if (this.logger && typeof result.checkedCount === 'number') {
@@ -354,7 +339,13 @@ class BaseContractOpener {
354
339
  const context = reason === 'not_found'
355
340
  ? ` address=${errorAddress ?? 'unknown'} hashType=${hashType ?? 'unknown'}`
356
341
  : '';
357
- throw (0, errors_1.txFinalizationError)(`${txHash}: reason=${reason} (exitCode=${exitCode}, resultCode=${resultCode})${context}`);
342
+ const message = `${txHash}: reason=${reason} (exitCode=${exitCode}, resultCode=${resultCode})${context}`;
343
+ if (reason === 'not_found') {
344
+ throw new Error(message);
345
+ }
346
+ else {
347
+ throw (0, errors_1.txFinalizationError)(message);
348
+ }
358
349
  }
359
350
  }
360
351
  /**
@@ -365,15 +356,21 @@ class BaseContractOpener {
365
356
  ignoreOpcodeList: Consts_1.IGNORE_OPCODE,
366
357
  limit: Consts_1.DEFAULT_FIND_TX_LIMIT,
367
358
  direction: 'both',
368
- waitForRootTransaction: Consts_1.DEFAULT_WAIT_FOR_ROOT_TRANSACTION,
359
+ retryOnNotFound: Consts_1.DEFAULT_RETRY_ON_NOT_FOUND,
369
360
  }) {
370
- const { maxDepth = Consts_1.DEFAULT_FIND_TX_MAX_DEPTH, ignoreOpcodeList = Consts_1.IGNORE_OPCODE, limit = Consts_1.DEFAULT_FIND_TX_LIMIT, maxScannedTransactions = Consts_1.DEFAULT_MAX_SCANNED_TRANSACTIONS, direction = 'both', waitForRootTransaction = Consts_1.DEFAULT_WAIT_FOR_ROOT_TRANSACTION, } = params;
361
+ const { maxDepth = Consts_1.DEFAULT_FIND_TX_MAX_DEPTH, ignoreOpcodeList = Consts_1.IGNORE_OPCODE, limit = Consts_1.DEFAULT_FIND_TX_LIMIT, maxScannedTransactions = Consts_1.DEFAULT_MAX_SCANNED_TRANSACTIONS, direction = 'both', retryOnNotFound = Consts_1.DEFAULT_RETRY_ON_NOT_FOUND, retryDelayMs, retries, } = params;
371
362
  const parsedAddress = ton_1.Address.parse(address);
372
363
  const normalizedRootHash = (0, Utils_1.normalizeHashToBase64)(hash);
373
364
  const visitedSearchKeys = new Set();
374
365
  const processedTxHashes = new Set();
375
366
  let checkedCount = 0;
376
- const searchOpts = { limit, archival: true, maxScannedTransactions };
367
+ const searchOpts = {
368
+ limit,
369
+ archival: true,
370
+ maxScannedTransactions,
371
+ retryDelayMs,
372
+ retries,
373
+ };
377
374
  const queue = [
378
375
  { address: parsedAddress, hash: normalizedRootHash, depth: 0, hashType: 'unknown' },
379
376
  ];
@@ -383,8 +380,8 @@ class BaseContractOpener {
383
380
  if (visitedSearchKeys.has(visitedKey))
384
381
  continue;
385
382
  visitedSearchKeys.add(visitedKey);
386
- const tx = currentDepth === 0
387
- ? await this.findRootTransactionWithRetry(currentAddress, currentHash, hashType, limit, maxScannedTransactions, waitForRootTransaction)
383
+ const tx = retryOnNotFound
384
+ ? await this.findTransactionWithRetry(currentAddress, currentHash, hashType, searchOpts, currentDepth)
388
385
  : await this.findTransactionByHashType(currentAddress, currentHash, hashType, searchOpts);
389
386
  if (!tx) {
390
387
  this.logger?.debug(`Transaction not found for hash: ${currentHash} (address=${currentAddress?.toString()}, hashType=${hashType ?? 'unknown'})`);
@@ -144,32 +144,35 @@ class RetryableContractOpener {
144
144
  for (let index = 0; index < this.openerConfigs.length; index++) {
145
145
  const config = this.openerConfigs[index];
146
146
  const openerLabel = `opener ${index + 1}/${this.openerConfigs.length}`;
147
- this.logger?.debug(`[RetryableContractOpener] ${operationName}: trying ${openerLabel}${useRetries ? ` (max retries ${config.retries})` : ' (single attempt)'}`);
147
+ this.logger?.debug(`[RetryableContractOpener] ${operationName}: trying ${openerLabel}`);
148
148
  const result = useRetries
149
149
  ? await this.tryWithRetries(() => operation(config), config, `${operationName} ${openerLabel}`)
150
150
  : await this.trySingleAttempt(() => operation(config));
151
151
  if (result.success) {
152
- this.logger?.debug(`[RetryableContractOpener] ${operationName}: ${openerLabel} succeeded`);
153
152
  return { success: true, data: result.data };
154
153
  }
155
154
  lastError = result.lastError;
155
+ const isTransactionError = lastError instanceof errors_1.TransactionError;
156
+ const isContractExecutionError = !!lastError && this.isContractExecutionError(lastError);
157
+ const shouldStopOnNonTransportError = !!lastError && !!shouldFallbackOnError && !shouldFallbackOnError(lastError);
156
158
  if (lastError) {
157
- this.logger?.debug(`[RetryableContractOpener] ${operationName}: ${openerLabel} failed: ${lastError.message}`);
159
+ const stopReason = isTransactionError
160
+ ? 'TransactionError'
161
+ : isContractExecutionError
162
+ ? 'contract execution error'
163
+ : shouldStopOnNonTransportError
164
+ ? 'non-transport error'
165
+ : undefined;
166
+ this.logger?.debug(`[RetryableContractOpener] ${operationName}: ${openerLabel} failed${stopReason ? ` (stopping fallback because of ${stopReason})` : ''}: ${lastError.message}`);
158
167
  }
159
- if (lastError instanceof errors_1.TransactionError) {
160
- this.logger?.debug(`[RetryableContractOpener] ${operationName}: stopping fallback because of TransactionError`);
168
+ if (isTransactionError) {
161
169
  return { success: false, lastError };
162
170
  }
163
- if (lastError && this.isContractExecutionError(lastError)) {
164
- this.logger?.debug(`[RetryableContractOpener] ${operationName}: stopping fallback because of contract execution error`);
171
+ if (isContractExecutionError) {
165
172
  return { success: false, lastError };
166
173
  }
167
- if (lastError && shouldFallbackOnError) {
168
- const shouldFallback = shouldFallbackOnError(lastError);
169
- if (!shouldFallback) {
170
- this.logger?.debug(`[RetryableContractOpener] ${operationName}: stopping fallback due to non-transport error`);
171
- return { success: false, lastError };
172
- }
174
+ if (shouldStopOnNonTransportError) {
175
+ return { success: false, lastError };
173
176
  }
174
177
  }
175
178
  return { success: false, lastError };
@@ -196,7 +199,7 @@ class RetryableContractOpener {
196
199
  return { success: false, lastError };
197
200
  }
198
201
  if (attempt < config.retries) {
199
- this.logger?.debug(`[RetryableContractOpener] ${operationContext}: attempt ${attempt + 1}/${config.retries + 1} failed, retrying in ${config.retryDelay}ms`);
202
+ this.logger?.debug(`[RetryableContractOpener] ${operationContext}: attempt ${attempt + 1}/${config.retries + 1} failed (${lastError.message}), retrying in ${config.retryDelay}ms`);
200
203
  await sleep(config.retryDelay);
201
204
  }
202
205
  }
@@ -37,8 +37,12 @@ function extractEndpoint(message) {
37
37
  }
38
38
  return match[0].replace(/[),.;]+$/, '');
39
39
  }
40
- function extractResponseMessage(data) {
40
+ function extractResponseMessage(data, includeFullTrace) {
41
41
  if (typeof data === 'string' && data.length > 0) {
42
+ const isHtml = data.includes('<!doctype html>') || data.includes('<html');
43
+ if (isHtml && !includeFullTrace) {
44
+ return '[HTML response]';
45
+ }
42
46
  return data;
43
47
  }
44
48
  if (!data || typeof data !== 'object') {
@@ -53,11 +57,11 @@ function extractResponseMessage(data) {
53
57
  }
54
58
  return undefined;
55
59
  }
56
- function buildInnerErrorSummary(inner) {
60
+ function buildInnerErrorSummary(inner, includeFullTrace) {
57
61
  if (inner && typeof inner === 'object') {
58
62
  const err = inner;
59
63
  const parts = [];
60
- const responseMessage = extractResponseMessage(err.response?.data);
64
+ const responseMessage = extractResponseMessage(err.response?.data, includeFullTrace);
61
65
  const httpStatus = [err.httpStatus, err.status, err.response?.status].find((value) => typeof value === 'number');
62
66
  const httpMessage = typeof err.innerMessage === 'string' && err.innerMessage.length > 0 ? err.innerMessage : responseMessage;
63
67
  if (typeof httpStatus === 'number') {
@@ -81,7 +85,7 @@ function buildInnerErrorSummary(inner) {
81
85
  }
82
86
  return 'message=unknown error';
83
87
  }
84
- const allEndpointsFailedError = (inner, includeInnerStack = false) => new errors_1.FetchError(`All endpoints failed, last err: ${buildInnerErrorSummary(inner)}`, 117, inner, {
88
+ const allEndpointsFailedError = (inner, includeInnerStack = false) => new errors_1.FetchError(`All endpoints failed, last err: ${buildInnerErrorSummary(inner, includeInnerStack)}`, 117, inner, {
85
89
  includeInnerStack,
86
90
  });
87
91
  exports.allEndpointsFailedError = allEndpointsFailedError;
@@ -3,55 +3,55 @@ export interface IOperationTracker {
3
3
  /**
4
4
  * Returns the operation type for the given id, optionally waiting according to the provided policy.
5
5
  * @param operationId Operation identifier.
6
- * @param waitOptions Optional waiting and polling settings.
6
+ * @param waitOptions Optional waiting and polling settings. Pass `null` to disable retries and use a single attempt.
7
7
  */
8
- getOperationType(operationId: string, waitOptions?: WaitOptions<OperationType>): Promise<OperationType>;
8
+ getOperationType(operationId: string, waitOptions?: WaitOptions<OperationType> | null): Promise<OperationType>;
9
9
  /**
10
10
  * Resolves an operation id for the given transaction linker, optionally waiting until available.
11
11
  * @param transactionLinker Reference to originating transaction across chains.
12
- * @param waitOptions Optional waiting settings.
12
+ * @param waitOptions Optional waiting settings. Pass `null` to disable retries and use a single attempt.
13
13
  */
14
- getOperationId(transactionLinker: TransactionLinker, waitOptions?: WaitOptions<string>): Promise<string>;
14
+ getOperationId(transactionLinker: TransactionLinker, waitOptions?: WaitOptions<string> | null): Promise<string>;
15
15
  /**
16
16
  * Resolves an operation id by a transaction hash, optionally waiting until available.
17
17
  * @param transactionHash Hash of the originating transaction.
18
- * @param waitOptions Optional waiting settings.
18
+ * @param waitOptions Optional waiting settings. Pass `null` to disable retries and use a single attempt.
19
19
  */
20
- getOperationIdByTransactionHash(transactionHash: string, waitOptions?: WaitOptions<string>): Promise<string>;
20
+ getOperationIdByTransactionHash(transactionHash: string, waitOptions?: WaitOptions<string> | null): Promise<string>;
21
21
  /**
22
22
  * Resolves operation ids by shard keys for a particular caller, with optional batching and waiting.
23
23
  * @param shardsKeys List of shard keys.
24
24
  * @param caller Human-readable identifier of the caller (for tracing/limits).
25
- * @param waitOptions Optional waiting settings.
25
+ * @param waitOptions Optional waiting settings. Pass `null` to disable retries and use a single attempt.
26
26
  * @param chunkSize Optional batching size for network requests.
27
27
  */
28
- getOperationIdsByShardsKeys(shardsKeys: string[], caller: string, waitOptions?: WaitOptions<OperationIdsByShardsKey>, chunkSize?: number): Promise<OperationIdsByShardsKey>;
28
+ getOperationIdsByShardsKeys(shardsKeys: string[], caller: string, waitOptions?: WaitOptions<OperationIdsByShardsKey> | null, chunkSize?: number): Promise<OperationIdsByShardsKey>;
29
29
  /**
30
30
  * Gets detailed stage profiling for a single operation, optionally waiting until available.
31
31
  * @param operationId Operation identifier.
32
- * @param waitOptions Optional waiting settings.
32
+ * @param waitOptions Optional waiting settings. Pass `null` to disable retries and use a single attempt.
33
33
  */
34
- getStageProfiling(operationId: string, waitOptions?: WaitOptions<ExecutionStages>): Promise<ExecutionStages>;
34
+ getStageProfiling(operationId: string, waitOptions?: WaitOptions<ExecutionStages> | null): Promise<ExecutionStages>;
35
35
  /**
36
36
  * Gets stage profiling for multiple operations in bulk.
37
37
  * @param operationIds Operation identifiers.
38
- * @param waitOptions Optional waiting settings.
38
+ * @param waitOptions Optional waiting settings. Pass `null` to disable retries and use a single attempt.
39
39
  * @param chunkSize Optional batching size for requests.
40
40
  */
41
- getStageProfilings(operationIds: string[], waitOptions?: WaitOptions<ExecutionStagesByOperationId>, chunkSize?: number): Promise<ExecutionStagesByOperationId>;
41
+ getStageProfilings(operationIds: string[], waitOptions?: WaitOptions<ExecutionStagesByOperationId> | null, chunkSize?: number): Promise<ExecutionStagesByOperationId>;
42
42
  /**
43
43
  * Gets statuses for multiple operations.
44
44
  * @param operationIds Operation identifiers.
45
- * @param waitOptions Optional waiting settings.
45
+ * @param waitOptions Optional waiting settings. Pass `null` to disable retries and use a single attempt.
46
46
  * @param chunkSize Optional batching size for requests.
47
47
  */
48
- getOperationStatuses(operationIds: string[], waitOptions?: WaitOptions<StatusInfosByOperationId>, chunkSize?: number): Promise<StatusInfosByOperationId>;
48
+ getOperationStatuses(operationIds: string[], waitOptions?: WaitOptions<StatusInfosByOperationId> | null, chunkSize?: number): Promise<StatusInfosByOperationId>;
49
49
  /**
50
50
  * Gets a single operation status, optionally waiting according to policy.
51
51
  * @param operationId Operation identifier.
52
- * @param waitOptions Optional waiting settings.
52
+ * @param waitOptions Optional waiting settings. Pass `null` to disable retries and use a single attempt.
53
53
  */
54
- getOperationStatus(operationId: string, waitOptions?: WaitOptions<StatusInfo>): Promise<StatusInfo>;
54
+ getOperationStatus(operationId: string, waitOptions?: WaitOptions<StatusInfo> | null): Promise<StatusInfo>;
55
55
  /**
56
56
  * Returns a simplified status for the provided transaction linker.
57
57
  * @param transactionLinker Reference to originating transaction across chains.
@@ -60,22 +60,22 @@ export interface IOperationTracker {
60
60
  /**
61
61
  * Converts currency using the tracker service, optionally waiting for completion.
62
62
  * @param params Conversion parameters.
63
- * @param waitOptions Optional waiting settings.
63
+ * @param waitOptions Optional waiting settings. Pass `null` to disable retries and use a single attempt.
64
64
  */
65
- convertCurrency(params: ConvertCurrencyParams, waitOptions?: WaitOptions<ConvertedCurrencyResult>): Promise<ConvertedCurrencyResult>;
65
+ convertCurrency(params: ConvertCurrencyParams, waitOptions?: WaitOptions<ConvertedCurrencyResult> | null): Promise<ConvertedCurrencyResult>;
66
66
  /**
67
67
  * Simulates execution of a TAC message without broadcasting it, optionally waiting until the result is available.
68
68
  * Useful to validate inputs and estimate effects before sending a real transaction.
69
69
  * @param params Simulation parameters and context.
70
- * @param waitOptions Optional waiting settings (polling/timeout policy).
70
+ * @param waitOptions Optional waiting settings (polling/timeout policy). Pass `null` to disable retries and use a single attempt.
71
71
  * @returns Promise with detailed simulation result.
72
72
  */
73
- simulateTACMessage(params: TACSimulationParams, waitOptions?: WaitOptions<TACSimulationResult>): Promise<TACSimulationResult>;
73
+ simulateTACMessage(params: TACSimulationParams, waitOptions?: WaitOptions<TACSimulationResult> | null): Promise<TACSimulationResult>;
74
74
  /**
75
75
  * Suggests/calculates a TVM executor fee for the provided parameters, optionally waiting for completion.
76
76
  * @param params Parameters affecting fee calculation.
77
- * @param waitOptions Optional waiting settings (polling/timeout policy).
77
+ * @param waitOptions Optional waiting settings (polling/timeout policy). Pass `null` to disable retries and use a single attempt.
78
78
  * @returns Promise with suggested fee information.
79
79
  */
80
- getTVMExecutorFee(params: GetTVMExecutorFeeParams, waitOptions?: WaitOptions<SuggestedTVMExecutorFee>): Promise<SuggestedTVMExecutorFee>;
80
+ getTVMExecutorFee(params: GetTVMExecutorFeeParams, waitOptions?: WaitOptions<SuggestedTVMExecutorFee> | null): Promise<SuggestedTVMExecutorFee>;
81
81
  }
@@ -19,12 +19,15 @@ export declare const TON_BURN_ADDRESS = "EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
19
19
  export declare const DEFAULT_HTTP_CLIENT_TIMEOUT_MS = 30000;
20
20
  export declare const DEFAULT_RETRY_MAX_COUNT = 5;
21
21
  export declare const DEFAULT_RETRY_DELAY_MS = 1000;
22
+ export declare const DEFAULT_WAIT_TIMEOUT_MS = 300000;
23
+ export declare const DEFAULT_WAIT_MAX_ATTEMPTS = 30;
24
+ export declare const DEFAULT_WAIT_DELAY_MS = 10000;
22
25
  export declare const DEFAULT_FIND_TX_LIMIT = 100;
23
26
  export declare const DEFAULT_MAX_SCANNED_TRANSACTIONS = 100;
24
27
  export declare const DEFAULT_FIND_TX_ARCHIVAL = true;
25
28
  export declare const DEFAULT_FIND_TX_MAX_DEPTH = 10;
26
- export declare const DEFAULT_WAIT_FOR_ROOT_TRANSACTION = true;
27
- export declare const DEFAULT_WAIT_FOR_ROOT_TRANSACTION_TIMEOUT_MS: number;
28
- export declare const DEFAULT_WAIT_FOR_ROOT_TRANSACTION_RETRY_DELAY_MS = 1000;
29
+ export declare const DEFAULT_RETRY_ON_NOT_FOUND = true;
30
+ export declare const DEFAULT_RETRY_ON_NOT_FOUND_RETRIES = 10;
31
+ export declare const DEFAULT_RETRY_ON_NOT_FOUND_DELAY_MS = 5000;
29
32
  export declare const IGNORE_MSG_VALUE_1_NANO = 1n;
30
33
  export declare const IGNORE_OPCODE: number[];
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.IGNORE_OPCODE = exports.IGNORE_MSG_VALUE_1_NANO = exports.DEFAULT_WAIT_FOR_ROOT_TRANSACTION_RETRY_DELAY_MS = exports.DEFAULT_WAIT_FOR_ROOT_TRANSACTION_TIMEOUT_MS = exports.DEFAULT_WAIT_FOR_ROOT_TRANSACTION = exports.DEFAULT_FIND_TX_MAX_DEPTH = exports.DEFAULT_FIND_TX_ARCHIVAL = exports.DEFAULT_MAX_SCANNED_TRANSACTIONS = exports.DEFAULT_FIND_TX_LIMIT = exports.DEFAULT_RETRY_DELAY_MS = exports.DEFAULT_RETRY_MAX_COUNT = exports.DEFAULT_HTTP_CLIENT_TIMEOUT_MS = exports.TON_BURN_ADDRESS = exports.MINUTE = exports.FIVE_MINUTES = exports.TAC_DECIMALS = exports.TON_DECIMALS = exports.ONE_YEAR_SECONDS = exports.FIFTEEN_MINUTES = exports.TAC_SYMBOL = exports.TON_SYMBOL = exports.MAX_MSG_DEPTH = exports.MAX_HIGHLOAD_GROUP_MSG_NUM = exports.MAX_EXT_MSG_SIZE = exports.SOLIDITY_METHOD_NAME_REGEX = exports.SOLIDITY_SIGNATURE_REGEX = exports.DEFAULT_DELAY = exports.MAX_ITERATION_COUNT = exports.NFT_TRANSFER_FORWARD_TON_AMOUNT = exports.JETTON_TRANSFER_FORWARD_TON_AMOUNT = void 0;
3
+ exports.IGNORE_OPCODE = exports.IGNORE_MSG_VALUE_1_NANO = exports.DEFAULT_RETRY_ON_NOT_FOUND_DELAY_MS = exports.DEFAULT_RETRY_ON_NOT_FOUND_RETRIES = exports.DEFAULT_RETRY_ON_NOT_FOUND = exports.DEFAULT_FIND_TX_MAX_DEPTH = exports.DEFAULT_FIND_TX_ARCHIVAL = exports.DEFAULT_MAX_SCANNED_TRANSACTIONS = exports.DEFAULT_FIND_TX_LIMIT = exports.DEFAULT_WAIT_DELAY_MS = exports.DEFAULT_WAIT_MAX_ATTEMPTS = exports.DEFAULT_WAIT_TIMEOUT_MS = exports.DEFAULT_RETRY_DELAY_MS = exports.DEFAULT_RETRY_MAX_COUNT = exports.DEFAULT_HTTP_CLIENT_TIMEOUT_MS = exports.TON_BURN_ADDRESS = exports.MINUTE = exports.FIVE_MINUTES = exports.TAC_DECIMALS = exports.TON_DECIMALS = exports.ONE_YEAR_SECONDS = exports.FIFTEEN_MINUTES = exports.TAC_SYMBOL = exports.TON_SYMBOL = exports.MAX_MSG_DEPTH = exports.MAX_HIGHLOAD_GROUP_MSG_NUM = exports.MAX_EXT_MSG_SIZE = exports.SOLIDITY_METHOD_NAME_REGEX = exports.SOLIDITY_SIGNATURE_REGEX = exports.DEFAULT_DELAY = exports.MAX_ITERATION_COUNT = exports.NFT_TRANSFER_FORWARD_TON_AMOUNT = exports.JETTON_TRANSFER_FORWARD_TON_AMOUNT = void 0;
4
4
  const ton_1 = require("@ton/ton");
5
5
  exports.JETTON_TRANSFER_FORWARD_TON_AMOUNT = (0, ton_1.toNano)(0.2);
6
6
  exports.NFT_TRANSFER_FORWARD_TON_AMOUNT = (0, ton_1.toNano)(0.3);
@@ -23,13 +23,16 @@ exports.TON_BURN_ADDRESS = 'EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c';
23
23
  exports.DEFAULT_HTTP_CLIENT_TIMEOUT_MS = 30000;
24
24
  exports.DEFAULT_RETRY_MAX_COUNT = 5;
25
25
  exports.DEFAULT_RETRY_DELAY_MS = 1000;
26
+ exports.DEFAULT_WAIT_TIMEOUT_MS = 300000; // 5 minutes
27
+ exports.DEFAULT_WAIT_MAX_ATTEMPTS = 30;
28
+ exports.DEFAULT_WAIT_DELAY_MS = 10000; // 10 seconds
26
29
  exports.DEFAULT_FIND_TX_LIMIT = 100;
27
30
  exports.DEFAULT_MAX_SCANNED_TRANSACTIONS = 100;
28
31
  exports.DEFAULT_FIND_TX_ARCHIVAL = true;
29
32
  exports.DEFAULT_FIND_TX_MAX_DEPTH = 10;
30
- exports.DEFAULT_WAIT_FOR_ROOT_TRANSACTION = true;
31
- exports.DEFAULT_WAIT_FOR_ROOT_TRANSACTION_TIMEOUT_MS = exports.MINUTE;
32
- exports.DEFAULT_WAIT_FOR_ROOT_TRANSACTION_RETRY_DELAY_MS = 1000;
33
+ exports.DEFAULT_RETRY_ON_NOT_FOUND = true;
34
+ exports.DEFAULT_RETRY_ON_NOT_FOUND_RETRIES = 10;
35
+ exports.DEFAULT_RETRY_ON_NOT_FOUND_DELAY_MS = 5000;
33
36
  exports.IGNORE_MSG_VALUE_1_NANO = 1n;
34
37
  exports.IGNORE_OPCODE = [
35
38
  0xd53276db, // Excess
@@ -7,16 +7,16 @@ export declare class OperationTracker implements IOperationTracker {
7
7
  private readonly clients;
8
8
  private readonly logger;
9
9
  constructor(network: Network, customLiteSequencerEndpoints?: string[], logger?: ILogger, clientFactory?: ILiteSequencerClientFactory);
10
- getOperationIdByTransactionHash(transactionHash: string, waitOptions?: WaitOptions<string>): Promise<string>;
11
- getOperationType(operationId: string, waitOptions?: WaitOptions<OperationType>): Promise<OperationType>;
12
- getOperationId(transactionLinker: TransactionLinker, waitOptions?: WaitOptions<string>): Promise<string>;
13
- getOperationIdsByShardsKeys(shardsKeys: string[], caller: string, waitOptions?: WaitOptions<OperationIdsByShardsKey>, chunkSize?: number): Promise<OperationIdsByShardsKey>;
14
- getStageProfiling(operationId: string, waitOptions?: WaitOptions<ExecutionStages>): Promise<ExecutionStages>;
15
- getStageProfilings(operationIds: string[], waitOptions?: WaitOptions<ExecutionStagesByOperationId>, chunkSize?: number): Promise<ExecutionStagesByOperationId>;
16
- getOperationStatuses(operationIds: string[], waitOptions?: WaitOptions<StatusInfosByOperationId>, chunkSize?: number): Promise<StatusInfosByOperationId>;
17
- getOperationStatus(operationId: string, waitOptions?: WaitOptions<StatusInfo>): Promise<StatusInfo>;
10
+ getOperationIdByTransactionHash(transactionHash: string, waitOptions?: WaitOptions<string> | null): Promise<string>;
11
+ getOperationType(operationId: string, waitOptions?: WaitOptions<OperationType> | null): Promise<OperationType>;
12
+ getOperationId(transactionLinker: TransactionLinker, waitOptions?: WaitOptions<string> | null): Promise<string>;
13
+ getOperationIdsByShardsKeys(shardsKeys: string[], caller: string, waitOptions?: WaitOptions<OperationIdsByShardsKey> | null, chunkSize?: number): Promise<OperationIdsByShardsKey>;
14
+ getStageProfiling(operationId: string, waitOptions?: WaitOptions<ExecutionStages> | null): Promise<ExecutionStages>;
15
+ getStageProfilings(operationIds: string[], waitOptions?: WaitOptions<ExecutionStagesByOperationId> | null, chunkSize?: number): Promise<ExecutionStagesByOperationId>;
16
+ getOperationStatuses(operationIds: string[], waitOptions?: WaitOptions<StatusInfosByOperationId> | null, chunkSize?: number): Promise<StatusInfosByOperationId>;
17
+ getOperationStatus(operationId: string, waitOptions?: WaitOptions<StatusInfo> | null): Promise<StatusInfo>;
18
18
  getSimplifiedOperationStatus(transactionLinker: TransactionLinker): Promise<SimplifiedStatuses>;
19
- convertCurrency(params: ConvertCurrencyParams, waitOptions?: WaitOptions<ConvertedCurrencyResult>): Promise<ConvertedCurrencyResult>;
20
- simulateTACMessage(params: TACSimulationParams, waitOptions?: WaitOptions<TACSimulationResult>): Promise<TACSimulationResult>;
21
- getTVMExecutorFee(params: GetTVMExecutorFeeParams, waitOptions?: WaitOptions<SuggestedTVMExecutorFee>): Promise<SuggestedTVMExecutorFee>;
19
+ convertCurrency(params: ConvertCurrencyParams, waitOptions?: WaitOptions<ConvertedCurrencyResult> | null): Promise<ConvertedCurrencyResult>;
20
+ simulateTACMessage(params: TACSimulationParams, waitOptions?: WaitOptions<TACSimulationResult> | null): Promise<TACSimulationResult>;
21
+ getTVMExecutorFee(params: GetTVMExecutorFeeParams, waitOptions?: WaitOptions<SuggestedTVMExecutorFee> | null): Promise<SuggestedTVMExecutorFee>;
22
22
  }
@@ -35,96 +35,78 @@ class OperationTracker {
35
35
  this.logger = logger;
36
36
  }
37
37
  async getOperationIdByTransactionHash(transactionHash, waitOptions) {
38
- this.logger.debug(`Getting operation ID for transactionHash: ${(0, Utils_1.formatObjectForLogging)(transactionHash)}`);
39
38
  const requestFn = async () => {
40
39
  let lastError;
41
40
  for (const client of this.clients) {
42
41
  try {
43
42
  const id = await client.getOperationIdByTransactionHash(transactionHash);
44
- this.logger.debug(`Operation ID ${id == '' ? 'does not exist' : 'retrieved successfully'}`);
45
43
  return id;
46
44
  }
47
45
  catch (error) {
48
- this.logger.warn(`Failed to get OperationId by transactionHash using one of the endpoints`);
49
46
  lastError = error;
50
47
  }
51
48
  }
52
- this.logger.error('All endpoints failed to get operation id by transactionHash');
53
49
  throw (0, errors_1.allEndpointsFailedError)(lastError, waitOptions?.includeErrorTrace ?? false);
54
50
  };
55
- return waitOptions
56
- ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn, 'OperationTracker: Getting operation ID by transaction hash')
57
- : await requestFn();
51
+ return waitOptions === null
52
+ ? await requestFn()
53
+ : await (0, Utils_1.waitUntilSuccess)({ logger: this.logger, ...waitOptions }, requestFn, `OperationTracker: Getting operation ID by transaction hash ${(0, Utils_1.formatObjectForLogging)(transactionHash)}`);
58
54
  }
59
55
  async getOperationType(operationId, waitOptions) {
60
- this.logger.debug(`Getting operation type for ${(0, Utils_1.formatObjectForLogging)(operationId)}`);
61
56
  const requestFn = async () => {
62
57
  let lastError;
63
58
  for (const client of this.clients) {
64
59
  try {
65
60
  const type = await client.getOperationType(operationId);
66
- this.logger.debug(`Operation retrieved successfully`);
67
61
  return type;
68
62
  }
69
63
  catch (error) {
70
- this.logger.warn(`Failed to get operationType using one of the endpoints`);
71
64
  lastError = error;
72
65
  }
73
66
  }
74
- this.logger.error('All endpoints failed to get operation type');
75
67
  throw (0, errors_1.allEndpointsFailedError)(lastError, waitOptions?.includeErrorTrace ?? false);
76
68
  };
77
- return waitOptions
78
- ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn, 'OperationTracker: Getting operation type')
79
- : await requestFn();
69
+ return waitOptions === null
70
+ ? await requestFn()
71
+ : await (0, Utils_1.waitUntilSuccess)({ logger: this.logger, ...waitOptions }, requestFn, `OperationTracker: Getting operation type for ${(0, Utils_1.formatObjectForLogging)(operationId)}`);
80
72
  }
81
73
  async getOperationId(transactionLinker, waitOptions) {
82
- this.logger.debug(`Getting operation ID for transaction linker: ${(0, Utils_1.formatObjectForLogging)(transactionLinker)}`);
83
74
  const requestFn = async () => {
84
75
  let lastError;
85
76
  for (const client of this.clients) {
86
77
  try {
87
78
  const id = await client.getOperationId(transactionLinker);
88
- this.logger.debug(`Operation ID ${id == '' ? 'does not exist' : 'retrieved successfully'}`);
89
79
  return id;
90
80
  }
91
81
  catch (error) {
92
- this.logger.warn(`Failed to get OperationId using one of the endpoints`);
93
82
  lastError = error;
94
83
  }
95
84
  }
96
- this.logger.error('All endpoints failed to get operation id');
97
85
  throw (0, errors_1.allEndpointsFailedError)(lastError, waitOptions?.includeErrorTrace ?? false);
98
86
  };
99
- return waitOptions
100
- ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn, 'OperationTracker: Getting operation ID by transaction linker')
101
- : await requestFn();
87
+ return waitOptions === null
88
+ ? await requestFn()
89
+ : await (0, Utils_1.waitUntilSuccess)({ logger: this.logger, ...waitOptions }, requestFn, `OperationTracker: Getting operation ID by transaction linker ${(0, Utils_1.formatObjectForLogging)(transactionLinker)}`);
102
90
  }
103
91
  async getOperationIdsByShardsKeys(shardsKeys, caller, waitOptions, chunkSize = 100) {
104
- this.logger.debug(`Getting operation IDs for shards keys: ${(0, Utils_1.formatObjectForLogging)(shardsKeys)}`);
105
- this.logger.debug(`Caller: ${caller}, Chunk size: ${chunkSize}`);
106
92
  const requestFn = async () => {
107
93
  let lastError;
108
94
  for (const client of this.clients) {
109
95
  try {
110
96
  const result = await client.getOperationIdsByShardsKeys(shardsKeys, caller, chunkSize);
111
- this.logger.debug(`Operation IDs by shards keys retrieved successfully`);
112
97
  return result;
113
98
  }
114
99
  catch (error) {
115
- this.logger.warn(`Failed to get OperationIds using one of the endpoints`);
116
100
  lastError = error;
117
101
  }
118
102
  }
119
- this.logger.error('All endpoints failed to get operation ids by shards keys');
120
103
  throw (0, errors_1.allEndpointsFailedError)(lastError, waitOptions?.includeErrorTrace ?? false);
121
104
  };
122
- return waitOptions
123
- ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn, 'OperationTracker: Getting operation IDs by shards keys')
124
- : await requestFn();
105
+ return waitOptions === null
106
+ ? await requestFn()
107
+ : await (0, Utils_1.waitUntilSuccess)({ logger: this.logger, ...waitOptions }, requestFn, `OperationTracker: Getting operation IDs by shards keys ${(0, Utils_1.formatObjectForLogging)(shardsKeys)} caller=${caller} chunkSize=${chunkSize}`);
125
108
  }
126
109
  async getStageProfiling(operationId, waitOptions) {
127
- this.logger.debug(`Getting stage profiling for operation ${operationId}`);
128
110
  const requestFn = async () => {
129
111
  let lastError;
130
112
  for (const client of this.clients) {
@@ -132,72 +114,57 @@ class OperationTracker {
132
114
  const map = await client.getStageProfilings([operationId]);
133
115
  const result = map[operationId];
134
116
  if (!result) {
135
- this.logger.warn(`No stageProfiling data for operationId=${operationId}`);
136
117
  throw new Error(`No stageProfiling data for operationId=${operationId}`);
137
118
  }
138
- this.logger.debug(`Stage profiling retrieved successfully`);
139
119
  return result;
140
120
  }
141
121
  catch (error) {
142
- this.logger.warn(`Failed to get stage profiling using one of the endpoints`);
143
122
  lastError = error;
144
123
  }
145
124
  }
146
- this.logger.error('All endpoints failed to get stage profiling');
147
125
  throw (0, errors_1.allEndpointsFailedError)(lastError, waitOptions?.includeErrorTrace ?? false);
148
126
  };
149
- return waitOptions
150
- ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn, 'OperationTracker: Getting stage profiling')
151
- : await requestFn();
127
+ return waitOptions === null
128
+ ? await requestFn()
129
+ : await (0, Utils_1.waitUntilSuccess)({ logger: this.logger, ...waitOptions }, requestFn, `OperationTracker: Getting stage profiling for operation ${operationId}`);
152
130
  }
153
131
  async getStageProfilings(operationIds, waitOptions, chunkSize = 100) {
154
- this.logger.debug(`Getting stage profilings for operations: ${operationIds.join(', ')}`);
155
- this.logger.debug(`Chunk size: ${chunkSize}`);
156
132
  const requestFn = async () => {
157
133
  let lastError;
158
134
  for (const client of this.clients) {
159
135
  try {
160
136
  const result = await client.getStageProfilings(operationIds, chunkSize);
161
- this.logger.debug(`Stage profilings retrieved successfully`);
162
137
  return result;
163
138
  }
164
139
  catch (error) {
165
- this.logger.warn(`Failed to get stage profilings using one of the endpoints`);
166
140
  lastError = error;
167
141
  }
168
142
  }
169
- this.logger.error('All endpoints failed to get stage profilings');
170
143
  throw (0, errors_1.allEndpointsFailedError)(lastError, waitOptions?.includeErrorTrace ?? false);
171
144
  };
172
- return waitOptions
173
- ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn, 'OperationTracker: Getting stage profilings')
174
- : await requestFn();
145
+ return waitOptions === null
146
+ ? await requestFn()
147
+ : await (0, Utils_1.waitUntilSuccess)({ logger: this.logger, ...waitOptions }, requestFn, `OperationTracker: Getting stage profilings for operations: ${operationIds.join(', ')} chunkSize=${chunkSize}`);
175
148
  }
176
149
  async getOperationStatuses(operationIds, waitOptions, chunkSize = 100) {
177
- this.logger.debug(`Getting operation statuses for operations: ${(0, Utils_1.formatObjectForLogging)(operationIds)}`);
178
- this.logger.debug(`Chunk size: ${chunkSize}`);
179
150
  const requestFn = async () => {
180
151
  let lastError;
181
152
  for (const client of this.clients) {
182
153
  try {
183
154
  const result = await client.getOperationStatuses(operationIds, chunkSize);
184
- this.logger.debug(`Operation statuses retrieved successfully`);
185
155
  return result;
186
156
  }
187
157
  catch (error) {
188
- this.logger.warn(`Failed to get operation statuses using one of the endpoints`);
189
158
  lastError = error;
190
159
  }
191
160
  }
192
- this.logger.error('All endpoints failed to get operation statuses');
193
161
  throw (0, errors_1.allEndpointsFailedError)(lastError, waitOptions?.includeErrorTrace ?? false);
194
162
  };
195
- return waitOptions
196
- ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn, 'OperationTracker: Getting operation statuses')
197
- : await requestFn();
163
+ return waitOptions === null
164
+ ? await requestFn()
165
+ : await (0, Utils_1.waitUntilSuccess)({ logger: this.logger, ...waitOptions }, requestFn, `OperationTracker: Getting operation statuses for operations: ${(0, Utils_1.formatObjectForLogging)(operationIds)} chunkSize=${chunkSize}`);
198
166
  }
199
167
  async getOperationStatus(operationId, waitOptions) {
200
- this.logger.debug(`Getting operation status for ${(0, Utils_1.formatObjectForLogging)(operationId)}`);
201
168
  const requestFn = async () => {
202
169
  let lastError;
203
170
  for (const client of this.clients) {
@@ -205,27 +172,23 @@ class OperationTracker {
205
172
  const map = await client.getOperationStatuses([operationId]);
206
173
  const result = map[operationId];
207
174
  if (!result) {
208
- this.logger.warn(`No operation status for operationId=${operationId}`);
209
175
  throw new Error(`No operation status for operationId=${operationId}`);
210
176
  }
211
177
  return result;
212
178
  }
213
179
  catch (error) {
214
- this.logger.warn(`Failed to get operation status using one of the endpoints`);
215
180
  lastError = error;
216
181
  }
217
182
  }
218
- this.logger.error('All endpoints failed to get operation status');
219
183
  throw (0, errors_1.allEndpointsFailedError)(lastError, waitOptions?.includeErrorTrace ?? false);
220
184
  };
221
- const status = waitOptions
222
- ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn, 'OperationTracker: Getting operation status')
223
- : await requestFn();
185
+ const status = waitOptions === null
186
+ ? await requestFn()
187
+ : await (0, Utils_1.waitUntilSuccess)({ logger: this.logger, ...waitOptions }, requestFn, `OperationTracker: Getting operation status for ${(0, Utils_1.formatObjectForLogging)(operationId)}`);
224
188
  this.logger.debug(`operation status resolved stage=${status.stage ?? 'unknown'} success=${(String(status.success))}`);
225
189
  return status;
226
190
  }
227
191
  async getSimplifiedOperationStatus(transactionLinker) {
228
- this.logger.debug(`Getting simplified operation status for transaction linker: ${(0, Utils_1.formatObjectForLogging)(transactionLinker)}`);
229
192
  const operationId = await this.getOperationId(transactionLinker);
230
193
  if (operationId == '') {
231
194
  this.logger.warn('Operation ID not found');
@@ -244,71 +207,59 @@ class OperationTracker {
244
207
  if (params.value <= 0n) {
245
208
  throw instances_1.convertCurrencyNegativeOrZeroValueError;
246
209
  }
247
- this.logger.debug(`Converting currency: ${(0, Utils_1.formatObjectForLogging)(params)}`);
248
210
  const requestFn = async () => {
249
211
  let lastError;
250
212
  for (const client of this.clients) {
251
213
  try {
252
214
  const result = await client.convertCurrency(params);
253
- this.logger.debug(`Conversion result retrieved successfully`);
254
215
  return result;
255
216
  }
256
217
  catch (error) {
257
- this.logger.warn(`Failed to convert currency using one of the endpoints`);
258
218
  lastError = error;
259
219
  }
260
220
  }
261
- this.logger.error('All endpoints failed to convert currency');
262
221
  throw (0, errors_1.allEndpointsFailedError)(lastError, waitOptions?.includeErrorTrace ?? false);
263
222
  };
264
- return waitOptions
265
- ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn, 'OperationTracker: Converting currency')
266
- : await requestFn();
223
+ return waitOptions === null
224
+ ? await requestFn()
225
+ : await (0, Utils_1.waitUntilSuccess)({ logger: this.logger, ...waitOptions }, requestFn, `OperationTracker: Converting currency ${(0, Utils_1.formatObjectForLogging)(params)}`);
267
226
  }
268
227
  async simulateTACMessage(params, waitOptions) {
269
228
  Validator_1.Validator.validateTACSimulationParams(params);
270
- this.logger.debug(`Simulating TAC message: ${(0, Utils_1.formatObjectForLogging)(params)}`);
271
229
  const requestFn = async () => {
272
230
  let lastError;
273
231
  for (const client of this.clients) {
274
232
  try {
275
233
  const result = await client.simulateTACMessage(params);
276
- this.logger.debug(`Simulation result retrieved successfully`);
277
234
  return result;
278
235
  }
279
236
  catch (error) {
280
- this.logger.warn(`Failed to simulate TAC message using one of the endpoints`);
281
237
  lastError = error;
282
238
  }
283
239
  }
284
- this.logger.error('All endpoints failed to simulate TAC message');
285
240
  throw (0, errors_1.allEndpointsFailedError)(lastError, waitOptions?.includeErrorTrace ?? false);
286
241
  };
287
- return waitOptions
288
- ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn, 'OperationTracker: Simulating TAC message')
289
- : await requestFn();
242
+ return waitOptions === null
243
+ ? await requestFn()
244
+ : await (0, Utils_1.waitUntilSuccess)({ logger: this.logger, ...waitOptions }, requestFn, `OperationTracker: Simulating TAC message ${(0, Utils_1.formatObjectForLogging)(params)}`);
290
245
  }
291
246
  async getTVMExecutorFee(params, waitOptions) {
292
- this.logger.debug(`get TVM executor fee: ${(0, Utils_1.formatObjectForLogging)(params)}`);
293
247
  const requestFn = async () => {
294
248
  let lastError;
295
249
  for (const client of this.clients) {
296
250
  try {
297
251
  const result = await client.getTVMExecutorFee(params);
298
- this.logger.debug(`Suggested TVM executor fee retrieved successfully`);
299
252
  return result;
300
253
  }
301
254
  catch (error) {
302
- this.logger.warn(`Failed to get TVM executor fee using one of the endpoints`);
303
255
  lastError = error;
304
256
  }
305
257
  }
306
- this.logger.error('All endpoints failed to get TVM executor fee');
307
258
  throw (0, errors_1.allEndpointsFailedError)(lastError, waitOptions?.includeErrorTrace ?? false);
308
259
  };
309
- return waitOptions
310
- ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn, 'OperationTracker: Getting TVM executor fee')
311
- : await requestFn();
260
+ return waitOptions === null
261
+ ? await requestFn()
262
+ : await (0, Utils_1.waitUntilSuccess)({ logger: this.logger, ...waitOptions }, requestFn, `OperationTracker: Getting TVM executor fee ${(0, Utils_1.formatObjectForLogging)(params)}`);
312
263
  }
313
264
  }
314
265
  exports.OperationTracker = OperationTracker;
@@ -42,7 +42,7 @@ class TacSdk {
42
42
  throw new Error(`Unsupported network: ${network}`);
43
43
  }
44
44
  const config = await Configuration_1.Configuration.create(network, artifacts, sdkParams.TONParams, sdkParams.TACParams, sdkParams.customLiteSequencerEndpoints, delay, logger, passLoggerToOpeners);
45
- const operationTracker = new OperationTracker_1.OperationTracker(network, config.liteSequencerEndpoints);
45
+ const operationTracker = new OperationTracker_1.OperationTracker(network, config.liteSequencerEndpoints, logger);
46
46
  const explorerClient = new TacExplorerClient_1.TacExplorerClient(artifacts.TAC_EXPLORER_API_ENDPOINT);
47
47
  const simulator = new Simulator_1.Simulator(config, operationTracker, logger);
48
48
  const tonTransactionManager = new TONTransactionManager_1.TONTransactionManager(config, simulator, operationTracker, logger);
@@ -151,13 +151,12 @@ const generateFeeData = (feeParams) => {
151
151
  };
152
152
  exports.generateFeeData = generateFeeData;
153
153
  async function waitUntilSuccess(options = {}, operation, operationDescription, ...args) {
154
- const timeout = options.timeout ?? 300000;
155
- const maxAttempts = options.maxAttempts ?? 30;
156
- const delay = options.delay ?? 10000;
154
+ const timeout = options.timeout ?? Struct_1.defaultWaitOptions.timeout;
155
+ const maxAttempts = options.maxAttempts ?? Struct_1.defaultWaitOptions.maxAttempts;
156
+ const delay = options.delay ?? Struct_1.defaultWaitOptions.delay;
157
157
  const successCheck = options.successCheck;
158
158
  const context = options.context;
159
159
  const contextPrefix = operationDescription ? `[${operationDescription}] ` : '';
160
- options.logger?.debug(`${contextPrefix}Starting wait for success with timeout=${timeout}ms, maxAttempts=${maxAttempts}, delay=${delay}ms`);
161
160
  const startTime = Date.now();
162
161
  let attempt = 1;
163
162
  while (true) {
@@ -171,8 +170,7 @@ async function waitUntilSuccess(options = {}, operation, operationDescription, .
171
170
  if (successCheck && !successCheck(result, context)) {
172
171
  throw new Error(`Result is not successful: ${formatObjectForLogging(result)}`);
173
172
  }
174
- options.logger?.debug(`${contextPrefix}Attempt ${attempt} successful`);
175
- // Execute custom onSuccess callback if provided
173
+ options.logger?.debug(`${contextPrefix}Success (attempt ${attempt}/${maxAttempts})`);
176
174
  if (options.onSuccess) {
177
175
  try {
178
176
  await options.onSuccess(result, context);
@@ -197,7 +195,11 @@ async function waitUntilSuccess(options = {}, operation, operationDescription, .
197
195
  options.logger?.debug(`${contextPrefix}${pendingMessage}`);
198
196
  }
199
197
  else {
200
- options.logger?.debug(`${contextPrefix}attempt=${attempt}/${maxAttempts} failed; retry_in=${delay}ms; error=${String(error)}`);
198
+ let errorMessage = error instanceof Error ? error.message : String(error);
199
+ if (errorMessage.includes('<!doctype html>') || errorMessage.includes('<html')) {
200
+ errorMessage = errorMessage.replace(/<!doctype html>[\s\S]*?<\/html>/gi, '[HTML response]');
201
+ }
202
+ options.logger?.debug(`${contextPrefix}attempt=${attempt}/${maxAttempts} failed; retry_in=${delay}ms; error=${errorMessage}`);
201
203
  }
202
204
  await (0, exports.sleep)(delay);
203
205
  attempt++;
@@ -353,17 +353,17 @@ export type BatchCrossChainTxWithAssetLike = Omit<BatchCrossChainTx, 'assets'> &
353
353
  export interface WaitOptions<T = unknown, TContext = unknown> {
354
354
  /**
355
355
  * Timeout in milliseconds
356
- * @default 300000 (5 minutes)
356
+ * @default 30000 (5 minutes)
357
357
  */
358
358
  timeout?: number;
359
359
  /**
360
360
  * Maximum number of attempts
361
- * @default 30
361
+ * @default 10
362
362
  */
363
363
  maxAttempts?: number;
364
364
  /**
365
365
  * Delay between attempts in milliseconds
366
- * @default 10000 (10 seconds)
366
+ * @default 1000 (1 seconds)
367
367
  */
368
368
  delay?: number;
369
369
  /**
@@ -496,11 +496,21 @@ export type TrackTransactionTreeParams = {
496
496
  */
497
497
  direction?: 'forward' | 'backward' | 'both';
498
498
  /**
499
- * Internal option: wait for the root transaction to appear before failing with `not_found`.
500
- * Useful right after sending a message when transaction indexing is eventually consistent.
499
+ * Retry transaction lookup when `not_found` error occurs.
500
+ * Useful when transaction indexing has delays or when transactions appear gradually.
501
501
  * @default true
502
502
  */
503
- waitForRootTransaction?: boolean;
503
+ retryOnNotFound?: boolean;
504
+ /**
505
+ * Delay in milliseconds between retry attempts for transaction lookup
506
+ * @default 5000
507
+ */
508
+ retryDelayMs?: number;
509
+ /**
510
+ * Number of retry attempts for transaction lookup
511
+ * @default 10
512
+ */
513
+ retries?: number;
504
514
  };
505
515
  /**
506
516
  * Details about a transaction validation error
@@ -570,6 +580,8 @@ export type GetTransactionsOptions = {
570
580
  timeoutMs?: number;
571
581
  /** Delay between retry attempts in milliseconds */
572
582
  retryDelayMs?: number;
583
+ /** Number of retry attempts */
584
+ retries?: number;
573
585
  /** Internal scan guard: maximum transactions to inspect while traversing history */
574
586
  maxScannedTransactions?: number;
575
587
  };
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Origin = exports.defaultWaitOptions = exports.TokenSymbol = exports.StageName = exports.NFTAddressType = exports.AssetType = exports.OperationType = exports.CurrencyType = exports.BlockchainType = exports.Network = exports.SimplifiedStatuses = void 0;
4
+ const Consts_1 = require("../sdk/Consts");
4
5
  var SimplifiedStatuses;
5
6
  (function (SimplifiedStatuses) {
6
7
  SimplifiedStatuses["PENDING"] = "PENDING";
@@ -58,9 +59,9 @@ var TokenSymbol;
58
59
  TokenSymbol["TON_SYMBOL"] = "TON";
59
60
  })(TokenSymbol || (exports.TokenSymbol = TokenSymbol = {}));
60
61
  exports.defaultWaitOptions = {
61
- timeout: 300000,
62
- maxAttempts: 30,
63
- delay: 10000,
62
+ timeout: Consts_1.DEFAULT_WAIT_TIMEOUT_MS,
63
+ maxAttempts: Consts_1.DEFAULT_WAIT_MAX_ATTEMPTS,
64
+ delay: Consts_1.DEFAULT_WAIT_DELAY_MS,
64
65
  };
65
66
  var Origin;
66
67
  (function (Origin) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tonappchain/sdk",
3
- "version": "0.7.2-alpha-20",
3
+ "version": "0.7.2-alpha-22",
4
4
  "repository": "https://github.com/TacBuild/tac-sdk.git",
5
5
  "author": "TAC. <developers@tac>",
6
6
  "license": "MIT",