@tonappchain/sdk 0.7.0-rc6 → 0.7.0-rc7.1

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.
@@ -0,0 +1,23 @@
1
+ import { Asset } from '../structs/Struct';
2
+ export declare class AssetCache {
3
+ private static readonly cache;
4
+ /**
5
+ * Get asset from cache
6
+ */
7
+ static get(token: {
8
+ address: string;
9
+ index?: bigint;
10
+ }): Asset | undefined;
11
+ /**
12
+ * Set asset in cache
13
+ */
14
+ static set(token: {
15
+ address: string;
16
+ index?: bigint;
17
+ }, asset: Asset): void;
18
+ /**
19
+ * Clear the cache
20
+ */
21
+ static clear(): void;
22
+ private static generateKey;
23
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AssetCache = void 0;
4
+ class AssetCache {
5
+ /**
6
+ * Get asset from cache
7
+ */
8
+ static get(token) {
9
+ const key = this.generateKey(token);
10
+ return this.cache.get(key);
11
+ }
12
+ /**
13
+ * Set asset in cache
14
+ */
15
+ static set(token, asset) {
16
+ const key = this.generateKey(token);
17
+ this.cache.set(key, asset);
18
+ }
19
+ /**
20
+ * Clear the cache
21
+ */
22
+ static clear() {
23
+ this.cache.clear();
24
+ }
25
+ static generateKey(token) {
26
+ // Normalize address to lowercase for consistency
27
+ const normalizedAddress = token.address.toLowerCase();
28
+ const parts = [normalizedAddress];
29
+ if (token.index !== undefined) {
30
+ parts.push(token.index.toString());
31
+ }
32
+ return parts.join('|');
33
+ }
34
+ }
35
+ exports.AssetCache = AssetCache;
36
+ AssetCache.cache = new Map();
@@ -1,13 +1,19 @@
1
1
  import { IConfiguration } from '../structs/Services';
2
- import { Asset, AssetType, ContractOpener, NFTAddressType } from '../structs/Struct';
2
+ import { Asset, AssetType, EVMAddress, NFTAddressType, TVMAddress } from '../structs/Struct';
3
3
  export declare class AssetFactory {
4
- static getType(contractOpener: ContractOpener, address: string): Promise<{
5
- type: AssetType;
6
- addressType?: NFTAddressType;
7
- }>;
8
4
  static from(configuration: IConfiguration, token: {
9
- address: string;
10
- index?: bigint;
11
- tokenType?: AssetType;
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;
12
16
  }): Promise<Asset>;
17
+ private static createFTAsset;
18
+ private static createNFTAsset;
13
19
  }
@@ -1,73 +1,45 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AssetFactory = void 0;
4
- const ethers_1 = require("ethers");
5
4
  const errors_1 = require("../errors");
6
5
  const Struct_1 = require("../structs/Struct");
6
+ const AssetCache_1 = require("./AssetCache");
7
7
  const FT_1 = require("./FT");
8
8
  const NFT_1 = require("./NFT");
9
9
  const TON_1 = require("./TON");
10
10
  class AssetFactory {
11
- static async getType(contractOpener, address) {
12
- try {
13
- await FT_1.FT.getJettonData(contractOpener, address);
14
- return { type: Struct_1.AssetType.FT };
15
- }
16
- catch {
17
- // not jetton
18
- }
19
- try {
20
- await NFT_1.NFT.getItemData(contractOpener, address);
21
- return { type: Struct_1.AssetType.NFT, addressType: Struct_1.NFTAddressType.ITEM };
22
- }
23
- catch {
24
- // not nft item
25
- }
26
- try {
27
- await NFT_1.NFT.getCollectionData(contractOpener, address);
28
- return { type: Struct_1.AssetType.NFT, addressType: Struct_1.NFTAddressType.COLLECTION };
29
- }
30
- catch {
31
- // not nft collection
32
- }
33
- throw (0, errors_1.unknownTokenTypeError)(address);
34
- }
11
+ /// PUBLIC
35
12
  static async from(configuration, token) {
36
- if ((0, ethers_1.isAddress)(token.address)) {
37
- if (!token.tokenType) {
38
- // cannot detect token type for evm address yet
39
- throw (0, errors_1.unknownTokenTypeError)(token.address);
40
- }
41
- if (token.tokenType === Struct_1.AssetType.FT) {
42
- token.address = await FT_1.FT.getTVMAddress(configuration, token.address);
43
- }
44
- if (token.tokenType === Struct_1.AssetType.NFT) {
45
- token.address = await NFT_1.NFT.getTVMAddress(configuration, token.address, token.index);
46
- }
47
- }
48
- if (!token.address || token.address === configuration.nativeTONAddress) {
13
+ if (token.address === '' || token.address === configuration.nativeTONAddress) {
49
14
  return TON_1.TON.create(configuration);
50
15
  }
51
- const { type, addressType } = await this.getType(configuration.TONParams.contractOpener, token.address);
52
- if (type === Struct_1.AssetType.FT) {
53
- const origin = await FT_1.FT.getOrigin(configuration.TONParams.contractOpener, token.address, configuration);
54
- return new FT_1.FT(token.address, origin, configuration);
16
+ const cachedAsset = AssetCache_1.AssetCache.get(token);
17
+ if (cachedAsset) {
18
+ return cachedAsset.clone.withAmount({ rawAmount: 0n });
55
19
  }
56
- if (type === Struct_1.AssetType.NFT) {
57
- if (addressType === Struct_1.NFTAddressType.ITEM) {
58
- const origin = await NFT_1.NFT.getOrigin(configuration.TONParams.contractOpener, token.address, configuration);
59
- return NFT_1.NFT.fromItem(configuration, token.address, origin);
60
- }
61
- if (addressType === Struct_1.NFTAddressType.COLLECTION) {
62
- if (!token.index) {
63
- throw (0, errors_1.indexRequiredError)(token.address);
64
- }
65
- const itemAddress = await NFT_1.NFT.getItemAddress(configuration.TONParams.contractOpener, token.address, token.index);
66
- const origin = await NFT_1.NFT.getOrigin(configuration.TONParams.contractOpener, itemAddress, configuration);
67
- return NFT_1.NFT.fromCollection(configuration, { collection: token.address, index: token.index }, origin);
20
+ const asset = token.tokenType === Struct_1.AssetType.FT
21
+ ? await this.createFTAsset(configuration, token.address)
22
+ : await this.createNFTAsset(configuration, token.address, token.addressType, token.addressType === Struct_1.NFTAddressType.COLLECTION ? token.index : undefined);
23
+ AssetCache_1.AssetCache.set(token, asset);
24
+ return asset;
25
+ }
26
+ /// PRIVATE
27
+ /// CREATE FT ASSET
28
+ static async createFTAsset(configuration, address) {
29
+ return FT_1.FT.fromAddress(configuration, address);
30
+ }
31
+ /// CREATE NFT ASSET
32
+ static async createNFTAsset(configuration, address, addressType, index) {
33
+ if (addressType === Struct_1.NFTAddressType.ITEM) {
34
+ return NFT_1.NFT.fromItem(configuration, address);
35
+ }
36
+ if (addressType === Struct_1.NFTAddressType.COLLECTION) {
37
+ if (index === undefined) {
38
+ throw (0, errors_1.indexRequiredError)(address);
68
39
  }
40
+ return NFT_1.NFT.fromCollection(configuration, { collection: address, index });
69
41
  }
70
- throw (0, errors_1.unknownTokenTypeError)(token.address);
42
+ throw (0, errors_1.unknownTokenTypeError)(address, 'NFT address type is unknown: should be either ITEM or COLLECTION');
71
43
  }
72
44
  }
73
45
  exports.AssetFactory = AssetFactory;
@@ -2,7 +2,7 @@ import { SandboxContract } from '@ton/sandbox';
2
2
  import { Cell, OpenedContract } from '@ton/ton';
3
3
  import { AssetOpType } from '../structs/InternalStruct';
4
4
  import { IConfiguration } from '../structs/Services';
5
- import { AssetType, ContractOpener, FeeParams, UserWalletBalanceExtended } from '../structs/Struct';
5
+ import { AssetType, ContractOpener, EVMAddress, FeeParams, TVMAddress, UserWalletBalanceExtended } from '../structs/Struct';
6
6
  import { Asset, Origin } from '../structs/Struct';
7
7
  import { JettonWallet } from '../wrappers/JettonWallet';
8
8
  export declare class FT implements Asset {
@@ -14,15 +14,12 @@ export declare class FT implements Asset {
14
14
  private _decimals?;
15
15
  private _transferAmount;
16
16
  private _evmAddress?;
17
- get addresses(): {
18
- tvmAddress: string;
19
- evmAddress?: string;
20
- };
21
17
  get address(): string;
22
- static getJettonData(contractOpener: ContractOpener, tvmAddress: string): Promise<import("../wrappers/JettonMaster").JettonMasterData>;
23
- static getOrigin(contractOpener: ContractOpener, address: string, configuration: IConfiguration): Promise<Origin>;
24
- static getTVMAddress(configuration: IConfiguration, evmAddress: string): Promise<string>;
25
- constructor(tvmTokenAddress: string, origin: Origin, configuration: IConfiguration);
18
+ static getJettonData(contractOpener: ContractOpener, address: TVMAddress): Promise<import("../wrappers/JettonMaster").JettonMasterData>;
19
+ static getOrigin(configuration: IConfiguration, address: TVMAddress): Promise<Origin>;
20
+ static getTVMAddress(configuration: IConfiguration, address: EVMAddress): Promise<string>;
21
+ private constructor();
22
+ static fromAddress(configuration: IConfiguration, address: TVMAddress | EVMAddress): Promise<FT>;
26
23
  get rawAmount(): bigint;
27
24
  get clone(): FT;
28
25
  withAmount(amount: {
@@ -45,7 +42,7 @@ export declare class FT implements Asset {
45
42
  forwardFeeTonAmount?: bigint;
46
43
  feeParams?: FeeParams;
47
44
  }): Promise<Cell>;
48
- getOpType(): Promise<AssetOpType.JETTON_BURN | AssetOpType.JETTON_TRANSFER>;
45
+ get opType(): AssetOpType.JETTON_BURN | AssetOpType.JETTON_TRANSFER;
49
46
  getWallet(userAddress: string): Promise<OpenedContract<JettonWallet> | SandboxContract<JettonWallet>>;
50
47
  getUserWalletAddress(userAddress: string): Promise<string>;
51
48
  getUserBalance(userAddress: string): Promise<bigint>;
package/dist/assets/FT.js CHANGED
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FT = void 0;
4
4
  const ton_1 = require("@ton/ton");
5
+ const ethers_1 = require("ethers");
5
6
  const errors_1 = require("../errors");
6
7
  const Consts_1 = require("../sdk/Consts");
7
8
  const Utils_1 = require("../sdk/Utils");
@@ -12,20 +13,17 @@ const Struct_2 = require("../structs/Struct");
12
13
  const JettonMaster_1 = require("../wrappers/JettonMaster");
13
14
  const JettonWallet_1 = require("../wrappers/JettonWallet");
14
15
  class FT {
15
- get addresses() {
16
- return { tvmAddress: this._tokenAddress.toString(), evmAddress: this._evmAddress };
17
- }
18
16
  get address() {
19
17
  return this._tokenAddress.toString();
20
18
  }
21
- static async getJettonData(contractOpener, tvmAddress) {
22
- Validator_1.Validator.validateTVMAddress(tvmAddress);
23
- const jetton = contractOpener.open(JettonMaster_1.JettonMaster.createFromAddress(ton_1.Address.parse(tvmAddress)));
19
+ static async getJettonData(contractOpener, address) {
20
+ Validator_1.Validator.validateTVMAddress(address);
21
+ const jetton = contractOpener.open(JettonMaster_1.JettonMaster.createFromAddress(ton_1.Address.parse(address)));
24
22
  return await jetton.getJettonData();
25
23
  }
26
- static async getOrigin(contractOpener, address, configuration) {
24
+ static async getOrigin(configuration, address) {
27
25
  const { jettonMinterCode, crossChainLayerAddress, jettonWalletCode } = configuration.TONParams;
28
- const { code: thisCodeBOC } = await contractOpener.getContractState(ton_1.Address.parse(address));
26
+ const { code: thisCodeBOC } = await configuration.TONParams.contractOpener.getContractState(ton_1.Address.parse(address));
29
27
  if (!thisCodeBOC) {
30
28
  throw errors_1.emptyContractError;
31
29
  }
@@ -33,7 +31,7 @@ class FT {
33
31
  if (!jettonMinterCode.equals(thisCode)) {
34
32
  return Struct_2.Origin.TON;
35
33
  }
36
- const jettonMinter = contractOpener.open(JettonMaster_1.JettonMaster.createFromAddress(ton_1.Address.parse(address)));
34
+ const jettonMinter = configuration.TONParams.contractOpener.open(JettonMaster_1.JettonMaster.createFromAddress(ton_1.Address.parse(address)));
37
35
  const evmAddress = await jettonMinter.getEVMAddress();
38
36
  const expectedMinterAddress = await (0, Utils_1.calculateContractAddress)(jettonMinterCode, (0, ton_1.beginCell)()
39
37
  .storeCoins(0)
@@ -48,30 +46,40 @@ class FT {
48
46
  }
49
47
  return Struct_2.Origin.TAC;
50
48
  }
51
- static async getTVMAddress(configuration, evmAddress) {
52
- Validator_1.Validator.validateEVMAddress(evmAddress);
53
- const exists = await configuration.TACParams.tokenUtils['exists(address)'](evmAddress);
49
+ static async getTVMAddress(configuration, address) {
50
+ Validator_1.Validator.validateEVMAddress(address);
51
+ const exists = await configuration.TACParams.tokenUtils['exists(address)'](address);
54
52
  if (exists) {
55
- const erc721Token = configuration.artifacts.tac.wrappers.CrossChainLayerERC20FactoryTAC.connect(evmAddress, configuration.TACParams.provider);
56
- const info = await erc721Token.getInfo();
53
+ const erc20Token = configuration.artifacts.tac.wrappers.CrossChainLayerERC20FactoryTAC.connect(address, configuration.TACParams.provider);
54
+ const info = await erc20Token.getInfo();
57
55
  return info.tvmAddress;
58
56
  }
59
57
  const jettonMaster = JettonMaster_1.JettonMaster.createFromConfig({
60
- evmTokenAddress: evmAddress,
58
+ evmTokenAddress: address,
61
59
  crossChainLayerAddress: ton_1.Address.parse(configuration.TONParams.crossChainLayerAddress),
62
60
  code: configuration.TONParams.jettonMinterCode,
63
61
  walletCode: configuration.TONParams.jettonWalletCode,
64
62
  });
65
63
  return jettonMaster.address.toString();
66
64
  }
67
- constructor(tvmTokenAddress, origin, configuration) {
65
+ constructor(address, origin, configuration) {
68
66
  this.type = Struct_1.AssetType.FT;
69
- this._tokenAddress = ton_1.Address.parse(tvmTokenAddress);
67
+ this._tokenAddress = ton_1.Address.parse(address);
70
68
  this._configuration = configuration;
71
69
  this._jettonMinter = this._configuration.TONParams.contractOpener.open(new JettonMaster_1.JettonMaster(this._tokenAddress));
72
70
  this.origin = origin;
73
71
  this._transferAmount = 0n;
74
72
  }
73
+ static async fromAddress(configuration, address) {
74
+ const tvmAddress = (0, ethers_1.isAddress)(address) ? await this.getTVMAddress(configuration, address) : address;
75
+ const origin = await FT.getOrigin(configuration, tvmAddress).catch((e) => {
76
+ if (e instanceof errors_1.ContractError) {
77
+ return Struct_2.Origin.TAC;
78
+ }
79
+ throw e;
80
+ });
81
+ return new FT(tvmAddress, origin, configuration);
82
+ }
75
83
  get rawAmount() {
76
84
  return this._transferAmount;
77
85
  }
@@ -133,10 +141,9 @@ class FT {
133
141
  }
134
142
  async generatePayload(params) {
135
143
  const { excessReceiver, evmData, crossChainTonAmount = 0n, forwardFeeTonAmount = 0n, feeParams } = params;
136
- const opType = this.origin === Struct_2.Origin.TAC ? InternalStruct_1.AssetOpType.JETTON_BURN : InternalStruct_1.AssetOpType.JETTON_TRANSFER;
137
144
  const feeData = (0, Utils_1.generateFeeData)(feeParams);
138
145
  let payload;
139
- switch (opType) {
146
+ switch (this.opType) {
140
147
  case InternalStruct_1.AssetOpType.JETTON_BURN:
141
148
  payload = this.getBurnPayload(this._transferAmount, this._configuration.TONParams.crossChainLayerAddress, evmData, crossChainTonAmount, feeData);
142
149
  break;
@@ -146,7 +153,7 @@ class FT {
146
153
  }
147
154
  return payload;
148
155
  }
149
- async getOpType() {
156
+ get opType() {
150
157
  return this.origin === 'TAC' ? InternalStruct_1.AssetOpType.JETTON_BURN : InternalStruct_1.AssetOpType.JETTON_TRANSFER;
151
158
  }
152
159
  async getWallet(userAddress) {
@@ -1,30 +1,45 @@
1
1
  import { Address, Cell } from '@ton/ton';
2
2
  import { IConfiguration } from '../structs/Services';
3
- import { Asset, AssetType, ContractOpener, FeeParams, NFTItemData, Origin } from '../structs/Struct';
3
+ import { Asset, AssetType, ContractOpener, EVMAddress, FeeParams, NFTItemData, Origin, TVMAddress } from '../structs/Struct';
4
4
  export declare class NFT implements Asset {
5
5
  private _addresses;
6
6
  readonly origin: Origin;
7
7
  readonly type: AssetType;
8
8
  private _nftCollection;
9
9
  private _configuration;
10
- static fromItem(configuration: IConfiguration, tvmItemAddress: string, origin: Origin): Promise<NFT>;
11
- static fromCollection(configuration: IConfiguration, tvmAddress: {
12
- collection: string;
10
+ /**
11
+ * @description Create NFT from item address. Item MUST BE deployed on TON.
12
+ * @param configuration - Configuration
13
+ * @param item - Item address (TVM address)
14
+ * @param origin - Origin
15
+ * @returns NFT
16
+ */
17
+ static fromItem(configuration: IConfiguration, item: TVMAddress): Promise<NFT>;
18
+ /**
19
+ * @description Create NFT from collection address. TON-native assets MUST BE deployed on TON.
20
+ * @param configuration - Configuration
21
+ * @param item - Item address (TVM address)
22
+ * @param origin - Origin
23
+ * @returns NFT
24
+ */
25
+ static fromCollection(configuration: IConfiguration, item: {
26
+ collection: TVMAddress | EVMAddress;
13
27
  index: bigint;
14
- }, origin: Origin): Promise<NFT>;
15
- static getItemData(contractOpener: ContractOpener, tvmAddress: string): Promise<NFTItemData>;
16
- static getCollectionData(contractOpener: ContractOpener, tvmAddress: string): Promise<{
28
+ }): Promise<NFT>;
29
+ static getItemData(contractOpener: ContractOpener, itemAddress: TVMAddress): Promise<NFTItemData>;
30
+ static getCollectionData(contractOpener: ContractOpener, collectionAddress: TVMAddress): Promise<{
17
31
  nextIndex: number;
18
32
  content: Cell;
19
33
  ownerAddress: Address;
20
34
  }>;
21
- static getOrigin(contractOpener: ContractOpener, tvmAddress: string, configuration: IConfiguration): Promise<Origin>;
22
- static getItemAddress(contractOpener: ContractOpener, tvmCollectionAddress: string, index: bigint): Promise<string>;
23
- static getTVMAddress(configuration: IConfiguration, evmAddress: string, tokenId?: bigint): Promise<string>;
24
- constructor(tvmNFTAddress: {
25
- item: string;
26
- collection: string;
35
+ static getOrigin(configuration: IConfiguration, itemOrCollection: TVMAddress): Promise<Origin>;
36
+ static getItemAddress(contractOpener: ContractOpener, collectionAddress: TVMAddress, index: bigint): Promise<string>;
37
+ static getTVMAddress(configuration: IConfiguration, collectionAddress: EVMAddress, tokenId?: bigint): Promise<string>;
38
+ constructor(nftAddress: {
39
+ item: TVMAddress;
40
+ collection: TVMAddress;
27
41
  index: bigint;
42
+ evmAddress?: EVMAddress;
28
43
  }, origin: Origin, configuration: IConfiguration);
29
44
  get addresses(): {
30
45
  item: string;
@@ -35,12 +50,6 @@ export declare class NFT implements Asset {
35
50
  get address(): string;
36
51
  get rawAmount(): bigint;
37
52
  get clone(): NFT;
38
- getItemData(): Promise<NFTItemData>;
39
- getCollectionData(): Promise<{
40
- nextIndex: number;
41
- content: Cell;
42
- ownerAddress: Address;
43
- }>;
44
53
  withAmount(): Promise<NFT>;
45
54
  addAmount(): Promise<NFT>;
46
55
  getEVMAddress(): Promise<string>;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NFT = void 0;
4
4
  const ton_1 = require("@ton/ton");
5
5
  const wrappers_1 = require("@tonappchain/artifacts/dist/src/ton/wrappers");
6
+ const ethers_1 = require("ethers");
6
7
  const errors_1 = require("../errors");
7
8
  const Consts_1 = require("../sdk/Consts");
8
9
  const Utils_1 = require("../sdk/Utils");
@@ -10,62 +11,97 @@ const Validator_1 = require("../sdk/Validator");
10
11
  const InternalStruct_1 = require("../structs/InternalStruct");
11
12
  const Struct_1 = require("../structs/Struct");
12
13
  class NFT {
13
- static async fromItem(configuration, tvmItemAddress, origin) {
14
- Validator_1.Validator.validateTVMAddress(tvmItemAddress);
15
- const { collectionAddress, index } = await NFT.getItemData(configuration.TONParams.contractOpener, tvmItemAddress);
16
- return new NFT({ item: tvmItemAddress, collection: collectionAddress.toString(), index: BigInt(index) }, origin, configuration);
17
- }
18
- static async fromCollection(configuration, tvmAddress, origin) {
19
- Validator_1.Validator.validateTVMAddress(tvmAddress.collection);
20
- const nftCollection = configuration.TONParams.contractOpener.open(wrappers_1.NFTCollection.createFromAddress(ton_1.Address.parse(tvmAddress.collection)));
21
- const itemAddress = await nftCollection.getNFTAddressByIndex(tvmAddress.index);
22
- return new NFT({ item: itemAddress.toString(), collection: tvmAddress.collection, index: tvmAddress.index }, origin, configuration);
23
- }
24
- static async getItemData(contractOpener, tvmAddress) {
25
- Validator_1.Validator.validateTVMAddress(tvmAddress);
26
- const nftItem = contractOpener.open(wrappers_1.NFTItem.createFromAddress(ton_1.Address.parse(tvmAddress)));
14
+ /**
15
+ * @description Create NFT from item address. Item MUST BE deployed on TON.
16
+ * @param configuration - Configuration
17
+ * @param item - Item address (TVM address)
18
+ * @param origin - Origin
19
+ * @returns NFT
20
+ */
21
+ static async fromItem(configuration, item) {
22
+ Validator_1.Validator.validateTVMAddress(item);
23
+ const nftItem = configuration.TONParams.contractOpener.open(wrappers_1.NFTItem.createFromAddress(ton_1.Address.parse(item)));
24
+ const { collectionAddress, index } = await nftItem.getNFTData();
25
+ const origin = await NFT.getOrigin(configuration, item);
26
+ return new NFT({ item, collection: collectionAddress.toString(), index: BigInt(index) }, origin, configuration);
27
+ }
28
+ /**
29
+ * @description Create NFT from collection address. TON-native assets MUST BE deployed on TON.
30
+ * @param configuration - Configuration
31
+ * @param item - Item address (TVM address)
32
+ * @param origin - Origin
33
+ * @returns NFT
34
+ */
35
+ static async fromCollection(configuration, item) {
36
+ const tvmCollectionAddress = (0, ethers_1.isAddress)(item.collection)
37
+ ? await this.getTVMAddress(configuration, item.collection)
38
+ : item.collection;
39
+ const origin = await NFT.getOrigin(configuration, tvmCollectionAddress).catch((e) => {
40
+ if (e instanceof errors_1.ContractError) {
41
+ return Struct_1.Origin.TAC;
42
+ }
43
+ throw e;
44
+ });
45
+ const nftCollection = configuration.TONParams.contractOpener.open(wrappers_1.NFTCollection.createFromAddress(ton_1.Address.parse(tvmCollectionAddress)));
46
+ const itemAddress = origin === Struct_1.Origin.TAC
47
+ ? wrappers_1.NFTItem.createFromConfig({
48
+ collectionAddress: nftCollection.address,
49
+ cclAddress: ton_1.Address.parse(configuration.TONParams.crossChainLayerAddress),
50
+ // @ts-expect-error // bigint can be used, wrapper is not typed properly
51
+ index: item.index,
52
+ }, configuration.TONParams.nftItemCode).address
53
+ : await nftCollection.getNFTAddressByIndex(item.index);
54
+ return new NFT({
55
+ item: itemAddress.toString(),
56
+ collection: tvmCollectionAddress,
57
+ index: item.index,
58
+ evmAddress: (0, ethers_1.isAddress)(item.collection) ? item.collection : undefined,
59
+ }, origin, configuration);
60
+ }
61
+ static async getItemData(contractOpener, itemAddress) {
62
+ Validator_1.Validator.validateTVMAddress(itemAddress);
63
+ const nftItem = contractOpener.open(wrappers_1.NFTItem.createFromAddress(ton_1.Address.parse(itemAddress)));
27
64
  return nftItem.getNFTData();
28
65
  }
29
- static async getCollectionData(contractOpener, tvmAddress) {
30
- Validator_1.Validator.validateTVMAddress(tvmAddress);
31
- const nftCollection = contractOpener.open(wrappers_1.NFTCollection.createFromAddress(ton_1.Address.parse(tvmAddress)));
66
+ static async getCollectionData(contractOpener, collectionAddress) {
67
+ Validator_1.Validator.validateTVMAddress(collectionAddress);
68
+ const nftCollection = contractOpener.open(wrappers_1.NFTCollection.createFromAddress(ton_1.Address.parse(collectionAddress)));
32
69
  return nftCollection.getCollectionData();
33
70
  }
34
- static async getOrigin(contractOpener, tvmAddress, configuration) {
35
- const { nftItemCode } = configuration.TONParams;
36
- const { code: itemCodeBOC } = await contractOpener.getContractState(ton_1.Address.parse(tvmAddress));
37
- if (!itemCodeBOC) {
71
+ static async getOrigin(configuration, itemOrCollection) {
72
+ const { nftItemCode, nftCollectionCode } = configuration.TONParams;
73
+ const { code: givenCodeBOC } = await configuration.TONParams.contractOpener.getContractState(ton_1.Address.parse(itemOrCollection));
74
+ if (!givenCodeBOC) {
38
75
  throw errors_1.emptyContractError;
39
76
  }
40
- const givenNFTItemCode = ton_1.Cell.fromBoc(itemCodeBOC)[0];
41
- if (!nftItemCode.equals(givenNFTItemCode)) {
42
- return Struct_1.Origin.TON;
77
+ const givenNFTCode = ton_1.Cell.fromBoc(givenCodeBOC)[0];
78
+ if (nftItemCode.equals(givenNFTCode) || nftCollectionCode.equals(givenNFTCode)) {
79
+ return Struct_1.Origin.TAC;
43
80
  }
44
- return Struct_1.Origin.TAC;
81
+ return Struct_1.Origin.TON;
45
82
  }
46
- static getItemAddress(contractOpener, tvmCollectionAddress, index) {
47
- Validator_1.Validator.validateTVMAddress(tvmCollectionAddress);
48
- const nftCollection = contractOpener.open(wrappers_1.NFTCollection.createFromAddress(ton_1.Address.parse(tvmCollectionAddress)));
83
+ static getItemAddress(contractOpener, collectionAddress, index) {
84
+ Validator_1.Validator.validateTVMAddress(collectionAddress);
85
+ const nftCollection = contractOpener.open(wrappers_1.NFTCollection.createFromAddress(ton_1.Address.parse(collectionAddress)));
49
86
  return nftCollection.getNFTAddressByIndex(index).then(toString);
50
87
  }
51
- static async getTVMAddress(configuration, evmAddress, tokenId) {
52
- Validator_1.Validator.validateEVMAddress(evmAddress);
53
- let nftCollection;
54
- const exists = await configuration.TACParams.tokenUtils['exists(address)'](evmAddress);
88
+ static async getTVMAddress(configuration, collectionAddress, tokenId) {
89
+ Validator_1.Validator.validateEVMAddress(collectionAddress);
90
+ const exists = await configuration.TACParams.tokenUtils['exists(address)'](collectionAddress);
55
91
  if (exists) {
56
- const erc721Token = configuration.artifacts.tac.wrappers.CrossChainLayerERC721FactoryTAC.connect(evmAddress, configuration.TACParams.provider);
92
+ const erc721Token = configuration.artifacts.tac.wrappers.CrossChainLayerERC721FactoryTAC.connect(collectionAddress, configuration.TACParams.provider);
57
93
  const info = await erc721Token.getInfo();
58
- nftCollection = configuration.TONParams.contractOpener.open(wrappers_1.NFTCollection.createFromAddress((0, ton_1.address)(info.tvmAddress)));
94
+ const nftCollection = configuration.TONParams.contractOpener.open(wrappers_1.NFTCollection.createFromAddress((0, ton_1.address)(info.tvmAddress)));
59
95
  return tokenId == undefined
60
96
  ? nftCollection.address.toString()
61
97
  : (await nftCollection.getNFTAddressByIndex(tokenId)).toString();
62
98
  }
63
99
  else {
64
- nftCollection = configuration.TONParams.contractOpener.open(wrappers_1.NFTCollection.createFromConfig({
100
+ const nftCollection = configuration.TONParams.contractOpener.open(wrappers_1.NFTCollection.createFromConfig({
65
101
  ownerAddress: ton_1.Address.parse(configuration.TONParams.crossChainLayerAddress),
66
102
  content: (0, ton_1.beginCell)().endCell(),
67
103
  nftItemCode: configuration.TONParams.nftItemCode,
68
- originalAddress: evmAddress,
104
+ originalAddress: collectionAddress,
69
105
  }, configuration.TONParams.nftCollectionCode));
70
106
  return tokenId == undefined
71
107
  ? nftCollection.address.toString()
@@ -77,9 +113,9 @@ class NFT {
77
113
  }, configuration.TONParams.nftItemCode).address.toString();
78
114
  }
79
115
  }
80
- constructor(tvmNFTAddress, origin, configuration) {
116
+ constructor(nftAddress, origin, configuration) {
81
117
  this.type = Struct_1.AssetType.NFT;
82
- this._addresses = tvmNFTAddress;
118
+ this._addresses = nftAddress;
83
119
  this._configuration = configuration;
84
120
  this.origin = origin;
85
121
  this._nftCollection = configuration.TONParams.contractOpener.open(wrappers_1.NFTCollection.createFromAddress(ton_1.Address.parse(this._addresses.collection)));
@@ -96,12 +132,6 @@ class NFT {
96
132
  get clone() {
97
133
  return new NFT(this._addresses, this.origin, this._configuration);
98
134
  }
99
- async getItemData() {
100
- return NFT.getItemData(this._configuration.TONParams.contractOpener, this._addresses.item);
101
- }
102
- async getCollectionData() {
103
- return NFT.getCollectionData(this._configuration.TONParams.contractOpener, this._addresses.collection);
104
- }
105
135
  async withAmount() {
106
136
  return this;
107
137
  }
@@ -20,5 +20,5 @@ export declare const noValidGroupFoundError: NoValidGroupFoundError;
20
20
  export declare const allEndpointsFailedError: (inner: unknown) => FetchError;
21
21
  export declare const allContractOpenerFailedError: (inner: unknown) => FetchError;
22
22
  export declare const insufficientBalanceError: (token: string) => InsufficientBalanceError;
23
- export declare const unknownTokenTypeError: (token: string) => TokenError;
23
+ export declare const unknownTokenTypeError: (token: string, reason?: string) => TokenError;
24
24
  export declare const indexRequiredError: (token: string) => TokenError;
@@ -41,7 +41,7 @@ const allContractOpenerFailedError = (inner) => new errors_1.FetchError('All con
41
41
  exports.allContractOpenerFailedError = allContractOpenerFailedError;
42
42
  const insufficientBalanceError = (token) => new errors_1.InsufficientBalanceError(`Insufficient balance of ${token}`, 120);
43
43
  exports.insufficientBalanceError = insufficientBalanceError;
44
- const unknownTokenTypeError = (token) => new errors_1.TokenError(`Unknown token type of ${token}`, 121);
44
+ const unknownTokenTypeError = (token, reason) => new errors_1.TokenError(`Unknown token type of ${token}: ${reason}`, 121);
45
45
  exports.unknownTokenTypeError = unknownTokenTypeError;
46
46
  const indexRequiredError = (token) => new errors_1.TokenError(`Index is required for collection ${token}`, 122);
47
47
  exports.indexRequiredError = indexRequiredError;
@@ -194,8 +194,15 @@ class TransactionManager {
194
194
  if (assets == undefined) {
195
195
  assets = [];
196
196
  }
197
+ const tonAssets = [...assets];
198
+ if (value > 0n) {
199
+ tonAssets.push(await (await assets_1.AssetFactory.from(this.config, {
200
+ address: await this.config.nativeTACAddress(),
201
+ tokenType: Struct_1.AssetType.FT,
202
+ })).withAmount({ rawAmount: value }));
203
+ }
197
204
  Validator_1.Validator.validateTVMAddress(tonTarget);
198
- const suggestedTONExecutorFee = await this.simulator.getTVMExecutorFeeInfo(assets, Consts_1.TAC_SYMBOL);
205
+ const suggestedTONExecutorFee = await this.simulator.getTVMExecutorFeeInfo(tonAssets, Consts_1.TAC_SYMBOL);
199
206
  this.logger.debug(`Suggested TON executor fee: ${(0, Utils_1.formatObjectForLogging)(suggestedTONExecutorFee)}`);
200
207
  const crossChainLayerAddress = await this.config.TACParams.crossChainLayer.getAddress();
201
208
  for (const asset of assets) {
@@ -35,7 +35,7 @@ class Validator {
35
35
  }
36
36
  }
37
37
  static validateEVMAddress(address) {
38
- if (!(0, ethers_1.isAddress)(address)) {
38
+ if (!address.startsWith('0x') || !(0, ethers_1.isAddress)(address)) {
39
39
  throw (0, instances_1.evmAddressError)(address);
40
40
  }
41
41
  }
@@ -354,3 +354,5 @@ export declare enum Origin {
354
354
  TON = "TON",
355
355
  TAC = "TAC"
356
356
  }
357
+ export type TVMAddress = string;
358
+ export type EVMAddress = string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tonappchain/sdk",
3
- "version": "0.7.0-rc6",
3
+ "version": "0.7.0-rc7.1",
4
4
  "repository": "https://github.com/TacBuild/tac-sdk.git",
5
5
  "author": "TAC. <developers@tac>",
6
6
  "license": "MIT",