@tonappchain/sdk 0.7.0-rc7 → 0.7.0-rc8

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.
@@ -1,19 +1,7 @@
1
1
  import { IConfiguration } from '../structs/Services';
2
- import { Asset, AssetType, EVMAddress, NFTAddressType, TVMAddress } from '../structs/Struct';
2
+ import { Asset, AssetFromFTArg, AssetFromNFTCollectionArg, AssetFromNFTItemArg, EVMAddress, NFTAddressType, TVMAddress } from '../structs/Struct';
3
3
  export declare class AssetFactory {
4
- static from(configuration: IConfiguration, token: {
5
- address: TVMAddress | EVMAddress;
6
- tokenType: AssetType.FT;
7
- } | {
8
- address: TVMAddress | EVMAddress;
9
- tokenType: AssetType.NFT;
10
- addressType: NFTAddressType.COLLECTION;
11
- index: bigint;
12
- } | {
13
- address: TVMAddress;
14
- tokenType: AssetType.NFT;
15
- addressType: NFTAddressType.ITEM;
16
- }): Promise<Asset>;
17
- private static createFTAsset;
18
- private static createNFTAsset;
4
+ static from(configuration: IConfiguration, token: AssetFromFTArg | AssetFromNFTCollectionArg | AssetFromNFTItemArg): Promise<Asset>;
5
+ static createFTAsset(configuration: IConfiguration, address: TVMAddress | EVMAddress): Promise<Asset>;
6
+ static createNFTAsset(configuration: IConfiguration, address: TVMAddress | EVMAddress, addressType: NFTAddressType, index?: bigint): Promise<Asset>;
19
7
  }
@@ -8,9 +8,10 @@ const FT_1 = require("./FT");
8
8
  const NFT_1 = require("./NFT");
9
9
  const TON_1 = require("./TON");
10
10
  class AssetFactory {
11
- /// PUBLIC
12
11
  static async from(configuration, token) {
13
12
  if (token.address === '' || token.address === configuration.nativeTONAddress) {
13
+ if (token.tokenType !== Struct_1.AssetType.FT)
14
+ throw (0, errors_1.unknownTokenTypeError)(token.address, 'detected TON, but token type is not FT');
14
15
  return TON_1.TON.create(configuration);
15
16
  }
16
17
  const cachedAsset = AssetCache_1.AssetCache.get(token);
@@ -23,18 +24,18 @@ class AssetFactory {
23
24
  AssetCache_1.AssetCache.set(token, asset);
24
25
  return asset;
25
26
  }
26
- /// PRIVATE
27
- /// CREATE FT ASSET
28
27
  static async createFTAsset(configuration, address) {
28
+ if (address === configuration.nativeTONAddress || address === '') {
29
+ return TON_1.TON.create(configuration);
30
+ }
29
31
  return FT_1.FT.fromAddress(configuration, address);
30
32
  }
31
- /// CREATE NFT ASSET
32
33
  static async createNFTAsset(configuration, address, addressType, index) {
33
34
  if (addressType === Struct_1.NFTAddressType.ITEM) {
34
35
  return NFT_1.NFT.fromItem(configuration, address);
35
36
  }
36
37
  if (addressType === Struct_1.NFTAddressType.COLLECTION) {
37
- if (!index) {
38
+ if (index === undefined) {
38
39
  throw (0, errors_1.indexRequiredError)(address);
39
40
  }
40
41
  return NFT_1.NFT.fromCollection(configuration, { collection: address, index });
@@ -6,7 +6,7 @@ import { AssetType, ContractOpener, EVMAddress, FeeParams, TVMAddress, UserWalle
6
6
  import { Asset, Origin } from '../structs/Struct';
7
7
  import { JettonWallet } from '../wrappers/JettonWallet';
8
8
  export declare class FT implements Asset {
9
- private _tokenAddress;
9
+ private _tvmAddress;
10
10
  readonly type: AssetType;
11
11
  readonly origin: Origin;
12
12
  private _configuration;
package/dist/assets/FT.js CHANGED
@@ -14,7 +14,7 @@ const JettonMaster_1 = require("../wrappers/JettonMaster");
14
14
  const JettonWallet_1 = require("../wrappers/JettonWallet");
15
15
  class FT {
16
16
  get address() {
17
- return this._tokenAddress.toString();
17
+ return this._tvmAddress.toString({ bounceable: true });
18
18
  }
19
19
  static async getJettonData(contractOpener, address) {
20
20
  Validator_1.Validator.validateTVMAddress(address);
@@ -48,12 +48,14 @@ class FT {
48
48
  }
49
49
  static async getTVMAddress(configuration, address) {
50
50
  Validator_1.Validator.validateEVMAddress(address);
51
- const exists = await configuration.TACParams.tokenUtils['exists(address)'](address);
52
- if (exists) {
51
+ // If token is TON native
52
+ const fromTVM = await configuration.TACParams.tokenUtils['exists(address)'](address);
53
+ if (fromTVM) {
53
54
  const erc20Token = configuration.artifacts.tac.wrappers.CrossChainLayerERC20FactoryTAC.connect(address, configuration.TACParams.provider);
54
55
  const info = await erc20Token.getInfo();
55
56
  return info.tvmAddress;
56
57
  }
58
+ // If token is TAC native
57
59
  const jettonMaster = JettonMaster_1.JettonMaster.createFromConfig({
58
60
  evmTokenAddress: address,
59
61
  crossChainLayerAddress: ton_1.Address.parse(configuration.TONParams.crossChainLayerAddress),
@@ -64,9 +66,9 @@ class FT {
64
66
  }
65
67
  constructor(address, origin, configuration) {
66
68
  this.type = Struct_1.AssetType.FT;
67
- this._tokenAddress = ton_1.Address.parse(address);
69
+ this._tvmAddress = ton_1.Address.parse(address);
68
70
  this._configuration = configuration;
69
- this._jettonMinter = this._configuration.TONParams.contractOpener.open(new JettonMaster_1.JettonMaster(this._tokenAddress));
71
+ this._jettonMinter = this._configuration.TONParams.contractOpener.open(new JettonMaster_1.JettonMaster(this._tvmAddress));
70
72
  this.origin = origin;
71
73
  this._transferAmount = 0n;
72
74
  }
@@ -78,13 +80,17 @@ class FT {
78
80
  }
79
81
  throw e;
80
82
  });
81
- return new FT(tvmAddress, origin, configuration);
83
+ const token = new FT(tvmAddress, origin, configuration);
84
+ if ((0, ethers_1.isAddress)(address)) {
85
+ token._evmAddress = address;
86
+ }
87
+ return token;
82
88
  }
83
89
  get rawAmount() {
84
90
  return this._transferAmount;
85
91
  }
86
92
  get clone() {
87
- const ft = new FT(this._tokenAddress.toString(), this.origin, this._configuration);
93
+ const ft = new FT(this._tvmAddress.toString(), this.origin, this._configuration);
88
94
  ft._transferAmount = this._transferAmount;
89
95
  ft._evmAddress = this._evmAddress;
90
96
  ft._decimals = this._decimals;
@@ -128,16 +134,21 @@ class FT {
128
134
  if (this._evmAddress) {
129
135
  return this._evmAddress;
130
136
  }
131
- if (this.origin === Struct_2.Origin.TAC) {
132
- this._evmAddress = await this._jettonMinter.getEVMAddress();
137
+ const tokenAddressString = this._tvmAddress.toString({ bounceable: true });
138
+ if (this.origin === Struct_2.Origin.TON) {
139
+ this._evmAddress = await this._configuration.TACParams.tokenUtils.computeAddress(tokenAddressString);
140
+ }
141
+ else if (this.origin === Struct_2.Origin.TAC) {
142
+ const givenMinter = this._configuration.TONParams.contractOpener.open(new JettonMaster_1.JettonMaster(ton_1.Address.parse(tokenAddressString)));
143
+ this._evmAddress = await givenMinter.getEVMAddress();
133
144
  }
134
145
  else {
135
- this._evmAddress = await this._configuration.TACParams.tokenUtils.computeAddress(this._tokenAddress.toString());
146
+ throw (0, errors_1.unknownTokenTypeError)(tokenAddressString, 'Token origin is neither TON nor TAC');
136
147
  }
137
148
  return this._evmAddress;
138
149
  }
139
150
  async getTVMAddress() {
140
- return this._tokenAddress.toString();
151
+ return this._tvmAddress.toString({ bounceable: true });
141
152
  }
142
153
  async generatePayload(params) {
143
154
  const { excessReceiver, evmData, crossChainTonAmount = 0n, forwardFeeTonAmount = 0n, feeParams } = params;
@@ -154,7 +165,7 @@ class FT {
154
165
  return payload;
155
166
  }
156
167
  get opType() {
157
- return this.origin === 'TAC' ? InternalStruct_1.AssetOpType.JETTON_BURN : InternalStruct_1.AssetOpType.JETTON_TRANSFER;
168
+ return this.origin === Struct_2.Origin.TAC ? InternalStruct_1.AssetOpType.JETTON_BURN : InternalStruct_1.AssetOpType.JETTON_TRANSFER;
158
169
  }
159
170
  async getWallet(userAddress) {
160
171
  const walletAddress = await this.getUserWalletAddress(userAddress);
@@ -168,7 +179,7 @@ class FT {
168
179
  return BigInt(await wallet.getJettonBalance());
169
180
  }
170
181
  async getUserBalanceExtended(userAddress) {
171
- const masterState = await this._configuration.TONParams.contractOpener.getContractState(this._tokenAddress);
182
+ const masterState = await this._configuration.TONParams.contractOpener.getContractState(this._tvmAddress);
172
183
  if (masterState.state !== 'active') {
173
184
  return { exists: false };
174
185
  }
@@ -185,7 +196,7 @@ class FT {
185
196
  async checkBalance(userAddress) {
186
197
  const balance = await this.getUserBalance(userAddress);
187
198
  if (balance < this._transferAmount) {
188
- throw (0, errors_1.insufficientBalanceError)(this._tokenAddress.toString());
199
+ throw (0, errors_1.insufficientBalanceError)(this._tvmAddress.toString());
189
200
  }
190
201
  }
191
202
  async checkCanBeTransferedBy(userAddress) {
@@ -142,11 +142,17 @@ class NFT {
142
142
  if (this._addresses.evmAddress) {
143
143
  return this._addresses.evmAddress;
144
144
  }
145
- if (this.origin === Struct_1.Origin.TAC) {
146
- this._addresses.evmAddress = await this._nftCollection.getOriginalAddress().toString();
145
+ const tvmNFTAddress = ton_1.Address.parse(this._addresses.collection).toString({ bounceable: true });
146
+ const { code: givenNFTCollection } = await this._configuration.TONParams.contractOpener.getContractState(ton_1.Address.parse(tvmNFTAddress));
147
+ if (givenNFTCollection &&
148
+ this._configuration.TONParams.nftCollectionCode.equals(ton_1.Cell.fromBoc(givenNFTCollection)[0])) {
149
+ const nftCollection = this._configuration.TONParams.contractOpener.open(wrappers_1.NFTCollection.createFromAddress((0, ton_1.address)(tvmNFTAddress)));
150
+ const evmAddress = await nftCollection.getOriginalAddress();
151
+ this._addresses.evmAddress = evmAddress.toString();
147
152
  }
148
153
  else {
149
- this._addresses.evmAddress = await this._configuration.TACParams.tokenUtils.computeAddressERC721(this._nftCollection.address.toString({ bounceable: true }));
154
+ this._addresses.evmAddress =
155
+ await this._configuration.TACParams.tokenUtils.computeAddressERC721(tvmNFTAddress);
150
156
  }
151
157
  return this._addresses.evmAddress;
152
158
  }
@@ -3,6 +3,7 @@ export declare class LiteSequencerClient {
3
3
  private readonly endpoint;
4
4
  private readonly maxChunkSize;
5
5
  constructor(endpoint: string, maxChunkSize?: number);
6
+ getOperationIdByTransactionHash(transactionHash: string): Promise<string>;
6
7
  getOperationType(operationId: string): Promise<OperationType>;
7
8
  getOperationId(transactionLinker: TransactionLinker): Promise<string>;
8
9
  getOperationIdsByShardsKeys(shardsKeys: string[], caller: string, chunkSize?: number): Promise<OperationIdsByShardsKey>;
@@ -12,6 +12,24 @@ class LiteSequencerClient {
12
12
  this.endpoint = endpoint;
13
13
  this.maxChunkSize = maxChunkSize;
14
14
  }
15
+ async getOperationIdByTransactionHash(transactionHash) {
16
+ const isEthHash = /^0x[a-fA-F0-9]{64}$/.test(transactionHash);
17
+ const path = isEthHash ? 'tac/operation-id' : 'ton/operation-id';
18
+ try {
19
+ const response = await axios_1.default.get(new URL(path, this.endpoint).toString(), {
20
+ params: { transactionHash },
21
+ });
22
+ return response.data.response || '';
23
+ }
24
+ catch (error) {
25
+ if (axios_1.default.isAxiosError(error)) {
26
+ if (error.response?.status === 404) {
27
+ return '';
28
+ }
29
+ }
30
+ throw (0, errors_1.operationFetchError)(`endpoint ${this.endpoint} failed to complete request`, error);
31
+ }
32
+ }
15
33
  async getOperationType(operationId) {
16
34
  try {
17
35
  const response = await axios_1.default.get(new URL('operation-type', this.endpoint).toString(), {
@@ -6,6 +6,7 @@ export interface ILiteSequencerClientFactory {
6
6
  export interface ILiteSequencerClient {
7
7
  getOperationType(operationId: string): Promise<OperationType>;
8
8
  getOperationId(transactionLinker: TransactionLinker): Promise<string>;
9
+ getOperationIdByTransactionHash(transactionHash: string): Promise<string>;
9
10
  getOperationIdsByShardsKeys(shardsKeys: string[], caller: string, chunkSize?: number): Promise<OperationIdsByShardsKey>;
10
11
  getStageProfilings(operationIds: string[], chunkSize?: number): Promise<ExecutionStagesByOperationId>;
11
12
  getOperationStatuses(operationIds: string[], chunkSize?: number): Promise<StatusInfosByOperationId>;
@@ -17,6 +18,7 @@ export declare class OperationTracker implements IOperationTracker {
17
18
  private readonly clients;
18
19
  private readonly logger;
19
20
  constructor(network: Network, customLiteSequencerEndpoints?: string[], logger?: ILogger, clientFactory?: ILiteSequencerClientFactory);
21
+ getOperationIdByTransactionHash(transactionHash: string, waitOptions?: WaitOptions<string>): Promise<string>;
20
22
  getOperationType(operationId: string, waitOptions?: WaitOptions<OperationType>): Promise<OperationType>;
21
23
  getOperationId(transactionLinker: TransactionLinker, waitOptions?: WaitOptions<string>): Promise<string>;
22
24
  getOperationIdsByShardsKeys(shardsKeys: string[], caller: string, waitOptions?: WaitOptions<OperationIdsByShardsKey>, chunkSize?: number): Promise<OperationIdsByShardsKey>;
@@ -22,6 +22,26 @@ class OperationTracker {
22
22
  this.clients = clientFactory.createClients(endpoints);
23
23
  this.logger = logger;
24
24
  }
25
+ async getOperationIdByTransactionHash(transactionHash, waitOptions) {
26
+ this.logger.debug(`Getting operation ID for transactionHash: ${(0, Utils_1.formatObjectForLogging)(transactionHash)}`);
27
+ const requestFn = async () => {
28
+ let lastError;
29
+ for (const client of this.clients) {
30
+ try {
31
+ const id = await client.getOperationIdByTransactionHash(transactionHash);
32
+ this.logger.debug(`Operation ID ${id == '' ? 'does not exist' : 'retrieved successfully'}`);
33
+ return id;
34
+ }
35
+ catch (error) {
36
+ this.logger.warn(`Failed to get OperationId by transactionHash using one of the endpoints`);
37
+ lastError = error;
38
+ }
39
+ }
40
+ this.logger.error('All endpoints failed to get operation id by transactionHash');
41
+ throw (0, errors_1.allEndpointsFailedError)(lastError);
42
+ };
43
+ return waitOptions ? await (0, Utils_1.waitUntilSuccess)(waitOptions, requestFn) : await requestFn();
44
+ }
25
45
  async getOperationType(operationId, waitOptions) {
26
46
  this.logger.debug(`Getting operation type for ${(0, Utils_1.formatObjectForLogging)(operationId)}`);
27
47
  const requestFn = async () => {
@@ -137,10 +137,15 @@ class TransactionManager {
137
137
  return waitOptions
138
138
  ? {
139
139
  sendTransactionResult,
140
- operationId: await this.operationTracker.getOperationId(transactionLinker, {
140
+ operationId: await this.operationTracker
141
+ .getOperationId(transactionLinker, {
141
142
  ...waitOptions,
142
143
  successCheck: (operationId) => !!operationId,
143
144
  logger: this.logger,
145
+ })
146
+ .catch((error) => {
147
+ this.logger.error(`Error while waiting for operation ID: ${error}`);
148
+ return undefined;
144
149
  }),
145
150
  ...transactionLinker,
146
151
  }
@@ -31,6 +31,7 @@ export interface ISimulator {
31
31
  export interface IOperationTracker {
32
32
  getOperationType(operationId: string, waitOptions?: WaitOptions<OperationType>): Promise<OperationType>;
33
33
  getOperationId(transactionLinker: TransactionLinker, waitOptions?: WaitOptions<string>): Promise<string>;
34
+ getOperationIdByTransactionHash(transactionHash: string, waitOptions?: WaitOptions<string>): Promise<string>;
34
35
  getOperationIdsByShardsKeys(shardsKeys: string[], caller: string, waitOptions?: WaitOptions<OperationIdsByShardsKey>, chunkSize?: number): Promise<OperationIdsByShardsKey>;
35
36
  getStageProfiling(operationId: string, waitOptions?: WaitOptions<ExecutionStages>): Promise<ExecutionStages>;
36
37
  getStageProfilings(operationIds: string[], waitOptions?: WaitOptions<ExecutionStagesByOperationId>, chunkSize?: number): Promise<ExecutionStagesByOperationId>;
@@ -356,3 +356,18 @@ export declare enum Origin {
356
356
  }
357
357
  export type TVMAddress = string;
358
358
  export type EVMAddress = string;
359
+ export type AssetFromFTArg = {
360
+ address: TVMAddress | EVMAddress;
361
+ tokenType: AssetType.FT;
362
+ };
363
+ export type AssetFromNFTCollectionArg = {
364
+ address: TVMAddress | EVMAddress;
365
+ tokenType: AssetType.NFT;
366
+ addressType: NFTAddressType.COLLECTION;
367
+ index: bigint;
368
+ };
369
+ export type AssetFromNFTItemArg = {
370
+ address: TVMAddress;
371
+ tokenType: AssetType.NFT;
372
+ addressType: NFTAddressType.ITEM;
373
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tonappchain/sdk",
3
- "version": "0.7.0-rc7",
3
+ "version": "0.7.0-rc8",
4
4
  "repository": "https://github.com/TacBuild/tac-sdk.git",
5
5
  "author": "TAC. <developers@tac>",
6
6
  "license": "MIT",