@tonappchain/sdk 0.7.0-rc31 → 0.7.0-rc34

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.
@@ -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}`;
@@ -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,
@@ -31,4 +31,4 @@ export declare const missingDecimals: MetadataError;
31
31
  export declare const missingJettonDataError: MetadataError;
32
32
  export declare const zeroRawAmountError: (assetAddress: string) => TokenError;
33
33
  export declare const sendCrossChainTransactionFailedError: (msg: string) => WalletError;
34
- export declare const convertCurrencyZeroValueError: FormatError;
34
+ export declare const convertCurrencyNegativeOrZeroValueError: FormatError;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.convertCurrencyZeroValueError = 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;
3
+ 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;
@@ -55,4 +55,4 @@ const zeroRawAmountError = (assetAddress) => new errors_1.TokenError(`FT asset w
55
55
  exports.zeroRawAmountError = zeroRawAmountError;
56
56
  const sendCrossChainTransactionFailedError = (msg) => new errors_1.WalletError(`failed to send cross chain transaction: ${msg}`, 131);
57
57
  exports.sendCrossChainTransactionFailedError = sendCrossChainTransactionFailedError;
58
- exports.convertCurrencyZeroValueError = new errors_1.FormatError('Value cannot be zero for currency conversion', 132);
58
+ exports.convertCurrencyNegativeOrZeroValueError = new errors_1.FormatError('Value cannot be negative or zero for currency conversion', 132);
@@ -123,9 +123,6 @@ class LiteSequencerClient {
123
123
  }
124
124
  }
125
125
  async convertCurrency(params) {
126
- if (params.value === 0n) {
127
- throw instances_1.convertCurrencyZeroValueError;
128
- }
129
126
  try {
130
127
  const payload = {
131
128
  currency: params.currency,
@@ -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;
@@ -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;
@@ -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,13 +1,13 @@
1
1
  import { IConfiguration, ILogger, IOperationTracker, ISimulator, ITONTransactionManager } from '../interfaces';
2
2
  import type { SenderAbstraction } from '../sender';
3
- import { BatchCrossChainTx, CrossChainTransactionsOptions, CrosschainTx, EvmProxyMsg, TransactionLinkerWithOperationId } 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
13
  sendCrossChainTransaction(evmProxyMsg: EvmProxyMsg, sender: SenderAbstraction, tx: CrosschainTx): Promise<TransactionLinkerWithOperationId>;
@@ -54,7 +54,7 @@ class TONTransactionManager {
54
54
  const { allowSimulationError = false, isRoundTrip = undefined, calculateRollbackFee = true, validateAssetsBalance = true, } = options || {};
55
55
  const { evmValidExecutors = [], tvmValidExecutors = [] } = options || {};
56
56
  Validator_1.Validator.validateEVMAddress(evmProxyMsg.evmTargetAddress);
57
- const aggregatedData = await (0, Utils_1.aggregateTokens)(assets);
57
+ const aggregatedData = (0, Utils_1.aggregateTokens)(assets);
58
58
  Validator_1.Validator.validateEVMAddresses(evmValidExecutors);
59
59
  Validator_1.Validator.validateTVMAddresses(tvmValidExecutors);
60
60
  const shouldValidateAssets = validateAssetsBalance && !skipAssetsBalanceValidation;
@@ -183,7 +183,7 @@ class TONTransactionManager {
183
183
  if (txsRequiringValidation.length) {
184
184
  // Aggregate only assets from txs that require validation and validate once per unique asset
185
185
  const assetsToValidate = txsRequiringValidation.flatMap((tx) => tx.assets ?? []);
186
- const aggregatedData = await (0, Utils_1.aggregateTokens)(assetsToValidate);
186
+ const aggregatedData = (0, Utils_1.aggregateTokens)(assetsToValidate);
187
187
  await Promise.all([
188
188
  ...aggregatedData.jettons.map((jetton) => jetton.checkCanBeTransferredBy(caller)),
189
189
  ...aggregatedData.nfts.map((nft) => nft.checkCanBeTransferredBy(caller)),
@@ -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 = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tonappchain/sdk",
3
- "version": "0.7.0-rc31",
3
+ "version": "0.7.0-rc34",
4
4
  "repository": "https://github.com/TacBuild/tac-sdk.git",
5
5
  "author": "TAC. <developers@tac>",
6
6
  "license": "MIT",