@tonappchain/sdk 0.7.2-alpha-13 → 0.7.2-alpha-15
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/dist/src/adapters/BaseContractOpener.d.ts +5 -0
- package/dist/src/adapters/BaseContractOpener.js +204 -49
- package/dist/src/adapters/LiteClientOpener.d.ts +7 -2
- package/dist/src/adapters/LiteClientOpener.js +32 -8
- package/dist/src/adapters/RetryableContractOpener.d.ts +5 -0
- package/dist/src/adapters/RetryableContractOpener.js +130 -29
- package/dist/src/adapters/TonClient4Opener.d.ts +7 -5
- package/dist/src/adapters/TonClient4Opener.js +11 -10
- package/dist/src/adapters/TonClientOpener.d.ts +5 -4
- package/dist/src/adapters/TonClientOpener.js +12 -10
- package/dist/src/interfaces/ContractOpener.d.ts +4 -2
- package/dist/src/interfaces/ITacSDK.d.ts +6 -1
- package/dist/src/sdk/Configuration.js +1 -0
- package/dist/src/sdk/Consts.d.ts +6 -2
- package/dist/src/sdk/Consts.js +7 -3
- package/dist/src/sdk/Fees.js +6 -6
- package/dist/src/sdk/StartTracking.d.ts +4 -0
- package/dist/src/sdk/StartTracking.js +10 -5
- package/dist/src/sdk/TONTransactionManager.js +1 -1
- package/dist/src/sdk/TxFinalizer.js +4 -3
- package/dist/src/sdk/Utils.d.ts +5 -0
- package/dist/src/sdk/Utils.js +44 -15
- package/dist/src/structs/InternalStruct.d.ts +1 -1
- package/dist/src/structs/Struct.d.ts +33 -6
- package/package.json +1 -1
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.RetryableContractOpener = void 0;
|
|
4
4
|
exports.createDefaultRetryableOpener = createDefaultRetryableOpener;
|
|
5
5
|
const ton_1 = require("@ton/ton");
|
|
6
|
+
const errors_1 = require("../errors");
|
|
6
7
|
const instances_1 = require("../errors/instances");
|
|
7
8
|
const Consts_1 = require("../sdk/Consts");
|
|
8
9
|
const Struct_1 = require("../structs/Struct");
|
|
@@ -16,24 +17,40 @@ class RetryableContractOpener {
|
|
|
16
17
|
}
|
|
17
18
|
this.openerConfigs = openerConfigs;
|
|
18
19
|
this.logger = logger;
|
|
20
|
+
if (logger) {
|
|
21
|
+
this.applyLoggerToOpeners(logger);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
setLogger(logger) {
|
|
25
|
+
if (!this.logger) {
|
|
26
|
+
this.logger = logger;
|
|
27
|
+
}
|
|
28
|
+
this.applyLoggerToOpeners(logger);
|
|
29
|
+
}
|
|
30
|
+
applyLoggerToOpeners(logger) {
|
|
31
|
+
for (const config of this.openerConfigs) {
|
|
32
|
+
config.opener.setLogger(logger);
|
|
33
|
+
}
|
|
19
34
|
}
|
|
20
35
|
async getTransactions(address, opts) {
|
|
21
|
-
const result = await this.executeWithFallback((config) => config.opener.getTransactions(address, opts)
|
|
22
|
-
|
|
36
|
+
const result = await this.executeWithFallback((config) => config.opener.getTransactions(address, opts), {
|
|
37
|
+
operationName: 'getTransactions',
|
|
38
|
+
});
|
|
39
|
+
if (result.success && result.data !== undefined) {
|
|
23
40
|
return result.data;
|
|
24
41
|
}
|
|
25
42
|
throw result.lastError || (0, instances_1.allContractOpenerFailedError)('Failed to get transactions');
|
|
26
43
|
}
|
|
27
44
|
async getTransactionByHash(address, hash, opts) {
|
|
28
|
-
const result = await this.executeWithFallback((config) => config.opener.getTransactionByHash(address, hash, opts));
|
|
29
|
-
if (result.success
|
|
30
|
-
return result.data;
|
|
45
|
+
const result = await this.executeWithFallback((config) => config.opener.getTransactionByHash(address, hash, opts), { operationName: 'getTransactionByHash' });
|
|
46
|
+
if (result.success) {
|
|
47
|
+
return result.data ?? null;
|
|
31
48
|
}
|
|
32
49
|
throw result.lastError || (0, instances_1.allContractOpenerFailedError)('Failed to get transaction by hash');
|
|
33
50
|
}
|
|
34
51
|
async getAdjacentTransactions(address, hash, opts) {
|
|
35
|
-
const result = await this.executeWithFallback((config) => config.opener.getAdjacentTransactions(address, hash, opts));
|
|
36
|
-
if (result.success && result.data) {
|
|
52
|
+
const result = await this.executeWithFallback((config) => config.opener.getAdjacentTransactions(address, hash, opts), { operationName: 'getAdjacentTransactions' });
|
|
53
|
+
if (result.success && result.data !== undefined) {
|
|
37
54
|
return result.data;
|
|
38
55
|
}
|
|
39
56
|
throw result.lastError || (0, instances_1.allContractOpenerFailedError)('Failed to get adjacent transactions');
|
|
@@ -44,42 +61,48 @@ class RetryableContractOpener {
|
|
|
44
61
|
return this.createRetryableContract(contract, src);
|
|
45
62
|
}
|
|
46
63
|
async getContractState(address) {
|
|
47
|
-
const result = await this.executeWithFallback((config) => config.opener.getContractState(address)
|
|
48
|
-
|
|
64
|
+
const result = await this.executeWithFallback((config) => config.opener.getContractState(address), {
|
|
65
|
+
operationName: 'getContractState',
|
|
66
|
+
});
|
|
67
|
+
if (result.success && result.data !== undefined) {
|
|
49
68
|
return result.data;
|
|
50
69
|
}
|
|
51
70
|
throw result.lastError || (0, instances_1.allContractOpenerFailedError)('Failed to get contract state');
|
|
52
71
|
}
|
|
53
72
|
async getAddressInformation(address) {
|
|
54
|
-
const result = await this.executeWithFallback((config) => config.opener.getAddressInformation(address)
|
|
55
|
-
|
|
73
|
+
const result = await this.executeWithFallback((config) => config.opener.getAddressInformation(address), {
|
|
74
|
+
operationName: 'getAddressInformation',
|
|
75
|
+
});
|
|
76
|
+
if (result.success && result.data !== undefined) {
|
|
56
77
|
return result.data;
|
|
57
78
|
}
|
|
58
79
|
throw result.lastError || (0, instances_1.allContractOpenerFailedError)('Failed to get address information');
|
|
59
80
|
}
|
|
60
81
|
async getConfig() {
|
|
61
|
-
const result = await this.executeWithFallback((config) => config.opener.getConfig()
|
|
62
|
-
|
|
82
|
+
const result = await this.executeWithFallback((config) => config.opener.getConfig(), {
|
|
83
|
+
operationName: 'getConfig',
|
|
84
|
+
});
|
|
85
|
+
if (result.success && result.data !== undefined) {
|
|
63
86
|
return result.data;
|
|
64
87
|
}
|
|
65
88
|
throw result.lastError || (0, instances_1.allContractOpenerFailedError)('Failed to get blockchain config');
|
|
66
89
|
}
|
|
67
90
|
async getTransactionByTxHash(address, txHash, opts) {
|
|
68
|
-
const result = await this.executeWithFallback((config) => config.opener.getTransactionByTxHash(address, txHash, opts));
|
|
91
|
+
const result = await this.executeWithFallback((config) => config.opener.getTransactionByTxHash(address, txHash, opts), { operationName: 'getTransactionByTxHash' });
|
|
69
92
|
if (result.success) {
|
|
70
93
|
return result.data ?? null;
|
|
71
94
|
}
|
|
72
95
|
throw result.lastError || (0, instances_1.allContractOpenerFailedError)('Failed to get transaction by transaction hash');
|
|
73
96
|
}
|
|
74
97
|
async getTransactionByInMsgHash(address, msgHash, opts) {
|
|
75
|
-
const result = await this.executeWithFallback((config) => config.opener.getTransactionByInMsgHash(address, msgHash, opts));
|
|
98
|
+
const result = await this.executeWithFallback((config) => config.opener.getTransactionByInMsgHash(address, msgHash, opts), { operationName: 'getTransactionByInMsgHash' });
|
|
76
99
|
if (result.success) {
|
|
77
100
|
return result.data ?? null;
|
|
78
101
|
}
|
|
79
102
|
throw result.lastError || (0, instances_1.allContractOpenerFailedError)('Failed to get transaction by message hash');
|
|
80
103
|
}
|
|
81
104
|
async getTransactionByOutMsgHash(address, msgHash, opts) {
|
|
82
|
-
const result = await this.executeWithFallback((config) => config.opener.getTransactionByOutMsgHash(address, msgHash, opts));
|
|
105
|
+
const result = await this.executeWithFallback((config) => config.opener.getTransactionByOutMsgHash(address, msgHash, opts), { operationName: 'getTransactionByOutMsgHash' });
|
|
83
106
|
if (result.success) {
|
|
84
107
|
return result.data ?? null;
|
|
85
108
|
}
|
|
@@ -91,34 +114,76 @@ class RetryableContractOpener {
|
|
|
91
114
|
}
|
|
92
115
|
}
|
|
93
116
|
async trackTransactionTree(address, hash, params) {
|
|
94
|
-
const result = await this.executeWithFallback(async (config) => {
|
|
95
|
-
|
|
117
|
+
const result = await this.executeWithFallback(async (config) => config.opener.trackTransactionTree(address, hash, params), {
|
|
118
|
+
shouldFallbackOnError: (error) => this.isTransportError(error),
|
|
119
|
+
operationName: 'trackTransactionTree',
|
|
96
120
|
});
|
|
97
121
|
if (!result.success) {
|
|
122
|
+
if (result.lastError instanceof errors_1.TransactionError) {
|
|
123
|
+
throw result.lastError;
|
|
124
|
+
}
|
|
98
125
|
throw result.lastError || (0, instances_1.allContractOpenerFailedError)('Failed to track transaction tree');
|
|
99
126
|
}
|
|
100
127
|
}
|
|
101
128
|
async trackTransactionTreeWithResult(address, hash, params) {
|
|
102
|
-
const result = await this.executeWithFallback(async (config) => {
|
|
103
|
-
|
|
129
|
+
const result = await this.executeWithFallback(async (config) => config.opener.trackTransactionTreeWithResult(address, hash, params), {
|
|
130
|
+
shouldFallbackOnError: (error) => this.isTransportError(error),
|
|
131
|
+
operationName: 'trackTransactionTreeWithResult',
|
|
104
132
|
});
|
|
105
133
|
if (!result.success) {
|
|
134
|
+
if (result.lastError instanceof errors_1.TransactionError) {
|
|
135
|
+
throw result.lastError;
|
|
136
|
+
}
|
|
106
137
|
throw result.lastError || (0, instances_1.allContractOpenerFailedError)('Failed to track transaction tree with result');
|
|
107
138
|
}
|
|
108
139
|
return result.data;
|
|
109
140
|
}
|
|
110
|
-
async executeWithFallback(operation) {
|
|
141
|
+
async executeWithFallback(operation, options = {}) {
|
|
142
|
+
const { useRetries = true, shouldFallbackOnError, operationName = 'operation' } = options;
|
|
111
143
|
let lastError;
|
|
112
|
-
for (
|
|
113
|
-
const
|
|
144
|
+
for (let index = 0; index < this.openerConfigs.length; index++) {
|
|
145
|
+
const config = this.openerConfigs[index];
|
|
146
|
+
const openerLabel = `opener ${index + 1}/${this.openerConfigs.length}`;
|
|
147
|
+
this.logger?.debug(`[RetryableContractOpener] ${operationName}: trying ${openerLabel}${useRetries ? ` (max retries ${config.retries})` : ' (single attempt)'}`);
|
|
148
|
+
const result = useRetries
|
|
149
|
+
? await this.tryWithRetries(() => operation(config), config, `${operationName} ${openerLabel}`)
|
|
150
|
+
: await this.trySingleAttempt(() => operation(config));
|
|
114
151
|
if (result.success) {
|
|
152
|
+
this.logger?.debug(`[RetryableContractOpener] ${operationName}: ${openerLabel} succeeded`);
|
|
115
153
|
return { success: true, data: result.data };
|
|
116
154
|
}
|
|
117
155
|
lastError = result.lastError;
|
|
156
|
+
if (lastError) {
|
|
157
|
+
this.logger?.debug(`[RetryableContractOpener] ${operationName}: ${openerLabel} failed: ${lastError.message}`);
|
|
158
|
+
}
|
|
159
|
+
if (lastError instanceof errors_1.TransactionError) {
|
|
160
|
+
this.logger?.debug(`[RetryableContractOpener] ${operationName}: stopping fallback because of TransactionError`);
|
|
161
|
+
return { success: false, lastError };
|
|
162
|
+
}
|
|
163
|
+
if (lastError && this.isContractExecutionError(lastError)) {
|
|
164
|
+
this.logger?.debug(`[RetryableContractOpener] ${operationName}: stopping fallback because of contract execution error`);
|
|
165
|
+
return { success: false, lastError };
|
|
166
|
+
}
|
|
167
|
+
if (lastError && shouldFallbackOnError) {
|
|
168
|
+
const shouldFallback = shouldFallbackOnError(lastError);
|
|
169
|
+
if (!shouldFallback) {
|
|
170
|
+
this.logger?.debug(`[RetryableContractOpener] ${operationName}: stopping fallback due to non-transport error`);
|
|
171
|
+
return { success: false, lastError };
|
|
172
|
+
}
|
|
173
|
+
}
|
|
118
174
|
}
|
|
119
175
|
return { success: false, lastError };
|
|
120
176
|
}
|
|
121
|
-
async
|
|
177
|
+
async trySingleAttempt(operation) {
|
|
178
|
+
try {
|
|
179
|
+
const data = await operation();
|
|
180
|
+
return { success: true, data };
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
return { success: false, lastError: error };
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
async tryWithRetries(operation, config, operationContext = 'operation') {
|
|
122
187
|
let lastError;
|
|
123
188
|
for (let attempt = 0; attempt <= config.retries; attempt++) {
|
|
124
189
|
try {
|
|
@@ -127,13 +192,45 @@ class RetryableContractOpener {
|
|
|
127
192
|
}
|
|
128
193
|
catch (error) {
|
|
129
194
|
lastError = error;
|
|
195
|
+
if (lastError instanceof errors_1.TransactionError || this.isContractExecutionError(lastError)) {
|
|
196
|
+
return { success: false, lastError };
|
|
197
|
+
}
|
|
130
198
|
if (attempt < config.retries) {
|
|
199
|
+
this.logger?.debug(`[RetryableContractOpener] ${operationContext}: attempt ${attempt + 1}/${config.retries + 1} failed, retrying in ${config.retryDelay}ms`);
|
|
131
200
|
await sleep(config.retryDelay);
|
|
132
201
|
}
|
|
133
202
|
}
|
|
134
203
|
}
|
|
135
204
|
return { success: false, lastError };
|
|
136
205
|
}
|
|
206
|
+
isContractExecutionError(error) {
|
|
207
|
+
const errorWithExit = error;
|
|
208
|
+
if (typeof errorWithExit.exitCode === 'number' ||
|
|
209
|
+
typeof errorWithExit.vmExitCode === 'number' ||
|
|
210
|
+
typeof errorWithExit.exit_code === 'number') {
|
|
211
|
+
return true;
|
|
212
|
+
}
|
|
213
|
+
const message = String(error.message ?? error);
|
|
214
|
+
return (/unable to execute get method/i.test(message) ||
|
|
215
|
+
/exit[_\s-]*code\s*:\s*\d+/i.test(message) ||
|
|
216
|
+
/vm exit code\s*:\s*\d+/i.test(message));
|
|
217
|
+
}
|
|
218
|
+
isTransportError(error) {
|
|
219
|
+
if (error instanceof errors_1.TransactionError) {
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
const errorWithResponse = error;
|
|
223
|
+
const status = errorWithResponse.response?.status ?? errorWithResponse.response?.statusCode;
|
|
224
|
+
if (typeof status === 'number') {
|
|
225
|
+
return status === 429 || status >= 500;
|
|
226
|
+
}
|
|
227
|
+
const code = errorWithResponse.code ?? '';
|
|
228
|
+
if (['ETIMEDOUT', 'ECONNRESET', 'ENOTFOUND', 'EAI_AGAIN'].includes(code)) {
|
|
229
|
+
return true;
|
|
230
|
+
}
|
|
231
|
+
const message = String(error.message ?? error);
|
|
232
|
+
return /too many requests|timeout|timed out|network|connection/i.test(message);
|
|
233
|
+
}
|
|
137
234
|
createRetryableContract(contract, src) {
|
|
138
235
|
return new Proxy(contract, {
|
|
139
236
|
get: (target, prop) => {
|
|
@@ -147,6 +244,7 @@ class RetryableContractOpener {
|
|
|
147
244
|
});
|
|
148
245
|
}
|
|
149
246
|
async callMethodAcrossOpeners(methodName, args, src) {
|
|
247
|
+
const addressLabel = src.address ? src.address.toString() : 'unknown';
|
|
150
248
|
const result = await this.executeWithFallback((config) => {
|
|
151
249
|
const contract = config.opener.open(src);
|
|
152
250
|
const method = Reflect.get(contract, methodName);
|
|
@@ -154,7 +252,7 @@ class RetryableContractOpener {
|
|
|
154
252
|
throw new Error(`Method ${String(methodName)} is not a function`);
|
|
155
253
|
}
|
|
156
254
|
return method.call(contract, ...args);
|
|
157
|
-
});
|
|
255
|
+
}, { operationName: `${String(methodName)} (address=${addressLabel})` });
|
|
158
256
|
if (result.success)
|
|
159
257
|
return result.data;
|
|
160
258
|
throw result.lastError || (0, instances_1.allContractOpenerFailedError)('failed to call method in contract');
|
|
@@ -163,19 +261,22 @@ class RetryableContractOpener {
|
|
|
163
261
|
exports.RetryableContractOpener = RetryableContractOpener;
|
|
164
262
|
async function createDefaultRetryableOpener(tonRpcEndpoint, networkType, maxRetries = Consts_1.DEFAULT_RETRY_MAX_COUNT, retryDelay = Consts_1.DEFAULT_RETRY_DELAY_MS, logger) {
|
|
165
263
|
const openers = [];
|
|
166
|
-
const tonClient = new ton_1.TonClient({
|
|
167
|
-
|
|
264
|
+
const tonClient = new ton_1.TonClient({
|
|
265
|
+
endpoint: new URL('api/v2/jsonRPC', tonRpcEndpoint).toString(),
|
|
266
|
+
timeout: Consts_1.DEFAULT_HTTP_CLIENT_TIMEOUT_MS,
|
|
267
|
+
});
|
|
268
|
+
const opener = (0, TonClientOpener_1.tonClientOpener)(tonClient, logger);
|
|
168
269
|
openers.push({ opener, retries: maxRetries, retryDelay });
|
|
169
270
|
if (networkType !== Struct_1.Network.DEV) {
|
|
170
271
|
try {
|
|
171
|
-
const opener = await (0, TonClientOpener_1.orbsOpener)(networkType);
|
|
272
|
+
const opener = await (0, TonClientOpener_1.orbsOpener)(networkType, logger);
|
|
172
273
|
openers.push({ opener: opener, retries: maxRetries, retryDelay });
|
|
173
274
|
}
|
|
174
275
|
catch {
|
|
175
276
|
// skip opener in case of failure
|
|
176
277
|
}
|
|
177
278
|
try {
|
|
178
|
-
const opener4 = await (0, TonClient4Opener_1.orbsOpener4)(networkType);
|
|
279
|
+
const opener4 = await (0, TonClient4Opener_1.orbsOpener4)(networkType, Consts_1.DEFAULT_HTTP_CLIENT_TIMEOUT_MS, logger);
|
|
179
280
|
openers.push({ opener: opener4, retries: maxRetries, retryDelay });
|
|
180
281
|
}
|
|
181
282
|
catch {
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Address, Contract, OpenedContract, TonClient4, Transaction } from '@ton/ton';
|
|
2
|
+
import { ILogger } from '../interfaces';
|
|
2
3
|
import { AddressInformation, ContractState, GetTransactionsOptions, Network } from '../structs/Struct';
|
|
3
4
|
import { BaseContractOpener } from './BaseContractOpener';
|
|
4
5
|
export declare class TonClient4Opener extends BaseContractOpener {
|
|
5
6
|
private readonly client4;
|
|
6
|
-
constructor(client4: TonClient4);
|
|
7
|
-
static create(endpoint: string, timeout?: number): TonClient4Opener;
|
|
7
|
+
constructor(client4: TonClient4, logger?: ILogger);
|
|
8
|
+
static create(endpoint: string, timeout?: number, logger?: ILogger): TonClient4Opener;
|
|
8
9
|
open<T extends Contract>(contract: T): OpenedContract<T>;
|
|
9
10
|
getContractState(address: Address): Promise<ContractState>;
|
|
10
11
|
getTransactions(address: Address, opts: GetTransactionsOptions): Promise<Transaction[]>;
|
|
@@ -15,7 +16,8 @@ export declare class TonClient4Opener extends BaseContractOpener {
|
|
|
15
16
|
* Creates a TonClient4Opener instance using TonHub public API
|
|
16
17
|
* @param network Network to connect to (mainnet or testnet)
|
|
17
18
|
* @param timeout Request timeout in milliseconds
|
|
19
|
+
* @param logger
|
|
18
20
|
*/
|
|
19
|
-
export declare function tonHubApi4Opener(network: Network, timeout?: number): TonClient4Opener;
|
|
20
|
-
export declare function tonClient4Opener(client: TonClient4): TonClient4Opener;
|
|
21
|
-
export declare function orbsOpener4(network: Network, timeout?: number): Promise<TonClient4Opener>;
|
|
21
|
+
export declare function tonHubApi4Opener(network: Network, timeout?: number, logger?: ILogger): TonClient4Opener;
|
|
22
|
+
export declare function tonClient4Opener(client: TonClient4, logger?: ILogger): TonClient4Opener;
|
|
23
|
+
export declare function orbsOpener4(network: Network, timeout?: number, logger?: ILogger): Promise<TonClient4Opener>;
|
|
@@ -10,13 +10,13 @@ const Struct_1 = require("../structs/Struct");
|
|
|
10
10
|
const BaseContractOpener_1 = require("./BaseContractOpener");
|
|
11
11
|
const OpenerUtils_1 = require("./OpenerUtils");
|
|
12
12
|
class TonClient4Opener extends BaseContractOpener_1.BaseContractOpener {
|
|
13
|
-
constructor(client4) {
|
|
14
|
-
super();
|
|
13
|
+
constructor(client4, logger) {
|
|
14
|
+
super(logger);
|
|
15
15
|
this.client4 = client4;
|
|
16
16
|
}
|
|
17
|
-
static create(endpoint, timeout = 10000) {
|
|
17
|
+
static create(endpoint, timeout = 10000, logger) {
|
|
18
18
|
const client4 = new ton_1.TonClient4({ endpoint, timeout });
|
|
19
|
-
return new TonClient4Opener(client4);
|
|
19
|
+
return new TonClient4Opener(client4, logger);
|
|
20
20
|
}
|
|
21
21
|
open(contract) {
|
|
22
22
|
return this.client4.open(contract);
|
|
@@ -71,16 +71,17 @@ exports.TonClient4Opener = TonClient4Opener;
|
|
|
71
71
|
* Creates a TonClient4Opener instance using TonHub public API
|
|
72
72
|
* @param network Network to connect to (mainnet or testnet)
|
|
73
73
|
* @param timeout Request timeout in milliseconds
|
|
74
|
+
* @param logger
|
|
74
75
|
*/
|
|
75
|
-
function tonHubApi4Opener(network, timeout = Consts_1.DEFAULT_HTTP_CLIENT_TIMEOUT_MS) {
|
|
76
|
+
function tonHubApi4Opener(network, timeout = Consts_1.DEFAULT_HTTP_CLIENT_TIMEOUT_MS, logger) {
|
|
76
77
|
const endpoint = network === Struct_1.Network.MAINNET ? 'https://mainnet-v4.tonhubapi.com' : 'https://testnet-v4.tonhubapi.com';
|
|
77
|
-
return TonClient4Opener.create(endpoint, timeout);
|
|
78
|
+
return TonClient4Opener.create(endpoint, timeout, logger);
|
|
78
79
|
}
|
|
79
|
-
function tonClient4Opener(client) {
|
|
80
|
-
return new TonClient4Opener(client);
|
|
80
|
+
function tonClient4Opener(client, logger) {
|
|
81
|
+
return new TonClient4Opener(client, logger);
|
|
81
82
|
}
|
|
82
|
-
async function orbsOpener4(network, timeout = Consts_1.DEFAULT_HTTP_CLIENT_TIMEOUT_MS) {
|
|
83
|
+
async function orbsOpener4(network, timeout = Consts_1.DEFAULT_HTTP_CLIENT_TIMEOUT_MS, logger) {
|
|
83
84
|
const endpoint = await (0, OpenerUtils_1.getHttpV4EndpointWithRetry)(network);
|
|
84
85
|
const client = new ton_1.TonClient4({ endpoint, timeout });
|
|
85
|
-
return new TonClient4Opener(client);
|
|
86
|
+
return new TonClient4Opener(client, logger);
|
|
86
87
|
}
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { Address, Contract, OpenedContract, TonClient, Transaction } from '@ton/ton';
|
|
2
|
+
import { ILogger } from '../interfaces';
|
|
2
3
|
import { AddressInformation, ContractState, GetTransactionsOptions, Network } from '../structs/Struct';
|
|
3
4
|
import { BaseContractOpener } from './BaseContractOpener';
|
|
4
5
|
export declare class TonClientOpener extends BaseContractOpener {
|
|
5
6
|
private readonly client;
|
|
6
7
|
private readonly httpClient;
|
|
7
|
-
constructor(client: TonClient);
|
|
8
|
-
static create(endpoint: string, timeout?: number): TonClientOpener;
|
|
8
|
+
constructor(client: TonClient, logger?: ILogger);
|
|
9
|
+
static create(endpoint: string, timeout?: number, logger?: ILogger): TonClientOpener;
|
|
9
10
|
open<T extends Contract>(contract: T): OpenedContract<T>;
|
|
10
11
|
getContractState(address: Address): Promise<ContractState>;
|
|
11
12
|
getTransactions(address: Address, opts: GetTransactionsOptions): Promise<Transaction[]>;
|
|
12
13
|
getAddressInformation(addr: Address): Promise<AddressInformation>;
|
|
13
14
|
getConfig(): Promise<string>;
|
|
14
15
|
}
|
|
15
|
-
export declare function tonClientOpener(client: TonClient): TonClientOpener;
|
|
16
|
-
export declare function orbsOpener(network: Network): Promise<TonClientOpener>;
|
|
16
|
+
export declare function tonClientOpener(client: TonClient, logger?: ILogger): TonClientOpener;
|
|
17
|
+
export declare function orbsOpener(network: Network, logger?: ILogger): Promise<TonClientOpener>;
|
|
@@ -6,17 +6,18 @@ exports.orbsOpener = orbsOpener;
|
|
|
6
6
|
const ton_1 = require("@ton/ton");
|
|
7
7
|
const AxiosHttpClient_1 = require("../sdk/AxiosHttpClient");
|
|
8
8
|
const Consts_1 = require("../sdk/Consts");
|
|
9
|
+
const Utils_1 = require("../sdk/Utils");
|
|
9
10
|
const BaseContractOpener_1 = require("./BaseContractOpener");
|
|
10
11
|
const OpenerUtils_1 = require("./OpenerUtils");
|
|
11
12
|
class TonClientOpener extends BaseContractOpener_1.BaseContractOpener {
|
|
12
|
-
constructor(client) {
|
|
13
|
-
super();
|
|
13
|
+
constructor(client, logger) {
|
|
14
|
+
super(logger);
|
|
14
15
|
this.client = client;
|
|
15
16
|
this.httpClient = new AxiosHttpClient_1.AxiosHttpClient({ timeout: Consts_1.DEFAULT_HTTP_CLIENT_TIMEOUT_MS });
|
|
16
17
|
}
|
|
17
|
-
static create(endpoint, timeout = Consts_1.DEFAULT_HTTP_CLIENT_TIMEOUT_MS) {
|
|
18
|
+
static create(endpoint, timeout = Consts_1.DEFAULT_HTTP_CLIENT_TIMEOUT_MS, logger) {
|
|
18
19
|
const client = new ton_1.TonClient({ endpoint, timeout });
|
|
19
|
-
return new TonClientOpener(client);
|
|
20
|
+
return new TonClientOpener(client, logger);
|
|
20
21
|
}
|
|
21
22
|
open(contract) {
|
|
22
23
|
return this.client.open(contract);
|
|
@@ -29,7 +30,8 @@ class TonClientOpener extends BaseContractOpener_1.BaseContractOpener {
|
|
|
29
30
|
const clientOpts = {
|
|
30
31
|
limit: opts.limit ?? Consts_1.DEFAULT_FIND_TX_LIMIT,
|
|
31
32
|
lt: opts.lt,
|
|
32
|
-
hash
|
|
33
|
+
// TonClient API expects base64 transaction hash and converts it to hex internally.
|
|
34
|
+
hash: opts.hash ? (0, Utils_1.normalizeHashToBase64)(opts.hash) : undefined,
|
|
33
35
|
to_lt: opts.to_lt,
|
|
34
36
|
inclusive: opts.inclusive,
|
|
35
37
|
archival: opts.archival,
|
|
@@ -60,11 +62,11 @@ class TonClientOpener extends BaseContractOpener_1.BaseContractOpener {
|
|
|
60
62
|
}
|
|
61
63
|
}
|
|
62
64
|
exports.TonClientOpener = TonClientOpener;
|
|
63
|
-
function tonClientOpener(client) {
|
|
64
|
-
return new TonClientOpener(client);
|
|
65
|
+
function tonClientOpener(client, logger) {
|
|
66
|
+
return new TonClientOpener(client, logger);
|
|
65
67
|
}
|
|
66
|
-
async function orbsOpener(network) {
|
|
68
|
+
async function orbsOpener(network, logger) {
|
|
67
69
|
const endpoint = await (0, OpenerUtils_1.getHttpEndpointWithRetry)(network);
|
|
68
|
-
const client = new ton_1.TonClient({ endpoint });
|
|
69
|
-
return new TonClientOpener(client);
|
|
70
|
+
const client = new ton_1.TonClient({ endpoint, timeout: Consts_1.DEFAULT_HTTP_CLIENT_TIMEOUT_MS });
|
|
71
|
+
return new TonClientOpener(client, logger);
|
|
70
72
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { SandboxContract } from '@ton/sandbox';
|
|
2
2
|
import type { Address, Contract, OpenedContract, Transaction } from '@ton/ton';
|
|
3
3
|
import { AddressInformation, ContractState, GetTransactionsOptions, TrackTransactionTreeParams, TrackTransactionTreeResult } from '../structs/Struct';
|
|
4
|
+
import { ILogger } from './ILogger';
|
|
4
5
|
export interface ContractOpener {
|
|
5
6
|
/**
|
|
6
7
|
* Opens a contract for interaction using the underlying client (lite client, sandbox, etc.).
|
|
@@ -78,7 +79,7 @@ export interface ContractOpener {
|
|
|
78
79
|
* @param address Root account address
|
|
79
80
|
* @param hash Root transaction or message hash
|
|
80
81
|
* @param params Tracking parameters (maxDepth, ignoreOpcodeList, etc.)
|
|
81
|
-
* @throws Error if any transaction in the tree failed
|
|
82
|
+
* @throws Error if any transaction in the tree failed or if a hash is not found
|
|
82
83
|
*/
|
|
83
84
|
trackTransactionTree(address: string, hash: string, params?: TrackTransactionTreeParams): Promise<void>;
|
|
84
85
|
/**
|
|
@@ -87,7 +88,8 @@ export interface ContractOpener {
|
|
|
87
88
|
* @param address Root account address
|
|
88
89
|
* @param hash Root transaction or message hash
|
|
89
90
|
* @param params Tracking parameters (maxDepth, ignoreOpcodeList, etc.)
|
|
90
|
-
* @returns Result object with success flag and error details if validation failed
|
|
91
|
+
* @returns Result object with success flag and error details if validation failed or a hash was not found
|
|
91
92
|
*/
|
|
92
93
|
trackTransactionTreeWithResult(address: string, hash: string, params?: TrackTransactionTreeParams): Promise<TrackTransactionTreeResult>;
|
|
94
|
+
setLogger(logger: ILogger): void;
|
|
93
95
|
}
|
|
@@ -2,7 +2,7 @@ import { Wallet } from 'ethers';
|
|
|
2
2
|
import { JettonMinterData, NFTItemData } from '../../artifacts/tonTypes';
|
|
3
3
|
import { FT, NFT } from '../assets';
|
|
4
4
|
import type { SenderAbstraction } from '../sender';
|
|
5
|
-
import { AssetFromFTArg, AssetFromNFTCollectionArg, AssetFromNFTItemArg, AssetLike, BatchCrossChainTxWithAssetLike, CrossChainPayloadResult, CrossChainTransactionOptions, CrossChainTransactionsOptions, CrosschainTx, EVMAddress, EvmProxyMsg, ExecutionFeeEstimationResult, NFTAddressType, SuggestedTVMExecutorFee, TACSimulationParams, TACSimulationResult, TransactionLinkerWithOperationId, TVMAddress, UserWalletBalanceExtended, WaitOptions } from '../structs/Struct';
|
|
5
|
+
import { AssetFromFTArg, AssetFromNFTCollectionArg, AssetFromNFTItemArg, AssetLike, BatchCrossChainTxWithAssetLike, CrossChainPayloadResult, CrossChainTransactionOptions, CrossChainTransactionsOptions, CrosschainTx, EVMAddress, EvmProxyMsg, ExecutionFeeEstimationResult, NFTAddressType, SuggestedTVMExecutorFee, TacGasPrice, TACSimulationParams, TACSimulationResult, TransactionLinkerWithOperationId, TVMAddress, UserWalletBalanceExtended, WaitOptions } from '../structs/Struct';
|
|
6
6
|
import { Asset } from './Asset';
|
|
7
7
|
import { ContractOpener } from './ContractOpener';
|
|
8
8
|
import { IConfiguration } from './IConfiguration';
|
|
@@ -201,4 +201,9 @@ export interface ITacSDK {
|
|
|
201
201
|
* @returns Promise with the prepared transaction payloads.
|
|
202
202
|
*/
|
|
203
203
|
prepareCrossChainTransactionPayload(evmProxyMsg: EvmProxyMsg, senderAddress: string, assets?: AssetLike[], options?: CrossChainTransactionOptions): Promise<CrossChainPayloadResult[]>;
|
|
204
|
+
/**
|
|
205
|
+
* Returns TAC gas price for the current network.
|
|
206
|
+
* @returns Promise resolving to the gas price in wei (bigint).
|
|
207
|
+
*/
|
|
208
|
+
getTACGasPrice(): Promise<TacGasPrice>;
|
|
204
209
|
}
|
|
@@ -55,6 +55,7 @@ class Configuration {
|
|
|
55
55
|
(await (0, adapters_1.createDefaultRetryableOpener)(artifacts.TON_RPC_ENDPOINT_BY_TAC, network, 5, delay, logger));
|
|
56
56
|
settingsAddress = TONParams?.settingsAddress ?? artifacts.TON_SETTINGS_ADDRESS;
|
|
57
57
|
}
|
|
58
|
+
contractOpener.setLogger(logger);
|
|
58
59
|
const settings = contractOpener.open(artifacts.ton.wrappers.Settings.createFromAddress(ton_1.Address.parse(settingsAddress)));
|
|
59
60
|
const allSettingsSlice = (await settings.getAll()).beginParse();
|
|
60
61
|
const allSettings = allSettingsSlice.loadDictDirect(ton_1.Dictionary.Keys.BigUint(256), ton_1.Dictionary.Values.Cell());
|
package/dist/src/sdk/Consts.d.ts
CHANGED
|
@@ -14,13 +14,17 @@ export declare const ONE_YEAR_SECONDS: number;
|
|
|
14
14
|
export declare const TON_DECIMALS = 9;
|
|
15
15
|
export declare const TAC_DECIMALS = 18;
|
|
16
16
|
export declare const FIVE_MINUTES: number;
|
|
17
|
+
export declare const MINUTE: number;
|
|
17
18
|
export declare const TON_BURN_ADDRESS = "EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c";
|
|
18
19
|
export declare const DEFAULT_HTTP_CLIENT_TIMEOUT_MS = 30000;
|
|
19
|
-
export declare const DEFAULT_FIND_TX_TIMEOUT_MS = 180000;
|
|
20
20
|
export declare const DEFAULT_RETRY_MAX_COUNT = 5;
|
|
21
21
|
export declare const DEFAULT_RETRY_DELAY_MS = 1000;
|
|
22
|
-
export declare const DEFAULT_FIND_TX_LIMIT =
|
|
22
|
+
export declare const DEFAULT_FIND_TX_LIMIT = 100;
|
|
23
|
+
export declare const DEFAULT_MAX_SCANNED_TRANSACTIONS = 100;
|
|
23
24
|
export declare const DEFAULT_FIND_TX_ARCHIVAL = true;
|
|
24
25
|
export declare const DEFAULT_FIND_TX_MAX_DEPTH = 10;
|
|
26
|
+
export declare const DEFAULT_WAIT_FOR_ROOT_TRANSACTION = true;
|
|
27
|
+
export declare const DEFAULT_WAIT_FOR_ROOT_TRANSACTION_TIMEOUT_MS: number;
|
|
28
|
+
export declare const DEFAULT_WAIT_FOR_ROOT_TRANSACTION_RETRY_DELAY_MS = 1000;
|
|
25
29
|
export declare const IGNORE_MSG_VALUE_1_NANO = 1n;
|
|
26
30
|
export declare const IGNORE_OPCODE: number[];
|
package/dist/src/sdk/Consts.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.IGNORE_OPCODE = exports.IGNORE_MSG_VALUE_1_NANO = exports.DEFAULT_FIND_TX_MAX_DEPTH = exports.DEFAULT_FIND_TX_ARCHIVAL = exports.DEFAULT_FIND_TX_LIMIT = exports.DEFAULT_RETRY_DELAY_MS = exports.DEFAULT_RETRY_MAX_COUNT = exports.
|
|
3
|
+
exports.IGNORE_OPCODE = exports.IGNORE_MSG_VALUE_1_NANO = exports.DEFAULT_WAIT_FOR_ROOT_TRANSACTION_RETRY_DELAY_MS = exports.DEFAULT_WAIT_FOR_ROOT_TRANSACTION_TIMEOUT_MS = exports.DEFAULT_WAIT_FOR_ROOT_TRANSACTION = exports.DEFAULT_FIND_TX_MAX_DEPTH = exports.DEFAULT_FIND_TX_ARCHIVAL = exports.DEFAULT_MAX_SCANNED_TRANSACTIONS = exports.DEFAULT_FIND_TX_LIMIT = exports.DEFAULT_RETRY_DELAY_MS = exports.DEFAULT_RETRY_MAX_COUNT = exports.DEFAULT_HTTP_CLIENT_TIMEOUT_MS = exports.TON_BURN_ADDRESS = exports.MINUTE = exports.FIVE_MINUTES = exports.TAC_DECIMALS = exports.TON_DECIMALS = exports.ONE_YEAR_SECONDS = exports.FIFTEEN_MINUTES = exports.TAC_SYMBOL = exports.TON_SYMBOL = exports.MAX_MSG_DEPTH = exports.MAX_HIGHLOAD_GROUP_MSG_NUM = exports.MAX_EXT_MSG_SIZE = exports.SOLIDITY_METHOD_NAME_REGEX = exports.SOLIDITY_SIGNATURE_REGEX = exports.DEFAULT_DELAY = exports.MAX_ITERATION_COUNT = exports.NFT_TRANSFER_FORWARD_TON_AMOUNT = exports.JETTON_TRANSFER_FORWARD_TON_AMOUNT = void 0;
|
|
4
4
|
const ton_1 = require("@ton/ton");
|
|
5
5
|
exports.JETTON_TRANSFER_FORWARD_TON_AMOUNT = (0, ton_1.toNano)(0.2);
|
|
6
6
|
exports.NFT_TRANSFER_FORWARD_TON_AMOUNT = (0, ton_1.toNano)(0.3);
|
|
@@ -18,14 +18,18 @@ exports.ONE_YEAR_SECONDS = 365 * 24 * 3600;
|
|
|
18
18
|
exports.TON_DECIMALS = 9;
|
|
19
19
|
exports.TAC_DECIMALS = 18;
|
|
20
20
|
exports.FIVE_MINUTES = 5 * 60 * 1000;
|
|
21
|
+
exports.MINUTE = 60 * 1000;
|
|
21
22
|
exports.TON_BURN_ADDRESS = 'EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c';
|
|
22
23
|
exports.DEFAULT_HTTP_CLIENT_TIMEOUT_MS = 30000;
|
|
23
|
-
exports.DEFAULT_FIND_TX_TIMEOUT_MS = 180000;
|
|
24
24
|
exports.DEFAULT_RETRY_MAX_COUNT = 5;
|
|
25
25
|
exports.DEFAULT_RETRY_DELAY_MS = 1000;
|
|
26
|
-
exports.DEFAULT_FIND_TX_LIMIT =
|
|
26
|
+
exports.DEFAULT_FIND_TX_LIMIT = 100;
|
|
27
|
+
exports.DEFAULT_MAX_SCANNED_TRANSACTIONS = 100;
|
|
27
28
|
exports.DEFAULT_FIND_TX_ARCHIVAL = true;
|
|
28
29
|
exports.DEFAULT_FIND_TX_MAX_DEPTH = 10;
|
|
30
|
+
exports.DEFAULT_WAIT_FOR_ROOT_TRANSACTION = true;
|
|
31
|
+
exports.DEFAULT_WAIT_FOR_ROOT_TRANSACTION_TIMEOUT_MS = exports.MINUTE;
|
|
32
|
+
exports.DEFAULT_WAIT_FOR_ROOT_TRANSACTION_RETRY_DELAY_MS = 1000;
|
|
29
33
|
exports.IGNORE_MSG_VALUE_1_NANO = 1n;
|
|
30
34
|
exports.IGNORE_OPCODE = [
|
|
31
35
|
0xd53276db, // Excess
|
package/dist/src/sdk/Fees.js
CHANGED
|
@@ -65,8 +65,8 @@ exports.DEFAULT_CONTRACT_FEE_USAGE_PARAMS = {
|
|
|
65
65
|
},
|
|
66
66
|
};
|
|
67
67
|
const createCrossChainLayerTvmMsgToEvmStep = (params, msgBits, msgCells) => ({
|
|
68
|
-
accountBits:
|
|
69
|
-
accountCells:
|
|
68
|
+
accountBits: 0,
|
|
69
|
+
accountCells: 0,
|
|
70
70
|
gasUsed: params.crossChainLayer.gas.tvmMsgToEvm,
|
|
71
71
|
msgBits,
|
|
72
72
|
msgCells,
|
|
@@ -101,8 +101,8 @@ const createJettonWalletBurnStep = (params, msgBits, msgCells) => ({
|
|
|
101
101
|
});
|
|
102
102
|
exports.createJettonWalletBurnStep = createJettonWalletBurnStep;
|
|
103
103
|
const createJettonProxyOwnershipAssignedStep = (params, msgBits, msgCells) => ({
|
|
104
|
-
accountBits:
|
|
105
|
-
accountCells:
|
|
104
|
+
accountBits: 0,
|
|
105
|
+
accountCells: 0,
|
|
106
106
|
gasUsed: params.jettonProxy.gas.ownershipAssigned,
|
|
107
107
|
msgBits,
|
|
108
108
|
msgCells,
|
|
@@ -137,8 +137,8 @@ const createNftItemBurnStep = (params, msgBits, msgCells) => ({
|
|
|
137
137
|
});
|
|
138
138
|
exports.createNftItemBurnStep = createNftItemBurnStep;
|
|
139
139
|
const createNftProxyOwnershipAssignedStep = (params, msgBits, msgCells) => ({
|
|
140
|
-
accountBits:
|
|
141
|
-
accountCells:
|
|
140
|
+
accountBits: 0,
|
|
141
|
+
accountCells: 0,
|
|
142
142
|
gasUsed: params.nftProxy.gas.ownershipAssigned,
|
|
143
143
|
msgBits,
|
|
144
144
|
msgCells,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ContractOpener, ILogger } from '../interfaces';
|
|
2
|
+
import { ITxFinalizer } from '../interfaces/ITxFinalizer';
|
|
2
3
|
import { ExecutionStages, Network, TransactionLinker } from '../structs/Struct';
|
|
3
4
|
export declare function startTracking(transactionLinker: TransactionLinker, network: Network, options?: {
|
|
4
5
|
customLiteSequencerEndpoints?: string[];
|
|
@@ -7,6 +8,7 @@ export declare function startTracking(transactionLinker: TransactionLinker, netw
|
|
|
7
8
|
returnValue?: boolean;
|
|
8
9
|
tableView?: boolean;
|
|
9
10
|
logger?: ILogger;
|
|
11
|
+
txFinalizer?: ITxFinalizer;
|
|
10
12
|
contractOpener?: ContractOpener;
|
|
11
13
|
cclAddress?: string;
|
|
12
14
|
}): Promise<void | ExecutionStages>;
|
|
@@ -17,6 +19,8 @@ export declare function startTrackingMultiple(transactionLinkers: TransactionLin
|
|
|
17
19
|
returnValue?: boolean;
|
|
18
20
|
tableView?: boolean;
|
|
19
21
|
logger?: ILogger;
|
|
22
|
+
txFinalizer?: ITxFinalizer;
|
|
20
23
|
contractOpener?: ContractOpener;
|
|
24
|
+
cclAddress?: string;
|
|
21
25
|
}): Promise<void | ExecutionStages[]>;
|
|
22
26
|
export declare function printExecutionStagesTable(stages: ExecutionStages, logger: ILogger): void;
|