@tonappchain/sdk 0.7.2-scaled-ui-support-2 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -20
- package/README.md +198 -198
- package/dist/artifacts/dev/index.d.ts +2 -2
- package/dist/artifacts/dev/index.js +2 -1
- package/dist/artifacts/dev/tac/endpoints.d.ts +1 -0
- package/dist/artifacts/dev/tac/endpoints.js +2 -1
- package/dist/artifacts/dev/ton/internal/build/CrossChainLayer.compiled.json +1 -1
- package/dist/artifacts/dev/ton/internal/build/Executor.compiled.json +1 -1
- package/dist/artifacts/dev/ton/internal/build/JettonProxy.compiled.json +1 -1
- package/dist/artifacts/dev/ton/internal/build/JettonWallet.compiled.json +1 -1
- package/dist/artifacts/dev/ton/internal/build/NFTItem.compiled.json +1 -1
- package/dist/artifacts/dev/ton/internal/build/NFTProxy.compiled.json +1 -1
- package/dist/artifacts/dev/ton/internal/build/Settings.compiled.json +1 -1
- package/dist/artifacts/dev/ton/internal/wrappers/CrossChainLayer.d.ts +53 -6
- package/dist/artifacts/dev/ton/internal/wrappers/CrossChainLayer.js +130 -17
- package/dist/artifacts/dev/ton/internal/wrappers/JettonMinter.d.ts +2 -0
- package/dist/artifacts/dev/ton/internal/wrappers/JettonMinter.js +3 -1
- package/dist/artifacts/dev/ton/internal/wrappers/JettonProxy.d.ts +9 -0
- package/dist/artifacts/dev/ton/internal/wrappers/JettonProxy.js +10 -1
- package/dist/artifacts/dev/ton/internal/wrappers/JettonWallet.d.ts +7 -0
- package/dist/artifacts/dev/ton/internal/wrappers/JettonWallet.js +9 -2
- package/dist/artifacts/dev/ton/internal/wrappers/NFTCollection.d.ts +9 -0
- package/dist/artifacts/dev/ton/internal/wrappers/NFTCollection.js +9 -0
- package/dist/artifacts/dev/ton/internal/wrappers/NFTItem.d.ts +7 -0
- package/dist/artifacts/dev/ton/internal/wrappers/NFTItem.js +7 -0
- package/dist/artifacts/dev/ton/internal/wrappers/NFTProxy.d.ts +7 -0
- package/dist/artifacts/dev/ton/internal/wrappers/NFTProxy.js +8 -1
- package/dist/artifacts/dev/ton/internal/wrappers/Settings.d.ts +1 -0
- package/dist/artifacts/dev/ton/internal/wrappers/Settings.js +1 -0
- package/dist/artifacts/dev/ton/internal/wrappers/utils/CrossChainLayerPayload.d.ts +10 -0
- package/dist/artifacts/dev/ton/internal/wrappers/utils/CrossChainLayerPayload.js +24 -0
- package/dist/artifacts/dev/ton/internal/wrappers/utils/MerkleRoots.d.ts +2 -1
- package/dist/artifacts/dev/ton/internal/wrappers/utils/MerkleRoots.js +9 -1
- package/dist/artifacts/mainnet/index.d.ts +2 -2
- package/dist/artifacts/mainnet/index.js +2 -1
- package/dist/artifacts/mainnet/tac/endpoints.d.ts +1 -0
- package/dist/artifacts/mainnet/tac/endpoints.js +2 -1
- package/dist/artifacts/mainnet/ton/endpoints.d.ts +1 -1
- package/dist/artifacts/mainnet/ton/endpoints.js +1 -1
- package/dist/artifacts/mainnet/ton/internal/build/CrossChainLayer.compiled.json +1 -1
- package/dist/artifacts/mainnet/ton/internal/build/Executor.compiled.json +1 -1
- package/dist/artifacts/mainnet/ton/internal/build/JettonMinter.compiled.json +1 -1
- package/dist/artifacts/mainnet/ton/internal/build/JettonProxy.compiled.json +1 -1
- package/dist/artifacts/mainnet/ton/internal/build/JettonWallet.compiled.json +1 -1
- package/dist/artifacts/mainnet/ton/internal/build/NFTItem.compiled.json +1 -1
- package/dist/artifacts/mainnet/ton/internal/build/NFTProxy.compiled.json +1 -1
- package/dist/artifacts/mainnet/ton/internal/wrappers/CrossChainLayer.d.ts +1 -13
- package/dist/artifacts/mainnet/ton/internal/wrappers/CrossChainLayer.js +7 -45
- package/dist/artifacts/mainnet/ton/internal/wrappers/JettonMinter.d.ts +2 -2
- package/dist/artifacts/mainnet/ton/internal/wrappers/JettonMinter.js +2 -2
- package/dist/artifacts/testnet/index.d.ts +2 -2
- package/dist/artifacts/testnet/index.js +2 -1
- package/dist/artifacts/testnet/tac/endpoints.d.ts +1 -0
- package/dist/artifacts/testnet/tac/endpoints.js +2 -1
- package/dist/artifacts/testnet/ton/endpoints.d.ts +1 -1
- package/dist/artifacts/testnet/ton/endpoints.js +1 -1
- package/dist/artifacts/testnet/ton/internal/build/CrossChainLayer.compiled.json +1 -1
- package/dist/artifacts/testnet/ton/internal/build/Executor.compiled.json +1 -1
- package/dist/artifacts/testnet/ton/internal/build/JettonProxy.compiled.json +1 -1
- package/dist/artifacts/testnet/ton/internal/build/JettonWallet.compiled.json +1 -1
- package/dist/artifacts/testnet/ton/internal/build/NFTItem.compiled.json +1 -1
- package/dist/artifacts/testnet/ton/internal/build/NFTProxy.compiled.json +1 -1
- package/dist/artifacts/testnet/ton/internal/build/Settings.compiled.json +1 -1
- package/dist/artifacts/testnet/ton/internal/wrappers/CrossChainLayer.d.ts +53 -6
- package/dist/artifacts/testnet/ton/internal/wrappers/CrossChainLayer.js +130 -17
- package/dist/artifacts/testnet/ton/internal/wrappers/JettonMinter.d.ts +2 -0
- package/dist/artifacts/testnet/ton/internal/wrappers/JettonMinter.js +3 -1
- package/dist/artifacts/testnet/ton/internal/wrappers/JettonProxy.d.ts +9 -0
- package/dist/artifacts/testnet/ton/internal/wrappers/JettonProxy.js +10 -1
- package/dist/artifacts/testnet/ton/internal/wrappers/JettonWallet.d.ts +7 -0
- package/dist/artifacts/testnet/ton/internal/wrappers/JettonWallet.js +9 -2
- package/dist/artifacts/testnet/ton/internal/wrappers/NFTCollection.d.ts +9 -0
- package/dist/artifacts/testnet/ton/internal/wrappers/NFTCollection.js +9 -0
- package/dist/artifacts/testnet/ton/internal/wrappers/NFTItem.d.ts +7 -0
- package/dist/artifacts/testnet/ton/internal/wrappers/NFTItem.js +7 -0
- package/dist/artifacts/testnet/ton/internal/wrappers/NFTProxy.d.ts +7 -0
- package/dist/artifacts/testnet/ton/internal/wrappers/NFTProxy.js +8 -1
- package/dist/artifacts/testnet/ton/internal/wrappers/Settings.d.ts +1 -0
- package/dist/artifacts/testnet/ton/internal/wrappers/Settings.js +1 -0
- package/dist/artifacts/testnet/ton/internal/wrappers/utils/CrossChainLayerPayload.d.ts +10 -0
- package/dist/artifacts/testnet/ton/internal/wrappers/utils/CrossChainLayerPayload.js +24 -0
- package/dist/artifacts/testnet/ton/internal/wrappers/utils/MerkleRoots.d.ts +2 -1
- package/dist/artifacts/testnet/ton/internal/wrappers/utils/MerkleRoots.js +9 -1
- package/dist/src/adapters/BaseContractOpener.d.ts +76 -0
- package/dist/src/adapters/BaseContractOpener.js +440 -0
- package/dist/src/adapters/LiteClientOpener.d.ts +38 -0
- package/dist/src/adapters/LiteClientOpener.js +141 -0
- package/dist/src/adapters/OpenerUtils.d.ts +3 -0
- package/dist/src/adapters/OpenerUtils.js +40 -0
- package/dist/src/adapters/RetryableContractOpener.d.ts +40 -0
- package/dist/src/adapters/RetryableContractOpener.js +290 -0
- package/dist/src/adapters/SandboxOpener.d.ts +15 -0
- package/dist/src/adapters/SandboxOpener.js +35 -0
- package/dist/src/adapters/TonClient4Opener.d.ts +24 -0
- package/dist/src/adapters/TonClient4Opener.js +95 -0
- package/dist/src/adapters/TonClientOpener.d.ts +19 -0
- package/dist/src/adapters/TonClientOpener.js +82 -0
- package/dist/src/adapters/index.d.ts +7 -2
- package/dist/src/adapters/index.js +7 -2
- package/dist/src/assets/AssetCache.d.ts +8 -8
- package/dist/src/assets/AssetCache.js +3 -0
- package/dist/src/assets/AssetFactory.js +8 -2
- package/dist/src/assets/FT.d.ts +2 -3
- package/dist/src/assets/FT.js +4 -7
- package/dist/src/assets/NFT.d.ts +1 -1
- package/dist/src/assets/NFT.js +1 -1
- package/dist/src/assets/TON.d.ts +3 -2
- package/dist/src/assets/TON.js +2 -1
- package/dist/src/errors/errors.d.ts +12 -1
- package/dist/src/errors/errors.js +66 -2
- package/dist/src/errors/index.d.ts +2 -2
- package/dist/src/errors/index.js +4 -1
- package/dist/src/errors/instances.d.ts +7 -2
- package/dist/src/errors/instances.js +67 -2
- package/dist/src/index.d.ts +3 -1
- package/dist/src/index.js +6 -4
- package/dist/src/interfaces/Asset.d.ts +4 -9
- package/dist/src/interfaces/ContractOpener.d.ts +76 -2
- package/dist/src/interfaces/IOperationTracker.d.ts +22 -22
- package/dist/src/interfaces/ISimulator.d.ts +9 -1
- package/dist/src/interfaces/ITONTransactionManager.d.ts +20 -1
- package/dist/src/interfaces/ITacExplorerClient.d.ts +8 -0
- package/dist/src/interfaces/ITacExplorerClient.js +2 -0
- package/dist/src/interfaces/ITacSDK.d.ts +25 -1
- package/dist/src/interfaces/ITxFinalizer.d.ts +4 -0
- package/dist/src/interfaces/ITxFinalizer.js +2 -0
- package/dist/src/interfaces/WalletInstanse.d.ts +4 -8
- package/dist/src/interfaces/index.d.ts +1 -0
- package/dist/src/interfaces/index.js +1 -0
- package/dist/src/sdk/Configuration.d.ts +5 -3
- package/dist/src/sdk/Configuration.js +54 -7
- package/dist/src/sdk/Consts.d.ts +18 -1
- package/dist/src/sdk/Consts.js +21 -2
- package/dist/src/sdk/Fees.d.ts +21 -0
- package/dist/src/sdk/Fees.js +201 -0
- package/dist/src/sdk/LiteSequencerClient.d.ts +1 -0
- package/dist/src/sdk/LiteSequencerClient.js +39 -17
- package/dist/src/sdk/OperationTracker.d.ts +11 -11
- package/dist/src/sdk/OperationTracker.js +46 -94
- package/dist/src/sdk/Simulator.d.ts +10 -2
- package/dist/src/sdk/Simulator.js +102 -0
- package/dist/src/sdk/StartTracking.d.ts +12 -7
- package/dist/src/sdk/StartTracking.js +75 -49
- package/dist/src/sdk/TONTransactionManager.d.ts +5 -4
- package/dist/src/sdk/TONTransactionManager.js +63 -8
- package/dist/src/sdk/TacExplorerClient.d.ts +8 -0
- package/dist/src/sdk/TacExplorerClient.js +22 -0
- package/dist/src/sdk/TacSdk.d.ts +8 -2
- package/dist/src/sdk/TacSdk.js +27 -4
- package/dist/src/sdk/TxFinalizer.d.ts +4 -3
- package/dist/src/sdk/TxFinalizer.js +41 -41
- package/dist/src/sdk/Utils.d.ts +20 -1
- package/dist/src/sdk/Utils.js +158 -10
- package/dist/src/sender/BatchSender.js +19 -0
- package/dist/src/sender/MockSender.d.ts +2 -0
- package/dist/src/sender/MockSender.js +13 -0
- package/dist/src/sender/RawSender.js +34 -1
- package/dist/src/sender/SenderFactory.js +1 -1
- package/dist/src/sender/TonConnectSender.js +2 -0
- package/dist/src/sender/index.d.ts +1 -0
- package/dist/src/sender/index.js +1 -0
- package/dist/src/structs/InternalStruct.d.ts +98 -4
- package/dist/src/structs/Struct.d.ts +183 -7
- package/dist/src/structs/Struct.js +4 -3
- package/dist/src/wrappers/HighloadWalletV3.d.ts +5 -3
- package/dist/src/wrappers/HighloadWalletV3.js +14 -3
- package/package.json +121 -117
- package/dist/src/adapters/contractOpener.d.ts +0 -20
- package/dist/src/adapters/contractOpener.js +0 -126
- package/dist/src/adapters/retryableContractOpener.d.ts +0 -24
- package/dist/src/adapters/retryableContractOpener.js +0 -111
|
@@ -1,26 +1,22 @@
|
|
|
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.startTracking = startTracking;
|
|
7
4
|
exports.startTrackingMultiple = startTrackingMultiple;
|
|
8
|
-
|
|
5
|
+
exports.printExecutionStagesTable = printExecutionStagesTable;
|
|
9
6
|
const Struct_1 = require("../structs/Struct");
|
|
10
7
|
const Consts_1 = require("./Consts");
|
|
11
8
|
const Logger_1 = require("./Logger");
|
|
12
9
|
const OperationTracker_1 = require("./OperationTracker");
|
|
13
|
-
const TxFinalizer_1 = require("./TxFinalizer");
|
|
14
10
|
const Utils_1 = require("./Utils");
|
|
15
11
|
async function startTracking(transactionLinker, network, options) {
|
|
16
|
-
const { customLiteSequencerEndpoints, delay = 10, maxIterationCount = Consts_1.MAX_ITERATION_COUNT, returnValue = false, tableView = true,
|
|
12
|
+
const { customLiteSequencerEndpoints, delay = 10, maxIterationCount = Consts_1.MAX_ITERATION_COUNT, returnValue = false, tableView = true, logger = new Logger_1.NoopLogger(), txFinalizer, contractOpener, cclAddress, } = options || {};
|
|
17
13
|
const tracker = new OperationTracker_1.OperationTracker(network, customLiteSequencerEndpoints, logger);
|
|
18
|
-
logger.debug(
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
let operationId = '';
|
|
14
|
+
logger.debug(`Start tracking operation\n` +
|
|
15
|
+
`caller: ${transactionLinker.caller}\n` +
|
|
16
|
+
`shardsKey: ${transactionLinker.shardsKey}\n` +
|
|
17
|
+
`shardCount: ${transactionLinker.shardCount}\n` +
|
|
18
|
+
`timestamp: ${transactionLinker.timestamp}`);
|
|
19
|
+
let operationId = transactionLinker.operationId ?? '';
|
|
24
20
|
let iteration = 0; // number of iterations
|
|
25
21
|
let operationType = '';
|
|
26
22
|
let ok = true; // finished successfully
|
|
@@ -37,7 +33,8 @@ async function startTracking(transactionLinker, network, options) {
|
|
|
37
33
|
try {
|
|
38
34
|
operationId = await tracker.getOperationId(transactionLinker);
|
|
39
35
|
}
|
|
40
|
-
catch {
|
|
36
|
+
catch (err) {
|
|
37
|
+
logger.debug('failed to get operationId: ' + err);
|
|
41
38
|
// Ignore error and continue
|
|
42
39
|
}
|
|
43
40
|
}
|
|
@@ -67,16 +64,18 @@ async function startTracking(transactionLinker, network, options) {
|
|
|
67
64
|
logger.debug(errorMessage);
|
|
68
65
|
}
|
|
69
66
|
const profilingData = await tracker.getStageProfiling(operationId);
|
|
70
|
-
// Check if EXECUTED_IN_TON stage exists and use
|
|
67
|
+
// Check if EXECUTED_IN_TON stage exists and use ContractOpener to verify transaction success
|
|
71
68
|
if (profilingData.executedInTON.exists && profilingData.executedInTON.stageData?.transactions) {
|
|
72
69
|
logger.debug('EXECUTED_IN_TON stage found, verifying transaction success in TON...');
|
|
73
|
-
|
|
74
|
-
|
|
70
|
+
const finalizer = txFinalizer || contractOpener;
|
|
71
|
+
if (finalizer && cclAddress) {
|
|
75
72
|
const transactions = profilingData.executedInTON.stageData.transactions;
|
|
76
73
|
for (const tx of transactions) {
|
|
77
74
|
try {
|
|
78
75
|
logger.debug(`Verifying transaction: ${tx.hash}`);
|
|
79
|
-
await
|
|
76
|
+
await finalizer.trackTransactionTree(cclAddress, tx.hash, {
|
|
77
|
+
maxDepth: Consts_1.DEFAULT_FIND_TX_MAX_DEPTH,
|
|
78
|
+
});
|
|
80
79
|
logger.debug(`Transaction ${tx.hash} verified successfully in TON`);
|
|
81
80
|
}
|
|
82
81
|
catch (error) {
|
|
@@ -88,7 +87,7 @@ async function startTracking(transactionLinker, network, options) {
|
|
|
88
87
|
}
|
|
89
88
|
}
|
|
90
89
|
else {
|
|
91
|
-
logger.debug('
|
|
90
|
+
logger.debug('Finalizer, ContractOpener or CCL address is not provided, skipping TON transaction verification');
|
|
92
91
|
}
|
|
93
92
|
}
|
|
94
93
|
if (returnValue) {
|
|
@@ -104,7 +103,7 @@ async function startTracking(transactionLinker, network, options) {
|
|
|
104
103
|
}
|
|
105
104
|
}
|
|
106
105
|
async function startTrackingMultiple(transactionLinkers, network, options) {
|
|
107
|
-
const { customLiteSequencerEndpoints, delay = 10, maxIterationCount = Consts_1.MAX_ITERATION_COUNT, returnValue = false, tableView = true,
|
|
106
|
+
const { customLiteSequencerEndpoints, delay = 10, maxIterationCount = Consts_1.MAX_ITERATION_COUNT, returnValue = false, tableView = true, txFinalizer, contractOpener, cclAddress, logger = new Logger_1.NoopLogger(), } = options || {};
|
|
108
107
|
logger.debug(`Start tracking ${transactionLinkers.length} operations`);
|
|
109
108
|
const results = await Promise.all(transactionLinkers.map((linker, index) => {
|
|
110
109
|
logger.debug(`\nProcessing operation ${index + 1}/${transactionLinkers.length}`);
|
|
@@ -114,7 +113,9 @@ async function startTrackingMultiple(transactionLinkers, network, options) {
|
|
|
114
113
|
maxIterationCount,
|
|
115
114
|
returnValue: true,
|
|
116
115
|
tableView: false,
|
|
117
|
-
|
|
116
|
+
txFinalizer,
|
|
117
|
+
contractOpener,
|
|
118
|
+
cclAddress,
|
|
118
119
|
logger,
|
|
119
120
|
});
|
|
120
121
|
}));
|
|
@@ -160,35 +161,60 @@ function formatExecutionStages(stages) {
|
|
|
160
161
|
bytesError: data.exists && data.stageData && data.stageData.note != null ? data.stageData.note.internalBytesError : '-',
|
|
161
162
|
}));
|
|
162
163
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
'
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
164
|
+
/**
|
|
165
|
+
* Simple table formatter that works in both browser and Node.js without external dependencies
|
|
166
|
+
*/
|
|
167
|
+
function createSimpleTable(headers, rows, colWidths) {
|
|
168
|
+
const lines = [];
|
|
169
|
+
// Helper to truncate and pad text to fit column width
|
|
170
|
+
const fitToWidth = (text, width) => {
|
|
171
|
+
// Handle multi-line text by taking only the first line for table cell
|
|
172
|
+
const firstLine = text.split('\n')[0];
|
|
173
|
+
if (firstLine.length > width - 2) {
|
|
174
|
+
return firstLine.substring(0, width - 5) + '...';
|
|
175
|
+
}
|
|
176
|
+
return firstLine.padEnd(width, ' ');
|
|
177
|
+
};
|
|
178
|
+
// Create separator line
|
|
179
|
+
const separator = '+' + colWidths.map((w) => '-'.repeat(w)).join('+') + '+';
|
|
180
|
+
// Create header row
|
|
181
|
+
const headerRow = '|' + headers.map((h, i) => fitToWidth(h, colWidths[i])).join('|') + '|';
|
|
182
|
+
lines.push(separator);
|
|
183
|
+
lines.push(headerRow);
|
|
184
|
+
lines.push(separator);
|
|
185
|
+
// Create data rows
|
|
186
|
+
rows.forEach((row) => {
|
|
187
|
+
const dataRow = '|' + row.map((cell, i) => fitToWidth(cell, colWidths[i])).join('|') + '|';
|
|
188
|
+
lines.push(dataRow);
|
|
178
189
|
});
|
|
190
|
+
lines.push(separator);
|
|
191
|
+
return '\n' + lines.join('\n');
|
|
192
|
+
}
|
|
193
|
+
function printExecutionStagesTable(stages, logger) {
|
|
194
|
+
const headers = [
|
|
195
|
+
'Stage',
|
|
196
|
+
'Exists',
|
|
197
|
+
'Success',
|
|
198
|
+
'Timestamp',
|
|
199
|
+
'Transactions',
|
|
200
|
+
'NoteContent',
|
|
201
|
+
'ErrorName',
|
|
202
|
+
'InternalMsg',
|
|
203
|
+
'BytesError',
|
|
204
|
+
];
|
|
205
|
+
const colWidths = [30, 8, 9, 13, 70, 13, 13, 13, 13];
|
|
179
206
|
const tableData = formatExecutionStages(stages);
|
|
180
|
-
tableData.
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
logger.debug(table.toString());
|
|
207
|
+
const rows = tableData.map((row) => [
|
|
208
|
+
row.stage,
|
|
209
|
+
row.exists,
|
|
210
|
+
row.success,
|
|
211
|
+
row.timestamp,
|
|
212
|
+
row.transactions,
|
|
213
|
+
row.noteContent,
|
|
214
|
+
row.errorName,
|
|
215
|
+
row.internalMsg,
|
|
216
|
+
row.bytesError,
|
|
217
|
+
]);
|
|
218
|
+
const table = createSimpleTable(headers, rows, colWidths);
|
|
219
|
+
logger.debug(table);
|
|
194
220
|
}
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import { IConfiguration, ILogger, IOperationTracker, ISimulator, ITONTransactionManager } from '../interfaces';
|
|
2
|
-
import type
|
|
3
|
-
import { BatchCrossChainTx, CrossChainTransactionOptions, CrossChainTransactionsOptions, CrosschainTx, EvmProxyMsg, FeeParams, TransactionLinkerWithOperationId } from '../structs/Struct';
|
|
1
|
+
import { Asset, IConfiguration, ILogger, IOperationTracker, ISimulator, ITONTransactionManager } from '../interfaces';
|
|
2
|
+
import { type SenderAbstraction } from '../sender';
|
|
3
|
+
import { BatchCrossChainTx, CrossChainPayloadResult, CrossChainTransactionOptions, CrossChainTransactionsOptions, CrosschainTx, EvmProxyMsg, FeeParams, TransactionLinkerWithOperationId } from '../structs/Struct';
|
|
4
4
|
export declare class TONTransactionManager implements ITONTransactionManager {
|
|
5
5
|
private readonly config;
|
|
6
6
|
private readonly simulator;
|
|
7
7
|
private readonly operationTracker;
|
|
8
8
|
private readonly logger;
|
|
9
9
|
constructor(config: IConfiguration, simulator: ISimulator, operationTracker: IOperationTracker, logger?: ILogger);
|
|
10
|
-
|
|
10
|
+
buildFeeParams(options: CrossChainTransactionOptions, evmProxyMsg: EvmProxyMsg, sender: SenderAbstraction, tx: CrosschainTx): Promise<FeeParams>;
|
|
11
11
|
private prepareCrossChainTransaction;
|
|
12
12
|
private generateCrossChainMessages;
|
|
13
13
|
sendCrossChainTransaction(evmProxyMsg: EvmProxyMsg, sender: SenderAbstraction, tx: CrosschainTx): Promise<TransactionLinkerWithOperationId>;
|
|
14
14
|
sendCrossChainTransactions(sender: SenderAbstraction, txs: BatchCrossChainTx[], options?: CrossChainTransactionsOptions): Promise<TransactionLinkerWithOperationId[]>;
|
|
15
15
|
private prepareBatchTransactions;
|
|
16
16
|
private waitForOperationIds;
|
|
17
|
+
prepareCrossChainTransactionPayload(evmProxyMsg: EvmProxyMsg, senderAddress: string, assets?: Asset[], options?: CrossChainTransactionOptions): Promise<CrossChainPayloadResult[]>;
|
|
17
18
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.TONTransactionManager = void 0;
|
|
4
|
+
const ton_1 = require("@ton/ton");
|
|
4
5
|
const assets_1 = require("../assets");
|
|
5
6
|
const errors_1 = require("../errors");
|
|
6
7
|
const instances_1 = require("../errors/instances");
|
|
8
|
+
const sender_1 = require("../sender");
|
|
7
9
|
const Consts_1 = require("./Consts");
|
|
8
10
|
const Logger_1 = require("./Logger");
|
|
9
11
|
const Utils_1 = require("./Utils");
|
|
@@ -16,7 +18,7 @@ class TONTransactionManager {
|
|
|
16
18
|
this.logger = logger;
|
|
17
19
|
}
|
|
18
20
|
async buildFeeParams(options, evmProxyMsg, sender, tx) {
|
|
19
|
-
const { withoutSimulation, protocolFee, evmExecutorFee, tvmExecutorFee, isRoundTrip } = options;
|
|
21
|
+
const { withoutSimulation, protocolFee, evmExecutorFee, tvmExecutorFee, isRoundTrip, shouldValidateFees = true, } = options;
|
|
20
22
|
if (withoutSimulation) {
|
|
21
23
|
if (protocolFee === undefined || evmExecutorFee === undefined) {
|
|
22
24
|
throw errors_1.missingFeeParamsError;
|
|
@@ -38,6 +40,20 @@ class TONTransactionManager {
|
|
|
38
40
|
const simulationResult = await this.simulator.getSimulationInfo(sender, tx);
|
|
39
41
|
if (!evmProxyMsg.gasLimit)
|
|
40
42
|
evmProxyMsg.gasLimit = simulationResult.feeParams.gasLimit;
|
|
43
|
+
const shouldValidateSuggestedFees = shouldValidateFees && (simulationResult.simulation?.simulationStatus ?? true);
|
|
44
|
+
if (shouldValidateSuggestedFees) {
|
|
45
|
+
if (protocolFee !== undefined && protocolFee < simulationResult.feeParams.protocolFee) {
|
|
46
|
+
throw (0, errors_1.insufficientFeeParamsError)('protocolFee', protocolFee, simulationResult.feeParams.protocolFee);
|
|
47
|
+
}
|
|
48
|
+
if (evmExecutorFee !== undefined && evmExecutorFee < simulationResult.feeParams.evmExecutorFee) {
|
|
49
|
+
throw (0, errors_1.insufficientFeeParamsError)('evmExecutorFee', evmExecutorFee, simulationResult.feeParams.evmExecutorFee);
|
|
50
|
+
}
|
|
51
|
+
if (simulationResult.feeParams.isRoundTrip &&
|
|
52
|
+
tvmExecutorFee !== undefined &&
|
|
53
|
+
tvmExecutorFee < simulationResult.feeParams.tvmExecutorFee) {
|
|
54
|
+
throw (0, errors_1.insufficientFeeParamsError)('tvmExecutorFee', tvmExecutorFee, simulationResult.feeParams.tvmExecutorFee);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
41
57
|
return {
|
|
42
58
|
protocolFee: protocolFee ?? simulationResult.feeParams.protocolFee,
|
|
43
59
|
evmExecutorFee: evmExecutorFee ?? simulationResult.feeParams.evmExecutorFee,
|
|
@@ -46,12 +62,13 @@ class TONTransactionManager {
|
|
|
46
62
|
: simulationResult.feeParams.tvmExecutorFee,
|
|
47
63
|
gasLimit: evmProxyMsg.gasLimit ?? simulationResult.feeParams.gasLimit,
|
|
48
64
|
isRoundTrip: isRoundTrip ?? simulationResult.feeParams.isRoundTrip,
|
|
65
|
+
evmEstimatedGas: simulationResult.simulation?.estimatedGas,
|
|
49
66
|
};
|
|
50
67
|
}
|
|
51
68
|
async prepareCrossChainTransaction(evmProxyMsg, sender, assets, options, skipAssetsBalanceValidation = false) {
|
|
52
69
|
this.logger.debug('Preparing cross-chain transaction');
|
|
53
70
|
const caller = sender.getSenderAddress();
|
|
54
|
-
const { allowSimulationError = false, isRoundTrip = undefined, calculateRollbackFee = true, validateAssetsBalance = true, } = options || {};
|
|
71
|
+
const { allowSimulationError = false, isRoundTrip = undefined, calculateRollbackFee = true, validateAssetsBalance = true, evmDataBuilder = Utils_1.buildEvmDataCell, } = options || {};
|
|
55
72
|
const { evmValidExecutors = [], tvmValidExecutors = [] } = options || {};
|
|
56
73
|
Validator_1.Validator.validateEVMAddress(evmProxyMsg.evmTargetAddress);
|
|
57
74
|
const aggregatedData = (0, Utils_1.aggregateTokens)(assets);
|
|
@@ -87,7 +104,7 @@ class TONTransactionManager {
|
|
|
87
104
|
tac: tacExecutors,
|
|
88
105
|
ton: tonExecutors,
|
|
89
106
|
};
|
|
90
|
-
const evmData = (
|
|
107
|
+
const evmData = evmDataBuilder(transactionLinker, evmProxyMsg, validExecutors);
|
|
91
108
|
const messages = await this.generateCrossChainMessages(caller, evmData, aggregatedData, feeParams);
|
|
92
109
|
return {
|
|
93
110
|
transaction: {
|
|
@@ -106,29 +123,45 @@ class TONTransactionManager {
|
|
|
106
123
|
let feeTonAmount = feeParams.protocolFee + feeParams.evmExecutorFee + feeParams.tvmExecutorFee;
|
|
107
124
|
this.logger.debug(`Crosschain ton amount: ${crossChainTonAmount}, Fee ton amount: ${feeTonAmount}`);
|
|
108
125
|
if (!totalAssets.length) {
|
|
126
|
+
const tonNetworkFee = this.simulator.estimateTONFee(ton, {
|
|
127
|
+
excessReceiver: caller,
|
|
128
|
+
evmData,
|
|
129
|
+
feeParams,
|
|
130
|
+
});
|
|
109
131
|
return [
|
|
110
132
|
{
|
|
111
133
|
address: this.config.TONParams.crossChainLayerAddress,
|
|
112
|
-
value: crossChainTonAmount + feeTonAmount +
|
|
134
|
+
value: crossChainTonAmount + feeTonAmount + tonNetworkFee,
|
|
113
135
|
payload: await ton.generatePayload({ excessReceiver: caller, evmData, feeParams }),
|
|
136
|
+
extra: {
|
|
137
|
+
tonNetworkFee,
|
|
138
|
+
tacEstimatedGas: feeParams.evmEstimatedGas,
|
|
139
|
+
},
|
|
114
140
|
},
|
|
115
141
|
];
|
|
116
142
|
}
|
|
117
143
|
const messages = [];
|
|
118
144
|
let currentFeeParams = feeParams;
|
|
119
145
|
for (const asset of totalAssets) {
|
|
120
|
-
const
|
|
146
|
+
const params = {
|
|
121
147
|
excessReceiver: caller,
|
|
122
148
|
evmData,
|
|
123
149
|
crossChainTonAmount,
|
|
124
150
|
forwardFeeTonAmount: feeTonAmount,
|
|
125
151
|
feeParams: currentFeeParams,
|
|
126
|
-
}
|
|
152
|
+
};
|
|
153
|
+
const payload = await asset.generatePayload(params);
|
|
127
154
|
const address = asset instanceof assets_1.FT ? await asset.getUserWalletAddress(caller) : asset.address;
|
|
155
|
+
const forwardAmount = asset instanceof assets_1.FT ? Consts_1.JETTON_TRANSFER_FORWARD_TON_AMOUNT : Consts_1.NFT_TRANSFER_FORWARD_TON_AMOUNT;
|
|
156
|
+
const tonNetworkFee = this.simulator.estimateTONFee(asset, params);
|
|
128
157
|
messages.push({
|
|
129
158
|
address,
|
|
130
|
-
value: crossChainTonAmount + feeTonAmount +
|
|
159
|
+
value: crossChainTonAmount + feeTonAmount + tonNetworkFee + forwardAmount,
|
|
131
160
|
payload,
|
|
161
|
+
extra: {
|
|
162
|
+
tonNetworkFee,
|
|
163
|
+
tacEstimatedGas: currentFeeParams?.evmEstimatedGas,
|
|
164
|
+
},
|
|
132
165
|
});
|
|
133
166
|
crossChainTonAmount = 0n;
|
|
134
167
|
feeTonAmount = 0n;
|
|
@@ -140,16 +173,25 @@ class TONTransactionManager {
|
|
|
140
173
|
async sendCrossChainTransaction(evmProxyMsg, sender, tx) {
|
|
141
174
|
const { transaction, transactionLinker } = await this.prepareCrossChainTransaction(evmProxyMsg, sender, tx.assets, tx.options);
|
|
142
175
|
await assets_1.TON.checkBalance(sender, this.config, [transaction]);
|
|
176
|
+
const shouldWaitForOperationId = tx.options?.waitOperationId ?? true;
|
|
143
177
|
this.logger.debug(`Sending transaction: ${(0, Utils_1.formatObjectForLogging)(transactionLinker)}`);
|
|
144
178
|
const sendTransactionResult = await sender.sendShardTransaction(transaction, this.config.network, this.config.TONParams.contractOpener);
|
|
145
179
|
if (!sendTransactionResult.success || sendTransactionResult.error) {
|
|
146
180
|
throw (0, instances_1.sendCrossChainTransactionFailedError)(sendTransactionResult.error?.message ?? 'Transaction failed to send');
|
|
147
181
|
}
|
|
148
|
-
const shouldWaitForOperationId = tx.options?.waitOperationId ?? true;
|
|
149
182
|
if (!shouldWaitForOperationId) {
|
|
150
183
|
return { sendTransactionResult, ...transactionLinker };
|
|
151
184
|
}
|
|
152
185
|
const waitOptions = tx.options?.waitOptions ?? {};
|
|
186
|
+
const ensureTxExecuted = tx.options?.ensureTxExecuted ?? true;
|
|
187
|
+
if (ensureTxExecuted && sendTransactionResult.boc) {
|
|
188
|
+
const hash = (0, Utils_1.getNormalizedExtMessageHash)((0, ton_1.loadMessage)(ton_1.Cell.fromBase64(sendTransactionResult.boc).beginParse()));
|
|
189
|
+
this.logger.info(`Tracking transaction tree for hash: ${hash}`);
|
|
190
|
+
await this.config.TONParams.contractOpener.trackTransactionTree(sender.getSenderAddress(), hash, {
|
|
191
|
+
maxDepth: Consts_1.DEFAULT_FIND_TX_MAX_DEPTH,
|
|
192
|
+
});
|
|
193
|
+
this.logger.info(`Transaction tree successful`);
|
|
194
|
+
}
|
|
153
195
|
waitOptions.successCheck = waitOptions.successCheck ?? ((id) => !!id);
|
|
154
196
|
waitOptions.logger = waitOptions.logger ?? this.logger;
|
|
155
197
|
const operationId = await this.operationTracker
|
|
@@ -216,5 +258,18 @@ class TONTransactionManager {
|
|
|
216
258
|
return transactionLinkers;
|
|
217
259
|
}
|
|
218
260
|
}
|
|
261
|
+
async prepareCrossChainTransactionPayload(evmProxyMsg, senderAddress, assets = [], options) {
|
|
262
|
+
this.logger.debug('Preparing cross-chain transaction payload');
|
|
263
|
+
const mockSender = (0, sender_1.getMockSender)(senderAddress);
|
|
264
|
+
const result = await this.prepareCrossChainTransaction(evmProxyMsg, mockSender, assets, options, true);
|
|
265
|
+
return result.transaction.messages.map((r) => ({
|
|
266
|
+
body: r.payload,
|
|
267
|
+
destinationAddress: r.address,
|
|
268
|
+
tonAmount: r.value,
|
|
269
|
+
tonNetworkFee: r.extra.tonNetworkFee,
|
|
270
|
+
tacEstimatedGas: r.extra.tacEstimatedGas,
|
|
271
|
+
transactionLinker: result.transactionLinker,
|
|
272
|
+
}));
|
|
273
|
+
}
|
|
219
274
|
}
|
|
220
275
|
exports.TONTransactionManager = TONTransactionManager;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { IHttpClient, ITacExplorerClient } from '../interfaces';
|
|
2
|
+
import { TacGasPriceResponse } from '../structs/InternalStruct';
|
|
3
|
+
export declare class TacExplorerClient implements ITacExplorerClient {
|
|
4
|
+
private readonly explorerApiEndpoint;
|
|
5
|
+
private readonly httpClient;
|
|
6
|
+
constructor(explorerApiEndpoint: string, httpClient?: IHttpClient);
|
|
7
|
+
getTACGasPrice(): Promise<TacGasPriceResponse>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TacExplorerClient = void 0;
|
|
4
|
+
const instances_1 = require("../errors/instances");
|
|
5
|
+
const AxiosHttpClient_1 = require("./AxiosHttpClient");
|
|
6
|
+
const Utils_1 = require("./Utils");
|
|
7
|
+
class TacExplorerClient {
|
|
8
|
+
constructor(explorerApiEndpoint, httpClient = new AxiosHttpClient_1.AxiosHttpClient()) {
|
|
9
|
+
this.explorerApiEndpoint = explorerApiEndpoint;
|
|
10
|
+
this.httpClient = httpClient;
|
|
11
|
+
}
|
|
12
|
+
async getTACGasPrice() {
|
|
13
|
+
try {
|
|
14
|
+
const response = await this.httpClient.get(new URL('stats', this.explorerApiEndpoint).toString(), { transformResponse: [Utils_1.toCamelCaseTransformer] });
|
|
15
|
+
return response.data;
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
throw (0, instances_1.gasPriceFetchError)(`endpoint ${this.explorerApiEndpoint} failed to complete request`, error);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
exports.TacExplorerClient = TacExplorerClient;
|
package/dist/src/sdk/TacSdk.d.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { Wallet } from 'ethers';
|
|
2
2
|
import { JettonMinterData, NFTItemData } from '../../artifacts/tonTypes';
|
|
3
3
|
import { FT, NFT } from '../assets';
|
|
4
|
-
import { IConfiguration, ILogger, IOperationTracker, ITacSDK } from '../interfaces';
|
|
4
|
+
import { ContractOpener, IConfiguration, ILogger, IOperationTracker, ITacExplorerClient, ITacSDK } from '../interfaces';
|
|
5
5
|
import type { SenderAbstraction } from '../sender';
|
|
6
|
-
import { AssetFromFTArg, AssetFromNFTCollectionArg, AssetFromNFTItemArg, AssetLike, BatchCrossChainTxWithAssetLike, CrossChainTransactionOptions, CrossChainTransactionsOptions, CrosschainTx, EVMAddress, EvmProxyMsg, ExecutionFeeEstimationResult, NFTAddressType, SDKParams, SuggestedTVMExecutorFee, TACSimulationParams, TACSimulationResult, TransactionLinkerWithOperationId, TVMAddress, UserWalletBalanceExtended } from '../structs/Struct';
|
|
6
|
+
import { AssetFromFTArg, AssetFromNFTCollectionArg, AssetFromNFTItemArg, AssetLike, BatchCrossChainTxWithAssetLike, CrossChainPayloadResult, CrossChainTransactionOptions, CrossChainTransactionsOptions, CrosschainTx, EVMAddress, EvmProxyMsg, ExecutionFeeEstimationResult, NFTAddressType, SDKParams, SuggestedTVMExecutorFee, TacGasPrice, TACSimulationParams, TACSimulationResult, TransactionLinkerWithOperationId, TVMAddress, UserWalletBalanceExtended } from '../structs/Struct';
|
|
7
7
|
export declare class TacSdk implements ITacSDK {
|
|
8
8
|
readonly config: IConfiguration;
|
|
9
|
+
readonly contactOpener: ContractOpener;
|
|
9
10
|
readonly operationTracker: IOperationTracker;
|
|
11
|
+
readonly explorerClient: ITacExplorerClient;
|
|
10
12
|
private readonly simulator;
|
|
11
13
|
private readonly tonTransactionManager;
|
|
12
14
|
private readonly tacTransactionManager;
|
|
@@ -41,4 +43,8 @@ export declare class TacSdk implements ITacSDK {
|
|
|
41
43
|
getTVMNFTAddress(evmNFTAddress: string, tokenId?: number | bigint): Promise<string>;
|
|
42
44
|
getEVMNFTAddress(tvmNFTAddress: string, addressType: NFTAddressType): Promise<string>;
|
|
43
45
|
getOperationTracker(): IOperationTracker;
|
|
46
|
+
getTacExplorerClient(): ITacExplorerClient;
|
|
47
|
+
prepareCrossChainTransactionPayload(evmProxyMsg: EvmProxyMsg, senderAddress: string, assets?: AssetLike[], options?: CrossChainTransactionOptions): Promise<CrossChainPayloadResult[]>;
|
|
48
|
+
getTACGasPrice(): Promise<TacGasPrice>;
|
|
49
|
+
getTonContractOpener(): ContractOpener;
|
|
44
50
|
}
|
package/dist/src/sdk/TacSdk.js
CHANGED
|
@@ -9,20 +9,24 @@ const Consts_1 = require("./Consts");
|
|
|
9
9
|
const Logger_1 = require("./Logger");
|
|
10
10
|
const OperationTracker_1 = require("./OperationTracker");
|
|
11
11
|
const Simulator_1 = require("./Simulator");
|
|
12
|
+
const TacExplorerClient_1 = require("./TacExplorerClient");
|
|
12
13
|
const TACTransactionManager_1 = require("./TACTransactionManager");
|
|
13
14
|
const TONTransactionManager_1 = require("./TONTransactionManager");
|
|
14
15
|
const Utils_1 = require("./Utils");
|
|
15
16
|
class TacSdk {
|
|
16
|
-
constructor(config, simulator, tonTransactionManager, tacTransactionManager, operationTracker) {
|
|
17
|
+
constructor(config, simulator, tonTransactionManager, tacTransactionManager, operationTracker, explorerClient) {
|
|
17
18
|
this.config = config;
|
|
19
|
+
this.contactOpener = config.TONParams.contractOpener;
|
|
18
20
|
this.simulator = simulator;
|
|
19
21
|
this.tonTransactionManager = tonTransactionManager;
|
|
20
22
|
this.tacTransactionManager = tacTransactionManager;
|
|
21
23
|
this.operationTracker = operationTracker;
|
|
24
|
+
this.explorerClient = explorerClient;
|
|
22
25
|
}
|
|
23
26
|
static async create(sdkParams, logger = new Logger_1.NoopLogger()) {
|
|
24
27
|
const network = sdkParams.network;
|
|
25
28
|
const delay = sdkParams.delay ?? Consts_1.DEFAULT_DELAY;
|
|
29
|
+
const passLoggerToOpeners = sdkParams.passLoggerToOpeners ?? true;
|
|
26
30
|
let artifacts;
|
|
27
31
|
switch (network) {
|
|
28
32
|
case Struct_1.Network.MAINNET:
|
|
@@ -37,12 +41,13 @@ class TacSdk {
|
|
|
37
41
|
default:
|
|
38
42
|
throw new Error(`Unsupported network: ${network}`);
|
|
39
43
|
}
|
|
40
|
-
const config = await Configuration_1.Configuration.create(network, artifacts, sdkParams.TONParams, sdkParams.TACParams, sdkParams.customLiteSequencerEndpoints, delay);
|
|
41
|
-
const operationTracker = new OperationTracker_1.OperationTracker(network, config.liteSequencerEndpoints);
|
|
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, logger);
|
|
46
|
+
const explorerClient = new TacExplorerClient_1.TacExplorerClient(artifacts.TAC_EXPLORER_API_ENDPOINT);
|
|
42
47
|
const simulator = new Simulator_1.Simulator(config, operationTracker, logger);
|
|
43
48
|
const tonTransactionManager = new TONTransactionManager_1.TONTransactionManager(config, simulator, operationTracker, logger);
|
|
44
49
|
const tacTransactionManager = new TACTransactionManager_1.TACTransactionManager(config, operationTracker, logger);
|
|
45
|
-
return new TacSdk(config, simulator, tonTransactionManager, tacTransactionManager, operationTracker);
|
|
50
|
+
return new TacSdk(config, simulator, tonTransactionManager, tacTransactionManager, operationTracker, explorerClient);
|
|
46
51
|
}
|
|
47
52
|
closeConnections() {
|
|
48
53
|
return this.config.closeConnections();
|
|
@@ -177,5 +182,23 @@ class TacSdk {
|
|
|
177
182
|
getOperationTracker() {
|
|
178
183
|
return this.operationTracker;
|
|
179
184
|
}
|
|
185
|
+
getTacExplorerClient() {
|
|
186
|
+
return this.explorerClient;
|
|
187
|
+
}
|
|
188
|
+
async prepareCrossChainTransactionPayload(evmProxyMsg, senderAddress, assets = [], options) {
|
|
189
|
+
const normalizedAssets = await (0, Utils_1.normalizeAssets)(this.config, assets);
|
|
190
|
+
return this.tonTransactionManager.prepareCrossChainTransactionPayload(evmProxyMsg, senderAddress, normalizedAssets, options);
|
|
191
|
+
}
|
|
192
|
+
async getTACGasPrice() {
|
|
193
|
+
const response = await this.explorerClient.getTACGasPrice();
|
|
194
|
+
return {
|
|
195
|
+
average: response.gasPrices.average,
|
|
196
|
+
fast: response.gasPrices.fast,
|
|
197
|
+
slow: response.gasPrices.slow,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
getTonContractOpener() {
|
|
201
|
+
return this.contactOpener;
|
|
202
|
+
}
|
|
180
203
|
}
|
|
181
204
|
exports.TacSdk = TacSdk;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { IHttpClient, ILogger } from '../interfaces';
|
|
2
|
+
import { ITxFinalizer } from '../interfaces/ITxFinalizer';
|
|
2
3
|
import { TxFinalizerConfig } from '../structs/InternalStruct';
|
|
3
|
-
|
|
4
|
+
import { TrackTransactionTreeParams } from '../structs/Struct';
|
|
5
|
+
export declare class TonTxFinalizer implements ITxFinalizer {
|
|
4
6
|
private logger;
|
|
5
7
|
private apiConfig;
|
|
6
8
|
private readonly httpClient;
|
|
7
9
|
constructor(apiConfig: TxFinalizerConfig, logger?: ILogger, httpClient?: IHttpClient);
|
|
8
|
-
private logHashFormats;
|
|
9
10
|
private fetchAdjacentTransactions;
|
|
10
|
-
trackTransactionTree(hash: string,
|
|
11
|
+
trackTransactionTree(_: string, hash: string, params?: TrackTransactionTreeParams): Promise<void>;
|
|
11
12
|
}
|
|
@@ -1,43 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.TonTxFinalizer = void 0;
|
|
4
|
+
const errors_1 = require("../errors");
|
|
4
5
|
const AxiosHttpClient_1 = require("./AxiosHttpClient");
|
|
6
|
+
const Consts_1 = require("./Consts");
|
|
5
7
|
const Logger_1 = require("./Logger");
|
|
6
8
|
const Utils_1 = require("./Utils");
|
|
7
|
-
const IGNORE_OPCODE = [
|
|
8
|
-
'0xd53276db', // Excess
|
|
9
|
-
'0x7362d09c', // Jetton Notify
|
|
10
|
-
];
|
|
11
9
|
class TonTxFinalizer {
|
|
12
10
|
constructor(apiConfig, logger = new Logger_1.NoopLogger(), httpClient = new AxiosHttpClient_1.AxiosHttpClient()) {
|
|
13
11
|
this.apiConfig = apiConfig;
|
|
14
12
|
this.logger = logger;
|
|
15
13
|
this.httpClient = httpClient;
|
|
16
14
|
}
|
|
17
|
-
logHashFormats(hash) {
|
|
18
|
-
let hex, base64;
|
|
19
|
-
if (hash.startsWith('0x')) {
|
|
20
|
-
hex = hash;
|
|
21
|
-
const cleanHex = hex.slice(2);
|
|
22
|
-
const buffer = Buffer.from(cleanHex, 'hex');
|
|
23
|
-
base64 = buffer.toString('base64');
|
|
24
|
-
}
|
|
25
|
-
else {
|
|
26
|
-
base64 = hash;
|
|
27
|
-
const buffer = Buffer.from(base64, 'base64');
|
|
28
|
-
hex = '0x' + buffer.toString('hex');
|
|
29
|
-
}
|
|
30
|
-
return { hex: hex, base64: base64 };
|
|
31
|
-
}
|
|
32
15
|
// Fetches adjacent transactions from toncenter
|
|
33
|
-
async fetchAdjacentTransactions(hash, retries =
|
|
16
|
+
async fetchAdjacentTransactions(hash, retries = Consts_1.DEFAULT_RETRY_MAX_COUNT, delay = Consts_1.DEFAULT_RETRY_DELAY_MS) {
|
|
34
17
|
for (let i = retries; i >= 0; i--) {
|
|
35
18
|
try {
|
|
36
19
|
const url = this.apiConfig.urlBuilder(hash);
|
|
20
|
+
const authHeaders = this.apiConfig.authorization
|
|
21
|
+
? { [this.apiConfig.authorization.header]: this.apiConfig.authorization.value }
|
|
22
|
+
: undefined;
|
|
37
23
|
const response = await this.httpClient.get(url, {
|
|
38
|
-
headers: {
|
|
39
|
-
[this.apiConfig.authorization.header]: this.apiConfig.authorization.value,
|
|
40
|
-
},
|
|
24
|
+
...(authHeaders ? { headers: authHeaders } : {}),
|
|
41
25
|
transformResponse: [Utils_1.toCamelCaseTransformer],
|
|
42
26
|
});
|
|
43
27
|
return response.data.transactions || [];
|
|
@@ -54,7 +38,7 @@ class TonTxFinalizer {
|
|
|
54
38
|
// Log all errors except 404 Not Found
|
|
55
39
|
if (!errorMessage.includes('404')) {
|
|
56
40
|
const logMessage = error instanceof Error ? error.message : error;
|
|
57
|
-
|
|
41
|
+
this.logger.warn(`Failed to fetch adjacent transactions for ${hash}:`, logMessage);
|
|
58
42
|
}
|
|
59
43
|
if (i > 0) {
|
|
60
44
|
await (0, Utils_1.sleep)(delay);
|
|
@@ -64,7 +48,8 @@ class TonTxFinalizer {
|
|
|
64
48
|
return [];
|
|
65
49
|
}
|
|
66
50
|
// Checks if all transactions in the tree are successful
|
|
67
|
-
async trackTransactionTree(hash,
|
|
51
|
+
async trackTransactionTree(_, hash, params = { maxDepth: Consts_1.DEFAULT_FIND_TX_MAX_DEPTH, ignoreOpcodeList: Consts_1.IGNORE_OPCODE }) {
|
|
52
|
+
const { maxDepth = Consts_1.DEFAULT_FIND_TX_MAX_DEPTH, ignoreOpcodeList = Consts_1.IGNORE_OPCODE } = params;
|
|
68
53
|
const visitedHashes = new Set();
|
|
69
54
|
const queue = [{ hash, depth: 0 }];
|
|
70
55
|
while (queue.length > 0) {
|
|
@@ -73,25 +58,40 @@ class TonTxFinalizer {
|
|
|
73
58
|
continue;
|
|
74
59
|
}
|
|
75
60
|
visitedHashes.add(currentHash);
|
|
76
|
-
this.logger.debug(`Checking hash (depth ${currentDepth})
|
|
61
|
+
this.logger.debug(`Checking hash (depth ${currentDepth}): ${currentHash}`);
|
|
77
62
|
const transactions = await this.fetchAdjacentTransactions(currentHash);
|
|
78
63
|
if (transactions.length === 0)
|
|
79
64
|
continue;
|
|
80
65
|
for (const tx of transactions) {
|
|
81
|
-
if (
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
66
|
+
if (tx.inMsg.value === Consts_1.IGNORE_MSG_VALUE_1_NANO.toString())
|
|
67
|
+
continue; // we ignore messages with 1 nanoton value as they are for notification purpose only
|
|
68
|
+
if (!ignoreOpcodeList.includes(Number(tx.inMsg.opcode)) && tx.inMsg.opcode !== null) {
|
|
69
|
+
const { aborted, computePh, action } = tx.description;
|
|
70
|
+
const failureCase = (() => {
|
|
71
|
+
if (aborted) {
|
|
72
|
+
return 'Transaction was aborted';
|
|
73
|
+
}
|
|
74
|
+
if (!computePh) {
|
|
75
|
+
return 'computePh not present';
|
|
76
|
+
}
|
|
77
|
+
if (!computePh.success) {
|
|
78
|
+
return 'computePh not successful';
|
|
79
|
+
}
|
|
80
|
+
if (computePh.exitCode !== 0) {
|
|
81
|
+
return `computePh.exitCode was not zero`;
|
|
82
|
+
}
|
|
83
|
+
if (action && !action.success) {
|
|
84
|
+
return 'action not successful';
|
|
85
|
+
}
|
|
86
|
+
if (action && action.resultCode !== 0) {
|
|
87
|
+
return `action.resultCode was not zero`;
|
|
88
|
+
}
|
|
89
|
+
return null;
|
|
90
|
+
})();
|
|
91
|
+
if (failureCase) {
|
|
92
|
+
const exitCode = computePh ? computePh.exitCode : 'N/A';
|
|
93
|
+
const resultCode = action ? action.resultCode : 'N/A';
|
|
94
|
+
throw (0, errors_1.txFinalizationError)(`${tx.hash}: ${failureCase} (exitCode=${exitCode}, resultCode=${resultCode})`);
|
|
95
95
|
}
|
|
96
96
|
if (currentDepth + 1 < maxDepth) {
|
|
97
97
|
if (tx.outMsgs.length > 0) {
|
|
@@ -100,7 +100,7 @@ class TonTxFinalizer {
|
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
else {
|
|
103
|
-
this.logger.debug(`Skipping hash (depth ${currentDepth})
|
|
103
|
+
this.logger.debug(`Skipping hash (depth ${currentDepth}): ${tx.hash}`);
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
}
|