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