@tonappchain/sdk 0.7.2-gas-price-0.1 → 0.7.2-gas-price-0.3
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/agnosticSdk/AbiHandler.js +1 -1
- package/dist/src/agnosticSdk/DebugHelpers.js +1 -1
- package/dist/src/agnosticSdk/HooksHandler.js +1 -1
- package/dist/src/agnosticSdk/ReplacementHelper.js +3 -1
- package/dist/src/assets/AssetFactory.js +3 -2
- package/dist/src/assets/TON.d.ts +1 -0
- package/dist/src/assets/TON.js +5 -1
- package/dist/src/errors/instances.d.ts +3 -0
- package/dist/src/errors/instances.js +7 -2
- package/dist/src/interfaces/ILiteSequencerClient.d.ts +6 -1
- package/dist/src/interfaces/IOperationTracker.d.ts +6 -1
- package/dist/src/interfaces/ITONTransactionManager.d.ts +4 -5
- package/dist/src/interfaces/ITacSDK.d.ts +3 -3
- package/dist/src/sdk/Configuration.js +9 -3
- package/dist/src/sdk/LiteSequencerClient.d.ts +2 -0
- package/dist/src/sdk/LiteSequencerClient.js +21 -4
- package/dist/src/sdk/Logger.d.ts +4 -4
- package/dist/src/sdk/Logger.js +12 -4
- package/dist/src/sdk/OperationTracker.d.ts +2 -1
- package/dist/src/sdk/OperationTracker.js +24 -0
- package/dist/src/sdk/Simulator.js +1 -1
- package/dist/src/sdk/TONTransactionManager.d.ts +4 -4
- package/dist/src/sdk/TONTransactionManager.js +29 -19
- package/dist/src/sdk/TacSdk.d.ts +8 -3
- package/dist/src/sdk/TacSdk.js +12 -4
- package/dist/src/sdk/TxFinalizer.js +6 -1
- package/dist/src/sdk/Utils.d.ts +2 -2
- package/dist/src/sdk/Utils.js +28 -27
- package/dist/src/sender/SenderFactory.js +1 -1
- package/dist/src/sender/TonConnectSender.js +1 -1
- package/dist/src/structs/InternalStruct.d.ts +12 -0
- package/dist/src/structs/Struct.d.ts +26 -3
- package/package.json +1 -1
|
@@ -56,7 +56,7 @@ class AbiHandler {
|
|
|
56
56
|
// Build parameter list with proper tuple handling
|
|
57
57
|
const params = func.inputs
|
|
58
58
|
.map((input) => {
|
|
59
|
-
|
|
59
|
+
const paramType = this._buildParameterType(input);
|
|
60
60
|
// Add parameter name if available
|
|
61
61
|
if (input.name) {
|
|
62
62
|
return `${paramType} ${input.name}`;
|
|
@@ -49,7 +49,9 @@ class ReplacementHelper {
|
|
|
49
49
|
// Find the parameter by name
|
|
50
50
|
const paramIndex = functionFragment.inputs.findIndex((input) => input.name === parameterName);
|
|
51
51
|
if (paramIndex === -1) {
|
|
52
|
-
const availableParams = functionFragment.inputs
|
|
52
|
+
const availableParams = functionFragment.inputs
|
|
53
|
+
.map((input) => `${input.name} (${input.type})`)
|
|
54
|
+
.join(', ');
|
|
53
55
|
throw new Error(`Parameter '${parameterName}' not found in function '${functionName}'. Available parameters: ${availableParams}`);
|
|
54
56
|
}
|
|
55
57
|
// Calculate position and length based on parameter type
|
|
@@ -25,8 +25,9 @@ class AssetFactory {
|
|
|
25
25
|
return asset;
|
|
26
26
|
}
|
|
27
27
|
static async createFTAsset(configuration, address) {
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
const ton = TON_1.TON.create(configuration);
|
|
29
|
+
if (address === configuration.nativeTONAddress || address === '' || address === (await ton.getEVMAddress())) {
|
|
30
|
+
return ton;
|
|
30
31
|
}
|
|
31
32
|
return FT_1.FT.fromAddress(configuration, address);
|
|
32
33
|
}
|
package/dist/src/assets/TON.d.ts
CHANGED
package/dist/src/assets/TON.js
CHANGED
|
@@ -12,6 +12,7 @@ class TON {
|
|
|
12
12
|
this.address = '';
|
|
13
13
|
this._config = config;
|
|
14
14
|
this._rawAmount = 0n;
|
|
15
|
+
this.evmAddress = '';
|
|
15
16
|
}
|
|
16
17
|
static create(config) {
|
|
17
18
|
return new TON(config);
|
|
@@ -51,7 +52,10 @@ class TON {
|
|
|
51
52
|
return this;
|
|
52
53
|
}
|
|
53
54
|
async getEVMAddress() {
|
|
54
|
-
|
|
55
|
+
if (this.evmAddress === '') {
|
|
56
|
+
this.evmAddress = await this._config.TACParams.tokenUtils.computeAddress(this._config.nativeTONAddress);
|
|
57
|
+
}
|
|
58
|
+
return this.evmAddress;
|
|
55
59
|
}
|
|
56
60
|
async getTVMAddress() {
|
|
57
61
|
return '';
|
|
@@ -30,3 +30,6 @@ export declare const missingGasLimitError: FormatError;
|
|
|
30
30
|
export declare const missingDecimals: MetadataError;
|
|
31
31
|
export declare const missingJettonDataError: MetadataError;
|
|
32
32
|
export declare const zeroRawAmountError: (assetAddress: string) => TokenError;
|
|
33
|
+
export declare const sendCrossChainTransactionFailedError: (msg: string) => WalletError;
|
|
34
|
+
export declare const convertCurrencyNegativeOrZeroValueError: FormatError;
|
|
35
|
+
export declare const gasPriceFetchError: (msg: string, inner?: unknown) => FetchError;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.zeroRawAmountError = exports.missingJettonDataError = exports.missingDecimals = exports.missingGasLimitError = exports.missingTvmExecutorFeeError = exports.missingFeeParamsError = exports.getTONFeeInfoFetchError = exports.simulationFetchError = exports.convertCurrencyFetchError = exports.indexRequiredError = exports.unknownTokenTypeError = exports.insufficientBalanceError = exports.allContractOpenerFailedError = exports.allEndpointsFailedError = exports.noValidGroupFoundError = exports.prepareMessageGroupError = exports.invalidAssetType = exports.emptyArrayError = exports.profilingFetchError = exports.invalidMethodNameError = exports.emptySettingError = exports.prefixError = exports.notMultiplyOf8Error = exports.unsupportedFormatError = exports.unsupportedKeyError = exports.unknownWalletError = exports.evmAddressError = exports.tvmAddressError = exports.statusFetchError = exports.operationFetchError = exports.emptyContractError = void 0;
|
|
3
|
+
exports.gasPriceFetchError = exports.convertCurrencyNegativeOrZeroValueError = exports.sendCrossChainTransactionFailedError = exports.zeroRawAmountError = exports.missingJettonDataError = exports.missingDecimals = exports.missingGasLimitError = exports.missingTvmExecutorFeeError = exports.missingFeeParamsError = exports.getTONFeeInfoFetchError = exports.simulationFetchError = exports.convertCurrencyFetchError = exports.indexRequiredError = exports.unknownTokenTypeError = exports.insufficientBalanceError = exports.allContractOpenerFailedError = exports.allEndpointsFailedError = exports.noValidGroupFoundError = exports.prepareMessageGroupError = exports.invalidAssetType = exports.emptyArrayError = exports.profilingFetchError = exports.invalidMethodNameError = exports.emptySettingError = exports.prefixError = exports.notMultiplyOf8Error = exports.unsupportedFormatError = exports.unsupportedKeyError = exports.unknownWalletError = exports.evmAddressError = exports.tvmAddressError = exports.statusFetchError = exports.operationFetchError = exports.emptyContractError = void 0;
|
|
4
4
|
const errors_1 = require("./errors");
|
|
5
5
|
exports.emptyContractError = new errors_1.ContractError('unexpected empty contract code of given jetton.', 100);
|
|
6
6
|
const operationFetchError = (msg, inner) => new errors_1.FetchError(`failed to fetch OperationId: ${msg}`, 101, inner);
|
|
@@ -30,7 +30,7 @@ exports.invalidAssetType = new errors_1.FormatError('Invalid asset type', 114);
|
|
|
30
30
|
const prepareMessageGroupError = (isBocSizeValid, isDepthValid) => new errors_1.PrepareMessageGroupError(`Failed to prepare message group: BOC size valid: ${isBocSizeValid}, depth valid: ${isDepthValid}`, 115);
|
|
31
31
|
exports.prepareMessageGroupError = prepareMessageGroupError;
|
|
32
32
|
exports.noValidGroupFoundError = new errors_1.NoValidGroupFoundError('Failed to prepare valid message group', 116);
|
|
33
|
-
const allEndpointsFailedError = (inner) => new errors_1.FetchError('All endpoints failed', 117, inner);
|
|
33
|
+
const allEndpointsFailedError = (inner) => new errors_1.FetchError('All endpoints failed, last err: ' + inner.message, 117, inner);
|
|
34
34
|
exports.allEndpointsFailedError = allEndpointsFailedError;
|
|
35
35
|
const allContractOpenerFailedError = (inner) => new errors_1.FetchError('All contract opener failed', 118, inner);
|
|
36
36
|
exports.allContractOpenerFailedError = allContractOpenerFailedError;
|
|
@@ -53,3 +53,8 @@ exports.missingDecimals = new errors_1.MetadataError('Missing decimals in jetton
|
|
|
53
53
|
exports.missingJettonDataError = new errors_1.MetadataError('Jetton data should be available for TON origin', 129);
|
|
54
54
|
const zeroRawAmountError = (assetAddress) => new errors_1.TokenError(`FT asset with zero rawAmount/amount is not allowed: ${assetAddress}`, 130);
|
|
55
55
|
exports.zeroRawAmountError = zeroRawAmountError;
|
|
56
|
+
const sendCrossChainTransactionFailedError = (msg) => new errors_1.WalletError(`failed to send cross chain transaction: ${msg}`, 131);
|
|
57
|
+
exports.sendCrossChainTransactionFailedError = sendCrossChainTransactionFailedError;
|
|
58
|
+
exports.convertCurrencyNegativeOrZeroValueError = new errors_1.FormatError('Value cannot be negative or zero for currency conversion', 132);
|
|
59
|
+
const gasPriceFetchError = (msg, inner) => new errors_1.FetchError(`failed to fetch gas price: ${msg}`, 133, inner);
|
|
60
|
+
exports.gasPriceFetchError = gasPriceFetchError;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ConvertCurrencyParams, ConvertedCurrencyResult, ExecutionStagesByOperationId, GetTVMExecutorFeeParams, OperationIdsByShardsKey, OperationType, StatusInfosByOperationId, SuggestedTVMExecutorFee, TACSimulationParams, TACSimulationResult, TransactionLinker } from '../structs/Struct';
|
|
1
|
+
import { ConvertCurrencyParams, ConvertedCurrencyResult, ExecutionStagesByOperationId, GetTVMExecutorFeeParams, OperationIdsByShardsKey, OperationType, StatusInfosByOperationId, SuggestedTVMExecutorFee, TACSimulationParams, TACSimulationResult, TacGasPriceResponse, TransactionLinker } from '../structs/Struct';
|
|
2
2
|
export interface ILiteSequencerClient {
|
|
3
3
|
/** Retrieves the operation type by id. */
|
|
4
4
|
getOperationType(operationId: string): Promise<OperationType>;
|
|
@@ -40,4 +40,9 @@ export interface ILiteSequencerClient {
|
|
|
40
40
|
* @returns Promise resolving to detailed simulation result.
|
|
41
41
|
*/
|
|
42
42
|
simulateTACMessage(params: TACSimulationParams): Promise<TACSimulationResult>;
|
|
43
|
+
/**
|
|
44
|
+
* Gets TAC gas price.
|
|
45
|
+
* @returns Promise resolving to TAC gas price.
|
|
46
|
+
*/
|
|
47
|
+
getTACGasPrice(): Promise<TacGasPriceResponse>;
|
|
43
48
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ConvertCurrencyParams, ConvertedCurrencyResult, ExecutionStages, ExecutionStagesByOperationId, GetTVMExecutorFeeParams, OperationIdsByShardsKey, OperationType, SimplifiedStatuses, StatusInfo, StatusInfosByOperationId, SuggestedTVMExecutorFee, TACSimulationParams, TACSimulationResult, TransactionLinker, WaitOptions } from '../structs/Struct';
|
|
1
|
+
import { ConvertCurrencyParams, ConvertedCurrencyResult, ExecutionStages, ExecutionStagesByOperationId, GetTVMExecutorFeeParams, OperationIdsByShardsKey, OperationType, SimplifiedStatuses, StatusInfo, StatusInfosByOperationId, SuggestedTVMExecutorFee, TACSimulationParams, TACSimulationResult, TacGasPriceResponse, TransactionLinker, WaitOptions } from '../structs/Struct';
|
|
2
2
|
export interface IOperationTracker {
|
|
3
3
|
/**
|
|
4
4
|
* Returns the operation type for the given id, optionally waiting according to the provided policy.
|
|
@@ -78,4 +78,9 @@ export interface IOperationTracker {
|
|
|
78
78
|
* @returns Promise with suggested fee information.
|
|
79
79
|
*/
|
|
80
80
|
getTVMExecutorFee(params: GetTVMExecutorFeeParams, waitOptions?: WaitOptions<SuggestedTVMExecutorFee>): Promise<SuggestedTVMExecutorFee>;
|
|
81
|
+
/**
|
|
82
|
+
* Gets TAC gas price.
|
|
83
|
+
* @returns Promise resolving to TAC gas price.
|
|
84
|
+
*/
|
|
85
|
+
getTACGasPrice(): Promise<TacGasPriceResponse>;
|
|
81
86
|
}
|
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
import type { SenderAbstraction } from '../sender';
|
|
2
|
-
import {
|
|
2
|
+
import { BatchCrossChainTx, CrossChainTransactionsOptions, CrosschainTx, EvmProxyMsg, TransactionLinkerWithOperationId } from '../structs/Struct';
|
|
3
3
|
export interface ITONTransactionManager {
|
|
4
4
|
/**
|
|
5
5
|
* Sends a single cross-chain transaction.
|
|
6
6
|
* @param evmProxyMsg Encoded EVM proxy message to bridge.
|
|
7
7
|
* @param sender Sender abstraction for TVM message sending.
|
|
8
8
|
* @param tx cross-chain transaction to bridge.
|
|
9
|
-
* @param waitOptions Optional policy to wait for operation id resolution.
|
|
10
9
|
* @returns Transaction linker with operation id for tracking.
|
|
11
10
|
*/
|
|
12
|
-
sendCrossChainTransaction(evmProxyMsg: EvmProxyMsg, sender: SenderAbstraction, tx: CrosschainTx
|
|
11
|
+
sendCrossChainTransaction(evmProxyMsg: EvmProxyMsg, sender: SenderAbstraction, tx: CrosschainTx): Promise<TransactionLinkerWithOperationId>;
|
|
13
12
|
/**
|
|
14
13
|
* Sends multiple cross-chain transactions in a batch.
|
|
15
14
|
* @param sender Sender abstraction for TVM message sending.
|
|
16
15
|
* @param txs List of cross-chain transactions to bridge.
|
|
17
|
-
* @param
|
|
16
|
+
* @param options Optional options controlling waiting behavior for operation ids.
|
|
18
17
|
* @returns Array of transaction linkers, one per submitted transaction.
|
|
19
18
|
*/
|
|
20
|
-
sendCrossChainTransactions(sender: SenderAbstraction, txs:
|
|
19
|
+
sendCrossChainTransactions(sender: SenderAbstraction, txs: BatchCrossChainTx[], options?: CrossChainTransactionsOptions): Promise<TransactionLinkerWithOperationId[]>;
|
|
21
20
|
}
|
|
@@ -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, CrossChainTransactionOptions,
|
|
5
|
+
import { AssetFromFTArg, AssetFromNFTCollectionArg, AssetFromNFTItemArg, AssetLike, BatchCrossChainTxWithAssetLike, CrossChainTransactionOptions, CrossChainTransactionsOptions, CrosschainTx, EVMAddress, EvmProxyMsg, ExecutionFeeEstimationResult, NFTAddressType, SuggestedTVMExecutorFee, TACSimulationParams, TACSimulationResult, TransactionLinkerWithOperationId, TVMAddress, UserWalletBalanceExtended, WaitOptions } from '../structs/Struct';
|
|
6
6
|
import { Asset } from './Asset';
|
|
7
7
|
import { IConfiguration } from './IConfiguration';
|
|
8
8
|
import { IOperationTracker } from './IOperationTracker';
|
|
@@ -98,10 +98,10 @@ export interface ITacSDK {
|
|
|
98
98
|
* Sends multiple cross-chain transactions in one batch and optionally waits for tracking info.
|
|
99
99
|
* @param sender Sender abstraction for signing/sending TVM messages.
|
|
100
100
|
* @param txs Array of cross-chain transactions to broadcast.
|
|
101
|
-
* @param
|
|
101
|
+
* @param options Optional options controlling waiting behavior for operation ids.
|
|
102
102
|
* @returns Promise with an array of TransactionLinkerWithOperationId for each submitted transaction.
|
|
103
103
|
*/
|
|
104
|
-
sendCrossChainTransactions(sender: SenderAbstraction, txs:
|
|
104
|
+
sendCrossChainTransactions(sender: SenderAbstraction, txs: BatchCrossChainTxWithAssetLike[], options?: CrossChainTransactionsOptions): Promise<TransactionLinkerWithOperationId[]>;
|
|
105
105
|
/**
|
|
106
106
|
* Bridges tokens/value from EVM to TON chain via the executor.
|
|
107
107
|
* @param signer Ethers Wallet used to sign the EVM-side transaction.
|
|
@@ -78,6 +78,7 @@ class Configuration {
|
|
|
78
78
|
const artifacts = network === Struct_1.Network.MAINNET ? artifacts_1.mainnet : network === Struct_1.Network.TESTNET ? artifacts_1.testnet : artifacts_1.dev;
|
|
79
79
|
let provider;
|
|
80
80
|
let settingsAddress;
|
|
81
|
+
let saFactoryAddress;
|
|
81
82
|
if (network === Struct_1.Network.DEV) {
|
|
82
83
|
if (!TACParams || !TACParams.provider) {
|
|
83
84
|
throw new Error('For dev network, a custom provider must be provided in TACParams');
|
|
@@ -86,11 +87,16 @@ class Configuration {
|
|
|
86
87
|
if (!TACParams.settingsAddress) {
|
|
87
88
|
throw new Error('For dev network, a custom settings address must be provided in TACParams');
|
|
88
89
|
}
|
|
89
|
-
settingsAddress = TACParams.settingsAddress
|
|
90
|
+
settingsAddress = TACParams.settingsAddress;
|
|
91
|
+
if (!TACParams.saFactoryAddress) {
|
|
92
|
+
throw new Error('For dev network, a custom smart account factory address must be provided in TACParams');
|
|
93
|
+
}
|
|
94
|
+
saFactoryAddress = TACParams.saFactoryAddress;
|
|
90
95
|
}
|
|
91
96
|
else {
|
|
92
97
|
provider = TACParams?.provider ?? ethers_1.ethers.getDefaultProvider(artifacts.TAC_RPC_ENDPOINT);
|
|
93
|
-
settingsAddress = TACParams?.settingsAddress
|
|
98
|
+
settingsAddress = TACParams?.settingsAddress ?? artifacts.TAC_SETTINGS_ADDRESS;
|
|
99
|
+
saFactoryAddress = TACParams?.saFactoryAddress ?? artifacts.TAC_SMART_ACCOUNT_FACTORY_ADDRESS;
|
|
94
100
|
}
|
|
95
101
|
Validator_1.Validator.validateEVMAddress(settingsAddress);
|
|
96
102
|
const settingsAbi = artifacts.tac.compilationArtifacts.ISettings.abi;
|
|
@@ -117,7 +123,7 @@ class Configuration {
|
|
|
117
123
|
const tokenUtilsAbi = artifacts.tac.compilationArtifacts.ITokenUtils.abi;
|
|
118
124
|
const tokenUtils = new ethers_1.ethers.Contract(tokenUtilsAddress, tokenUtilsAbi, provider);
|
|
119
125
|
const TacSAFactoryAbi = artifacts.tac.compilationArtifacts.ISAFactory.abi;
|
|
120
|
-
const smartAccountFactory = new ethers_1.ethers.Contract(
|
|
126
|
+
const smartAccountFactory = new ethers_1.ethers.Contract(saFactoryAddress, TacSAFactoryAbi, provider);
|
|
121
127
|
return {
|
|
122
128
|
provider,
|
|
123
129
|
settings,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { IHttpClient, ILiteSequencerClient } from '../interfaces';
|
|
2
|
+
import { TacGasPriceResponse } from '../structs/InternalStruct';
|
|
2
3
|
import { ConvertCurrencyParams, ConvertedCurrencyResult, ExecutionStagesByOperationId, GetTVMExecutorFeeParams, OperationIdsByShardsKey, OperationType, StatusInfosByOperationId, SuggestedTVMExecutorFee, TACSimulationParams, TACSimulationResult, TransactionLinker } from '../structs/Struct';
|
|
3
4
|
export declare class LiteSequencerClient implements ILiteSequencerClient {
|
|
4
5
|
private readonly endpoint;
|
|
@@ -13,6 +14,7 @@ export declare class LiteSequencerClient implements ILiteSequencerClient {
|
|
|
13
14
|
getOperationStatuses(operationIds: string[], chunkSize?: number): Promise<StatusInfosByOperationId>;
|
|
14
15
|
convertCurrency(params: ConvertCurrencyParams): Promise<ConvertedCurrencyResult>;
|
|
15
16
|
simulateTACMessage(params: TACSimulationParams): Promise<TACSimulationResult>;
|
|
17
|
+
getTACGasPrice(): Promise<TacGasPriceResponse>;
|
|
16
18
|
getTVMExecutorFee(params: GetTVMExecutorFeeParams): Promise<SuggestedTVMExecutorFee>;
|
|
17
19
|
private processChunkedRequest;
|
|
18
20
|
}
|
|
@@ -15,10 +15,18 @@ class LiteSequencerClient {
|
|
|
15
15
|
const isEthHash = /^0x[a-fA-F0-9]{64}$/.test(transactionHash);
|
|
16
16
|
const path = isEthHash ? 'tac/operation-id' : 'ton/operation-id';
|
|
17
17
|
try {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
if (isEthHash) {
|
|
19
|
+
const response = await this.httpClient.get(new URL(path, this.endpoint).toString(), {
|
|
20
|
+
params: { transactionHash },
|
|
21
|
+
});
|
|
22
|
+
return response.data.response?.operationId || '';
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
const response = await this.httpClient.get(new URL(path, this.endpoint).toString(), {
|
|
26
|
+
params: { transactionHash },
|
|
27
|
+
});
|
|
28
|
+
return response.data.response || '';
|
|
29
|
+
}
|
|
22
30
|
}
|
|
23
31
|
catch (error) {
|
|
24
32
|
if (error?.response?.status === 404) {
|
|
@@ -156,6 +164,15 @@ class LiteSequencerClient {
|
|
|
156
164
|
throw (0, instances_1.simulationFetchError)(`endpoint ${this.endpoint} failed to complete request`, error);
|
|
157
165
|
}
|
|
158
166
|
}
|
|
167
|
+
async getTACGasPrice() {
|
|
168
|
+
try {
|
|
169
|
+
const response = await this.httpClient.get(new URL('stats', 'https://explorer.tac.build/api/v2/').toString());
|
|
170
|
+
return response.data;
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
throw (0, instances_1.gasPriceFetchError)(`endpoint https://explorer.tac.build/api/v2/ failed to complete request`, error);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
159
176
|
async getTVMExecutorFee(params) {
|
|
160
177
|
try {
|
|
161
178
|
const response = await this.httpClient.post(new URL('/ton/calculator/ton-executor-fee', this.endpoint).toString(), params, {
|
package/dist/src/sdk/Logger.d.ts
CHANGED
|
@@ -6,8 +6,8 @@ export declare class ConsoleLogger implements ILogger {
|
|
|
6
6
|
error(...arg: unknown[]): void;
|
|
7
7
|
}
|
|
8
8
|
export declare class NoopLogger implements ILogger {
|
|
9
|
-
debug(): void;
|
|
10
|
-
info(): void;
|
|
11
|
-
warn(): void;
|
|
12
|
-
error(): void;
|
|
9
|
+
debug(..._arg: unknown[]): void;
|
|
10
|
+
info(..._arg: unknown[]): void;
|
|
11
|
+
warn(..._arg: unknown[]): void;
|
|
12
|
+
error(..._arg: unknown[]): void;
|
|
13
13
|
}
|
package/dist/src/sdk/Logger.js
CHANGED
|
@@ -17,9 +17,17 @@ class ConsoleLogger {
|
|
|
17
17
|
}
|
|
18
18
|
exports.ConsoleLogger = ConsoleLogger;
|
|
19
19
|
class NoopLogger {
|
|
20
|
-
debug() {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
debug(..._arg) {
|
|
21
|
+
void _arg;
|
|
22
|
+
}
|
|
23
|
+
info(..._arg) {
|
|
24
|
+
void _arg;
|
|
25
|
+
}
|
|
26
|
+
warn(..._arg) {
|
|
27
|
+
void _arg;
|
|
28
|
+
}
|
|
29
|
+
error(..._arg) {
|
|
30
|
+
void _arg;
|
|
31
|
+
}
|
|
24
32
|
}
|
|
25
33
|
exports.NoopLogger = NoopLogger;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ILiteSequencerClient, ILiteSequencerClientFactory, ILogger, IOperationTracker } from '../interfaces';
|
|
2
|
-
import { ConvertCurrencyParams, ConvertedCurrencyResult, ExecutionStages, ExecutionStagesByOperationId, GetTVMExecutorFeeParams, Network, OperationIdsByShardsKey, OperationType, SimplifiedStatuses, StatusInfo, StatusInfosByOperationId, SuggestedTVMExecutorFee, TACSimulationParams, TACSimulationResult, TransactionLinker, WaitOptions } from '../structs/Struct';
|
|
2
|
+
import { ConvertCurrencyParams, ConvertedCurrencyResult, ExecutionStages, ExecutionStagesByOperationId, GetTVMExecutorFeeParams, Network, OperationIdsByShardsKey, OperationType, SimplifiedStatuses, StatusInfo, StatusInfosByOperationId, SuggestedTVMExecutorFee, TacGasPriceResponse, TACSimulationParams, TACSimulationResult, TransactionLinker, WaitOptions } from '../structs/Struct';
|
|
3
3
|
export declare class DefaultLiteSequencerClientFactory implements ILiteSequencerClientFactory {
|
|
4
4
|
createClients(endpoints: string[]): ILiteSequencerClient[];
|
|
5
5
|
}
|
|
@@ -18,5 +18,6 @@ export declare class OperationTracker implements IOperationTracker {
|
|
|
18
18
|
getSimplifiedOperationStatus(transactionLinker: TransactionLinker): Promise<SimplifiedStatuses>;
|
|
19
19
|
convertCurrency(params: ConvertCurrencyParams, waitOptions?: WaitOptions<ConvertedCurrencyResult>): Promise<ConvertedCurrencyResult>;
|
|
20
20
|
simulateTACMessage(params: TACSimulationParams, waitOptions?: WaitOptions<TACSimulationResult>): Promise<TACSimulationResult>;
|
|
21
|
+
getTACGasPrice(): Promise<TacGasPriceResponse>;
|
|
21
22
|
getTVMExecutorFee(params: GetTVMExecutorFeeParams, waitOptions?: WaitOptions<SuggestedTVMExecutorFee>): Promise<SuggestedTVMExecutorFee>;
|
|
22
23
|
}
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.OperationTracker = exports.DefaultLiteSequencerClientFactory = void 0;
|
|
4
4
|
const artifacts_1 = require("../../artifacts");
|
|
5
5
|
const errors_1 = require("../errors");
|
|
6
|
+
const instances_1 = require("../errors/instances");
|
|
6
7
|
const Struct_1 = require("../structs/Struct");
|
|
7
8
|
const LiteSequencerClient_1 = require("./LiteSequencerClient");
|
|
8
9
|
const Logger_1 = require("./Logger");
|
|
@@ -239,6 +240,9 @@ class OperationTracker {
|
|
|
239
240
|
return Struct_1.SimplifiedStatuses.SUCCESSFUL;
|
|
240
241
|
}
|
|
241
242
|
async convertCurrency(params, waitOptions) {
|
|
243
|
+
if (params.value <= 0n) {
|
|
244
|
+
throw instances_1.convertCurrencyNegativeOrZeroValueError;
|
|
245
|
+
}
|
|
242
246
|
this.logger.debug(`Converting currency: ${(0, Utils_1.formatObjectForLogging)(params)}`);
|
|
243
247
|
const requestFn = async () => {
|
|
244
248
|
let lastError;
|
|
@@ -283,6 +287,26 @@ class OperationTracker {
|
|
|
283
287
|
? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn, 'OperationTracker: Simulating TAC message')
|
|
284
288
|
: await requestFn();
|
|
285
289
|
}
|
|
290
|
+
async getTACGasPrice() {
|
|
291
|
+
this.logger.debug(`Getting TAC gas price`);
|
|
292
|
+
const requestFn = async () => {
|
|
293
|
+
let lastError;
|
|
294
|
+
for (const client of this.clients) {
|
|
295
|
+
try {
|
|
296
|
+
const result = await client.getTACGasPrice();
|
|
297
|
+
this.logger.debug(`TAC gas price retrieved successfully`);
|
|
298
|
+
return result;
|
|
299
|
+
}
|
|
300
|
+
catch (error) {
|
|
301
|
+
this.logger.warn(`Failed to get TAC gas price using one of the endpoints`);
|
|
302
|
+
lastError = error;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
this.logger.error('All endpoints failed to get TAC gas price');
|
|
306
|
+
throw (0, errors_1.allEndpointsFailedError)(lastError);
|
|
307
|
+
};
|
|
308
|
+
return await requestFn();
|
|
309
|
+
}
|
|
286
310
|
async getTVMExecutorFee(params, waitOptions) {
|
|
287
311
|
this.logger.debug(`get TVM executor fee: ${(0, Utils_1.formatObjectForLogging)(params)}`);
|
|
288
312
|
const requestFn = async () => {
|
|
@@ -27,7 +27,7 @@ class Simulator {
|
|
|
27
27
|
Validator_1.Validator.validateEVMAddress(evmProxyMsg.evmTargetAddress);
|
|
28
28
|
Validator_1.Validator.validateEVMAddresses(evmValidExecutors);
|
|
29
29
|
Validator_1.Validator.validateTVMAddresses(tvmValidExecutors);
|
|
30
|
-
const aggregatedData =
|
|
30
|
+
const aggregatedData = (0, Utils_1.aggregateTokens)(assets);
|
|
31
31
|
const shardCount = aggregatedData.jettons.length || 1;
|
|
32
32
|
const transactionLinker = (0, Utils_1.generateTransactionLinker)(sender.getSenderAddress(), shardCount);
|
|
33
33
|
const tacSimulationParams = {
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { IConfiguration, ILogger, IOperationTracker, ISimulator, ITONTransactionManager } from '../interfaces';
|
|
2
2
|
import type { SenderAbstraction } from '../sender';
|
|
3
|
-
import { CrosschainTx, EvmProxyMsg,
|
|
3
|
+
import { BatchCrossChainTx, 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
|
+
protected buildFeeParams(options: CrossChainTransactionOptions, evmProxyMsg: EvmProxyMsg, sender: SenderAbstraction, tx: CrosschainTx): Promise<FeeParams>;
|
|
11
11
|
private prepareCrossChainTransaction;
|
|
12
12
|
private generateCrossChainMessages;
|
|
13
|
-
sendCrossChainTransaction(evmProxyMsg: EvmProxyMsg, sender: SenderAbstraction, tx: CrosschainTx
|
|
14
|
-
sendCrossChainTransactions(sender: SenderAbstraction, txs:
|
|
13
|
+
sendCrossChainTransaction(evmProxyMsg: EvmProxyMsg, sender: SenderAbstraction, tx: CrosschainTx): Promise<TransactionLinkerWithOperationId>;
|
|
14
|
+
sendCrossChainTransactions(sender: SenderAbstraction, txs: BatchCrossChainTx[], options?: CrossChainTransactionsOptions): Promise<TransactionLinkerWithOperationId[]>;
|
|
15
15
|
private prepareBatchTransactions;
|
|
16
16
|
private waitForOperationIds;
|
|
17
17
|
}
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.TONTransactionManager = void 0;
|
|
4
4
|
const assets_1 = require("../assets");
|
|
5
5
|
const errors_1 = require("../errors");
|
|
6
|
+
const instances_1 = require("../errors/instances");
|
|
6
7
|
const Consts_1 = require("./Consts");
|
|
7
8
|
const Logger_1 = require("./Logger");
|
|
8
9
|
const Utils_1 = require("./Utils");
|
|
@@ -53,7 +54,7 @@ class TONTransactionManager {
|
|
|
53
54
|
const { allowSimulationError = false, isRoundTrip = undefined, calculateRollbackFee = true, validateAssetsBalance = true, } = options || {};
|
|
54
55
|
const { evmValidExecutors = [], tvmValidExecutors = [] } = options || {};
|
|
55
56
|
Validator_1.Validator.validateEVMAddress(evmProxyMsg.evmTargetAddress);
|
|
56
|
-
const aggregatedData =
|
|
57
|
+
const aggregatedData = (0, Utils_1.aggregateTokens)(assets);
|
|
57
58
|
Validator_1.Validator.validateEVMAddresses(evmValidExecutors);
|
|
58
59
|
Validator_1.Validator.validateTVMAddresses(tvmValidExecutors);
|
|
59
60
|
const shouldValidateAssets = validateAssetsBalance && !skipAssetsBalanceValidation;
|
|
@@ -136,35 +137,44 @@ class TONTransactionManager {
|
|
|
136
137
|
this.logger.debug('Cross-chain messages generated successfully');
|
|
137
138
|
return messages;
|
|
138
139
|
}
|
|
139
|
-
async sendCrossChainTransaction(evmProxyMsg, sender, tx
|
|
140
|
+
async sendCrossChainTransaction(evmProxyMsg, sender, tx) {
|
|
140
141
|
const { transaction, transactionLinker } = await this.prepareCrossChainTransaction(evmProxyMsg, sender, tx.assets, tx.options);
|
|
141
142
|
await assets_1.TON.checkBalance(sender, this.config, [transaction]);
|
|
142
143
|
this.logger.debug(`Sending transaction: ${(0, Utils_1.formatObjectForLogging)(transactionLinker)}`);
|
|
143
144
|
const sendTransactionResult = await sender.sendShardTransaction(transaction, this.config.network, this.config.TONParams.contractOpener);
|
|
144
|
-
if (!
|
|
145
|
+
if (!sendTransactionResult.success || sendTransactionResult.error) {
|
|
146
|
+
throw (0, instances_1.sendCrossChainTransactionFailedError)(sendTransactionResult.error?.message ?? 'Transaction failed to send');
|
|
147
|
+
}
|
|
148
|
+
const shouldWaitForOperationId = tx.options?.waitOperationId ?? true;
|
|
149
|
+
if (!shouldWaitForOperationId) {
|
|
145
150
|
return { sendTransactionResult, ...transactionLinker };
|
|
146
151
|
}
|
|
152
|
+
const waitOptions = tx.options?.waitOptions ?? {};
|
|
153
|
+
waitOptions.successCheck = waitOptions.successCheck ?? ((id) => !!id);
|
|
154
|
+
waitOptions.logger = waitOptions.logger ?? this.logger;
|
|
147
155
|
const operationId = await this.operationTracker
|
|
148
|
-
.getOperationId(transactionLinker,
|
|
149
|
-
...waitOptions,
|
|
150
|
-
successCheck: (id) => !!id,
|
|
151
|
-
logger: this.logger,
|
|
152
|
-
})
|
|
156
|
+
.getOperationId(transactionLinker, waitOptions)
|
|
153
157
|
.catch((error) => {
|
|
154
158
|
this.logger.error(`Error while waiting for operation ID: ${error}`);
|
|
155
159
|
return undefined;
|
|
156
160
|
});
|
|
157
161
|
return { sendTransactionResult, operationId, ...transactionLinker };
|
|
158
162
|
}
|
|
159
|
-
async sendCrossChainTransactions(sender, txs,
|
|
163
|
+
async sendCrossChainTransactions(sender, txs, options) {
|
|
160
164
|
const caller = sender.getSenderAddress();
|
|
161
165
|
this.logger.debug(`Preparing ${txs.length} cross-chain transactions for ${caller}`);
|
|
162
166
|
const { transactions, transactionLinkers } = await this.prepareBatchTransactions(txs, sender);
|
|
163
167
|
await assets_1.TON.checkBalance(sender, this.config, transactions);
|
|
164
168
|
this.logger.debug(`Sending transactions: ${(0, Utils_1.formatObjectForLogging)(transactionLinkers)}`);
|
|
165
|
-
await sender.sendShardTransactions(transactions, this.config.network, this.config.TONParams.contractOpener);
|
|
166
|
-
|
|
167
|
-
|
|
169
|
+
const results = await sender.sendShardTransactions(transactions, this.config.network, this.config.TONParams.contractOpener);
|
|
170
|
+
for (const result of results) {
|
|
171
|
+
if (!result.success || result.error) {
|
|
172
|
+
throw (0, instances_1.sendCrossChainTransactionFailedError)(result.error?.message ?? 'Transaction failed to send');
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
const shouldWaitForOperationIds = options?.waitOperationIds ?? true;
|
|
176
|
+
return shouldWaitForOperationIds
|
|
177
|
+
? await this.waitForOperationIds(transactionLinkers, caller, options?.waitOptions ?? {})
|
|
168
178
|
: transactionLinkers;
|
|
169
179
|
}
|
|
170
180
|
async prepareBatchTransactions(txs, sender) {
|
|
@@ -173,7 +183,7 @@ class TONTransactionManager {
|
|
|
173
183
|
if (txsRequiringValidation.length) {
|
|
174
184
|
// Aggregate only assets from txs that require validation and validate once per unique asset
|
|
175
185
|
const assetsToValidate = txsRequiringValidation.flatMap((tx) => tx.assets ?? []);
|
|
176
|
-
const aggregatedData =
|
|
186
|
+
const aggregatedData = (0, Utils_1.aggregateTokens)(assetsToValidate);
|
|
177
187
|
await Promise.all([
|
|
178
188
|
...aggregatedData.jettons.map((jetton) => jetton.checkCanBeTransferredBy(caller)),
|
|
179
189
|
...aggregatedData.nfts.map((nft) => nft.checkCanBeTransferredBy(caller)),
|
|
@@ -189,12 +199,12 @@ class TONTransactionManager {
|
|
|
189
199
|
async waitForOperationIds(transactionLinkers, caller, waitOptions) {
|
|
190
200
|
this.logger.debug(`Waiting for operation IDs`);
|
|
191
201
|
try {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
202
|
+
waitOptions.successCheck =
|
|
203
|
+
waitOptions.successCheck ??
|
|
204
|
+
((operationIds) => Object.keys(operationIds).length == transactionLinkers.length &&
|
|
205
|
+
Object.values(operationIds).every((ids) => ids.operationIds.length > 0));
|
|
206
|
+
waitOptions.logger = waitOptions.logger ?? this.logger;
|
|
207
|
+
const operationIds = await this.operationTracker.getOperationIdsByShardsKeys(transactionLinkers.map((linker) => linker.shardsKey), caller, waitOptions);
|
|
198
208
|
this.logger.debug(`Operation IDs: ${(0, Utils_1.formatObjectForLogging)(operationIds)}`);
|
|
199
209
|
return transactionLinkers.map((linker) => ({
|
|
200
210
|
...linker,
|
package/dist/src/sdk/TacSdk.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { JettonMinterData, NFTItemData } from '../../artifacts/tonTypes';
|
|
|
3
3
|
import { FT, NFT } from '../assets';
|
|
4
4
|
import { IConfiguration, ILogger, IOperationTracker, ITacSDK } from '../interfaces';
|
|
5
5
|
import type { SenderAbstraction } from '../sender';
|
|
6
|
-
import { AssetFromFTArg, AssetFromNFTCollectionArg, AssetFromNFTItemArg, AssetLike, CrossChainTransactionOptions,
|
|
6
|
+
import { AssetFromFTArg, AssetFromNFTCollectionArg, AssetFromNFTItemArg, AssetLike, BatchCrossChainTxWithAssetLike, CrossChainTransactionOptions, CrossChainTransactionsOptions, CrosschainTx, EVMAddress, EvmProxyMsg, ExecutionFeeEstimationResult, NFTAddressType, SDKParams, SuggestedTVMExecutorFee, TACSimulationParams, TACSimulationResult, TransactionLinkerWithOperationId, TVMAddress, UserWalletBalanceExtended } from '../structs/Struct';
|
|
7
7
|
export declare class TacSdk implements ITacSDK {
|
|
8
8
|
readonly config: IConfiguration;
|
|
9
9
|
readonly operationTracker: IOperationTracker;
|
|
@@ -16,12 +16,17 @@ export declare class TacSdk implements ITacSDK {
|
|
|
16
16
|
get nativeTONAddress(): string;
|
|
17
17
|
getSmartAccountAddressForTvmWallet(tvmWallet: string, applicationAddress: string): Promise<string>;
|
|
18
18
|
nativeTACAddress(): Promise<string>;
|
|
19
|
+
getTACGasPrice(): Promise<{
|
|
20
|
+
average: number;
|
|
21
|
+
fast: number;
|
|
22
|
+
slow: number;
|
|
23
|
+
}>;
|
|
19
24
|
get getTrustedTACExecutors(): string[];
|
|
20
25
|
get getTrustedTONExecutors(): string[];
|
|
21
26
|
getSimulationInfo(evmProxyMsg: EvmProxyMsg, sender: SenderAbstraction, assets?: AssetLike[], options?: CrossChainTransactionOptions): Promise<ExecutionFeeEstimationResult>;
|
|
22
27
|
getTVMExecutorFeeInfo(assets: AssetLike[], feeSymbol: string, tvmValidExecutors?: string[]): Promise<SuggestedTVMExecutorFee>;
|
|
23
|
-
sendCrossChainTransaction(evmProxyMsg: EvmProxyMsg, sender: SenderAbstraction, assets?: AssetLike[], options?: CrossChainTransactionOptions
|
|
24
|
-
sendCrossChainTransactions(sender: SenderAbstraction, txs:
|
|
28
|
+
sendCrossChainTransaction(evmProxyMsg: EvmProxyMsg, sender: SenderAbstraction, assets?: AssetLike[], options?: CrossChainTransactionOptions): Promise<TransactionLinkerWithOperationId>;
|
|
29
|
+
sendCrossChainTransactions(sender: SenderAbstraction, txs: BatchCrossChainTxWithAssetLike[], options?: CrossChainTransactionsOptions): Promise<TransactionLinkerWithOperationId[]>;
|
|
25
30
|
bridgeTokensToTON(signer: Wallet, value: bigint, tonTarget: string, assets?: AssetLike[], tvmExecutorFee?: bigint, tvmValidExecutors?: string[]): Promise<string>;
|
|
26
31
|
isContractDeployedOnTVM(address: string): Promise<boolean>;
|
|
27
32
|
simulateTACMessage(req: TACSimulationParams): Promise<TACSimulationResult>;
|
package/dist/src/sdk/TacSdk.js
CHANGED
|
@@ -57,6 +57,14 @@ class TacSdk {
|
|
|
57
57
|
async nativeTACAddress() {
|
|
58
58
|
return this.config.nativeTACAddress();
|
|
59
59
|
}
|
|
60
|
+
async getTACGasPrice() {
|
|
61
|
+
const response = await this.operationTracker.getTACGasPrice();
|
|
62
|
+
return {
|
|
63
|
+
average: response.gas_prices.average,
|
|
64
|
+
fast: response.gas_prices.fast,
|
|
65
|
+
slow: response.gas_prices.slow,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
60
68
|
get getTrustedTACExecutors() {
|
|
61
69
|
return this.config.getTrustedTACExecutors;
|
|
62
70
|
}
|
|
@@ -77,18 +85,18 @@ class TacSdk {
|
|
|
77
85
|
};
|
|
78
86
|
return this.operationTracker.getTVMExecutorFee(params);
|
|
79
87
|
}
|
|
80
|
-
async sendCrossChainTransaction(evmProxyMsg, sender, assets = [], options
|
|
88
|
+
async sendCrossChainTransaction(evmProxyMsg, sender, assets = [], options) {
|
|
81
89
|
const normalizedAssets = await (0, Utils_1.normalizeAssets)(this.config, assets);
|
|
82
90
|
const tx = { evmProxyMsg, assets: normalizedAssets, options };
|
|
83
|
-
return this.tonTransactionManager.sendCrossChainTransaction(evmProxyMsg, sender, tx
|
|
91
|
+
return this.tonTransactionManager.sendCrossChainTransaction(evmProxyMsg, sender, tx);
|
|
84
92
|
}
|
|
85
|
-
async sendCrossChainTransactions(sender, txs,
|
|
93
|
+
async sendCrossChainTransactions(sender, txs, options) {
|
|
86
94
|
const normalizedTxs = await Promise.all(txs.map(async (tx) => ({
|
|
87
95
|
evmProxyMsg: tx.evmProxyMsg,
|
|
88
96
|
options: tx.options,
|
|
89
97
|
assets: await (0, Utils_1.normalizeAssets)(this.config, tx.assets),
|
|
90
98
|
})));
|
|
91
|
-
return this.tonTransactionManager.sendCrossChainTransactions(sender, normalizedTxs,
|
|
99
|
+
return this.tonTransactionManager.sendCrossChainTransactions(sender, normalizedTxs, options);
|
|
92
100
|
}
|
|
93
101
|
async bridgeTokensToTON(signer, value, tonTarget, assets, tvmExecutorFee, tvmValidExecutors) {
|
|
94
102
|
const normalizedAssets = await (0, Utils_1.normalizeAssets)(this.config, assets);
|
|
@@ -46,6 +46,9 @@ class TonTxFinalizer {
|
|
|
46
46
|
const errorMessage = error.message;
|
|
47
47
|
// Rate limit error (429) - retry
|
|
48
48
|
if (errorMessage.includes('429')) {
|
|
49
|
+
if (i > 0) {
|
|
50
|
+
await (0, Utils_1.sleep)(delay);
|
|
51
|
+
}
|
|
49
52
|
continue;
|
|
50
53
|
}
|
|
51
54
|
// Log all errors except 404 Not Found
|
|
@@ -53,8 +56,10 @@ class TonTxFinalizer {
|
|
|
53
56
|
const logMessage = error instanceof Error ? error.message : error;
|
|
54
57
|
console.warn(`Failed to fetch adjacent transactions for ${hash}:`, logMessage);
|
|
55
58
|
}
|
|
59
|
+
if (i > 0) {
|
|
60
|
+
await (0, Utils_1.sleep)(delay);
|
|
61
|
+
}
|
|
56
62
|
}
|
|
57
|
-
await (0, Utils_1.sleep)(delay);
|
|
58
63
|
}
|
|
59
64
|
return [];
|
|
60
65
|
}
|
package/dist/src/sdk/Utils.d.ts
CHANGED
|
@@ -20,11 +20,11 @@ export declare const generateFeeData: (feeParams?: FeeParams) => Cell | undefine
|
|
|
20
20
|
export declare function waitUntilSuccess<T, TContext = unknown, A extends unknown[] = unknown[]>(options: WaitOptions<T, TContext> | undefined, operation: (...args: A) => Promise<T>, operationDescription?: string, ...args: A): Promise<T>;
|
|
21
21
|
export declare function formatObjectForLogging(obj: unknown): string;
|
|
22
22
|
export declare function getBouncedAddress(tvmAddress: string): string;
|
|
23
|
-
export declare function aggregateTokens(assets?: Asset[]):
|
|
23
|
+
export declare function aggregateTokens(assets?: Asset[]): {
|
|
24
24
|
jettons: FT[];
|
|
25
25
|
nfts: NFT[];
|
|
26
26
|
ton?: TON;
|
|
27
|
-
}
|
|
27
|
+
};
|
|
28
28
|
export declare function sha256toBigInt(ContractName: string): bigint;
|
|
29
29
|
export declare function mapAssetsToTonAssets(assets: Asset[]): TONAsset[];
|
|
30
30
|
export declare function normalizeAsset(config: IConfiguration, input: AssetLike): Promise<Asset>;
|
package/dist/src/sdk/Utils.js
CHANGED
|
@@ -199,39 +199,30 @@ function getBouncedAddress(tvmAddress) {
|
|
|
199
199
|
bounceable: true,
|
|
200
200
|
});
|
|
201
201
|
}
|
|
202
|
-
|
|
203
|
-
const
|
|
202
|
+
function aggregateTokens(assets) {
|
|
203
|
+
const jettonsMap = new Map();
|
|
204
|
+
const nftsMap = new Map();
|
|
204
205
|
let ton;
|
|
205
|
-
for
|
|
206
|
-
if (asset.type
|
|
207
|
-
continue;
|
|
208
|
-
if (asset.rawAmount === 0n) {
|
|
206
|
+
for (const asset of assets ?? []) {
|
|
207
|
+
if (asset.rawAmount === 0n && asset.type === Struct_1.AssetType.FT) {
|
|
209
208
|
throw (0, errors_1.zeroRawAmountError)(asset.address || 'NATIVE TON');
|
|
210
209
|
}
|
|
211
|
-
if (
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
210
|
+
if (asset.type === Struct_1.AssetType.FT) {
|
|
211
|
+
if (!asset.address) {
|
|
212
|
+
ton = ton ? ton.addRawAmount(asset.rawAmount) : asset.clone;
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
const existing = jettonsMap.get(asset.address);
|
|
216
|
+
jettonsMap.set(asset.address, (existing ? existing.addRawAmount(asset.rawAmount) : asset.clone));
|
|
217
|
+
}
|
|
218
218
|
}
|
|
219
|
-
else {
|
|
220
|
-
|
|
219
|
+
else if (asset.type === Struct_1.AssetType.NFT) {
|
|
220
|
+
nftsMap.set(asset.address, asset.clone);
|
|
221
221
|
}
|
|
222
|
-
uniqueAssetsMap.set(asset.address, jetton);
|
|
223
|
-
}
|
|
224
|
-
const jettons = Array.from(uniqueAssetsMap.values());
|
|
225
|
-
uniqueAssetsMap.clear();
|
|
226
|
-
for await (const asset of assets ?? []) {
|
|
227
|
-
if (asset.type !== Struct_1.AssetType.NFT)
|
|
228
|
-
continue;
|
|
229
|
-
uniqueAssetsMap.set(asset.address, asset.clone);
|
|
230
222
|
}
|
|
231
|
-
const nfts = Array.from(uniqueAssetsMap.values());
|
|
232
223
|
return {
|
|
233
|
-
jettons,
|
|
234
|
-
nfts,
|
|
224
|
+
jettons: Array.from(jettonsMap.values()),
|
|
225
|
+
nfts: Array.from(nftsMap.values()),
|
|
235
226
|
ton,
|
|
236
227
|
};
|
|
237
228
|
}
|
|
@@ -240,7 +231,11 @@ function sha256toBigInt(ContractName) {
|
|
|
240
231
|
return BigInt('0x' + hash.toString('hex'));
|
|
241
232
|
}
|
|
242
233
|
function mapAssetsToTonAssets(assets) {
|
|
243
|
-
|
|
234
|
+
const { jettons, nfts, ton } = aggregateTokens(assets);
|
|
235
|
+
const result = [...jettons, ...nfts];
|
|
236
|
+
if (ton)
|
|
237
|
+
result.push(ton);
|
|
238
|
+
return result.map((asset) => ({
|
|
244
239
|
amount: asset.rawAmount.toString(),
|
|
245
240
|
tokenAddress: asset.address || '',
|
|
246
241
|
assetType: asset.type,
|
|
@@ -268,9 +263,15 @@ async function normalizeAsset(config, input) {
|
|
|
268
263
|
const asset = await assets_1.AssetFactory.from(config, ftArgs);
|
|
269
264
|
const rawAmount = 'rawAmount' in input ? input.rawAmount : undefined;
|
|
270
265
|
const amount = 'amount' in input ? input.amount : 0;
|
|
266
|
+
if (!rawAmount && !amount && asset.type === Struct_1.AssetType.FT) {
|
|
267
|
+
throw (0, errors_1.zeroRawAmountError)(asset.address || 'NATIVE TON');
|
|
268
|
+
}
|
|
271
269
|
return rawAmount ? asset.withRawAmount(rawAmount) : asset.withAmount(amount);
|
|
272
270
|
}
|
|
273
271
|
catch (e) {
|
|
272
|
+
if (e instanceof errors_1.TokenError && e.errorCode === (0, errors_1.zeroRawAmountError)('').errorCode) {
|
|
273
|
+
throw e;
|
|
274
|
+
}
|
|
274
275
|
console.warn('Failed to normalize FT asset', e);
|
|
275
276
|
}
|
|
276
277
|
const itemArgs = {
|
|
@@ -38,7 +38,7 @@ class SenderFactory {
|
|
|
38
38
|
if (params.version === 'V5R1') {
|
|
39
39
|
// manual setup of wallet id required to support wallet w5 both on mainnet and testnet
|
|
40
40
|
config.walletId = {
|
|
41
|
-
networkGlobalId: params.network === Struct_1.Network.
|
|
41
|
+
networkGlobalId: params.network === Struct_1.Network.MAINNET ? -239 : -3,
|
|
42
42
|
context: {
|
|
43
43
|
walletVersion: 'v5r1',
|
|
44
44
|
workchain: 0,
|
|
@@ -28,7 +28,7 @@ class TonConnectSender {
|
|
|
28
28
|
const transaction = {
|
|
29
29
|
validUntil,
|
|
30
30
|
messages: chunk,
|
|
31
|
-
network: chain == Struct_1.Network.
|
|
31
|
+
network: chain == Struct_1.Network.MAINNET ? ui_1.CHAIN.MAINNET : ui_1.CHAIN.TESTNET,
|
|
32
32
|
};
|
|
33
33
|
try {
|
|
34
34
|
const response = await this.tonConnect.sendTransaction(transaction);
|
|
@@ -54,6 +54,11 @@ export type StageProfilingResponse = ResponseBase<ExecutionStagesByOperationId>;
|
|
|
54
54
|
export type TACSimulationResponse = ResponseBase<TACSimulationResult>;
|
|
55
55
|
export type SuggestedTVMExecutorFeeResponse = ResponseBase<SuggestedTVMExecutorFee>;
|
|
56
56
|
export type ConvertCurrencyResponse = ResponseBase<ConvertedCurrencyRawResult>;
|
|
57
|
+
export type OperationIdWithLogIndex = {
|
|
58
|
+
operationId: string;
|
|
59
|
+
logIndex: number;
|
|
60
|
+
};
|
|
61
|
+
export type OperationIdWithLogIndexResponse = ResponseBase<OperationIdWithLogIndex>;
|
|
57
62
|
export interface SendResult {
|
|
58
63
|
success: boolean;
|
|
59
64
|
result?: unknown;
|
|
@@ -86,6 +91,13 @@ export type TransactionDepth = {
|
|
|
86
91
|
hash: string;
|
|
87
92
|
depth: number;
|
|
88
93
|
};
|
|
94
|
+
export type TacGasPriceResponse = {
|
|
95
|
+
gas_prices: {
|
|
96
|
+
average: number;
|
|
97
|
+
fast: number;
|
|
98
|
+
slow: number;
|
|
99
|
+
};
|
|
100
|
+
};
|
|
89
101
|
export type AdjacentTransactionsResponse = {
|
|
90
102
|
transactions: ToncenterTransaction[];
|
|
91
103
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SandboxContract } from '@ton/sandbox';
|
|
2
2
|
import { OpenedContract } from '@ton/ton';
|
|
3
|
-
import { AbstractProvider
|
|
3
|
+
import { AbstractProvider } from 'ethers';
|
|
4
4
|
import { JettonMinter, JettonMinterData } from '../../artifacts/tonTypes';
|
|
5
5
|
import type { FT, NFT } from '../assets';
|
|
6
6
|
import type { Asset, ContractOpener, ILogger } from '../interfaces';
|
|
@@ -44,7 +44,11 @@ export type TACParams = {
|
|
|
44
44
|
/**
|
|
45
45
|
* Address of TAC settings contract. Use only for tests.
|
|
46
46
|
*/
|
|
47
|
-
settingsAddress?: string
|
|
47
|
+
settingsAddress?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Address of TAC smart account factory contract. Use only for tests.
|
|
50
|
+
*/
|
|
51
|
+
saFactoryAddress?: string;
|
|
48
52
|
};
|
|
49
53
|
export type TONParams = {
|
|
50
54
|
/**
|
|
@@ -287,6 +291,13 @@ export type CrossChainTransactionOptions = {
|
|
|
287
291
|
calculateRollbackFee?: boolean;
|
|
288
292
|
withoutSimulation?: boolean;
|
|
289
293
|
validateAssetsBalance?: boolean;
|
|
294
|
+
waitOperationId?: boolean;
|
|
295
|
+
waitOptions?: WaitOptions<string>;
|
|
296
|
+
};
|
|
297
|
+
export type BatchCrossChainTransactionOptions = Omit<CrossChainTransactionOptions, 'waitOperationId' | 'waitOptions'>;
|
|
298
|
+
export type CrossChainTransactionsOptions = {
|
|
299
|
+
waitOperationIds?: boolean;
|
|
300
|
+
waitOptions?: WaitOptions<OperationIdsByShardsKey>;
|
|
290
301
|
};
|
|
291
302
|
export type ExecutionFeeEstimationResult = {
|
|
292
303
|
feeParams: FeeParams;
|
|
@@ -297,6 +308,11 @@ export type CrosschainTx = {
|
|
|
297
308
|
assets?: Asset[];
|
|
298
309
|
options?: CrossChainTransactionOptions;
|
|
299
310
|
};
|
|
311
|
+
export type BatchCrossChainTx = {
|
|
312
|
+
evmProxyMsg: EvmProxyMsg;
|
|
313
|
+
assets?: Asset[];
|
|
314
|
+
options?: BatchCrossChainTransactionOptions;
|
|
315
|
+
};
|
|
300
316
|
export type AssetLike = Asset | FT | NFT | {
|
|
301
317
|
rawAmount: bigint;
|
|
302
318
|
} | {
|
|
@@ -313,7 +329,7 @@ export type AssetLike = Asset | FT | NFT | {
|
|
|
313
329
|
address: TVMAddress | EVMAddress;
|
|
314
330
|
itemIndex: bigint;
|
|
315
331
|
};
|
|
316
|
-
export type
|
|
332
|
+
export type BatchCrossChainTxWithAssetLike = Omit<BatchCrossChainTx, 'assets'> & {
|
|
317
333
|
assets?: AssetLike[];
|
|
318
334
|
};
|
|
319
335
|
export interface WaitOptions<T = unknown, TContext = unknown> {
|
|
@@ -402,3 +418,10 @@ export type FTOriginAndData = {
|
|
|
402
418
|
evmAddress?: string;
|
|
403
419
|
jettonData?: JettonMinterData;
|
|
404
420
|
};
|
|
421
|
+
export type TacGasPriceResponse = {
|
|
422
|
+
gas_prices: {
|
|
423
|
+
average: number;
|
|
424
|
+
fast: number;
|
|
425
|
+
slow: number;
|
|
426
|
+
};
|
|
427
|
+
};
|