@tonappchain/sdk 0.6.6-mainnet-alpha → 0.7.0-rc10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +191 -191
  3. package/dist/adapters/contractOpener.d.ts +6 -5
  4. package/dist/adapters/contractOpener.js +6 -6
  5. package/dist/adapters/retryableContractOpener.d.ts +9 -5
  6. package/dist/adapters/retryableContractOpener.js +2 -2
  7. package/dist/assets/AssetCache.d.ts +23 -0
  8. package/dist/assets/AssetCache.js +36 -0
  9. package/dist/assets/AssetFactory.d.ts +7 -0
  10. package/dist/assets/AssetFactory.js +46 -0
  11. package/dist/assets/FT.d.ts +58 -0
  12. package/dist/assets/FT.js +231 -0
  13. package/dist/assets/NFT.d.ts +65 -0
  14. package/dist/assets/NFT.js +210 -0
  15. package/dist/assets/TON.d.ts +38 -0
  16. package/dist/assets/TON.js +91 -0
  17. package/dist/assets/index.d.ts +4 -0
  18. package/dist/assets/index.js +11 -0
  19. package/dist/errors/errors.d.ts +6 -0
  20. package/dist/errors/errors.js +15 -1
  21. package/dist/errors/index.d.ts +2 -2
  22. package/dist/errors/index.js +26 -22
  23. package/dist/errors/instances.d.ts +4 -1
  24. package/dist/errors/instances.js +11 -2
  25. package/dist/index.d.ts +7 -0
  26. package/dist/index.js +14 -1
  27. package/dist/interfaces/IAsset.d.ts +73 -0
  28. package/dist/interfaces/IAsset.js +2 -0
  29. package/dist/interfaces/IConfiguration.d.ts +35 -0
  30. package/dist/interfaces/IConfiguration.js +2 -0
  31. package/dist/interfaces/IContractOpener.d.ts +21 -0
  32. package/dist/interfaces/IContractOpener.js +2 -0
  33. package/dist/interfaces/IHttpClient.d.ts +16 -0
  34. package/dist/interfaces/IHttpClient.js +2 -0
  35. package/dist/interfaces/ILiteSequencerClient.d.ts +30 -0
  36. package/dist/interfaces/ILiteSequencerClient.js +2 -0
  37. package/dist/interfaces/ILiteSequencerClientFactory.d.ts +9 -0
  38. package/dist/interfaces/ILiteSequencerClientFactory.js +2 -0
  39. package/dist/interfaces/ILogger.d.ts +10 -0
  40. package/dist/interfaces/ILogger.js +2 -0
  41. package/dist/interfaces/IOperationTracker.d.ts +66 -0
  42. package/dist/interfaces/IOperationTracker.js +2 -0
  43. package/dist/interfaces/ISender.d.ts +35 -0
  44. package/dist/interfaces/ISender.js +2 -0
  45. package/dist/interfaces/ISimulator.d.ts +47 -0
  46. package/dist/interfaces/ISimulator.js +2 -0
  47. package/dist/interfaces/ITacSDK.d.ts +147 -0
  48. package/dist/interfaces/ITacSDK.js +2 -0
  49. package/dist/interfaces/ITransactionManager.d.ts +35 -0
  50. package/dist/interfaces/ITransactionManager.js +2 -0
  51. package/dist/interfaces/IWallet.d.ts +20 -0
  52. package/dist/interfaces/IWallet.js +2 -0
  53. package/dist/interfaces/index.d.ts +13 -0
  54. package/dist/interfaces/index.js +29 -0
  55. package/dist/sdk/AxiosHttpClient.d.ts +12 -0
  56. package/dist/sdk/AxiosHttpClient.js +23 -0
  57. package/dist/sdk/Configuration.d.ts +21 -0
  58. package/dist/sdk/Configuration.js +90 -0
  59. package/dist/sdk/LiteSequencerClient.d.ts +6 -2
  60. package/dist/sdk/LiteSequencerClient.js +58 -14
  61. package/dist/sdk/Logger.d.ts +13 -0
  62. package/dist/sdk/Logger.js +25 -0
  63. package/dist/sdk/OperationTracker.d.ts +10 -5
  64. package/dist/sdk/OperationTracker.js +87 -45
  65. package/dist/sdk/Simulator.d.ts +17 -0
  66. package/dist/sdk/Simulator.js +163 -0
  67. package/dist/sdk/StartTracking.d.ts +6 -0
  68. package/dist/sdk/StartTracking.js +69 -32
  69. package/dist/sdk/TacSdk.d.ts +27 -44
  70. package/dist/sdk/TacSdk.js +121 -816
  71. package/dist/sdk/TransactionManager.d.ts +22 -0
  72. package/dist/sdk/TransactionManager.js +272 -0
  73. package/dist/sdk/TxFinalizer.d.ts +10 -0
  74. package/dist/sdk/TxFinalizer.js +104 -0
  75. package/dist/sdk/Utils.d.ts +7 -2
  76. package/dist/sdk/Utils.js +43 -24
  77. package/dist/sdk/Validator.d.ts +9 -0
  78. package/dist/sdk/Validator.js +43 -0
  79. package/dist/sender/BatchSender.d.ts +7 -5
  80. package/dist/sender/BatchSender.js +18 -6
  81. package/dist/sender/RawSender.d.ts +11 -6
  82. package/dist/sender/RawSender.js +46 -18
  83. package/dist/sender/SenderFactory.d.ts +2 -2
  84. package/dist/sender/SenderFactory.js +5 -4
  85. package/dist/sender/TonConnectSender.d.ts +7 -5
  86. package/dist/sender/TonConnectSender.js +14 -10
  87. package/dist/sender/index.d.ts +2 -2
  88. package/dist/sender/index.js +2 -2
  89. package/dist/structs/InternalStruct.d.ts +52 -33
  90. package/dist/structs/Struct.d.ts +92 -94
  91. package/dist/structs/Struct.js +11 -1
  92. package/dist/wrappers/HighloadQueryId.js +0 -1
  93. package/dist/wrappers/HighloadWalletV3.d.ts +4 -3
  94. package/dist/wrappers/HighloadWalletV3.js +5 -2
  95. package/package.json +67 -67
  96. package/dist/sender/SenderAbstraction.d.ts +0 -20
  97. package/dist/sender/SenderAbstraction.js +0 -5
@@ -1,20 +1,34 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.LiteSequencerClient = void 0;
7
- const axios_1 = __importDefault(require("axios"));
8
4
  const errors_1 = require("../errors");
9
5
  const Utils_1 = require("./Utils");
6
+ const AxiosHttpClient_1 = require("./AxiosHttpClient");
10
7
  class LiteSequencerClient {
11
- constructor(endpoint, maxChunkSize = 100) {
8
+ constructor(endpoint, maxChunkSize = 100, httpClient = new AxiosHttpClient_1.AxiosHttpClient()) {
12
9
  this.endpoint = endpoint;
13
10
  this.maxChunkSize = maxChunkSize;
11
+ this.httpClient = httpClient;
12
+ }
13
+ async getOperationIdByTransactionHash(transactionHash) {
14
+ const isEthHash = /^0x[a-fA-F0-9]{64}$/.test(transactionHash);
15
+ const path = isEthHash ? 'tac/operation-id' : 'ton/operation-id';
16
+ try {
17
+ const response = await this.httpClient.get(new URL(path, this.endpoint).toString(), {
18
+ params: { transactionHash },
19
+ });
20
+ return response.data.response || '';
21
+ }
22
+ catch (error) {
23
+ if (error?.response?.status === 404) {
24
+ return '';
25
+ }
26
+ throw (0, errors_1.operationFetchError)(`endpoint ${this.endpoint} failed to complete request`, error);
27
+ }
14
28
  }
15
29
  async getOperationType(operationId) {
16
30
  try {
17
- const response = await axios_1.default.get(new URL('operation-type', this.endpoint).toString(), {
31
+ const response = await this.httpClient.get(new URL('operation-type', this.endpoint).toString(), {
18
32
  params: {
19
33
  operationId,
20
34
  },
@@ -33,14 +47,12 @@ class LiteSequencerClient {
33
47
  timestamp: transactionLinker.timestamp,
34
48
  };
35
49
  try {
36
- const response = await axios_1.default.post(new URL('ton/operation-id', this.endpoint).toString(), requestBody);
50
+ const response = await this.httpClient.post(new URL('ton/operation-id', this.endpoint).toString(), requestBody);
37
51
  return response.data.response || '';
38
52
  }
39
53
  catch (error) {
40
- if (axios_1.default.isAxiosError(error)) {
41
- if (error.response?.status === 404) {
42
- return '';
43
- }
54
+ if (error?.response?.status === 404) {
55
+ return '';
44
56
  }
45
57
  throw (0, errors_1.operationFetchError)(`endpoint ${this.endpoint} failed to complete request`, error);
46
58
  }
@@ -51,7 +63,7 @@ class LiteSequencerClient {
51
63
  }
52
64
  try {
53
65
  const response = await this.processChunkedRequest(shardsKeys, async (chunk) => {
54
- const response = await axios_1.default.post(new URL('operation-ids-by-shards-keys', this.endpoint).toString(), {
66
+ const response = await this.httpClient.post(new URL('operation-ids-by-shards-keys', this.endpoint).toString(), {
55
67
  shardsKeys: chunk,
56
68
  caller: caller,
57
69
  });
@@ -69,7 +81,7 @@ class LiteSequencerClient {
69
81
  }
70
82
  try {
71
83
  const response = await this.processChunkedRequest(operationIds, async (chunk) => {
72
- const response = await axios_1.default.post(new URL('stage-profiling', this.endpoint).toString(), {
84
+ const response = await this.httpClient.post(new URL('stage-profiling', this.endpoint).toString(), {
73
85
  operationIds: chunk,
74
86
  }, {
75
87
  transformResponse: [Utils_1.toCamelCaseTransformer],
@@ -88,7 +100,7 @@ class LiteSequencerClient {
88
100
  }
89
101
  try {
90
102
  const response = await this.processChunkedRequest(operationIds, async (chunk) => {
91
- const response = await axios_1.default.post(new URL('status', this.endpoint).toString(), {
103
+ const response = await this.httpClient.post(new URL('status', this.endpoint).toString(), {
92
104
  operationIds: chunk,
93
105
  }, {
94
106
  transformResponse: [Utils_1.toCamelCaseTransformer],
@@ -101,6 +113,38 @@ class LiteSequencerClient {
101
113
  throw (0, errors_1.statusFetchError)(`endpoint ${this.endpoint} failed to complete request`, error);
102
114
  }
103
115
  }
116
+ async convertCurrency(params) {
117
+ try {
118
+ const payload = {
119
+ currencyType: params.currencyType,
120
+ rawValue: params.rawValue.toString(),
121
+ };
122
+ const response = await this.httpClient.post(new URL('convert_currency', this.endpoint).toString(), payload, {
123
+ transformResponse: [Utils_1.toCamelCaseTransformer],
124
+ });
125
+ const raw = response.data.response;
126
+ return {
127
+ spotRawValue: BigInt(raw.spotRawValue),
128
+ spotFriendlyValue: raw.spotFriendlyValue,
129
+ emaValue: BigInt(raw.emaValue),
130
+ emaFriendlyValue: raw.emaFriendlyValue,
131
+ spotValueInUSD: Number(raw.spotValueInUSD),
132
+ emaValueInUSD: Number(raw.emaValueInUSD),
133
+ currencyType: raw.currencyType,
134
+ tacPrice: {
135
+ spot: BigInt(raw.tacPrice.spot),
136
+ ema: BigInt(raw.tacPrice.ema),
137
+ },
138
+ tonPrice: {
139
+ spot: BigInt(raw.tonPrice.spot),
140
+ ema: BigInt(raw.tonPrice.ema),
141
+ },
142
+ };
143
+ }
144
+ catch (error) {
145
+ throw (0, errors_1.operationFetchError)(`endpoint ${this.endpoint} failed to complete request`, error);
146
+ }
147
+ }
104
148
  async processChunkedRequest(identificators, requestFn, chunkSize = this.maxChunkSize) {
105
149
  const results = [];
106
150
  for (let i = 0; i < identificators.length; i += chunkSize) {
@@ -0,0 +1,13 @@
1
+ import { ILogger } from '../interfaces';
2
+ export declare class ConsoleLogger implements ILogger {
3
+ debug(...arg: unknown[]): void;
4
+ info(...arg: unknown[]): void;
5
+ warn(...arg: unknown[]): void;
6
+ error(...arg: unknown[]): void;
7
+ }
8
+ export declare class NoopLogger implements ILogger {
9
+ debug(): void;
10
+ info(): void;
11
+ warn(): void;
12
+ error(): void;
13
+ }
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NoopLogger = exports.ConsoleLogger = void 0;
4
+ class ConsoleLogger {
5
+ debug(...arg) {
6
+ console.debug(`[DEBUG]`, ...arg);
7
+ }
8
+ info(...arg) {
9
+ console.info(`[INFO]`, ...arg);
10
+ }
11
+ warn(...arg) {
12
+ console.warn(`[WARN]`, ...arg);
13
+ }
14
+ error(...arg) {
15
+ console.error(`[ERROR]`, ...arg);
16
+ }
17
+ }
18
+ exports.ConsoleLogger = ConsoleLogger;
19
+ class NoopLogger {
20
+ debug() { }
21
+ info() { }
22
+ warn() { }
23
+ error() { }
24
+ }
25
+ exports.NoopLogger = NoopLogger;
@@ -1,9 +1,13 @@
1
- import { ExecutionStages, ExecutionStagesByOperationId, Network, OperationIdsByShardsKey, OperationType, SimplifiedStatuses, StatusInfo, StatusInfosByOperationId, TransactionLinker, WaitOptions } from '../structs/Struct';
2
- export declare class OperationTracker {
1
+ import { ILogger, IOperationTracker, ILiteSequencerClientFactory, ILiteSequencerClient } from '../interfaces';
2
+ import { ConvertCurrencyParams, ConvertedCurrencyResult, ExecutionStages, ExecutionStagesByOperationId, Network, OperationIdsByShardsKey, OperationType, SimplifiedStatuses, StatusInfo, StatusInfosByOperationId, TransactionLinker, WaitOptions } from '../structs/Struct';
3
+ export declare class DefaultLiteSequencerClientFactory implements ILiteSequencerClientFactory {
4
+ createClients(endpoints: string[]): ILiteSequencerClient[];
5
+ }
6
+ export declare class OperationTracker implements IOperationTracker {
3
7
  private readonly clients;
4
- private readonly debug;
5
- constructor(network: Network, customLiteSequencerEndpoints?: string[], debug?: boolean);
6
- private debugLog;
8
+ private readonly logger;
9
+ constructor(network: Network, customLiteSequencerEndpoints?: string[], logger?: ILogger, clientFactory?: ILiteSequencerClientFactory);
10
+ getOperationIdByTransactionHash(transactionHash: string, waitOptions?: WaitOptions<string>): Promise<string>;
7
11
  getOperationType(operationId: string, waitOptions?: WaitOptions<OperationType>): Promise<OperationType>;
8
12
  getOperationId(transactionLinker: TransactionLinker, waitOptions?: WaitOptions<string>): Promise<string>;
9
13
  getOperationIdsByShardsKeys(shardsKeys: string[], caller: string, waitOptions?: WaitOptions<OperationIdsByShardsKey>, chunkSize?: number): Promise<OperationIdsByShardsKey>;
@@ -12,4 +16,5 @@ export declare class OperationTracker {
12
16
  getOperationStatuses(operationIds: string[], waitOptions?: WaitOptions<StatusInfosByOperationId>, chunkSize?: number): Promise<StatusInfosByOperationId>;
13
17
  getOperationStatus(operationId: string, waitOptions?: WaitOptions<StatusInfo>): Promise<StatusInfo>;
14
18
  getSimplifiedOperationStatus(transactionLinker: TransactionLinker): Promise<SimplifiedStatuses>;
19
+ convertCurrency(params: ConvertCurrencyParams, waitOptions?: WaitOptions<ConvertedCurrencyResult>): Promise<ConvertedCurrencyResult>;
15
20
  }
@@ -1,88 +1,110 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.OperationTracker = void 0;
3
+ exports.OperationTracker = exports.DefaultLiteSequencerClientFactory = void 0;
4
4
  const artifacts_1 = require("@tonappchain/artifacts");
5
5
  const errors_1 = require("../errors");
6
6
  const Struct_1 = require("../structs/Struct");
7
7
  const LiteSequencerClient_1 = require("./LiteSequencerClient");
8
+ const Logger_1 = require("./Logger");
8
9
  const Utils_1 = require("./Utils");
10
+ class DefaultLiteSequencerClientFactory {
11
+ createClients(endpoints) {
12
+ return endpoints.map((endpoint) => new LiteSequencerClient_1.LiteSequencerClient(endpoint));
13
+ }
14
+ }
15
+ exports.DefaultLiteSequencerClientFactory = DefaultLiteSequencerClientFactory;
9
16
  class OperationTracker {
10
- constructor(network, customLiteSequencerEndpoints, debug = false) {
17
+ constructor(network, customLiteSequencerEndpoints, logger = new Logger_1.NoopLogger(), clientFactory = new DefaultLiteSequencerClientFactory()) {
11
18
  const endpoints = customLiteSequencerEndpoints ??
12
19
  (network === Struct_1.Network.TESTNET
13
20
  ? artifacts_1.testnet.PUBLIC_LITE_SEQUENCER_ENDPOINTS
14
21
  : artifacts_1.mainnet.PUBLIC_LITE_SEQUENCER_ENDPOINTS);
15
- this.clients = endpoints.map((endpoint) => new LiteSequencerClient_1.LiteSequencerClient(endpoint));
16
- this.debug = debug;
22
+ this.clients = clientFactory.createClients(endpoints);
23
+ this.logger = logger;
17
24
  }
18
- debugLog(message) {
19
- if (this.debug) {
20
- console.log(`[OperationTracker Debug] ${message}`);
21
- }
25
+ async getOperationIdByTransactionHash(transactionHash, waitOptions) {
26
+ this.logger.debug(`Getting operation ID for transactionHash: ${(0, Utils_1.formatObjectForLogging)(transactionHash)}`);
27
+ const requestFn = async () => {
28
+ let lastError;
29
+ for (const client of this.clients) {
30
+ try {
31
+ const id = await client.getOperationIdByTransactionHash(transactionHash);
32
+ this.logger.debug(`Operation ID ${id == '' ? 'does not exist' : 'retrieved successfully'}`);
33
+ return id;
34
+ }
35
+ catch (error) {
36
+ this.logger.warn(`Failed to get OperationId by transactionHash using one of the endpoints`);
37
+ lastError = error;
38
+ }
39
+ }
40
+ this.logger.error('All endpoints failed to get operation id by transactionHash');
41
+ throw (0, errors_1.allEndpointsFailedError)(lastError);
42
+ };
43
+ return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn) : await requestFn();
22
44
  }
23
45
  async getOperationType(operationId, waitOptions) {
24
- this.debugLog(`Getting operation type for ${(0, Utils_1.formatObjectForLogging)(operationId)}`);
46
+ this.logger.debug(`Getting operation type for ${(0, Utils_1.formatObjectForLogging)(operationId)}`);
25
47
  const requestFn = async () => {
26
48
  let lastError;
27
49
  for (const client of this.clients) {
28
50
  try {
29
51
  const type = await client.getOperationType(operationId);
30
- this.debugLog(`Operation retrieved successfully`);
52
+ this.logger.debug(`Operation retrieved successfully`);
31
53
  return type;
32
54
  }
33
55
  catch (error) {
34
- this.debugLog(`Failed to get operationType using one of the endpoints`);
56
+ this.logger.warn(`Failed to get operationType using one of the endpoints`);
35
57
  lastError = error;
36
58
  }
37
59
  }
38
- this.debugLog('All endpoints failed to get operation type');
60
+ this.logger.error('All endpoints failed to get operation type');
39
61
  throw (0, errors_1.allEndpointsFailedError)(lastError);
40
62
  };
41
63
  return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn) : await requestFn();
42
64
  }
43
65
  async getOperationId(transactionLinker, waitOptions) {
44
- this.debugLog(`Getting operation ID for transaction linker: ${(0, Utils_1.formatObjectForLogging)(transactionLinker)}`);
66
+ this.logger.debug(`Getting operation ID for transaction linker: ${(0, Utils_1.formatObjectForLogging)(transactionLinker)}`);
45
67
  const requestFn = async () => {
46
68
  let lastError;
47
69
  for (const client of this.clients) {
48
70
  try {
49
71
  const id = await client.getOperationId(transactionLinker);
50
- this.debugLog(`Operation ID ${id == '' ? 'does not exist' : 'retrieved successfully'}`);
72
+ this.logger.debug(`Operation ID ${id == '' ? 'does not exist' : 'retrieved successfully'}`);
51
73
  return id;
52
74
  }
53
75
  catch (error) {
54
- this.debugLog(`Failed to get OperationId using one of the endpoints`);
76
+ this.logger.warn(`Failed to get OperationId using one of the endpoints`);
55
77
  lastError = error;
56
78
  }
57
79
  }
58
- this.debugLog('All endpoints failed to get operation id');
80
+ this.logger.error('All endpoints failed to get operation id');
59
81
  throw (0, errors_1.allEndpointsFailedError)(lastError);
60
82
  };
61
83
  return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn) : await requestFn();
62
84
  }
63
85
  async getOperationIdsByShardsKeys(shardsKeys, caller, waitOptions, chunkSize = 100) {
64
- this.debugLog(`Getting operation IDs for shards keys: ${(0, Utils_1.formatObjectForLogging)(shardsKeys)}`);
65
- this.debugLog(`Caller: ${caller}, Chunk size: ${chunkSize}`);
86
+ this.logger.debug(`Getting operation IDs for shards keys: ${(0, Utils_1.formatObjectForLogging)(shardsKeys)}`);
87
+ this.logger.debug(`Caller: ${caller}, Chunk size: ${chunkSize}`);
66
88
  const requestFn = async () => {
67
89
  let lastError;
68
90
  for (const client of this.clients) {
69
91
  try {
70
92
  const result = await client.getOperationIdsByShardsKeys(shardsKeys, caller, chunkSize);
71
- this.debugLog(`Operation IDs by shards keys retrieved successfully`);
93
+ this.logger.debug(`Operation IDs by shards keys retrieved successfully`);
72
94
  return result;
73
95
  }
74
96
  catch (error) {
75
- this.debugLog(`Failed to get OperationIds using one of the endpoints`);
97
+ this.logger.warn(`Failed to get OperationIds using one of the endpoints`);
76
98
  lastError = error;
77
99
  }
78
100
  }
79
- this.debugLog('All endpoints failed to get operation ids by shards keys');
101
+ this.logger.error('All endpoints failed to get operation ids by shards keys');
80
102
  throw (0, errors_1.allEndpointsFailedError)(lastError);
81
103
  };
82
104
  return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn) : await requestFn();
83
105
  }
84
106
  async getStageProfiling(operationId, waitOptions) {
85
- this.debugLog(`Getting stage profiling for operation ${operationId}`);
107
+ this.logger.debug(`Getting stage profiling for operation ${operationId}`);
86
108
  const requestFn = async () => {
87
109
  let lastError;
88
110
  for (const client of this.clients) {
@@ -90,66 +112,66 @@ class OperationTracker {
90
112
  const map = await client.getStageProfilings([operationId]);
91
113
  const result = map[operationId];
92
114
  if (!result) {
93
- this.debugLog(`No stageProfiling data for operationId=${operationId}`);
115
+ this.logger.warn(`No stageProfiling data for operationId=${operationId}`);
94
116
  throw new Error(`No stageProfiling data for operationId=${operationId}`);
95
117
  }
96
- this.debugLog(`Stage profiling retrieved successfully`);
118
+ this.logger.debug(`Stage profiling retrieved successfully`);
97
119
  return result;
98
120
  }
99
121
  catch (error) {
100
- this.debugLog(`Failed to get stage profiling using one of the endpoints`);
122
+ this.logger.warn(`Failed to get stage profiling using one of the endpoints`);
101
123
  lastError = error;
102
124
  }
103
125
  }
104
- this.debugLog('All endpoints failed to get stage profiling');
126
+ this.logger.error('All endpoints failed to get stage profiling');
105
127
  throw (0, errors_1.allEndpointsFailedError)(lastError);
106
128
  };
107
129
  return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn) : await requestFn();
108
130
  }
109
131
  async getStageProfilings(operationIds, waitOptions, chunkSize = 100) {
110
- this.debugLog(`Getting stage profilings for operations: ${operationIds.join(', ')}`);
111
- this.debugLog(`Chunk size: ${chunkSize}`);
132
+ this.logger.debug(`Getting stage profilings for operations: ${operationIds.join(', ')}`);
133
+ this.logger.debug(`Chunk size: ${chunkSize}`);
112
134
  const requestFn = async () => {
113
135
  let lastError;
114
136
  for (const client of this.clients) {
115
137
  try {
116
138
  const result = await client.getStageProfilings(operationIds, chunkSize);
117
- this.debugLog(`Stage profilings retrieved successfully`);
139
+ this.logger.debug(`Stage profilings retrieved successfully`);
118
140
  return result;
119
141
  }
120
142
  catch (error) {
121
- this.debugLog(`Failed to get stage profilings using one of the endpoints`);
143
+ this.logger.warn(`Failed to get stage profilings using one of the endpoints`);
122
144
  lastError = error;
123
145
  }
124
146
  }
125
- this.debugLog('All endpoints failed to get stage profilings');
147
+ this.logger.error('All endpoints failed to get stage profilings');
126
148
  throw (0, errors_1.allEndpointsFailedError)(lastError);
127
149
  };
128
150
  return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn) : await requestFn();
129
151
  }
130
152
  async getOperationStatuses(operationIds, waitOptions, chunkSize = 100) {
131
- this.debugLog(`Getting operation statuses for operations: ${(0, Utils_1.formatObjectForLogging)(operationIds)}`);
132
- this.debugLog(`Chunk size: ${chunkSize}`);
153
+ this.logger.debug(`Getting operation statuses for operations: ${(0, Utils_1.formatObjectForLogging)(operationIds)}`);
154
+ this.logger.debug(`Chunk size: ${chunkSize}`);
133
155
  const requestFn = async () => {
134
156
  let lastError;
135
157
  for (const client of this.clients) {
136
158
  try {
137
159
  const result = await client.getOperationStatuses(operationIds, chunkSize);
138
- this.debugLog(`Operation statuses retrieved successfully`);
160
+ this.logger.debug(`Operation statuses retrieved successfully`);
139
161
  return result;
140
162
  }
141
163
  catch (error) {
142
- this.debugLog(`Failed to get operation statuses using one of the endpoints`);
164
+ this.logger.warn(`Failed to get operation statuses using one of the endpoints`);
143
165
  lastError = error;
144
166
  }
145
167
  }
146
- this.debugLog('All endpoints failed to get operation statuses');
168
+ this.logger.error('All endpoints failed to get operation statuses');
147
169
  throw (0, errors_1.allEndpointsFailedError)(lastError);
148
170
  };
149
171
  return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn) : await requestFn();
150
172
  }
151
173
  async getOperationStatus(operationId, waitOptions) {
152
- this.debugLog(`Getting operation status for ${(0, Utils_1.formatObjectForLogging)(operationId)}`);
174
+ this.logger.debug(`Getting operation status for ${(0, Utils_1.formatObjectForLogging)(operationId)}`);
153
175
  const requestFn = async () => {
154
176
  let lastError;
155
177
  for (const client of this.clients) {
@@ -157,32 +179,32 @@ class OperationTracker {
157
179
  const map = await client.getOperationStatuses([operationId]);
158
180
  const result = map[operationId];
159
181
  if (!result) {
160
- this.debugLog(`No operation status for operationId=${operationId}`);
182
+ this.logger.warn(`No operation status for operationId=${operationId}`);
161
183
  throw new Error(`No operation status for operationId=${operationId}`);
162
184
  }
163
- this.debugLog(`Operation status retrieved successfully`);
185
+ this.logger.debug(`Operation status retrieved successfully`);
164
186
  return result;
165
187
  }
166
188
  catch (error) {
167
- this.debugLog(`Failed to get operation status using one of the endpoints`);
189
+ this.logger.warn(`Failed to get operation status using one of the endpoints`);
168
190
  lastError = error;
169
191
  }
170
192
  }
171
- this.debugLog('All endpoints failed to get operation status');
193
+ this.logger.error('All endpoints failed to get operation status');
172
194
  throw (0, errors_1.allEndpointsFailedError)(lastError);
173
195
  };
174
196
  return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn) : await requestFn();
175
197
  }
176
198
  async getSimplifiedOperationStatus(transactionLinker) {
177
- this.debugLog(`Getting simplified operation status for transaction linker: ${(0, Utils_1.formatObjectForLogging)(transactionLinker)}`);
199
+ this.logger.debug(`Getting simplified operation status for transaction linker: ${(0, Utils_1.formatObjectForLogging)(transactionLinker)}`);
178
200
  const operationId = await this.getOperationId(transactionLinker);
179
201
  if (operationId == '') {
180
- this.debugLog('Operation ID not found');
202
+ this.logger.warn('Operation ID not found');
181
203
  return Struct_1.SimplifiedStatuses.OPERATION_ID_NOT_FOUND;
182
204
  }
183
- this.debugLog(`Operation ID: ${operationId}`);
205
+ this.logger.debug(`Operation ID: ${operationId}`);
184
206
  const operationType = await this.getOperationType(operationId);
185
- this.debugLog(`Operation type: ${operationType}`);
207
+ this.logger.debug(`Operation type: ${operationType}`);
186
208
  if (operationType == Struct_1.OperationType.PENDING || operationType == Struct_1.OperationType.UNKNOWN) {
187
209
  return Struct_1.SimplifiedStatuses.PENDING;
188
210
  }
@@ -191,5 +213,25 @@ class OperationTracker {
191
213
  }
192
214
  return Struct_1.SimplifiedStatuses.SUCCESSFUL;
193
215
  }
216
+ async convertCurrency(params, waitOptions) {
217
+ this.logger.debug(`Converting currency: ${(0, Utils_1.formatObjectForLogging)(params)}`);
218
+ const requestFn = async () => {
219
+ let lastError;
220
+ for (const client of this.clients) {
221
+ try {
222
+ const result = await client.convertCurrency(params);
223
+ this.logger.debug(`Conversion result retrieved successfully`);
224
+ return result;
225
+ }
226
+ catch (error) {
227
+ this.logger.warn(`Failed to convert currency using one of the endpoints`);
228
+ lastError = error;
229
+ }
230
+ }
231
+ this.logger.error('All endpoints failed to convert currency');
232
+ throw (0, errors_1.allEndpointsFailedError)(lastError);
233
+ };
234
+ return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn) : await requestFn();
235
+ }
194
236
  }
195
237
  exports.OperationTracker = OperationTracker;
@@ -0,0 +1,17 @@
1
+ import type { ISender } from '../sender';
2
+ import { IConfiguration, ILogger, ISimulator } from '../interfaces';
3
+ import { IAsset, CrosschainTx, EvmProxyMsg, ExecutionFeeEstimationResult, SuggestedTONExecutorFee, TACSimulationRequest, TACSimulationResult, TransactionLinker } from '../structs/Struct';
4
+ import { IHttpClient } from '../interfaces';
5
+ export declare class Simulator implements ISimulator {
6
+ private readonly config;
7
+ private readonly logger;
8
+ private readonly httpClient;
9
+ constructor(config: IConfiguration, logger?: ILogger, httpClient?: IHttpClient);
10
+ simulateTACMessage(req: TACSimulationRequest): Promise<TACSimulationResult>;
11
+ simulateTransactions(sender: ISender, txs: CrosschainTx[]): Promise<TACSimulationResult[]>;
12
+ private buildTACSimulationRequest;
13
+ getTVMExecutorFeeInfo(assets: IAsset[], feeSymbol: string, tvmValidExecutors?: string[]): Promise<SuggestedTONExecutorFee>;
14
+ private getFeeInfo;
15
+ getTransactionSimulationInfo(evmProxyMsg: EvmProxyMsg, sender: ISender, assets?: IAsset[]): Promise<ExecutionFeeEstimationResult>;
16
+ getSimulationInfoForTransaction(evmProxyMsg: EvmProxyMsg, transactionLinker: TransactionLinker, assets: IAsset[], allowSimulationError?: boolean, isRoundTrip?: boolean, evmValidExecutors?: string[], tvmValidExecutors?: string[], calculateRollbackFee?: boolean): Promise<ExecutionFeeEstimationResult>;
17
+ }
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Simulator = void 0;
4
+ const ton_1 = require("@ton/ton");
5
+ const errors_1 = require("../errors");
6
+ const Logger_1 = require("./Logger");
7
+ const Utils_1 = require("./Utils");
8
+ const Validator_1 = require("./Validator");
9
+ const AxiosHttpClient_1 = require("./AxiosHttpClient");
10
+ class Simulator {
11
+ constructor(config, logger = new Logger_1.NoopLogger(), httpClient = new AxiosHttpClient_1.AxiosHttpClient()) {
12
+ this.config = config;
13
+ this.logger = logger;
14
+ this.httpClient = httpClient;
15
+ }
16
+ async simulateTACMessage(req) {
17
+ Validator_1.Validator.validateTACSimulationRequest(req);
18
+ this.logger.debug('Simulating TAC message');
19
+ let lastError;
20
+ for (const endpoint of this.config.liteSequencerEndpoints) {
21
+ try {
22
+ const response = await this.httpClient.post(new URL('tac/simulator/simulate-message', endpoint).toString(), req, {
23
+ transformResponse: [Utils_1.toCamelCaseTransformer],
24
+ });
25
+ this.logger.debug('TAC message simulation success');
26
+ return response.data.response;
27
+ }
28
+ catch (error) {
29
+ this.logger.error(`Error while simulating with ${endpoint}: ${error}`);
30
+ lastError = error;
31
+ }
32
+ }
33
+ throw (0, errors_1.simulationError)(lastError);
34
+ }
35
+ async simulateTransactions(sender, txs) {
36
+ this.logger.debug(`Simulating ${txs.length} TAC messages`);
37
+ const results = [];
38
+ for (const tx of txs) {
39
+ const req = await this.buildTACSimulationRequest(sender, tx);
40
+ const result = await this.simulateTACMessage(req);
41
+ results.push(result);
42
+ }
43
+ return results;
44
+ }
45
+ async buildTACSimulationRequest(sender, tx) {
46
+ const { evmProxyMsg, assets = [], options = {} } = tx;
47
+ const { evmValidExecutors = this.config.TACParams.trustedTACExecutors, tvmValidExecutors = this.config.TACParams.trustedTONExecutors, calculateRollbackFee = true, } = options;
48
+ Validator_1.Validator.validateEVMAddresses(evmValidExecutors);
49
+ Validator_1.Validator.validateTVMAddresses(tvmValidExecutors);
50
+ const aggregatedData = await (0, Utils_1.aggregateTokens)(assets);
51
+ const transactionLinkerShardCount = aggregatedData.jettons.length == 0 ? 1 : aggregatedData.jettons.length;
52
+ const transactionLinker = (0, Utils_1.generateTransactionLinker)(sender.getSenderAddress(), transactionLinkerShardCount);
53
+ return {
54
+ tacCallParams: {
55
+ arguments: evmProxyMsg.encodedParameters ?? '0x',
56
+ methodName: (0, Utils_1.formatSolidityMethodName)(evmProxyMsg.methodName),
57
+ target: evmProxyMsg.evmTargetAddress,
58
+ },
59
+ evmValidExecutors: evmValidExecutors,
60
+ tvmValidExecutors: tvmValidExecutors,
61
+ extraData: '0x',
62
+ shardsKey: transactionLinker.shardsKey,
63
+ tonAssets: assets.map((asset) => ({
64
+ amount: asset.rawAmount.toString(),
65
+ tokenAddress: asset.address || '',
66
+ assetType: asset.type,
67
+ })),
68
+ tonCaller: transactionLinker.caller,
69
+ calculateRollbackFee: calculateRollbackFee,
70
+ };
71
+ }
72
+ async getTVMExecutorFeeInfo(assets, feeSymbol, tvmValidExecutors = this.config.TACParams.trustedTONExecutors) {
73
+ this.logger.debug('Getting TVM executor fee info');
74
+ const requestBody = {
75
+ tonAssets: assets.map((asset) => ({
76
+ amount: asset.rawAmount.toString(),
77
+ tokenAddress: asset.address || '',
78
+ assetType: asset.type,
79
+ })),
80
+ feeSymbol: feeSymbol,
81
+ tvmValidExecutors: tvmValidExecutors,
82
+ };
83
+ let lastError;
84
+ for (const endpoint of this.config.liteSequencerEndpoints) {
85
+ try {
86
+ const response = await this.httpClient.post(`${endpoint}/ton/calculator/ton-executor-fee`, requestBody);
87
+ return response.data.response;
88
+ }
89
+ catch (error) {
90
+ this.logger.error(`Error while calculating tvm executor fee ${endpoint}: ${error}`);
91
+ lastError = error;
92
+ }
93
+ }
94
+ this.logger.error('Error while calculating tvm executor fee on all endpoints');
95
+ throw (0, errors_1.simulationError)(lastError);
96
+ }
97
+ async getFeeInfo(evmProxyMsg, transactionLinker, assets, allowSimulationError = false, isRoundTrip = true, evmValidExecutors = this.config.TACParams.trustedTACExecutors, tvmValidExecutors = this.config.TACParams.trustedTONExecutors, calculateRollbackFee = true) {
98
+ this.logger.debug('Getting fee info');
99
+ Validator_1.Validator.validateEVMAddress(evmProxyMsg.evmTargetAddress);
100
+ Validator_1.Validator.validateEVMAddresses(evmValidExecutors);
101
+ Validator_1.Validator.validateTVMAddresses(tvmValidExecutors);
102
+ const crossChainLayer = this.config.TONParams.contractOpener.open(this.config.artifacts.ton.wrappers.CrossChainLayer.createFromAddress(ton_1.Address.parse(this.config.TONParams.crossChainLayerAddress)));
103
+ const fullStateCCL = await crossChainLayer.getFullData();
104
+ this.logger.debug(`Full state CCL: ${(0, Utils_1.formatObjectForLogging)(fullStateCCL)}`);
105
+ const tacSimulationBody = {
106
+ tacCallParams: {
107
+ arguments: evmProxyMsg.encodedParameters ?? '0x',
108
+ methodName: (0, Utils_1.formatSolidityMethodName)(evmProxyMsg.methodName),
109
+ target: evmProxyMsg.evmTargetAddress,
110
+ },
111
+ evmValidExecutors: evmValidExecutors,
112
+ tvmValidExecutors: tvmValidExecutors,
113
+ extraData: '0x',
114
+ shardsKey: transactionLinker.shardsKey,
115
+ tonAssets: assets.map((asset) => ({
116
+ amount: asset.rawAmount.toString(),
117
+ tokenAddress: asset.address || '',
118
+ assetType: asset.type,
119
+ })),
120
+ tonCaller: transactionLinker.caller,
121
+ calculateRollbackFee: calculateRollbackFee,
122
+ };
123
+ isRoundTrip = isRoundTrip ?? assets.length != 0;
124
+ this.logger.debug(`Is round trip: ${isRoundTrip}`);
125
+ const tacSimulationResult = await this.simulateTACMessage(tacSimulationBody);
126
+ this.logger.debug(`TAC simulation ${tacSimulationResult.simulationStatus ? 'success' : 'failed'}`);
127
+ const protocolFee = BigInt((0, ton_1.toNano)(fullStateCCL.tacProtocolFee)) +
128
+ BigInt(isRoundTrip) * BigInt((0, ton_1.toNano)(fullStateCCL.tonProtocolFee));
129
+ const feeParams = {
130
+ isRoundTrip: isRoundTrip,
131
+ gasLimit: !tacSimulationResult.simulationStatus ? 0n : tacSimulationResult.estimatedGas,
132
+ protocolFee: protocolFee,
133
+ evmExecutorFee: BigInt(tacSimulationResult.suggestedTacExecutionFee),
134
+ tvmExecutorFee: BigInt(tacSimulationResult.suggestedTonExecutionFee) * BigInt(isRoundTrip),
135
+ };
136
+ if (!tacSimulationResult.simulationStatus) {
137
+ if (allowSimulationError) {
138
+ this.logger.info('Force send is true, returning fee params');
139
+ return {
140
+ feeParams,
141
+ simulation: tacSimulationResult,
142
+ };
143
+ }
144
+ throw tacSimulationResult;
145
+ }
146
+ this.logger.debug(`Collected fee params: ${(0, Utils_1.formatObjectForLogging)(feeParams)}`);
147
+ return { feeParams, simulation: tacSimulationResult };
148
+ }
149
+ async getTransactionSimulationInfo(evmProxyMsg, sender, assets) {
150
+ this.logger.debug('Getting transaction simulation info');
151
+ Validator_1.Validator.validateEVMAddress(evmProxyMsg.evmTargetAddress);
152
+ const aggregatedData = await (0, Utils_1.aggregateTokens)(assets);
153
+ const transactionLinkerShardCount = aggregatedData.jettons.length == 0 ? 1 : aggregatedData.jettons.length;
154
+ this.logger.debug(`Transaction linker shard count: ${transactionLinkerShardCount}`);
155
+ const transactionLinker = (0, Utils_1.generateTransactionLinker)(sender.getSenderAddress(), transactionLinkerShardCount);
156
+ this.logger.debug(`Transaction linker: ${(0, Utils_1.formatObjectForLogging)(transactionLinker)}`);
157
+ return await this.getFeeInfo(evmProxyMsg, transactionLinker, assets ?? []);
158
+ }
159
+ async getSimulationInfoForTransaction(evmProxyMsg, transactionLinker, assets, allowSimulationError = false, isRoundTrip, evmValidExecutors, tvmValidExecutors, calculateRollbackFee) {
160
+ return await this.getFeeInfo(evmProxyMsg, transactionLinker, assets, allowSimulationError, isRoundTrip, evmValidExecutors, tvmValidExecutors, calculateRollbackFee);
161
+ }
162
+ }
163
+ exports.Simulator = Simulator;