@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.
Files changed (33) hide show
  1. package/dist/src/agnosticSdk/AbiHandler.js +1 -1
  2. package/dist/src/agnosticSdk/DebugHelpers.js +1 -1
  3. package/dist/src/agnosticSdk/HooksHandler.js +1 -1
  4. package/dist/src/agnosticSdk/ReplacementHelper.js +3 -1
  5. package/dist/src/assets/AssetFactory.js +3 -2
  6. package/dist/src/assets/TON.d.ts +1 -0
  7. package/dist/src/assets/TON.js +5 -1
  8. package/dist/src/errors/instances.d.ts +3 -0
  9. package/dist/src/errors/instances.js +7 -2
  10. package/dist/src/interfaces/ILiteSequencerClient.d.ts +6 -1
  11. package/dist/src/interfaces/IOperationTracker.d.ts +6 -1
  12. package/dist/src/interfaces/ITONTransactionManager.d.ts +4 -5
  13. package/dist/src/interfaces/ITacSDK.d.ts +3 -3
  14. package/dist/src/sdk/Configuration.js +9 -3
  15. package/dist/src/sdk/LiteSequencerClient.d.ts +2 -0
  16. package/dist/src/sdk/LiteSequencerClient.js +21 -4
  17. package/dist/src/sdk/Logger.d.ts +4 -4
  18. package/dist/src/sdk/Logger.js +12 -4
  19. package/dist/src/sdk/OperationTracker.d.ts +2 -1
  20. package/dist/src/sdk/OperationTracker.js +24 -0
  21. package/dist/src/sdk/Simulator.js +1 -1
  22. package/dist/src/sdk/TONTransactionManager.d.ts +4 -4
  23. package/dist/src/sdk/TONTransactionManager.js +29 -19
  24. package/dist/src/sdk/TacSdk.d.ts +8 -3
  25. package/dist/src/sdk/TacSdk.js +12 -4
  26. package/dist/src/sdk/TxFinalizer.js +6 -1
  27. package/dist/src/sdk/Utils.d.ts +2 -2
  28. package/dist/src/sdk/Utils.js +28 -27
  29. package/dist/src/sender/SenderFactory.js +1 -1
  30. package/dist/src/sender/TonConnectSender.js +1 -1
  31. package/dist/src/structs/InternalStruct.d.ts +12 -0
  32. package/dist/src/structs/Struct.d.ts +26 -3
  33. 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
- let paramType = this._buildParameterType(input);
59
+ const paramType = this._buildParameterType(input);
60
60
  // Add parameter name if available
61
61
  if (input.name) {
62
62
  return `${paramType} ${input.name}`;
@@ -17,7 +17,7 @@ class DebugHelpers {
17
17
  bridgeData: {
18
18
  tokens: bridgeTokens,
19
19
  nfts: bridgeNFTs,
20
- isRequired: bridgeTokens.length > 0 || bridgeNFTs.length > 0 ? true : false,
20
+ isRequired: bridgeTokens.length > 0 || bridgeNFTs.length > 0,
21
21
  },
22
22
  };
23
23
  }
@@ -30,7 +30,7 @@ class HooksHandler {
30
30
  }
31
31
  const customHookData = {
32
32
  isFromSAPerspective,
33
- contractAddress,
33
+ contractAddress: ethers_1.ethers.getAddress(contractAddress.toLowerCase()), // Normalize address to checksum format
34
34
  value,
35
35
  data,
36
36
  improvedMissionInfo,
@@ -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.map((input) => `${input.name} (${input.type})`).join(', ');
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
- if (address === configuration.nativeTONAddress || address === '') {
29
- return TON_1.TON.create(configuration);
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
  }
@@ -6,6 +6,7 @@ import { AssetType, FeeParams } from '../structs/Struct';
6
6
  export declare class TON implements Asset {
7
7
  readonly address: string;
8
8
  readonly type: AssetType;
9
+ private evmAddress;
9
10
  private _rawAmount;
10
11
  private _config;
11
12
  constructor(config: IConfiguration);
@@ -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
- return this._config.TACParams.tokenUtils.computeAddress(this._config.nativeTONAddress);
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 { CrosschainTx, EvmProxyMsg, OperationIdsByShardsKey, TransactionLinkerWithOperationId, WaitOptions } from '../structs/Struct';
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, waitOptions?: WaitOptions<string>): Promise<TransactionLinkerWithOperationId>;
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 waitOptions Optional policy for waiting on operation ids by shard keys.
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: CrosschainTx[], waitOptions?: WaitOptions<OperationIdsByShardsKey>): Promise<TransactionLinkerWithOperationId[]>;
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, CrosschainTx, CrosschainTxWithAssetLike, EVMAddress, EvmProxyMsg, ExecutionFeeEstimationResult, NFTAddressType, OperationIdsByShardsKey, SuggestedTVMExecutorFee, TACSimulationParams, TACSimulationResult, TransactionLinkerWithOperationId, TVMAddress, UserWalletBalanceExtended, WaitOptions } from '../structs/Struct';
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 waitOptions Optional waiting policy for operation ids by shard keys.
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: CrosschainTxWithAssetLike[], waitOptions?: WaitOptions<OperationIdsByShardsKey>): Promise<TransactionLinkerWithOperationId[]>;
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.toString();
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?.toString() ?? artifacts.TAC_SETTINGS_ADDRESS;
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(artifacts.TAC_SMART_ACCOUNT_FACTORY_ADDRESS, TacSAFactoryAbi, provider);
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
- const response = await this.httpClient.get(new URL(path, this.endpoint).toString(), {
19
- params: { transactionHash },
20
- });
21
- return response.data.response || '';
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, {
@@ -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
  }
@@ -17,9 +17,17 @@ class ConsoleLogger {
17
17
  }
18
18
  exports.ConsoleLogger = ConsoleLogger;
19
19
  class NoopLogger {
20
- debug() { }
21
- info() { }
22
- warn() { }
23
- error() { }
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 = await (0, Utils_1.aggregateTokens)(assets);
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, OperationIdsByShardsKey, TransactionLinkerWithOperationId, WaitOptions } from '../structs/Struct';
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
- private buildFeeParams;
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, waitOptions?: WaitOptions<string>): Promise<TransactionLinkerWithOperationId>;
14
- sendCrossChainTransactions(sender: SenderAbstraction, txs: CrosschainTx[], waitOptions?: WaitOptions<OperationIdsByShardsKey>): Promise<TransactionLinkerWithOperationId[]>;
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 = await (0, Utils_1.aggregateTokens)(assets);
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, waitOptions) {
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 (!waitOptions) {
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, waitOptions) {
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
- return waitOptions
167
- ? await this.waitForOperationIds(transactionLinkers, caller, waitOptions)
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 = await (0, Utils_1.aggregateTokens)(assetsToValidate);
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
- const operationIds = await this.operationTracker.getOperationIdsByShardsKeys(transactionLinkers.map((linker) => linker.shardsKey), caller, {
193
- ...waitOptions,
194
- logger: this.logger,
195
- successCheck: (operationIds) => Object.keys(operationIds).length == transactionLinkers.length &&
196
- Object.values(operationIds).every((ids) => ids.operationIds.length > 0),
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,
@@ -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, CrosschainTx, CrosschainTxWithAssetLike, EVMAddress, EvmProxyMsg, ExecutionFeeEstimationResult, NFTAddressType, OperationIdsByShardsKey, SDKParams, SuggestedTVMExecutorFee, TACSimulationParams, TACSimulationResult, TransactionLinkerWithOperationId, TVMAddress, UserWalletBalanceExtended, WaitOptions } from '../structs/Struct';
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, waitOptions?: WaitOptions<string>): Promise<TransactionLinkerWithOperationId>;
24
- sendCrossChainTransactions(sender: SenderAbstraction, txs: CrosschainTxWithAssetLike[], waitOptions?: WaitOptions<OperationIdsByShardsKey>): Promise<TransactionLinkerWithOperationId[]>;
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>;
@@ -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, waitOptions) {
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, waitOptions);
91
+ return this.tonTransactionManager.sendCrossChainTransaction(evmProxyMsg, sender, tx);
84
92
  }
85
- async sendCrossChainTransactions(sender, txs, waitOptions) {
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, waitOptions);
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
  }
@@ -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[]): Promise<{
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>;
@@ -199,39 +199,30 @@ function getBouncedAddress(tvmAddress) {
199
199
  bounceable: true,
200
200
  });
201
201
  }
202
- async function aggregateTokens(assets) {
203
- const uniqueAssetsMap = new Map();
202
+ function aggregateTokens(assets) {
203
+ const jettonsMap = new Map();
204
+ const nftsMap = new Map();
204
205
  let ton;
205
- for await (const asset of assets ?? []) {
206
- if (asset.type !== Struct_1.AssetType.FT)
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 (!asset.address) {
212
- ton = ton ? ton.addRawAmount(asset.rawAmount) : asset.clone;
213
- continue;
214
- }
215
- let jetton = uniqueAssetsMap.get(asset.address);
216
- if (!jetton) {
217
- jetton = asset.clone;
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
- jetton = jetton.addRawAmount(asset.rawAmount);
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
- return assets.map((asset) => ({
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.TESTNET ? -3 : -239,
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.TESTNET ? ui_1.CHAIN.TESTNET : ui_1.CHAIN.MAINNET,
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, Addressable } from 'ethers';
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 | Addressable;
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 CrosschainTxWithAssetLike = Omit<CrosschainTx, 'assets'> & {
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
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tonappchain/sdk",
3
- "version": "0.7.2-gas-price-0.1",
3
+ "version": "0.7.2-gas-price-0.3",
4
4
  "repository": "https://github.com/TacBuild/tac-sdk.git",
5
5
  "author": "TAC. <developers@tac>",
6
6
  "license": "MIT",