@tonappchain/sdk 0.6.6-mainnet-alpha → 0.7.0-rc10

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 (97) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +191 -191
  3. package/dist/adapters/contractOpener.d.ts +6 -5
  4. package/dist/adapters/contractOpener.js +6 -6
  5. package/dist/adapters/retryableContractOpener.d.ts +9 -5
  6. package/dist/adapters/retryableContractOpener.js +2 -2
  7. package/dist/assets/AssetCache.d.ts +23 -0
  8. package/dist/assets/AssetCache.js +36 -0
  9. package/dist/assets/AssetFactory.d.ts +7 -0
  10. package/dist/assets/AssetFactory.js +46 -0
  11. package/dist/assets/FT.d.ts +58 -0
  12. package/dist/assets/FT.js +231 -0
  13. package/dist/assets/NFT.d.ts +65 -0
  14. package/dist/assets/NFT.js +210 -0
  15. package/dist/assets/TON.d.ts +38 -0
  16. package/dist/assets/TON.js +91 -0
  17. package/dist/assets/index.d.ts +4 -0
  18. package/dist/assets/index.js +11 -0
  19. package/dist/errors/errors.d.ts +6 -0
  20. package/dist/errors/errors.js +15 -1
  21. package/dist/errors/index.d.ts +2 -2
  22. package/dist/errors/index.js +26 -22
  23. package/dist/errors/instances.d.ts +4 -1
  24. package/dist/errors/instances.js +11 -2
  25. package/dist/index.d.ts +7 -0
  26. package/dist/index.js +14 -1
  27. package/dist/interfaces/IAsset.d.ts +73 -0
  28. package/dist/interfaces/IAsset.js +2 -0
  29. package/dist/interfaces/IConfiguration.d.ts +35 -0
  30. package/dist/interfaces/IConfiguration.js +2 -0
  31. package/dist/interfaces/IContractOpener.d.ts +21 -0
  32. package/dist/interfaces/IContractOpener.js +2 -0
  33. package/dist/interfaces/IHttpClient.d.ts +16 -0
  34. package/dist/interfaces/IHttpClient.js +2 -0
  35. package/dist/interfaces/ILiteSequencerClient.d.ts +30 -0
  36. package/dist/interfaces/ILiteSequencerClient.js +2 -0
  37. package/dist/interfaces/ILiteSequencerClientFactory.d.ts +9 -0
  38. package/dist/interfaces/ILiteSequencerClientFactory.js +2 -0
  39. package/dist/interfaces/ILogger.d.ts +10 -0
  40. package/dist/interfaces/ILogger.js +2 -0
  41. package/dist/interfaces/IOperationTracker.d.ts +66 -0
  42. package/dist/interfaces/IOperationTracker.js +2 -0
  43. package/dist/interfaces/ISender.d.ts +35 -0
  44. package/dist/interfaces/ISender.js +2 -0
  45. package/dist/interfaces/ISimulator.d.ts +47 -0
  46. package/dist/interfaces/ISimulator.js +2 -0
  47. package/dist/interfaces/ITacSDK.d.ts +147 -0
  48. package/dist/interfaces/ITacSDK.js +2 -0
  49. package/dist/interfaces/ITransactionManager.d.ts +35 -0
  50. package/dist/interfaces/ITransactionManager.js +2 -0
  51. package/dist/interfaces/IWallet.d.ts +20 -0
  52. package/dist/interfaces/IWallet.js +2 -0
  53. package/dist/interfaces/index.d.ts +13 -0
  54. package/dist/interfaces/index.js +29 -0
  55. package/dist/sdk/AxiosHttpClient.d.ts +12 -0
  56. package/dist/sdk/AxiosHttpClient.js +23 -0
  57. package/dist/sdk/Configuration.d.ts +21 -0
  58. package/dist/sdk/Configuration.js +90 -0
  59. package/dist/sdk/LiteSequencerClient.d.ts +6 -2
  60. package/dist/sdk/LiteSequencerClient.js +58 -14
  61. package/dist/sdk/Logger.d.ts +13 -0
  62. package/dist/sdk/Logger.js +25 -0
  63. package/dist/sdk/OperationTracker.d.ts +10 -5
  64. package/dist/sdk/OperationTracker.js +87 -45
  65. package/dist/sdk/Simulator.d.ts +17 -0
  66. package/dist/sdk/Simulator.js +163 -0
  67. package/dist/sdk/StartTracking.d.ts +6 -0
  68. package/dist/sdk/StartTracking.js +69 -32
  69. package/dist/sdk/TacSdk.d.ts +27 -44
  70. package/dist/sdk/TacSdk.js +121 -816
  71. package/dist/sdk/TransactionManager.d.ts +22 -0
  72. package/dist/sdk/TransactionManager.js +272 -0
  73. package/dist/sdk/TxFinalizer.d.ts +10 -0
  74. package/dist/sdk/TxFinalizer.js +104 -0
  75. package/dist/sdk/Utils.d.ts +7 -2
  76. package/dist/sdk/Utils.js +43 -24
  77. package/dist/sdk/Validator.d.ts +9 -0
  78. package/dist/sdk/Validator.js +43 -0
  79. package/dist/sender/BatchSender.d.ts +7 -5
  80. package/dist/sender/BatchSender.js +18 -6
  81. package/dist/sender/RawSender.d.ts +11 -6
  82. package/dist/sender/RawSender.js +46 -18
  83. package/dist/sender/SenderFactory.d.ts +2 -2
  84. package/dist/sender/SenderFactory.js +5 -4
  85. package/dist/sender/TonConnectSender.d.ts +7 -5
  86. package/dist/sender/TonConnectSender.js +14 -10
  87. package/dist/sender/index.d.ts +2 -2
  88. package/dist/sender/index.js +2 -2
  89. package/dist/structs/InternalStruct.d.ts +52 -33
  90. package/dist/structs/Struct.d.ts +92 -94
  91. package/dist/structs/Struct.js +11 -1
  92. package/dist/wrappers/HighloadQueryId.js +0 -1
  93. package/dist/wrappers/HighloadWalletV3.d.ts +4 -3
  94. package/dist/wrappers/HighloadWalletV3.js +5 -2
  95. package/package.json +67 -67
  96. package/dist/sender/SenderAbstraction.d.ts +0 -20
  97. package/dist/sender/SenderAbstraction.js +0 -5
@@ -1,867 +1,172 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
5
35
  Object.defineProperty(exports, "__esModule", { value: true });
6
36
  exports.TacSdk = void 0;
7
- const ton_1 = require("@ton/ton");
8
- const artifacts_1 = require("@tonappchain/artifacts");
9
- const wrappers_1 = require("@tonappchain/artifacts/dist/src/ton/wrappers");
10
- const axios_1 = __importDefault(require("axios"));
11
- const ethers_1 = require("ethers");
12
- const errors_1 = require("../errors");
13
- const instances_1 = require("../errors/instances");
14
- const retryableContractOpener_1 = require("../adapters/retryableContractOpener");
15
- // import internal structs
16
- const InternalStruct_1 = require("../structs/InternalStruct");
17
- // import structs
37
+ const assets_1 = require("../assets");
18
38
  const Struct_1 = require("../structs/Struct");
19
- // jetton imports
20
- const JettonMaster_1 = require("../wrappers/JettonMaster");
21
- const JettonWallet_1 = require("../wrappers/JettonWallet");
22
- // ton settings
23
- const Settings_1 = require("../wrappers/Settings");
39
+ const Configuration_1 = require("./Configuration");
24
40
  const Consts_1 = require("./Consts");
41
+ const Logger_1 = require("./Logger");
25
42
  const OperationTracker_1 = require("./OperationTracker");
26
- const Utils_1 = require("./Utils");
43
+ const Simulator_1 = require("./Simulator");
44
+ const TransactionManager_1 = require("./TransactionManager");
27
45
  class TacSdk {
28
- constructor(network, delay, artifacts, TONParams, TACParams, liteSequencerEndpoints, debug) {
29
- this.network = network;
30
- this.delay = delay;
31
- this.artifacts = artifacts;
32
- this.TONParams = TONParams;
33
- this.TACParams = TACParams;
34
- this.liteSequencerEndpoints = liteSequencerEndpoints;
35
- this.debug = debug;
36
- this.operationTracker = new OperationTracker_1.OperationTracker(network, liteSequencerEndpoints, debug);
46
+ constructor(config, simulator, transactionManager) {
47
+ this.config = config;
48
+ this.simulator = simulator;
49
+ this.transactionManager = transactionManager;
37
50
  }
38
- static async create(sdkParams) {
51
+ static async create(sdkParams, logger = new Logger_1.NoopLogger()) {
39
52
  const network = sdkParams.network;
40
53
  const delay = sdkParams.delay ?? Consts_1.DEFAULT_DELAY;
41
- const artifacts = network === Struct_1.Network.TESTNET ? artifacts_1.testnet : artifacts_1.mainnet;
42
- const TONParams = await this.prepareTONParams(delay, artifacts, sdkParams.TONParams);
43
- const TACParams = await this.prepareTACParams(artifacts, delay, sdkParams.TACParams);
44
- const debug = sdkParams.debug ?? false;
45
- const liteSequencerEndpoints = sdkParams.customLiteSequencerEndpoints ??
46
- (network === Struct_1.Network.TESTNET
47
- ? artifacts_1.testnet.PUBLIC_LITE_SEQUENCER_ENDPOINTS
48
- : artifacts_1.mainnet.PUBLIC_LITE_SEQUENCER_ENDPOINTS);
49
- return new TacSdk(network, delay, artifacts, TONParams, TACParams, liteSequencerEndpoints, debug);
50
- }
51
- static async prepareTONParams(delay, artifacts, TONParams) {
52
- const contractOpener = TONParams?.contractOpener ?? (await (0, retryableContractOpener_1.createDefaultRetryableOpener)(artifacts));
53
- const settingsAddress = TONParams?.settingsAddress ?? artifacts.TON_SETTINGS_ADDRESS;
54
- const settings = contractOpener.open(new Settings_1.Settings(ton_1.Address.parse(settingsAddress)));
55
- const jettonProxyAddress = await settings.getAddressSetting('JettonProxyAddress');
56
- await (0, Utils_1.sleep)(delay * 1000);
57
- const crossChainLayerAddress = await settings.getAddressSetting('CrossChainLayerAddress');
58
- await (0, Utils_1.sleep)(delay * 1000);
59
- const jettonMinterCode = await settings.getCellSetting('JettonMinterCode');
60
- await (0, Utils_1.sleep)(delay * 1000);
61
- const jettonWalletCode = await settings.getCellSetting('JettonWalletCode');
62
- await (0, Utils_1.sleep)(delay * 1000);
63
- const nftProxyAddress = await settings.getAddressSetting('NFTProxyAddress');
64
- await (0, Utils_1.sleep)(delay * 1000);
65
- const nftItemCode = await settings.getCellSetting('NFTItemCode');
66
- await (0, Utils_1.sleep)(delay * 1000);
67
- const nftCollectionCode = await settings.getCellSetting('NFTCollectionCode');
68
- await (0, Utils_1.sleep)(delay * 1000);
69
- return {
70
- contractOpener,
71
- jettonProxyAddress,
72
- crossChainLayerAddress,
73
- jettonMinterCode,
74
- jettonWalletCode,
75
- nftProxyAddress,
76
- nftItemCode,
77
- nftCollectionCode,
78
- };
79
- }
80
- static async prepareTACParams(artifacts, delay, TACParams) {
81
- const provider = TACParams?.provider ?? ethers_1.ethers.getDefaultProvider(artifacts.TAC_RPC_ENDPOINT);
82
- const settingsAddress = TACParams?.settingsAddress?.toString() ?? artifacts.TAC_SETTINGS_ADDRESS;
83
- const settings = artifacts.tac.wrappers.SettingsFactoryTAC.connect(settingsAddress, provider);
84
- const crossChainLayerABI = TACParams?.crossChainLayerABI ?? artifacts.tac.compilationArtifacts.CrossChainLayer.abi;
85
- const crossChainLayerAddress = await settings.getAddressSetting((0, ethers_1.keccak256)((0, ethers_1.toUtf8Bytes)('CrossChainLayerAddress')));
86
- const crossChainLayer = artifacts.tac.wrappers.CrossChainLayerFactoryTAC.connect(crossChainLayerAddress, provider);
87
- await (0, Utils_1.sleep)(delay * 1000);
88
- const tokenUtilsAddress = await settings.getAddressSetting((0, ethers_1.keccak256)((0, ethers_1.toUtf8Bytes)('TokenUtilsAddress')));
89
- const tokenUtils = artifacts.tac.wrappers.TokenUtilsFactoryTAC.connect(tokenUtilsAddress, provider);
90
- await (0, Utils_1.sleep)(delay * 1000);
91
- const trustedTACExecutors = await settings.getTrustedEVMExecutors();
92
- await (0, Utils_1.sleep)(delay * 1000);
93
- const trustedTONExecutors = await settings.getTrustedTVMExecutors();
94
- const crossChainLayerTokenABI = TACParams?.crossChainLayerTokenABI ?? artifacts.tac.compilationArtifacts.CrossChainLayerToken.abi;
95
- const crossChainLayerTokenBytecode = TACParams?.crossChainLayerTokenBytecode ?? artifacts.tac.compilationArtifacts.CrossChainLayerToken.bytecode;
96
- const crossChainLayerNFTABI = TACParams?.crossChainLayerNFTABI ?? artifacts.tac.compilationArtifacts.CrossChainLayerNFT.abi;
97
- const crossChainLayerNFTBytecode = TACParams?.crossChainLayerNFTBytecode ?? artifacts.tac.compilationArtifacts.CrossChainLayerNFT.bytecode;
98
- return {
99
- provider,
100
- settings,
101
- tokenUtils,
102
- crossChainLayer,
103
- trustedTACExecutors,
104
- trustedTONExecutors,
105
- abiCoder: new ethers_1.ethers.AbiCoder(),
106
- crossChainLayerABI,
107
- crossChainLayerTokenABI,
108
- crossChainLayerTokenBytecode,
109
- crossChainLayerNFTABI,
110
- crossChainLayerNFTBytecode,
111
- };
54
+ const { testnet, mainnet } = await Promise.resolve().then(() => __importStar(require('@tonappchain/artifacts')));
55
+ const artifacts = network === Struct_1.Network.TESTNET ? testnet : mainnet;
56
+ const config = await Configuration_1.Configuration.create(network, artifacts, sdkParams.TONParams, sdkParams.TACParams, sdkParams.customLiteSequencerEndpoints, delay);
57
+ const simulator = new Simulator_1.Simulator(config, logger);
58
+ const operationTracker = new OperationTracker_1.OperationTracker(network, config.liteSequencerEndpoints);
59
+ const transactionManager = new TransactionManager_1.TransactionManager(config, simulator, operationTracker, logger);
60
+ return new TacSdk(config, simulator, transactionManager);
112
61
  }
113
62
  closeConnections() {
114
- return this.TONParams.contractOpener.closeConnections?.call(this);
63
+ return this.config.closeConnections();
115
64
  }
116
65
  get nativeTONAddress() {
117
- return 'NONE';
66
+ return this.config.nativeTONAddress;
118
67
  }
119
68
  async nativeTACAddress() {
120
- return this.TACParams.crossChainLayer.NATIVE_TOKEN_ADDRESS.staticCall();
121
- }
122
- async getUserJettonWalletAddress(userAddress, tokenAddress) {
123
- const jettonMaster = this.TONParams.contractOpener.open(new JettonMaster_1.JettonMaster(ton_1.Address.parse(tokenAddress)));
124
- return jettonMaster.getWalletAddress(userAddress);
125
- }
126
- async getUserJettonBalance(userAddress, tokenAddress) {
127
- const jettonMaster = this.TONParams.contractOpener.open(new JettonMaster_1.JettonMaster(ton_1.Address.parse(tokenAddress)));
128
- const userJettonWalletAddress = await jettonMaster.getWalletAddress(userAddress);
129
- await (0, Utils_1.sleep)(this.delay * 1000);
130
- const userJettonWallet = this.TONParams.contractOpener.open(new JettonWallet_1.JettonWallet(ton_1.Address.parse(userJettonWalletAddress)));
131
- return userJettonWallet.getJettonBalance();
69
+ return this.config.nativeTACAddress();
132
70
  }
133
- async getUserJettonBalanceExtended(userAddress, tokenAddress) {
134
- const masterAddress = ton_1.Address.parse(tokenAddress);
135
- const masterState = await this.TONParams.contractOpener.getContractState(masterAddress);
136
- if (masterState.state !== 'active') {
137
- return { exists: false };
138
- }
139
- await (0, Utils_1.sleep)(this.delay * 1000);
140
- const jettonMaster = this.TONParams.contractOpener.open(new JettonMaster_1.JettonMaster(masterAddress));
141
- const userJettonWalletAddress = await jettonMaster.getWalletAddress(userAddress);
142
- await (0, Utils_1.sleep)(this.delay * 1000);
143
- const userJettonWallet = this.TONParams.contractOpener.open(new JettonWallet_1.JettonWallet(ton_1.Address.parse(userJettonWalletAddress)));
144
- const rawAmount = await userJettonWallet.getJettonBalance();
145
- const decimalsRaw = (await jettonMaster.getJettonData()).content.metadata.decimals;
146
- const decimals = decimalsRaw ? Number(decimalsRaw) : 9;
147
- return {
148
- rawAmount,
149
- decimals,
150
- amount: (0, Utils_1.calculateAmount)(rawAmount, decimals),
151
- exists: true,
152
- };
153
- }
154
- getJettonTransferPayload(jettonData, responseAddress, evmData, crossChainTonAmount, forwardFeeAmount, feeData) {
155
- const queryId = (0, Utils_1.generateRandomNumberByTimestamp)().randomNumber;
156
- return JettonWallet_1.JettonWallet.transferMessage(jettonData.rawAmount, this.TONParams.jettonProxyAddress, responseAddress, Consts_1.JETTON_TRANSFER_FORWARD_TON_AMOUNT + forwardFeeAmount + crossChainTonAmount, crossChainTonAmount, feeData, evmData, queryId);
157
- }
158
- getJettonBurnPayload(jettonData, evmData, crossChainTonAmount, feeData) {
159
- const queryId = (0, Utils_1.generateRandomNumberByTimestamp)().randomNumber;
160
- return JettonWallet_1.JettonWallet.burnMessage(jettonData.rawAmount, jettonData.notificationReceiverAddress, crossChainTonAmount, feeData, evmData, queryId);
161
- }
162
- getNFTBurnPayload(burnData) {
163
- const queryId = (0, Utils_1.generateRandomNumberByTimestamp)().randomNumber;
164
- return wrappers_1.NFTItem.burnMessage(queryId, (0, ton_1.address)(burnData.notificationReceiverAddress), burnData.crossChainTonAmount ?? 0, burnData.evmData, burnData.feeData);
165
- }
166
- getNFTTransferPayload(transferData, forwardFeeAmount) {
167
- const queryId = (0, Utils_1.generateRandomNumberByTimestamp)().randomNumber;
168
- const crossChainTonAmount = transferData.crossChainTonAmount ?? 0n;
169
- const forwardPayload = (0, ton_1.beginCell)()
170
- .storeCoins(crossChainTonAmount)
171
- .storeMaybeRef(transferData.feeData)
172
- .storeMaybeRef(transferData.evmData)
173
- .endCell();
174
- return wrappers_1.NFTItem.transferMessage(queryId, (0, ton_1.address)(transferData.to ?? this.TONParams.nftProxyAddress), (0, ton_1.address)(transferData.responseAddress), Number((0, ton_1.fromNano)(Consts_1.NFT_TRANSFER_FORWARD_TON_AMOUNT + forwardFeeAmount + crossChainTonAmount)), forwardPayload);
175
- }
176
- getTonTransferPayload(responseAddress, evmData, crossChainTonAmount, feeParams) {
177
- const queryId = (0, Utils_1.generateRandomNumberByTimestamp)().randomNumber;
178
- const feeData = (0, Utils_1.generateFeeData)(feeParams);
179
- return (0, ton_1.beginCell)()
180
- .storeUint(this.artifacts.ton.wrappers.CrossChainLayerOpCodes.anyone_tvmMsgToEVM, 32)
181
- .storeUint(queryId, 64)
182
- .storeUint(this.artifacts.ton.wrappers.OperationType.tonTransfer, 32)
183
- .storeCoins(crossChainTonAmount)
184
- .storeMaybeRef(feeData)
185
- .storeAddress(ton_1.Address.parse(responseAddress))
186
- .storeMaybeRef(evmData)
187
- .endCell();
188
- }
189
- debugLog(message) {
190
- if (this.debug) {
191
- console.log(`[TacSdk Debug] ${message}`);
192
- }
71
+ get getTrustedTACExecutors() {
72
+ return this.config.getTrustedTACExecutors;
193
73
  }
194
- async getJettonOpType(asset) {
195
- this.debugLog(`Getting jetton op type for ${(0, Utils_1.formatObjectForLogging)(asset)}`);
196
- const { code: givenMinterCodeBOC } = await this.TONParams.contractOpener.getContractState((0, ton_1.address)(asset.address));
197
- if (!givenMinterCodeBOC) {
198
- throw errors_1.emptyContractError;
199
- }
200
- const givenMinterCode = ton_1.Cell.fromBoc(givenMinterCodeBOC)[0];
201
- await (0, Utils_1.sleep)(this.delay * 1000);
202
- if (!this.TONParams.jettonMinterCode.equals(givenMinterCode)) {
203
- this.debugLog(`Jetton ${(0, Utils_1.formatObjectForLogging)(asset)} requires JETTON_TRANSFER operation`);
204
- return InternalStruct_1.AssetOpType.JETTON_TRANSFER;
205
- }
206
- const givenMinter = this.TONParams.contractOpener.open(new JettonMaster_1.JettonMaster((0, ton_1.address)(asset.address)));
207
- const evmAddress = await givenMinter.getEVMAddress();
208
- await (0, Utils_1.sleep)(this.delay * 1000);
209
- this.debugLog(`Jetton ${(0, Utils_1.formatObjectForLogging)(asset)} has evm address ${evmAddress}`);
210
- const expectedMinterAddress = await (0, Utils_1.calculateContractAddress)(this.TONParams.jettonMinterCode, (0, ton_1.beginCell)()
211
- .storeCoins(0)
212
- .storeAddress((0, ton_1.address)(this.TONParams.crossChainLayerAddress))
213
- .storeAddress(null)
214
- .storeRef((0, ton_1.beginCell)().endCell())
215
- .storeRef(this.TONParams.jettonWalletCode)
216
- .storeStringTail(evmAddress)
217
- .endCell());
218
- if (!expectedMinterAddress.equals(givenMinter.address)) {
219
- this.debugLog(`Jetton ${(0, Utils_1.formatObjectForLogging)(asset)} requires JETTON_TRANSFER operation`);
220
- return InternalStruct_1.AssetOpType.JETTON_TRANSFER;
221
- }
222
- this.debugLog(`Jetton ${(0, Utils_1.formatObjectForLogging)(asset)} requires JETTON_BURN operation`);
223
- return InternalStruct_1.AssetOpType.JETTON_BURN;
74
+ get getTrustedTONExecutors() {
75
+ return this.config.getTrustedTONExecutors;
224
76
  }
225
- async getNFTOpType(asset) {
226
- this.debugLog(`Getting NFT op type for ${(0, Utils_1.formatObjectForLogging)(asset)}`);
227
- const { code: itemCodeBOC } = await this.TONParams.contractOpener.getContractState((0, ton_1.address)(asset.address));
228
- if (!itemCodeBOC) {
229
- throw errors_1.emptyContractError;
230
- }
231
- const givenNFTItemCode = ton_1.Cell.fromBoc(itemCodeBOC)[0];
232
- await (0, Utils_1.sleep)(this.delay * 1000);
233
- if (!this.TONParams.nftItemCode.equals(givenNFTItemCode)) {
234
- this.debugLog(`NFT ${(0, Utils_1.formatObjectForLogging)(asset)} requires NFT_TRANSFER operation`);
235
- return InternalStruct_1.AssetOpType.NFT_TRANSFER;
236
- }
237
- this.debugLog(`NFT ${(0, Utils_1.formatObjectForLogging)(asset)} requires NFT_BURN operation`);
238
- return InternalStruct_1.AssetOpType.NFT_BURN;
77
+ async getTransactionSimulationInfo(evmProxyMsg, sender, assets) {
78
+ return this.simulator.getTransactionSimulationInfo(evmProxyMsg, sender, assets);
239
79
  }
240
- async getNFTItemAddressTON(collectionAddress, itemIndex) {
241
- (0, Utils_1.validateTVMAddress)(collectionAddress);
242
- const nftCollection = this.TONParams.contractOpener.open(wrappers_1.NFTCollection.createFromAddress((0, ton_1.address)(collectionAddress)));
243
- return (await nftCollection.getNFTAddressByIndex(itemIndex)).toString();
80
+ async getTVMExecutorFeeInfo(assets, feeSymbol, tvmValidExecutors) {
81
+ return this.simulator.getTVMExecutorFeeInfo(assets, feeSymbol, tvmValidExecutors);
244
82
  }
245
- async getNFTItemData(itemAddress) {
246
- (0, Utils_1.validateTVMAddress)(itemAddress);
247
- const nftItem = this.TONParams.contractOpener.open(wrappers_1.NFTItem.createFromAddress((0, ton_1.address)(itemAddress)));
248
- return await nftItem.getNFTData();
83
+ async sendCrossChainTransaction(evmProxyMsg, sender, assets, options, waitOptions) {
84
+ return this.transactionManager.sendCrossChainTransaction(evmProxyMsg, sender, assets, options, waitOptions);
249
85
  }
250
- async aggregateTokens(assets) {
251
- this.debugLog(`Aggregating tokens`);
252
- const uniqueAssetsMap = new Map();
253
- let crossChainTonAmount = 0n;
254
- for await (const asset of assets ?? []) {
255
- if (asset.rawAmount <= 0)
256
- continue;
257
- if (asset.type !== Struct_1.AssetType.FT)
258
- continue;
259
- if (asset.address) {
260
- (0, Utils_1.validateTVMAddress)(asset.address);
261
- uniqueAssetsMap.set(asset.address, (uniqueAssetsMap.get(asset.address) || 0n) + BigInt(asset.rawAmount));
262
- }
263
- else {
264
- crossChainTonAmount += BigInt(asset.rawAmount);
265
- }
266
- }
267
- const jettons = Array.from(uniqueAssetsMap.entries()).map(([address, rawAmount]) => ({
268
- address,
269
- rawAmount,
270
- type: Struct_1.AssetType.FT,
271
- }));
272
- this.debugLog(`Aggregated ${jettons.length} jettons`);
273
- this.debugLog(`Crosschain ton amount: ${crossChainTonAmount}`);
274
- uniqueAssetsMap.clear();
275
- for await (const asset of assets ?? []) {
276
- if (asset.type !== Struct_1.AssetType.NFT)
277
- continue;
278
- (0, Utils_1.validateTVMAddress)(asset.address);
279
- uniqueAssetsMap.set(asset.address, 1n);
280
- }
281
- const nfts = Array.from(uniqueAssetsMap.entries()).map(([address, rawAmount]) => ({
282
- address,
283
- rawAmount,
284
- type: Struct_1.AssetType.NFT,
285
- }));
286
- this.debugLog(`Aggregated ${nfts.length} nfts`);
287
- return {
288
- jettons,
289
- nfts,
290
- crossChainTonAmount,
291
- };
86
+ async sendCrossChainTransactions(sender, txs, waitOptions) {
87
+ return this.transactionManager.sendCrossChainTransactions(sender, txs, waitOptions);
292
88
  }
293
- async generateJettonPayload(jetton, caller, evmData, crossChainTonAmount, forwardFeeTonAmount, feeParams) {
294
- this.debugLog(`Generating jetton payload for ${(0, Utils_1.formatObjectForLogging)(jetton)}`);
295
- const opType = await this.getJettonOpType(jetton);
296
- await (0, Utils_1.sleep)(this.delay * 1000);
297
- this.debugLog(`Generation fee data with params: ${(0, Utils_1.formatObjectForLogging)(feeParams)}`);
298
- const feeData = (0, Utils_1.generateFeeData)(feeParams);
299
- let payload;
300
- switch (opType) {
301
- case InternalStruct_1.AssetOpType.JETTON_BURN:
302
- payload = this.getJettonBurnPayload({
303
- notificationReceiverAddress: this.TONParams.crossChainLayerAddress,
304
- ...jetton,
305
- }, evmData, crossChainTonAmount, feeData);
306
- break;
307
- case InternalStruct_1.AssetOpType.JETTON_TRANSFER:
308
- payload = this.getJettonTransferPayload(jetton, caller, evmData, crossChainTonAmount, forwardFeeTonAmount, feeData);
309
- break;
310
- }
311
- this.debugLog('Generating jetton payload success');
312
- return payload;
89
+ async bridgeTokensToTON(signer, value, tonTarget, assets, tvmExecutorFee, tvmValidExecutors) {
90
+ return this.transactionManager.bridgeTokensToTON(signer, value, tonTarget, assets, tvmExecutorFee, tvmValidExecutors);
313
91
  }
314
- async generateNFTPayload(nft, caller, evmData, crossChainTonAmount, forwardFeeTonAmount, feeParams) {
315
- this.debugLog(`Generating NFT payload for ${(0, Utils_1.formatObjectForLogging)(nft)}`);
316
- const opType = await this.getNFTOpType(nft);
317
- await (0, Utils_1.sleep)(this.delay * 1000);
318
- this.debugLog(`Generation fee data with params: ${(0, Utils_1.formatObjectForLogging)(feeParams)}`);
319
- const feeData = (0, Utils_1.generateFeeData)(feeParams);
320
- let payload;
321
- switch (opType) {
322
- case InternalStruct_1.AssetOpType.NFT_BURN:
323
- payload = this.getNFTBurnPayload({
324
- notificationReceiverAddress: this.TONParams.crossChainLayerAddress,
325
- ...nft,
326
- evmData,
327
- crossChainTonAmount,
328
- feeData,
329
- });
330
- break;
331
- case InternalStruct_1.AssetOpType.NFT_TRANSFER:
332
- payload = this.getNFTTransferPayload({
333
- to: this.TONParams.nftProxyAddress,
334
- responseAddress: caller,
335
- evmData,
336
- crossChainTonAmount,
337
- feeData,
338
- ...nft,
339
- }, forwardFeeTonAmount);
340
- break;
341
- }
342
- this.debugLog('Generating NFT payload success');
343
- return payload;
92
+ async isContractDeployedOnTVM(address) {
93
+ return this.config.isContractDeployedOnTVM(address);
344
94
  }
345
- async generateCrossChainMessages(caller, evmData, aggregatedData, feeParams) {
346
- this.debugLog(`Generating cross-chain messages`);
347
- let crossChainTonAmount = aggregatedData.crossChainTonAmount;
348
- let feeTonAmount = feeParams.protocolFee + feeParams.evmExecutorFee + feeParams.tvmExecutorFee;
349
- this.debugLog(`Crosschain ton amount: ${crossChainTonAmount}`);
350
- this.debugLog(`Fee ton amount: ${feeTonAmount}`);
351
- if (aggregatedData.jettons.length == 0 && aggregatedData.nfts.length == 0) {
352
- return [
353
- {
354
- address: this.TONParams.crossChainLayerAddress,
355
- value: crossChainTonAmount + feeTonAmount + Consts_1.TRANSACTION_TON_AMOUNT,
356
- payload: this.getTonTransferPayload(caller, evmData, crossChainTonAmount, feeParams),
357
- },
358
- ];
359
- }
360
- const messages = [];
361
- let currentFeeParams = feeParams;
362
- for (const jetton of aggregatedData.jettons) {
363
- const payload = await this.generateJettonPayload(jetton, caller, evmData, crossChainTonAmount, feeTonAmount, currentFeeParams);
364
- await (0, Utils_1.sleep)(this.delay * 1000);
365
- const jettonWalletAddress = await this.getUserJettonWalletAddress(caller, jetton.address);
366
- await (0, Utils_1.sleep)(this.delay * 1000);
367
- messages.push({
368
- address: jettonWalletAddress,
369
- value: crossChainTonAmount + feeTonAmount + Consts_1.TRANSACTION_TON_AMOUNT,
370
- payload,
371
- });
372
- crossChainTonAmount = 0n;
373
- feeTonAmount = 0n;
374
- currentFeeParams = undefined;
375
- }
376
- for (const nft of aggregatedData.nfts) {
377
- const payload = await this.generateNFTPayload(nft, caller, evmData, crossChainTonAmount, feeTonAmount, currentFeeParams);
378
- await (0, Utils_1.sleep)(this.delay * 1000);
379
- messages.push({
380
- address: nft.address,
381
- value: crossChainTonAmount + feeTonAmount + Consts_1.TRANSACTION_TON_AMOUNT,
382
- payload,
383
- });
384
- crossChainTonAmount = 0n;
385
- feeTonAmount = 0n;
386
- currentFeeParams = undefined;
387
- }
388
- this.debugLog('Generating cross-chain messages success');
389
- return messages;
95
+ async simulateTACMessage(req) {
96
+ return this.simulator.simulateTACMessage(req);
390
97
  }
391
- async getRawAmount(asset, precalculatedAddress) {
392
- this.debugLog(`Getting raw amount for ${(0, Utils_1.formatObjectForLogging)(precalculatedAddress ?? 'TON')}`);
393
- if ('rawAmount' in asset) {
394
- this.debugLog(`Provided raw amount: ${asset.rawAmount}`);
395
- return asset.rawAmount;
396
- }
397
- if (!precalculatedAddress) {
398
- // User specified TON Coin
399
- const rawAmount = (0, ton_1.toNano)(asset.amount);
400
- this.debugLog(`TON raw amount: ${rawAmount}`);
401
- return rawAmount;
402
- }
403
- if (typeof asset.decimals === 'number') {
404
- // User manually set decimals
405
- const rawAmount = (0, Utils_1.calculateRawAmount)(asset.amount, asset.decimals);
406
- this.debugLog(`Raw amount calculated from decimals: ${rawAmount}`);
407
- return rawAmount;
408
- }
409
- // Get decimals from chain
410
- (0, Utils_1.validateTVMAddress)(precalculatedAddress);
411
- this.debugLog('Getting decimals from chain');
412
- const contract = this.TONParams.contractOpener.open(new JettonMaster_1.JettonMaster((0, ton_1.address)(precalculatedAddress)));
413
- const { content } = await contract.getJettonData();
414
- await (0, Utils_1.sleep)(this.delay * 1000);
415
- if (!content.metadata.decimals) {
416
- // if decimals not specified use default value 9
417
- this.debugLog('Decimals not specified, using default value 9');
418
- return (0, ton_1.toNano)(asset.amount);
419
- }
420
- const rawAmount = (0, Utils_1.calculateRawAmount)(asset.amount, Number(content.metadata.decimals));
421
- this.debugLog(`Raw amount calculated from decimals(${content.metadata.decimals}): ${rawAmount}`);
422
- return rawAmount;
98
+ async simulateTransactions(sender, txs) {
99
+ return this.simulator.simulateTransactions(sender, txs);
423
100
  }
424
- async convertAssetsToRawFormat(assets) {
425
- this.debugLog(`Converting assets to raw format`);
426
- return await Promise.all((assets ?? []).map(async (asset) => {
427
- this.debugLog(`Converting asset to raw format: ${(0, Utils_1.formatObjectForLogging)(asset)}`);
428
- if (asset.type === Struct_1.AssetType.FT) {
429
- const address = (0, ethers_1.isAddress)(asset.address)
430
- ? await this.getTVMTokenAddress(asset.address)
431
- : asset.address;
432
- this.debugLog(`Token address on TON: ${address}`);
433
- return {
434
- address,
435
- rawAmount: await this.getRawAmount(asset, address),
436
- type: asset.type,
437
- };
438
- }
439
- if (asset.type === Struct_1.AssetType.NFT) {
440
- if ('collectionAddress' in asset) {
441
- const address = (0, ethers_1.isAddress)(asset.collectionAddress)
442
- ? await this.getTVMNFTAddress(asset.collectionAddress, asset.itemIndex)
443
- : await this.getNFTItemAddressTON(asset.collectionAddress, asset.itemIndex);
444
- this.debugLog(`NFT address on TON: ${address}`);
445
- await (0, Utils_1.sleep)(this.delay * 1000);
446
- return {
447
- address,
448
- rawAmount: 1n,
449
- type: asset.type,
450
- };
451
- }
452
- (0, Utils_1.validateTVMAddress)(asset.address);
453
- return {
454
- address: asset.address,
455
- rawAmount: 1n,
456
- type: asset.type,
457
- };
458
- }
459
- throw instances_1.invalidAssetType;
460
- }));
101
+ async getAsset(args) {
102
+ return await assets_1.AssetFactory.from(this.config, args);
461
103
  }
462
- async getFeeInfo(evmProxyMsg, transactionLinker, rawAssets, forceSend = false, isRoundTrip = true, evmValidExecutors = this.TACParams.trustedTACExecutors, tvmValidExecutors = this.TACParams.trustedTONExecutors) {
463
- this.debugLog('Getting fee info');
464
- const crossChainLayer = this.TONParams.contractOpener.open(this.artifacts.ton.wrappers.CrossChainLayer.createFromAddress(ton_1.Address.parse(this.TONParams.crossChainLayerAddress)));
465
- const fullStateCCL = await crossChainLayer.getFullData();
466
- await (0, Utils_1.sleep)(this.delay * 1000);
467
- this.debugLog(`Full state CCL: ${(0, Utils_1.formatObjectForLogging)(fullStateCCL)}`);
468
- const tacSimulationBody = {
469
- tacCallParams: {
470
- arguments: evmProxyMsg.encodedParameters ?? '0x',
471
- methodName: (0, Utils_1.formatSolidityMethodName)(evmProxyMsg.methodName),
472
- target: evmProxyMsg.evmTargetAddress,
473
- },
474
- evmValidExecutors: evmValidExecutors,
475
- tvmValidExecutors: tvmValidExecutors,
476
- extraData: '0x',
477
- shardsKey: transactionLinker.shardsKey,
478
- tonAssets: rawAssets.map((asset) => ({
479
- amount: asset.rawAmount.toString(),
480
- tokenAddress: asset.address || '',
481
- assetType: asset.type,
482
- })),
483
- tonCaller: transactionLinker.caller,
484
- };
485
- isRoundTrip = isRoundTrip ?? rawAssets.length != 0;
486
- this.debugLog(`Is round trip: ${isRoundTrip}`);
487
- const tacSimulationResult = await this.simulateTACMessage(tacSimulationBody);
488
- this.debugLog(`TAC simulation ${tacSimulationResult.simulationStatus ? 'success' : 'failed'}`);
489
- if (!tacSimulationResult.simulationStatus) {
490
- if (forceSend) {
491
- this.debugLog('Force send is true, returning fee params');
492
- return {
493
- feeParams: {
494
- isRoundTrip,
495
- gasLimit: 0n,
496
- protocolFee: BigInt((0, ton_1.toNano)(fullStateCCL.tacProtocolFee)) +
497
- BigInt(isRoundTrip) * BigInt((0, ton_1.toNano)(fullStateCCL.tonProtocolFee)),
498
- evmExecutorFee: BigInt(tacSimulationResult.suggestedTacExecutionFee),
499
- tvmExecutorFee: BigInt(tacSimulationResult.suggestedTonExecutionFee) * BigInt(isRoundTrip),
500
- },
501
- simulation: tacSimulationResult,
502
- };
503
- }
504
- throw tacSimulationResult;
505
- }
506
- const protocolFee = BigInt((0, ton_1.toNano)(fullStateCCL.tacProtocolFee)) +
507
- BigInt(isRoundTrip) * BigInt((0, ton_1.toNano)(fullStateCCL.tonProtocolFee));
508
- const feeParams = {
509
- isRoundTrip: isRoundTrip,
510
- gasLimit: tacSimulationResult.estimatedGas,
511
- protocolFee: protocolFee,
512
- evmExecutorFee: BigInt(tacSimulationResult.suggestedTacExecutionFee),
513
- tvmExecutorFee: BigInt(tacSimulationResult.suggestedTonExecutionFee) * BigInt(isRoundTrip),
514
- };
515
- this.debugLog(`Collected fee params: ${(0, Utils_1.formatObjectForLogging)(feeParams)}`);
516
- return { feeParams: feeParams, simulation: tacSimulationResult };
104
+ // Jetton methods
105
+ async getUserJettonWalletAddress(userAddress, tokenAddress) {
106
+ const ft = await assets_1.AssetFactory.from(this.config, {
107
+ address: tokenAddress,
108
+ tokenType: Struct_1.AssetType.FT,
109
+ });
110
+ return ft.getUserWalletAddress(userAddress);
517
111
  }
518
- async getTransactionSimulationInfo(evmProxyMsg, sender, assets) {
519
- this.debugLog('Getting transaction simulation info');
520
- const rawAssets = await this.convertAssetsToRawFormat(assets);
521
- const aggregatedData = await this.aggregateTokens(rawAssets);
522
- const transactionLinkerShardCount = aggregatedData.jettons.length == 0 ? 1 : aggregatedData.jettons.length;
523
- this.debugLog(`Transaction linker shard count: ${transactionLinkerShardCount}`);
524
- const transactionLinker = (0, Utils_1.generateTransactionLinker)(sender.getSenderAddress(), transactionLinkerShardCount);
525
- this.debugLog(`Transaction linker: ${(0, Utils_1.formatObjectForLogging)(transactionLinker)}`);
526
- return await this.getFeeInfo(evmProxyMsg, transactionLinker, rawAssets);
112
+ async getUserJettonBalance(userAddress, tokenAddress) {
113
+ const ft = await assets_1.AssetFactory.from(this.config, {
114
+ address: tokenAddress,
115
+ tokenType: Struct_1.AssetType.FT,
116
+ });
117
+ return ft.getUserBalance(userAddress);
527
118
  }
528
- async getTVMExecutorFeeInfo(assets, feeSymbol) {
529
- this.debugLog('Getting TVM executor fee info');
530
- const rawAssets = await this.convertAssetsToRawFormat(assets);
531
- const requestBody = {
532
- tonAssets: rawAssets.map((asset) => ({
533
- amount: asset.rawAmount.toString(),
534
- tokenAddress: asset.address || '',
535
- assetType: asset.type,
536
- })),
537
- feeSymbol: feeSymbol,
538
- };
539
- let lastError;
540
- for (const endpoint of this.liteSequencerEndpoints) {
541
- try {
542
- const response = await axios_1.default.post(`${endpoint}/ton/calculator/ton-executor-fee`, requestBody);
543
- return response.data.response;
544
- }
545
- catch (error) {
546
- this.debugLog(`Error while calculating tvm executor fee ${endpoint}: ${error}`);
547
- lastError = error;
548
- }
549
- }
550
- this.debugLog('Error while calculating tvm executor fee on all endpoints');
551
- throw (0, errors_1.simulationError)(lastError);
119
+ async getUserJettonBalanceExtended(userAddress, tokenAddress) {
120
+ const ft = await assets_1.AssetFactory.from(this.config, {
121
+ address: tokenAddress,
122
+ tokenType: Struct_1.AssetType.FT,
123
+ });
124
+ return ft.getUserBalanceExtended(userAddress);
552
125
  }
553
- async prepareCrossChainTransaction(evmProxyMsg, caller, assets, options) {
554
- this.debugLog('Preparing cross-chain transaction');
555
- const { forceSend = false, isRoundTrip = undefined, protocolFee = undefined, evmExecutorFee = undefined, tvmExecutorFee = undefined, } = options || {};
556
- let { evmValidExecutors = [], tvmValidExecutors = [] } = options || {};
557
- const rawAssets = await this.convertAssetsToRawFormat(assets);
558
- const aggregatedData = await this.aggregateTokens(rawAssets);
559
- const tokensLength = aggregatedData.jettons.length + aggregatedData.nfts.length;
560
- this.debugLog(`Tokens length: ${tokensLength}`);
561
- const transactionLinkerShardCount = tokensLength == 0 ? 1 : tokensLength;
562
- this.debugLog(`Transaction linker shard count: ${transactionLinkerShardCount}`);
563
- const transactionLinker = (0, Utils_1.generateTransactionLinker)(caller, transactionLinkerShardCount);
564
- this.debugLog(`Generated transaction linker: ${(0, Utils_1.formatObjectForLogging)(transactionLinker)}`);
565
- if (evmValidExecutors.length == 0) {
566
- evmValidExecutors = this.TACParams.trustedTACExecutors;
567
- }
568
- if (tvmValidExecutors.length == 0) {
569
- tvmValidExecutors = this.TACParams.trustedTONExecutors;
570
- }
571
- const { feeParams } = await this.getFeeInfo(evmProxyMsg, transactionLinker, rawAssets, forceSend, isRoundTrip, evmValidExecutors, tvmValidExecutors);
572
- if (evmProxyMsg.gasLimit == undefined) {
573
- evmProxyMsg.gasLimit = feeParams.gasLimit;
574
- }
575
- if (evmExecutorFee != undefined) {
576
- feeParams.evmExecutorFee = evmExecutorFee;
577
- }
578
- if (feeParams.isRoundTrip && tvmExecutorFee != undefined) {
579
- feeParams.tvmExecutorFee = tvmExecutorFee;
580
- }
581
- if (protocolFee != undefined) {
582
- feeParams.protocolFee = protocolFee;
583
- }
584
- this.debugLog(`Resulting fee params: ${(0, Utils_1.formatObjectForLogging)(feeParams)}`);
585
- const validExecutors = {
586
- tac: evmValidExecutors,
587
- ton: tvmValidExecutors,
588
- };
589
- this.debugLog(`Valid executors: ${(0, Utils_1.formatObjectForLogging)(validExecutors)}`);
590
- const evmData = (0, Utils_1.buildEvmDataCell)(transactionLinker, evmProxyMsg, validExecutors);
591
- const messages = await this.generateCrossChainMessages(caller, evmData, aggregatedData, feeParams);
592
- await (0, Utils_1.sleep)(this.delay * 1000);
593
- const transaction = {
594
- validUntil: +new Date() + 15 * 60 * 1000,
595
- messages,
596
- network: this.network,
597
- };
598
- this.debugLog('Transaction prepared');
599
- return { transaction, transactionLinker };
126
+ async getJettonData(itemAddress) {
127
+ return assets_1.FT.getJettonData(this.config.TONParams.contractOpener, itemAddress);
600
128
  }
601
- async sendCrossChainTransaction(evmProxyMsg, sender, assets, options, waitOptions) {
602
- const caller = sender.getSenderAddress();
603
- this.debugLog(`Caller: ${caller}`);
604
- const { transaction, transactionLinker } = await this.prepareCrossChainTransaction(evmProxyMsg, caller, assets, options);
605
- this.debugLog(`*****Sending transaction: ${(0, Utils_1.formatObjectForLogging)(transaction)}`);
606
- const sendTransactionResult = await sender.sendShardTransaction(transaction, this.delay, this.network, this.TONParams.contractOpener);
607
- return waitOptions
608
- ? {
609
- sendTransactionResult,
610
- operationId: await this.operationTracker.getOperationId(transactionLinker, {
611
- ...waitOptions,
612
- successCheck: (operationId) => !!operationId,
613
- log: this.debugLog.bind(this),
614
- }),
615
- ...transactionLinker,
616
- }
617
- : { sendTransactionResult, ...transactionLinker };
129
+ async getFT(address) {
130
+ return await assets_1.FT.fromAddress(this.config, address);
618
131
  }
619
- async sendCrossChainTransactions(sender, txs, waitOptions) {
620
- const transactions = [];
621
- const transactionLinkers = [];
622
- const caller = sender.getSenderAddress();
623
- this.debugLog(`Caller: ${caller}`);
624
- this.debugLog('Preparing multiple cross-chain transactions');
625
- for (const { options, assets, evmProxyMsg } of txs) {
626
- const { transaction, transactionLinker } = await this.prepareCrossChainTransaction(evmProxyMsg, caller, assets, options);
627
- transactions.push(transaction);
628
- transactionLinkers.push(transactionLinker);
629
- }
630
- this.debugLog(`*****Sending transactions: ${(0, Utils_1.formatObjectForLogging)(transactions)}`);
631
- await sender.sendShardTransactions(transactions, this.delay, this.network, this.TONParams.contractOpener);
632
- if (waitOptions) {
633
- this.debugLog(`Waiting for operation IDs`);
634
- try {
635
- const operationIds = await this.operationTracker.getOperationIdsByShardsKeys(transactionLinkers.map((linker) => linker.shardsKey), caller, {
636
- ...waitOptions,
637
- log: this.debugLog.bind(this),
638
- successCheck: (operationIds) => {
639
- return (Object.keys(operationIds).length == transactionLinkers.length &&
640
- Object.values(operationIds).every((ids) => ids.operationIds.length > 0));
641
- },
642
- });
643
- this.debugLog(`Operation IDs: ${(0, Utils_1.formatObjectForLogging)(operationIds)}`);
644
- return transactionLinkers.map((linker) => ({
645
- ...linker,
646
- operationId: operationIds[linker.shardsKey].operationIds.at(0),
647
- }));
648
- }
649
- catch (error) {
650
- this.debugLog(`Error while waiting for operation IDs: ${error}`);
651
- }
652
- }
653
- return transactionLinkers;
132
+ // NFT methods
133
+ async getNFTItemData(itemAddress) {
134
+ return assets_1.NFT.getItemData(this.config.TONParams.contractOpener, itemAddress);
654
135
  }
655
- // TODO move to sdk.TAC, sdk.TON
656
- async bridgeTokensToTON(signer, value, tonTarget, assets, tvmExecutorFee) {
657
- this.debugLog('Bridging tokens to TON');
658
- if (assets == undefined) {
659
- assets = [];
136
+ async getNFT(args) {
137
+ if ('addressType' in args && args.addressType === Struct_1.NFTAddressType.ITEM) {
138
+ return assets_1.NFT.fromItem(this.config, args.address);
660
139
  }
661
- const tonAssets = [];
662
- for (const asset of assets) {
663
- if (asset.type == Struct_1.AssetType.FT) {
664
- const tvmAddress = await this.getTVMTokenAddress(asset.address);
665
- tonAssets.push({
666
- address: tvmAddress,
667
- rawAmount: asset.rawAmount,
668
- type: Struct_1.AssetType.FT,
669
- });
670
- }
671
- else {
672
- const nftItemAddress = await this.getTVMNFTAddress(asset.collectionAddress, asset.itemIndex);
673
- tonAssets.push({
674
- address: nftItemAddress,
675
- amount: 1,
676
- type: Struct_1.AssetType.NFT,
677
- });
678
- }
679
- }
680
- this.debugLog(`TON assets: ${(0, Utils_1.formatObjectForLogging)(tonAssets)}`);
681
- if (value > 0) {
682
- this.debugLog('Adding native TAC to TON assets');
683
- const tvmAddress = await this.getTVMTokenAddress(await this.nativeTACAddress());
684
- tonAssets.push({
685
- address: tvmAddress,
686
- rawAmount: value,
687
- type: Struct_1.AssetType.FT,
140
+ else {
141
+ const collectionArgs = args;
142
+ return assets_1.NFT.fromCollection(this.config, {
143
+ collection: collectionArgs.address,
144
+ index: collectionArgs.index,
688
145
  });
689
146
  }
690
- const suggestedTONExecutorFee = await this.getTVMExecutorFeeInfo(tonAssets, Consts_1.TAC_SYMBOL);
691
- this.debugLog(`Suggested TON executor fee: ${(0, Utils_1.formatObjectForLogging)(suggestedTONExecutorFee)}`);
692
- const crossChainLayerAddress = await this.TACParams.crossChainLayer.getAddress();
693
- for (const asset of assets) {
694
- if (asset.type == Struct_1.AssetType.FT) {
695
- this.debugLog(`Approving token ${asset.address} for ${crossChainLayerAddress}`);
696
- const tokenContract = this.artifacts.tac.wrappers.ERC20FactoryTAC.connect(asset.address, this.TACParams.provider);
697
- const tx = await tokenContract.connect(signer).approve(crossChainLayerAddress, asset.rawAmount);
698
- await tx.wait();
699
- this.debugLog(`Approved ${asset.address} for ${crossChainLayerAddress}`);
700
- }
701
- if (asset.type == Struct_1.AssetType.NFT) {
702
- this.debugLog(`Approving collection ${asset.collectionAddress} for ${crossChainLayerAddress}`);
703
- const tokenContract = this.artifacts.tac.wrappers.ERC721FactoryTAC.connect(asset.collectionAddress, this.TACParams.provider);
704
- const tx = await tokenContract.connect(signer).approve(crossChainLayerAddress, asset.itemIndex);
705
- await tx.wait();
706
- this.debugLog(`Approved ${asset.collectionAddress} for ${crossChainLayerAddress}`);
707
- }
708
- }
709
- const shardsKey = BigInt(Math.round(Math.random() * 1e18));
710
- this.debugLog(`Shards key: ${shardsKey}`);
711
- const protocolFee = await this.TACParams.crossChainLayer.getProtocolFee();
712
- this.debugLog(`Protocol fee: ${protocolFee}`);
713
- const outMessage = {
714
- shardsKey: shardsKey,
715
- tvmTarget: tonTarget,
716
- tvmPayload: '',
717
- tvmProtocolFee: protocolFee,
718
- tvmExecutorFee: tvmExecutorFee ?? BigInt(suggestedTONExecutorFee.inTAC),
719
- tvmValidExecutors: this.TACParams.trustedTONExecutors,
720
- toBridge: assets
721
- .filter((asset) => asset.type === Struct_1.AssetType.FT)
722
- .map((asset) => ({
723
- evmAddress: asset.address,
724
- amount: asset.rawAmount,
725
- })),
726
- toBridgeNFT: assets
727
- .filter((asset) => asset.type === Struct_1.AssetType.NFT)
728
- .map((asset) => ({
729
- evmAddress: asset.collectionAddress,
730
- amount: 1n,
731
- tokenId: asset.itemIndex,
732
- })),
733
- };
734
- const encodedOutMessage = this.artifacts.tac.utils.encodeOutMessageV1(outMessage);
735
- const outMsgVersion = 1n;
736
- const totalValue = value + BigInt(outMessage.tvmProtocolFee) + BigInt(outMessage.tvmExecutorFee);
737
- this.debugLog(`Total value: ${totalValue}`);
738
- const tx = await this.TACParams.crossChainLayer
739
- .connect(signer)
740
- .sendMessage(outMsgVersion, encodedOutMessage, { value: totalValue });
741
- await tx.wait();
742
- this.debugLog(`Transaction hash: ${tx.hash}`);
743
- return tx.hash;
744
- }
745
- get getTrustedTACExecutors() {
746
- return this.TACParams.trustedTACExecutors;
747
- }
748
- get getTrustedTONExecutors() {
749
- return this.TACParams.trustedTONExecutors;
750
147
  }
148
+ // Address conversion methods
751
149
  async getEVMTokenAddress(tvmTokenAddress) {
752
- this.debugLog(`Getting EVM token address for ${tvmTokenAddress}`);
753
- if (tvmTokenAddress !== this.nativeTONAddress) {
754
- (0, Utils_1.validateTVMAddress)(tvmTokenAddress);
755
- tvmTokenAddress = ton_1.Address.parse(tvmTokenAddress).toString({ bounceable: true });
756
- const { code: givenMinterCodeBOC } = await this.TONParams.contractOpener.getContractState((0, ton_1.address)(tvmTokenAddress));
757
- await (0, Utils_1.sleep)(this.delay * 1000);
758
- if (givenMinterCodeBOC && this.TONParams.jettonMinterCode.equals(ton_1.Cell.fromBoc(givenMinterCodeBOC)[0])) {
759
- this.debugLog(`Computing EVM token address using jetton minter`);
760
- const givenMinter = this.TONParams.contractOpener.open(new JettonMaster_1.JettonMaster((0, ton_1.address)(tvmTokenAddress)));
761
- const evmAddress = await givenMinter.getEVMAddress();
762
- await (0, Utils_1.sleep)(this.delay * 1000);
763
- return evmAddress;
764
- }
150
+ if (tvmTokenAddress === this.nativeTONAddress || tvmTokenAddress === '') {
151
+ return assets_1.TON.create(this.config).getEVMAddress();
765
152
  }
766
- this.debugLog(`Computing EVM token address using token utils`);
767
- return this.TACParams.tokenUtils.computeAddress(tvmTokenAddress);
153
+ return assets_1.FT.getEVMAddress(this.config, tvmTokenAddress);
768
154
  }
769
155
  async getTVMTokenAddress(evmTokenAddress) {
770
- this.debugLog(`Getting TVM token address for ${evmTokenAddress}`);
771
- (0, Utils_1.validateEVMAddress)(evmTokenAddress);
772
- const exists = await this.TACParams.tokenUtils['exists(address)'](evmTokenAddress);
773
- if (exists) {
774
- this.debugLog(`Getting TVM token address using cross chain layer ERC20 factory`);
775
- const erc721Token = this.artifacts.tac.wrappers.CrossChainLayerERC20FactoryTAC.connect(evmTokenAddress, this.TACParams.provider);
776
- const info = await erc721Token.getInfo();
777
- return info.tvmAddress;
778
- }
779
- this.debugLog(`Getting TVM token address using jetton minter`);
780
- const jettonMaster = JettonMaster_1.JettonMaster.createFromConfig({
781
- evmTokenAddress,
782
- crossChainLayerAddress: (0, ton_1.address)(this.TONParams.crossChainLayerAddress),
783
- code: this.TONParams.jettonMinterCode,
784
- walletCode: this.TONParams.jettonWalletCode,
785
- });
786
- return jettonMaster.address.toString();
156
+ return assets_1.FT.getTVMAddress(this.config, evmTokenAddress);
787
157
  }
788
158
  async getTVMNFTAddress(evmNFTAddress, tokenId) {
789
- this.debugLog(`Getting TVM NFT ${tokenId ? `item ${tokenId}` : 'collection'} address for ${evmNFTAddress}`);
790
- (0, Utils_1.validateEVMAddress)(evmNFTAddress);
791
- let nftCollection;
792
- const exists = await this.TACParams.tokenUtils['exists(address)'](evmNFTAddress);
793
- if (exists) {
794
- this.debugLog(`Getting TVM NFT address using cross chain layer ERC721 factory`);
795
- const erc721Token = this.artifacts.tac.wrappers.CrossChainLayerERC721FactoryTAC.connect(evmNFTAddress, this.TACParams.provider);
796
- const info = await erc721Token.getInfo();
797
- nftCollection = this.TONParams.contractOpener.open(wrappers_1.NFTCollection.createFromAddress((0, ton_1.address)(info.tvmAddress)));
798
- return tokenId == undefined
799
- ? nftCollection.address.toString()
800
- : (await nftCollection.getNFTAddressByIndex(tokenId)).toString();
801
- }
802
- else {
803
- this.debugLog(`Getting TVM NFT address using TON NFT collection contract`);
804
- nftCollection = this.TONParams.contractOpener.open(wrappers_1.NFTCollection.createFromConfig({
805
- adminAddress: (0, ton_1.address)(this.TONParams.crossChainLayerAddress),
806
- newAdminAddress: null,
807
- collectionContent: (0, ton_1.beginCell)().endCell(),
808
- commonContent: (0, ton_1.beginCell)().endCell(),
809
- nftItemCode: this.TONParams.nftItemCode,
810
- originalAddress: evmNFTAddress,
811
- }, this.TONParams.nftCollectionCode));
812
- return tokenId == undefined
813
- ? nftCollection.address.toString()
814
- : wrappers_1.NFTItem.createFromConfig({
815
- collectionAddress: nftCollection.address,
816
- cclAddress: (0, ton_1.address)(this.TONParams.crossChainLayerAddress),
817
- // @ts-expect-error // bigint can be used, wrapper is not typed properly
818
- index: tokenId,
819
- }, this.TONParams.nftItemCode).address.toString();
820
- }
159
+ return assets_1.NFT.getTVMAddress(this.config, evmNFTAddress, tokenId === undefined ? undefined : BigInt(tokenId));
821
160
  }
822
161
  async getEVMNFTAddress(tvmNFTAddress, addressType) {
823
- this.debugLog(`Getting EVM NFT address for ${tvmNFTAddress}`);
824
- (0, Utils_1.validateTVMAddress)(tvmNFTAddress);
825
- tvmNFTAddress = ton_1.Address.parse(tvmNFTAddress).toString({ bounceable: true });
826
- if (addressType == Struct_1.NFTAddressType.ITEM) {
827
- this.debugLog(`Retrieving collection address for item ${tvmNFTAddress}`);
828
- tvmNFTAddress = (await this.getNFTItemData(tvmNFTAddress)).collectionAddress.toString();
829
- this.debugLog(`Collection address: ${tvmNFTAddress}`);
830
- addressType = Struct_1.NFTAddressType.COLLECTION;
831
- await (0, Utils_1.sleep)(this.delay * 1000);
832
- }
833
- const { code: givenNFTCollection } = await this.TONParams.contractOpener.getContractState((0, ton_1.address)(tvmNFTAddress));
834
- await (0, Utils_1.sleep)(this.delay * 1000);
835
- if (givenNFTCollection && this.TONParams.nftCollectionCode.equals(ton_1.Cell.fromBoc(givenNFTCollection)[0])) {
836
- this.debugLog(`Getting EVM NFT address using TON NFT collection contract`);
837
- const nftCollection = this.TONParams.contractOpener.open(wrappers_1.NFTCollection.createFromAddress((0, ton_1.address)(tvmNFTAddress)));
838
- const evmAddress = await nftCollection.getOriginalAddress();
839
- await (0, Utils_1.sleep)(this.delay * 1000);
840
- return evmAddress.toString();
162
+ if (addressType === Struct_1.NFTAddressType.ITEM) {
163
+ const nft = await assets_1.NFT.fromItem(this.config, tvmNFTAddress);
164
+ return nft.getEVMAddress();
841
165
  }
842
- this.debugLog(`Computing EVM NFT address using token utils`);
843
- return this.TACParams.tokenUtils.computeAddressERC721(tvmNFTAddress);
844
- }
845
- async isContractDeployedOnTVM(address) {
846
- return (await this.TONParams.contractOpener.getContractState(ton_1.Address.parse(address))).state === 'active';
847
- }
848
- async simulateTACMessage(req) {
849
- this.debugLog('Simulating TAC message');
850
- let lastError;
851
- for (const endpoint of this.liteSequencerEndpoints) {
852
- try {
853
- const response = await axios_1.default.post(new URL('tac/simulator/simulate-message', endpoint).toString(), req, {
854
- transformResponse: [Utils_1.toCamelCaseTransformer],
855
- });
856
- this.debugLog('TAC message simulation success');
857
- return response.data.response;
858
- }
859
- catch (error) {
860
- this.debugLog(`Error while simulating with ${endpoint}: ${error}`);
861
- lastError = error;
862
- }
166
+ else {
167
+ const nftCollection = await assets_1.NFT.fromCollection(this.config, { collection: tvmNFTAddress, index: 0n });
168
+ return nftCollection.getEVMAddress();
863
169
  }
864
- throw (0, errors_1.simulationError)(lastError);
865
170
  }
866
171
  }
867
172
  exports.TacSdk = TacSdk;