@tonappchain/sdk 0.7.0-rc13 → 0.7.0-rc15

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 (57) hide show
  1. package/README.md +7 -7
  2. package/dist/adapters/contractOpener.js +33 -4
  3. package/dist/adapters/retryableContractOpener.js +1 -1
  4. package/dist/assets/AssetFactory.js +1 -1
  5. package/dist/assets/FT.d.ts +8 -12
  6. package/dist/assets/FT.js +69 -36
  7. package/dist/assets/NFT.d.ts +4 -2
  8. package/dist/assets/NFT.js +14 -2
  9. package/dist/assets/TON.d.ts +4 -10
  10. package/dist/assets/TON.js +17 -15
  11. package/dist/errors/index.d.ts +1 -1
  12. package/dist/errors/index.js +7 -2
  13. package/dist/errors/instances.d.ts +8 -1
  14. package/dist/errors/instances.js +22 -16
  15. package/dist/index.d.ts +2 -1
  16. package/dist/index.js +5 -3
  17. package/dist/interfaces/Asset.d.ts +22 -17
  18. package/dist/interfaces/ILiteSequencerClient.d.ts +14 -1
  19. package/dist/interfaces/IOperationTracker.d.ts +16 -1
  20. package/dist/interfaces/ISimulator.d.ts +7 -36
  21. package/dist/interfaces/ITACTransactionManager.d.ts +15 -0
  22. package/dist/interfaces/ITONTransactionManager.d.ts +21 -0
  23. package/dist/interfaces/ITONTransactionManager.js +2 -0
  24. package/dist/interfaces/ITacSDK.d.ts +51 -13
  25. package/dist/interfaces/index.d.ts +2 -1
  26. package/dist/interfaces/index.js +2 -1
  27. package/dist/sdk/Configuration.d.ts +1 -0
  28. package/dist/sdk/Configuration.js +67 -14
  29. package/dist/sdk/Consts.d.ts +1 -0
  30. package/dist/sdk/Consts.js +5 -4
  31. package/dist/sdk/LiteSequencerClient.d.ts +5 -3
  32. package/dist/sdk/LiteSequencerClient.js +27 -4
  33. package/dist/sdk/OperationTracker.d.ts +3 -1
  34. package/dist/sdk/OperationTracker.js +51 -11
  35. package/dist/sdk/Simulator.d.ts +6 -12
  36. package/dist/sdk/Simulator.js +30 -124
  37. package/dist/sdk/TACTransactionManager.d.ts +10 -0
  38. package/dist/sdk/TACTransactionManager.js +92 -0
  39. package/dist/sdk/TONTransactionManager.d.ts +17 -0
  40. package/dist/sdk/TONTransactionManager.js +209 -0
  41. package/dist/sdk/TacSdk.d.ts +16 -10
  42. package/dist/sdk/TacSdk.js +52 -19
  43. package/dist/sdk/TxFinalizer.d.ts +3 -2
  44. package/dist/sdk/TxFinalizer.js +8 -8
  45. package/dist/sdk/Utils.d.ts +9 -4
  46. package/dist/sdk/Utils.js +86 -12
  47. package/dist/sdk/Validator.d.ts +2 -2
  48. package/dist/sdk/Validator.js +1 -1
  49. package/dist/structs/InternalStruct.d.ts +6 -2
  50. package/dist/structs/Struct.d.ts +70 -16
  51. package/dist/wrappers/Settings.d.ts +5 -1
  52. package/dist/wrappers/Settings.js +17 -0
  53. package/package.json +4 -3
  54. package/dist/interfaces/ITransactionManager.d.ts +0 -35
  55. package/dist/sdk/TransactionManager.d.ts +0 -22
  56. package/dist/sdk/TransactionManager.js +0 -272
  57. /package/dist/interfaces/{ITransactionManager.js → ITACTransactionManager.js} +0 -0
@@ -7,6 +7,7 @@ const Struct_1 = require("../structs/Struct");
7
7
  const LiteSequencerClient_1 = require("./LiteSequencerClient");
8
8
  const Logger_1 = require("./Logger");
9
9
  const Utils_1 = require("./Utils");
10
+ const Validator_1 = require("./Validator");
10
11
  class DefaultLiteSequencerClientFactory {
11
12
  createClients(endpoints) {
12
13
  return endpoints.map((endpoint) => new LiteSequencerClient_1.LiteSequencerClient(endpoint));
@@ -40,7 +41,7 @@ class OperationTracker {
40
41
  this.logger.error('All endpoints failed to get operation id by transactionHash');
41
42
  throw (0, errors_1.allEndpointsFailedError)(lastError);
42
43
  };
43
- return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn) : await requestFn();
44
+ return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn, "OperationTracker: Getting operation ID by transaction hash") : await requestFn();
44
45
  }
45
46
  async getOperationType(operationId, waitOptions) {
46
47
  this.logger.debug(`Getting operation type for ${(0, Utils_1.formatObjectForLogging)(operationId)}`);
@@ -60,7 +61,7 @@ class OperationTracker {
60
61
  this.logger.error('All endpoints failed to get operation type');
61
62
  throw (0, errors_1.allEndpointsFailedError)(lastError);
62
63
  };
63
- return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn) : await requestFn();
64
+ return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn, "OperationTracker: Getting operation type") : await requestFn();
64
65
  }
65
66
  async getOperationId(transactionLinker, waitOptions) {
66
67
  this.logger.debug(`Getting operation ID for transaction linker: ${(0, Utils_1.formatObjectForLogging)(transactionLinker)}`);
@@ -80,7 +81,7 @@ class OperationTracker {
80
81
  this.logger.error('All endpoints failed to get operation id');
81
82
  throw (0, errors_1.allEndpointsFailedError)(lastError);
82
83
  };
83
- return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn) : await requestFn();
84
+ return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn, "OperationTracker: Getting operation ID by transaction linker") : await requestFn();
84
85
  }
85
86
  async getOperationIdsByShardsKeys(shardsKeys, caller, waitOptions, chunkSize = 100) {
86
87
  this.logger.debug(`Getting operation IDs for shards keys: ${(0, Utils_1.formatObjectForLogging)(shardsKeys)}`);
@@ -101,7 +102,7 @@ class OperationTracker {
101
102
  this.logger.error('All endpoints failed to get operation ids by shards keys');
102
103
  throw (0, errors_1.allEndpointsFailedError)(lastError);
103
104
  };
104
- return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn) : await requestFn();
105
+ return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn, "OperationTracker: Getting operation IDs by shards keys") : await requestFn();
105
106
  }
106
107
  async getStageProfiling(operationId, waitOptions) {
107
108
  this.logger.debug(`Getting stage profiling for operation ${operationId}`);
@@ -126,7 +127,7 @@ class OperationTracker {
126
127
  this.logger.error('All endpoints failed to get stage profiling');
127
128
  throw (0, errors_1.allEndpointsFailedError)(lastError);
128
129
  };
129
- return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn) : await requestFn();
130
+ return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn, "OperationTracker: Getting stage profiling") : await requestFn();
130
131
  }
131
132
  async getStageProfilings(operationIds, waitOptions, chunkSize = 100) {
132
133
  this.logger.debug(`Getting stage profilings for operations: ${operationIds.join(', ')}`);
@@ -147,7 +148,7 @@ class OperationTracker {
147
148
  this.logger.error('All endpoints failed to get stage profilings');
148
149
  throw (0, errors_1.allEndpointsFailedError)(lastError);
149
150
  };
150
- return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn) : await requestFn();
151
+ return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn, "OperationTracker: Getting stage profilings") : await requestFn();
151
152
  }
152
153
  async getOperationStatuses(operationIds, waitOptions, chunkSize = 100) {
153
154
  this.logger.debug(`Getting operation statuses for operations: ${(0, Utils_1.formatObjectForLogging)(operationIds)}`);
@@ -168,7 +169,7 @@ class OperationTracker {
168
169
  this.logger.error('All endpoints failed to get operation statuses');
169
170
  throw (0, errors_1.allEndpointsFailedError)(lastError);
170
171
  };
171
- return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn) : await requestFn();
172
+ return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn, "OperationTracker: Getting operation statuses") : await requestFn();
172
173
  }
173
174
  async getOperationStatus(operationId, waitOptions) {
174
175
  this.logger.debug(`Getting operation status for ${(0, Utils_1.formatObjectForLogging)(operationId)}`);
@@ -193,7 +194,7 @@ class OperationTracker {
193
194
  this.logger.error('All endpoints failed to get operation status');
194
195
  throw (0, errors_1.allEndpointsFailedError)(lastError);
195
196
  };
196
- return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn) : await requestFn();
197
+ return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn, "OperationTracker: Getting operation status") : await requestFn();
197
198
  }
198
199
  async getSimplifiedOperationStatus(transactionLinker) {
199
200
  this.logger.debug(`Getting simplified operation status for transaction linker: ${(0, Utils_1.formatObjectForLogging)(transactionLinker)}`);
@@ -202,9 +203,7 @@ class OperationTracker {
202
203
  this.logger.warn('Operation ID not found');
203
204
  return Struct_1.SimplifiedStatuses.OPERATION_ID_NOT_FOUND;
204
205
  }
205
- this.logger.debug(`Operation ID: ${operationId}`);
206
206
  const operationType = await this.getOperationType(operationId);
207
- this.logger.debug(`Operation type: ${operationType}`);
208
207
  if (operationType == Struct_1.OperationType.PENDING || operationType == Struct_1.OperationType.UNKNOWN) {
209
208
  return Struct_1.SimplifiedStatuses.PENDING;
210
209
  }
@@ -231,7 +230,48 @@ class OperationTracker {
231
230
  this.logger.error('All endpoints failed to convert currency');
232
231
  throw (0, errors_1.allEndpointsFailedError)(lastError);
233
232
  };
234
- return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn) : await requestFn();
233
+ return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn, "OperationTracker: Converting currency") : await requestFn();
234
+ }
235
+ async simulateTACMessage(params, waitOptions) {
236
+ Validator_1.Validator.validateTACSimulationParams(params);
237
+ this.logger.debug(`Simulating TAC message: ${(0, Utils_1.formatObjectForLogging)(params)}`);
238
+ const requestFn = async () => {
239
+ let lastError;
240
+ for (const client of this.clients) {
241
+ try {
242
+ const result = await client.simulateTACMessage(params);
243
+ this.logger.debug(`Simulation result retrieved successfully`);
244
+ return result;
245
+ }
246
+ catch (error) {
247
+ this.logger.warn(`Failed to simulate TAC message using one of the endpoints`);
248
+ lastError = error;
249
+ }
250
+ }
251
+ this.logger.error('All endpoints failed to simulate TAC message');
252
+ throw (0, errors_1.allEndpointsFailedError)(lastError);
253
+ };
254
+ return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn, "OperationTracker: Simulating TAC message") : await requestFn();
255
+ }
256
+ async getTVMExecutorFee(params, waitOptions) {
257
+ this.logger.debug(`get TVM executor fee: ${(0, Utils_1.formatObjectForLogging)(params)}`);
258
+ const requestFn = async () => {
259
+ let lastError;
260
+ for (const client of this.clients) {
261
+ try {
262
+ const result = await client.getTVMExecutorFee(params);
263
+ this.logger.debug(`Suggested TVM executor fee retrieved successfully`);
264
+ return result;
265
+ }
266
+ catch (error) {
267
+ this.logger.warn(`Failed to get TVM executor fee using one of the endpoints`);
268
+ lastError = error;
269
+ }
270
+ }
271
+ this.logger.error('All endpoints failed to get TVM executor fee');
272
+ throw (0, errors_1.allEndpointsFailedError)(lastError);
273
+ };
274
+ return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn, "OperationTracker: Getting TVM executor fee") : await requestFn();
235
275
  }
236
276
  }
237
277
  exports.OperationTracker = OperationTracker;
@@ -1,17 +1,11 @@
1
- import { Asset, IConfiguration, ILogger, ISimulator } from '../interfaces';
2
- import { IHttpClient } from '../interfaces';
1
+ import { IConfiguration, ILogger, IOperationTracker, ISimulator } from '../interfaces';
3
2
  import type { SenderAbstraction } from '../sender';
4
- import { CrosschainTx, EvmProxyMsg, ExecutionFeeEstimationResult, SuggestedTONExecutorFee, TACSimulationRequest, TACSimulationResult, TransactionLinker } from '../structs/Struct';
3
+ import { CrosschainTx, ExecutionFeeEstimationResult } from '../structs/Struct';
5
4
  export declare class Simulator implements ISimulator {
6
5
  private readonly config;
6
+ private readonly operationTracker;
7
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: SenderAbstraction, txs: CrosschainTx[]): Promise<TACSimulationResult[]>;
12
- private buildTACSimulationRequest;
13
- getTVMExecutorFeeInfo(assets: Asset[], feeSymbol: string, tvmValidExecutors?: string[]): Promise<SuggestedTONExecutorFee>;
14
- private getFeeInfo;
15
- getTransactionSimulationInfo(evmProxyMsg: EvmProxyMsg, sender: SenderAbstraction, assets?: Asset[]): Promise<ExecutionFeeEstimationResult>;
16
- getSimulationInfoForTransaction(evmProxyMsg: EvmProxyMsg, transactionLinker: TransactionLinker, assets: Asset[], allowSimulationError?: boolean, isRoundTrip?: boolean, evmValidExecutors?: string[], tvmValidExecutors?: string[], calculateRollbackFee?: boolean): Promise<ExecutionFeeEstimationResult>;
8
+ constructor(config: IConfiguration, operationTracker: IOperationTracker, logger?: ILogger);
9
+ getSimulationsInfo(sender: SenderAbstraction, txs: CrosschainTx[]): Promise<ExecutionFeeEstimationResult[]>;
10
+ getSimulationInfo(sender: SenderAbstraction, tx: CrosschainTx): Promise<ExecutionFeeEstimationResult>;
17
11
  }
@@ -2,162 +2,68 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Simulator = void 0;
4
4
  const ton_1 = require("@ton/ton");
5
- const errors_1 = require("../errors");
6
- const AxiosHttpClient_1 = require("./AxiosHttpClient");
7
5
  const Logger_1 = require("./Logger");
8
6
  const Utils_1 = require("./Utils");
9
7
  const Validator_1 = require("./Validator");
10
8
  class Simulator {
11
- constructor(config, logger = new Logger_1.NoopLogger(), httpClient = new AxiosHttpClient_1.AxiosHttpClient()) {
9
+ constructor(config, operationTracker, logger = new Logger_1.NoopLogger()) {
12
10
  this.config = config;
11
+ this.operationTracker = operationTracker;
13
12
  this.logger = logger;
14
- this.httpClient = httpClient;
15
13
  }
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) {
14
+ async getSimulationsInfo(sender, txs) {
36
15
  this.logger.debug(`Simulating ${txs.length} TAC messages`);
37
16
  const results = [];
38
17
  for (const tx of txs) {
39
- const req = await this.buildTACSimulationRequest(sender, tx);
40
- const result = await this.simulateTACMessage(req);
18
+ const result = await this.getSimulationInfo(sender, tx);
41
19
  results.push(result);
42
20
  }
43
21
  return results;
44
22
  }
45
- async buildTACSimulationRequest(sender, tx) {
23
+ async getSimulationInfo(sender, tx) {
24
+ this.logger.debug('Getting simulation info');
46
25
  const { evmProxyMsg, assets = [], options = {} } = tx;
47
- const { evmValidExecutors = this.config.TACParams.trustedTACExecutors, tvmValidExecutors = this.config.TACParams.trustedTONExecutors, calculateRollbackFee = true, } = options;
26
+ const { evmValidExecutors = this.config.TACParams.trustedTACExecutors, tvmValidExecutors = this.config.TACParams.trustedTONExecutors, calculateRollbackFee = true, allowSimulationError = false, } = options;
27
+ Validator_1.Validator.validateEVMAddress(evmProxyMsg.evmTargetAddress);
48
28
  Validator_1.Validator.validateEVMAddresses(evmValidExecutors);
49
29
  Validator_1.Validator.validateTVMAddresses(tvmValidExecutors);
50
30
  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 {
31
+ const shardCount = aggregatedData.jettons.length || 1;
32
+ const transactionLinker = (0, Utils_1.generateTransactionLinker)(sender.getSenderAddress(), shardCount);
33
+ const tacSimulationParams = {
54
34
  tacCallParams: {
55
35
  arguments: evmProxyMsg.encodedParameters ?? '0x',
56
36
  methodName: (0, Utils_1.formatSolidityMethodName)(evmProxyMsg.methodName),
57
37
  target: evmProxyMsg.evmTargetAddress,
58
38
  },
59
- evmValidExecutors: evmValidExecutors,
60
- tvmValidExecutors: tvmValidExecutors,
39
+ evmValidExecutors,
40
+ tvmValidExecutors,
61
41
  extraData: '0x',
62
42
  shardsKey: transactionLinker.shardsKey,
63
- tonAssets: assets.map((asset) => ({
64
- amount: asset.rawAmount.toString(),
65
- tokenAddress: asset.address || '',
66
- assetType: asset.type,
67
- })),
43
+ tonAssets: (0, Utils_1.mapAssetsToTonAssets)(assets),
68
44
  tonCaller: transactionLinker.caller,
69
- calculateRollbackFee: calculateRollbackFee,
45
+ calculateRollbackFee,
70
46
  };
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);
47
+ const simulation = await this.operationTracker.simulateTACMessage(tacSimulationParams);
48
+ this.logger.debug(`TAC simulation ${simulation.simulationStatus ? 'success' : 'failed'}`);
49
+ const isRoundTrip = options.isRoundTrip ?? assets.length !== 0;
102
50
  const crossChainLayer = this.config.TONParams.contractOpener.open(this.config.artifacts.ton.wrappers.CrossChainLayer.createFromAddress(ton_1.Address.parse(this.config.TONParams.crossChainLayerAddress)));
103
51
  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
52
  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),
53
+ isRoundTrip,
54
+ gasLimit: simulation.simulationStatus ? simulation.estimatedGas : 0n,
55
+ protocolFee: BigInt((0, ton_1.toNano)(fullStateCCL.tacProtocolFee)) +
56
+ BigInt(isRoundTrip) * BigInt((0, ton_1.toNano)(fullStateCCL.tonProtocolFee)),
57
+ evmExecutorFee: BigInt(simulation.suggestedTacExecutionFee),
58
+ tvmExecutorFee: BigInt(simulation.suggestedTonExecutionFee) * BigInt(isRoundTrip),
135
59
  };
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;
60
+ if (!simulation.simulationStatus && !allowSimulationError) {
61
+ throw simulation;
145
62
  }
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);
63
+ if (allowSimulationError && !simulation.simulationStatus) {
64
+ this.logger.info('Simulation failed but allowSimulationError is true, returning partial fee params');
65
+ }
66
+ return { feeParams, simulation };
161
67
  }
162
68
  }
163
69
  exports.Simulator = Simulator;
@@ -0,0 +1,10 @@
1
+ import { Wallet } from 'ethers';
2
+ import { Asset, IConfiguration, ILogger, IOperationTracker, ITACTransactionManager } from '../interfaces';
3
+ export declare class TACTransactionManager implements ITACTransactionManager {
4
+ private readonly config;
5
+ private readonly operationTracker;
6
+ private readonly logger;
7
+ constructor(config: IConfiguration, operationTracker: IOperationTracker, logger?: ILogger);
8
+ private approveAsset;
9
+ bridgeTokensToTON(signer: Wallet, value: bigint, tonTarget: string, assets?: Asset[], tvmExecutorFee?: bigint, tvmValidExecutors?: string[]): Promise<string>;
10
+ }
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TACTransactionManager = void 0;
4
+ const assets_1 = require("../assets");
5
+ const Struct_1 = require("../structs/Struct");
6
+ const Consts_1 = require("./Consts");
7
+ const Logger_1 = require("./Logger");
8
+ const Utils_1 = require("./Utils");
9
+ const Validator_1 = require("./Validator");
10
+ class TACTransactionManager {
11
+ constructor(config, operationTracker, logger = new Logger_1.NoopLogger()) {
12
+ this.config = config;
13
+ this.operationTracker = operationTracker;
14
+ this.logger = logger;
15
+ }
16
+ async approveAsset(asset, signer, spenderAddress) {
17
+ const evmAddress = await asset.getEVMAddress();
18
+ if (asset.type === Struct_1.AssetType.FT) {
19
+ this.logger.debug(`Approving FT ${evmAddress} for ${spenderAddress}`);
20
+ const contract = this.config.artifacts.tac.wrappers.ERC20FactoryTAC.connect(evmAddress, this.config.TACParams.provider);
21
+ const tx = await contract.connect(signer).approve(spenderAddress, asset.rawAmount);
22
+ await tx.wait();
23
+ }
24
+ else if (asset.type === Struct_1.AssetType.NFT) {
25
+ this.logger.debug(`Approving NFT ${evmAddress} for ${spenderAddress}`);
26
+ const contract = this.config.artifacts.tac.wrappers.ERC721FactoryTAC.connect(evmAddress, this.config.TACParams.provider);
27
+ const tx = await contract.connect(signer).approve(spenderAddress, asset.addresses.index);
28
+ await tx.wait();
29
+ }
30
+ this.logger.debug(`Approved ${evmAddress} for ${spenderAddress}`);
31
+ }
32
+ async bridgeTokensToTON(signer, value, tonTarget, assets = [], tvmExecutorFee, tvmValidExecutors) {
33
+ this.logger.debug('Bridging tokens to TON');
34
+ Validator_1.Validator.validateTVMAddress(tonTarget);
35
+ // Add native TAC asset if value > 0
36
+ if (value > 0n) {
37
+ const nativeTacAsset = (await assets_1.AssetFactory.from(this.config, {
38
+ address: await this.config.nativeTACAddress(),
39
+ tokenType: Struct_1.AssetType.FT,
40
+ })).withRawAmount(value);
41
+ assets = [...assets, nativeTacAsset];
42
+ }
43
+ // Calculate executor fee if not provided
44
+ if (!tvmExecutorFee) {
45
+ const feeParams = {
46
+ tonAssets: (0, Utils_1.mapAssetsToTonAssets)(assets),
47
+ feeSymbol: Consts_1.TAC_SYMBOL,
48
+ tvmValidExecutors: tvmValidExecutors ?? [],
49
+ };
50
+ const suggestedFee = await this.operationTracker.getTVMExecutorFee(feeParams);
51
+ this.logger.debug(`Suggested TON executor fee: ${(0, Utils_1.formatObjectForLogging)(suggestedFee)}`);
52
+ tvmExecutorFee = BigInt(suggestedFee.inTAC);
53
+ }
54
+ // Approve all assets
55
+ const crossChainLayerAddress = await this.config.TACParams.crossChainLayer.getAddress();
56
+ await Promise.all(assets.map(asset => this.approveAsset(asset, signer, crossChainLayerAddress)));
57
+ const protocolFee = await this.config.TACParams.crossChainLayer.getProtocolFee();
58
+ const shardsKey = BigInt(Math.round(Math.random() * 1e18));
59
+ this.logger.debug(`Shards key: ${shardsKey}, Protocol fee: ${protocolFee}`);
60
+ // Prepare bridge data
61
+ const [toBridge, toBridgeNFT] = await Promise.all([
62
+ Promise.all(assets.filter(a => a.type === Struct_1.AssetType.FT).map(async (a) => ({
63
+ evmAddress: await a.getEVMAddress(),
64
+ amount: a.rawAmount,
65
+ }))),
66
+ Promise.all(assets.filter(a => a.type === Struct_1.AssetType.NFT).map(async (a) => ({
67
+ evmAddress: await a.getEVMAddress(),
68
+ amount: 1n,
69
+ tokenId: a.addresses.index,
70
+ }))),
71
+ ]);
72
+ const outMessage = {
73
+ shardsKey,
74
+ tvmTarget: tonTarget,
75
+ tvmPayload: '',
76
+ tvmProtocolFee: protocolFee,
77
+ tvmExecutorFee,
78
+ tvmValidExecutors: this.config.getTrustedTONExecutors,
79
+ toBridge,
80
+ toBridgeNFT,
81
+ };
82
+ const totalValue = value + BigInt(outMessage.tvmProtocolFee) + BigInt(outMessage.tvmExecutorFee);
83
+ this.logger.debug(`Total value: ${totalValue}`);
84
+ const tx = await this.config.TACParams.crossChainLayer
85
+ .connect(signer)
86
+ .sendMessage(1n, this.config.artifacts.tac.utils.encodeOutMessageV1(outMessage), { value: totalValue });
87
+ await tx.wait();
88
+ this.logger.debug(`Transaction hash: ${tx.hash}`);
89
+ return tx.hash;
90
+ }
91
+ }
92
+ exports.TACTransactionManager = TACTransactionManager;
@@ -0,0 +1,17 @@
1
+ import { IConfiguration, ILogger, IOperationTracker, ISimulator, ITONTransactionManager } from '../interfaces';
2
+ import type { SenderAbstraction } from '../sender';
3
+ import { CrosschainTx, EvmProxyMsg, OperationIdsByShardsKey, TransactionLinkerWithOperationId, WaitOptions } from '../structs/Struct';
4
+ export declare class TONTransactionManager implements ITONTransactionManager {
5
+ private readonly config;
6
+ private readonly simulator;
7
+ private readonly operationTracker;
8
+ private readonly logger;
9
+ constructor(config: IConfiguration, simulator: ISimulator, operationTracker: IOperationTracker, logger?: ILogger);
10
+ private buildFeeParams;
11
+ private prepareCrossChainTransaction;
12
+ private generateCrossChainMessages;
13
+ sendCrossChainTransaction(evmProxyMsg: EvmProxyMsg, sender: SenderAbstraction, tx: CrosschainTx, waitOptions?: WaitOptions<string>): Promise<TransactionLinkerWithOperationId>;
14
+ sendCrossChainTransactions(sender: SenderAbstraction, txs: CrosschainTx[], waitOptions?: WaitOptions<OperationIdsByShardsKey>): Promise<TransactionLinkerWithOperationId[]>;
15
+ private prepareBatchTransactions;
16
+ private waitForOperationIds;
17
+ }