@tonappchain/sdk 0.6.5-mainnet-alpha → 0.7.0-rc7
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.
- package/dist/adapters/contractOpener.d.ts +1 -1
- package/dist/adapters/contractOpener.js +7 -8
- package/dist/adapters/retryableContractOpener.d.ts +21 -0
- package/dist/adapters/retryableContractOpener.js +101 -0
- package/dist/assets/AssetCache.d.ts +23 -0
- package/dist/assets/AssetCache.js +36 -0
- package/dist/assets/AssetFactory.d.ts +19 -0
- package/dist/assets/AssetFactory.js +45 -0
- package/dist/assets/FT.d.ts +55 -0
- package/dist/assets/FT.js +206 -0
- package/dist/assets/NFT.d.ts +69 -0
- package/dist/assets/NFT.js +200 -0
- package/dist/assets/TON.d.ts +38 -0
- package/dist/assets/TON.js +91 -0
- package/dist/assets/index.d.ts +4 -0
- package/dist/assets/index.js +11 -0
- package/dist/errors/errors.d.ts +6 -0
- package/dist/errors/errors.js +15 -1
- package/dist/errors/index.d.ts +2 -2
- package/dist/errors/index.js +26 -21
- package/dist/errors/instances.d.ts +9 -4
- package/dist/errors/instances.js +19 -5
- package/dist/index.d.ts +12 -6
- package/dist/index.js +24 -13
- package/dist/sdk/Configuration.d.ts +21 -0
- package/dist/sdk/Configuration.js +90 -0
- package/dist/sdk/LiteSequencerClient.d.ts +1 -1
- package/dist/sdk/LiteSequencerClient.js +5 -11
- package/dist/sdk/Logger.d.ts +13 -0
- package/dist/sdk/Logger.js +25 -0
- package/dist/sdk/OperationTracker.d.ts +21 -6
- package/dist/sdk/OperationTracker.js +155 -75
- package/dist/sdk/Simulator.d.ts +23 -0
- package/dist/sdk/Simulator.js +169 -0
- package/dist/sdk/StartTracking.d.ts +6 -0
- package/dist/sdk/StartTracking.js +66 -29
- package/dist/sdk/TacSdk.d.ts +12 -41
- package/dist/sdk/TacSdk.js +69 -712
- package/dist/sdk/TransactionManager.d.ts +22 -0
- package/dist/sdk/TransactionManager.js +264 -0
- package/dist/sdk/TxFinalizer.d.ts +10 -0
- package/dist/sdk/TxFinalizer.js +104 -0
- package/dist/sdk/Utils.d.ts +12 -4
- package/dist/sdk/Utils.js +80 -16
- package/dist/sdk/Validator.d.ts +9 -0
- package/dist/sdk/Validator.js +43 -0
- package/dist/sender/BatchSender.d.ts +7 -4
- package/dist/sender/BatchSender.js +18 -6
- package/dist/sender/RawSender.d.ts +9 -4
- package/dist/sender/RawSender.js +46 -18
- package/dist/sender/SenderAbstraction.d.ts +5 -3
- package/dist/sender/SenderFactory.d.ts +1 -1
- package/dist/sender/SenderFactory.js +5 -4
- package/dist/sender/TonConnectSender.d.ts +5 -3
- package/dist/sender/TonConnectSender.js +12 -8
- package/dist/sender/index.d.ts +1 -1
- package/dist/sender/index.js +1 -1
- package/dist/structs/InternalStruct.d.ts +36 -33
- package/dist/structs/Services.d.ts +40 -0
- package/dist/structs/Services.js +2 -0
- package/dist/structs/Struct.d.ts +100 -79
- package/dist/structs/Struct.js +11 -1
- package/dist/wrappers/HighloadQueryId.js +0 -1
- package/dist/wrappers/HighloadWalletV3.d.ts +3 -2
- package/dist/wrappers/HighloadWalletV3.js +5 -2
- package/dist/wrappers/JettonWallet.d.ts +11 -2
- package/dist/wrappers/JettonWallet.js +33 -16
- package/package.json +2 -2
package/dist/sdk/TacSdk.js
CHANGED
|
@@ -1,744 +1,101 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
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 axios_1 = __importDefault(require("axios"));
|
|
8
|
-
const ton_1 = require("@ton/ton");
|
|
9
|
-
const ethers_1 = require("ethers");
|
|
10
|
-
// import structs
|
|
11
37
|
const Struct_1 = require("../structs/Struct");
|
|
12
|
-
|
|
13
|
-
const InternalStruct_1 = require("../structs/InternalStruct");
|
|
14
|
-
// jetton imports
|
|
15
|
-
const JettonMaster_1 = require("../wrappers/JettonMaster");
|
|
16
|
-
const JettonWallet_1 = require("../wrappers/JettonWallet");
|
|
17
|
-
// ton settings
|
|
18
|
-
const Settings_1 = require("../wrappers/Settings");
|
|
38
|
+
const Configuration_1 = require("./Configuration");
|
|
19
39
|
const Consts_1 = require("./Consts");
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
const instances_1 = require("../errors/instances");
|
|
40
|
+
const Logger_1 = require("./Logger");
|
|
41
|
+
const OperationTracker_1 = require("./OperationTracker");
|
|
42
|
+
const Simulator_1 = require("./Simulator");
|
|
43
|
+
const TransactionManager_1 = require("./TransactionManager");
|
|
25
44
|
class TacSdk {
|
|
26
|
-
constructor(
|
|
27
|
-
this.
|
|
28
|
-
this.
|
|
29
|
-
this.
|
|
30
|
-
this.TONParams = TONParams;
|
|
31
|
-
this.TACParams = TACParams;
|
|
32
|
-
this.liteSequencerEndpoints = liteSequencerEndpoints;
|
|
45
|
+
constructor(config, simulator, transactionManager) {
|
|
46
|
+
this.config = config;
|
|
47
|
+
this.simulator = simulator;
|
|
48
|
+
this.transactionManager = transactionManager;
|
|
33
49
|
}
|
|
34
|
-
static async create(sdkParams) {
|
|
50
|
+
static async create(sdkParams, logger = new Logger_1.NoopLogger()) {
|
|
35
51
|
const network = sdkParams.network;
|
|
36
52
|
const delay = sdkParams.delay ?? Consts_1.DEFAULT_DELAY;
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
const
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return new TacSdk(network, delay, artifacts, TONParams, TACParams, liteSequencerEndpoints);
|
|
45
|
-
}
|
|
46
|
-
static async prepareTONParams(delay, artifacts, TONParams) {
|
|
47
|
-
const contractOpener = TONParams?.contractOpener ??
|
|
48
|
-
new ton_1.TonClient({
|
|
49
|
-
endpoint: new URL('api/v2/jsonRPC', artifacts.TON_RPC_ENDPOINT_BY_TAC).toString()
|
|
50
|
-
});
|
|
51
|
-
const settingsAddress = TONParams?.settingsAddress
|
|
52
|
-
?? artifacts.TON_SETTINGS_ADDRESS;
|
|
53
|
-
const settings = contractOpener.open(new Settings_1.Settings(ton_1.Address.parse(settingsAddress)));
|
|
54
|
-
const jettonProxyAddress = await settings.getAddressSetting('JettonProxyAddress');
|
|
55
|
-
await (0, Utils_1.sleep)(delay * 1000);
|
|
56
|
-
const crossChainLayerAddress = await settings.getAddressSetting('CrossChainLayerAddress');
|
|
57
|
-
await (0, Utils_1.sleep)(delay * 1000);
|
|
58
|
-
const jettonMinterCode = await settings.getCellSetting('JettonMinterCode');
|
|
59
|
-
await (0, Utils_1.sleep)(delay * 1000);
|
|
60
|
-
const jettonWalletCode = await settings.getCellSetting('JettonWalletCode');
|
|
61
|
-
await (0, Utils_1.sleep)(delay * 1000);
|
|
62
|
-
const nftProxyAddress = await settings.getAddressSetting('NFTProxyAddress');
|
|
63
|
-
await (0, Utils_1.sleep)(delay * 1000);
|
|
64
|
-
const nftItemCode = await settings.getCellSetting('NFTItemCode');
|
|
65
|
-
await (0, Utils_1.sleep)(delay * 1000);
|
|
66
|
-
const nftCollectionCode = await settings.getCellSetting('NFTCollectionCode');
|
|
67
|
-
await (0, Utils_1.sleep)(delay * 1000);
|
|
68
|
-
return {
|
|
69
|
-
contractOpener,
|
|
70
|
-
jettonProxyAddress,
|
|
71
|
-
crossChainLayerAddress,
|
|
72
|
-
jettonMinterCode,
|
|
73
|
-
jettonWalletCode,
|
|
74
|
-
nftProxyAddress,
|
|
75
|
-
nftItemCode,
|
|
76
|
-
nftCollectionCode,
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
static async prepareTACParams(artifacts, delay, TACParams) {
|
|
80
|
-
const provider = TACParams?.provider ?? ethers_1.ethers.getDefaultProvider(artifacts.TAC_RPC_ENDPOINT);
|
|
81
|
-
const settingsAddress = TACParams?.settingsAddress?.toString()
|
|
82
|
-
?? 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
|
-
};
|
|
53
|
+
const { testnet, mainnet } = await Promise.resolve().then(() => __importStar(require('@tonappchain/artifacts')));
|
|
54
|
+
const artifacts = network === Struct_1.Network.TESTNET ? testnet : mainnet;
|
|
55
|
+
const config = await Configuration_1.Configuration.create(network, artifacts, sdkParams.TONParams, sdkParams.TACParams, sdkParams.customLiteSequencerEndpoints, delay);
|
|
56
|
+
const simulator = new Simulator_1.Simulator(config, logger);
|
|
57
|
+
const operationTracker = new OperationTracker_1.OperationTracker(network, config.liteSequencerEndpoints);
|
|
58
|
+
const transactionManager = new TransactionManager_1.TransactionManager(config, simulator, operationTracker, logger);
|
|
59
|
+
return new TacSdk(config, simulator, transactionManager);
|
|
112
60
|
}
|
|
113
61
|
closeConnections() {
|
|
114
|
-
return this.
|
|
62
|
+
return this.config.closeConnections();
|
|
115
63
|
}
|
|
116
64
|
get nativeTONAddress() {
|
|
117
|
-
return
|
|
65
|
+
return this.config.nativeTONAddress;
|
|
118
66
|
}
|
|
119
67
|
async nativeTACAddress() {
|
|
120
|
-
return this.
|
|
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();
|
|
132
|
-
}
|
|
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
|
-
async getJettonOpType(asset) {
|
|
190
|
-
const { code: givenMinterCodeBOC } = await this.TONParams.contractOpener.getContractState((0, ton_1.address)(asset.address));
|
|
191
|
-
if (!givenMinterCodeBOC) {
|
|
192
|
-
throw errors_1.emptyContractError;
|
|
193
|
-
}
|
|
194
|
-
const givenMinterCode = ton_1.Cell.fromBoc(givenMinterCodeBOC)[0];
|
|
195
|
-
await (0, Utils_1.sleep)(this.delay * 1000);
|
|
196
|
-
if (!this.TONParams.jettonMinterCode.equals(givenMinterCode)) {
|
|
197
|
-
return InternalStruct_1.AssetOpType.JETTON_TRANSFER;
|
|
198
|
-
}
|
|
199
|
-
const givenMinter = this.TONParams.contractOpener.open(new JettonMaster_1.JettonMaster((0, ton_1.address)(asset.address)));
|
|
200
|
-
const evmAddress = await givenMinter.getEVMAddress();
|
|
201
|
-
await (0, Utils_1.sleep)(this.delay * 1000);
|
|
202
|
-
const expectedMinterAddress = await (0, Utils_1.calculateContractAddress)(this.TONParams.jettonMinterCode, (0, ton_1.beginCell)()
|
|
203
|
-
.storeCoins(0)
|
|
204
|
-
.storeAddress((0, ton_1.address)(this.TONParams.crossChainLayerAddress))
|
|
205
|
-
.storeAddress(null)
|
|
206
|
-
.storeRef((0, ton_1.beginCell)().endCell())
|
|
207
|
-
.storeRef(this.TONParams.jettonWalletCode)
|
|
208
|
-
.storeStringTail(evmAddress)
|
|
209
|
-
.endCell());
|
|
210
|
-
if (!expectedMinterAddress.equals(givenMinter.address)) {
|
|
211
|
-
return InternalStruct_1.AssetOpType.JETTON_TRANSFER;
|
|
212
|
-
}
|
|
213
|
-
return InternalStruct_1.AssetOpType.JETTON_BURN;
|
|
214
|
-
}
|
|
215
|
-
async getNFTOpType(asset) {
|
|
216
|
-
const { code: itemCodeBOC } = await this.TONParams.contractOpener.getContractState((0, ton_1.address)(asset.address));
|
|
217
|
-
if (!itemCodeBOC) {
|
|
218
|
-
throw errors_1.emptyContractError;
|
|
219
|
-
}
|
|
220
|
-
const givenNFTItemCode = ton_1.Cell.fromBoc(itemCodeBOC)[0];
|
|
221
|
-
await (0, Utils_1.sleep)(this.delay * 1000);
|
|
222
|
-
if (!this.TONParams.nftItemCode.equals(givenNFTItemCode)) {
|
|
223
|
-
return InternalStruct_1.AssetOpType.NFT_TRANSFER;
|
|
224
|
-
}
|
|
225
|
-
return InternalStruct_1.AssetOpType.NFT_BURN;
|
|
226
|
-
}
|
|
227
|
-
async getNFTItemAddressTON(collectionAddress, itemIndex) {
|
|
228
|
-
(0, Utils_1.validateTVMAddress)(collectionAddress);
|
|
229
|
-
const nftCollection = this.TONParams.contractOpener.open(wrappers_1.NFTCollection.createFromAddress((0, ton_1.address)(collectionAddress)));
|
|
230
|
-
return (await nftCollection.getNFTAddressByIndex(itemIndex)).toString();
|
|
231
|
-
}
|
|
232
|
-
async getNFTItemData(itemAddress) {
|
|
233
|
-
(0, Utils_1.validateTVMAddress)(itemAddress);
|
|
234
|
-
const nftItem = this.TONParams.contractOpener.open(wrappers_1.NFTItem.createFromAddress((0, ton_1.address)(itemAddress)));
|
|
235
|
-
return await nftItem.getNFTData();
|
|
236
|
-
}
|
|
237
|
-
async aggregateTokens(assets) {
|
|
238
|
-
const uniqueAssetsMap = new Map();
|
|
239
|
-
let crossChainTonAmount = 0n;
|
|
240
|
-
for await (const asset of assets ?? []) {
|
|
241
|
-
if (asset.rawAmount <= 0)
|
|
242
|
-
continue;
|
|
243
|
-
if (asset.type !== Struct_1.AssetType.FT)
|
|
244
|
-
continue;
|
|
245
|
-
if (asset.address) {
|
|
246
|
-
(0, Utils_1.validateTVMAddress)(asset.address);
|
|
247
|
-
uniqueAssetsMap.set(asset.address, (uniqueAssetsMap.get(asset.address) || 0n) + BigInt(asset.rawAmount));
|
|
248
|
-
}
|
|
249
|
-
else {
|
|
250
|
-
crossChainTonAmount += BigInt(asset.rawAmount);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
const jettons = Array.from(uniqueAssetsMap.entries()).map(([address, rawAmount]) => ({
|
|
254
|
-
address,
|
|
255
|
-
rawAmount,
|
|
256
|
-
type: Struct_1.AssetType.FT,
|
|
257
|
-
}));
|
|
258
|
-
uniqueAssetsMap.clear();
|
|
259
|
-
for await (const asset of assets ?? []) {
|
|
260
|
-
if (asset.type !== Struct_1.AssetType.NFT)
|
|
261
|
-
continue;
|
|
262
|
-
(0, Utils_1.validateTVMAddress)(asset.address);
|
|
263
|
-
uniqueAssetsMap.set(asset.address, 1n);
|
|
264
|
-
}
|
|
265
|
-
const nfts = Array.from(uniqueAssetsMap.entries()).map(([address, rawAmount]) => ({
|
|
266
|
-
address,
|
|
267
|
-
rawAmount,
|
|
268
|
-
type: Struct_1.AssetType.NFT,
|
|
269
|
-
}));
|
|
270
|
-
return {
|
|
271
|
-
jettons,
|
|
272
|
-
nfts,
|
|
273
|
-
crossChainTonAmount,
|
|
274
|
-
};
|
|
275
|
-
}
|
|
276
|
-
async generateJettonPayload(jetton, caller, evmData, crossChainTonAmount, forwardFeeTonAmount, feeParams) {
|
|
277
|
-
const opType = await this.getJettonOpType(jetton);
|
|
278
|
-
await (0, Utils_1.sleep)(this.delay * 1000);
|
|
279
|
-
console.log(`***** Jetton ${jetton.address} requires ${opType} operation`);
|
|
280
|
-
const feeData = (0, Utils_1.generateFeeData)(feeParams);
|
|
281
|
-
let payload;
|
|
282
|
-
switch (opType) {
|
|
283
|
-
case InternalStruct_1.AssetOpType.JETTON_BURN:
|
|
284
|
-
payload = this.getJettonBurnPayload({
|
|
285
|
-
notificationReceiverAddress: this.TONParams.crossChainLayerAddress,
|
|
286
|
-
...jetton,
|
|
287
|
-
}, evmData, crossChainTonAmount, feeData);
|
|
288
|
-
break;
|
|
289
|
-
case InternalStruct_1.AssetOpType.JETTON_TRANSFER:
|
|
290
|
-
payload = this.getJettonTransferPayload(jetton, caller, evmData, crossChainTonAmount, forwardFeeTonAmount, feeData);
|
|
291
|
-
break;
|
|
292
|
-
}
|
|
293
|
-
return payload;
|
|
68
|
+
return this.config.nativeTACAddress();
|
|
294
69
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
await (0, Utils_1.sleep)(this.delay * 1000);
|
|
298
|
-
console.log(`***** NFT ${nft.address} requires ${opType} operation`);
|
|
299
|
-
const feeData = (0, Utils_1.generateFeeData)(feeParams);
|
|
300
|
-
let payload;
|
|
301
|
-
switch (opType) {
|
|
302
|
-
case InternalStruct_1.AssetOpType.NFT_BURN:
|
|
303
|
-
payload = this.getNFTBurnPayload({
|
|
304
|
-
notificationReceiverAddress: this.TONParams.crossChainLayerAddress,
|
|
305
|
-
...nft,
|
|
306
|
-
evmData,
|
|
307
|
-
crossChainTonAmount,
|
|
308
|
-
feeData,
|
|
309
|
-
});
|
|
310
|
-
break;
|
|
311
|
-
case InternalStruct_1.AssetOpType.NFT_TRANSFER:
|
|
312
|
-
payload = this.getNFTTransferPayload({
|
|
313
|
-
to: this.TONParams.nftProxyAddress,
|
|
314
|
-
responseAddress: caller,
|
|
315
|
-
evmData,
|
|
316
|
-
crossChainTonAmount,
|
|
317
|
-
feeData,
|
|
318
|
-
...nft,
|
|
319
|
-
}, forwardFeeTonAmount);
|
|
320
|
-
break;
|
|
321
|
-
}
|
|
322
|
-
return payload;
|
|
323
|
-
}
|
|
324
|
-
async generateCrossChainMessages(caller, evmData, aggregatedData, feeParams) {
|
|
325
|
-
let crossChainTonAmount = aggregatedData.crossChainTonAmount;
|
|
326
|
-
let feeTonAmount = feeParams.protocolFee + feeParams.evmExecutorFee + feeParams.tvmExecutorFee;
|
|
327
|
-
if (aggregatedData.jettons.length == 0 && aggregatedData.nfts.length == 0) {
|
|
328
|
-
return [
|
|
329
|
-
{
|
|
330
|
-
address: this.TONParams.crossChainLayerAddress,
|
|
331
|
-
value: crossChainTonAmount + feeTonAmount + Consts_1.TRANSACTION_TON_AMOUNT,
|
|
332
|
-
payload: this.getTonTransferPayload(caller, evmData, crossChainTonAmount, feeParams),
|
|
333
|
-
},
|
|
334
|
-
];
|
|
335
|
-
}
|
|
336
|
-
const messages = [];
|
|
337
|
-
let currentFeeParams = feeParams;
|
|
338
|
-
for (const jetton of aggregatedData.jettons) {
|
|
339
|
-
const payload = await this.generateJettonPayload(jetton, caller, evmData, crossChainTonAmount, feeTonAmount, currentFeeParams);
|
|
340
|
-
await (0, Utils_1.sleep)(this.delay * 1000);
|
|
341
|
-
const jettonWalletAddress = await this.getUserJettonWalletAddress(caller, jetton.address);
|
|
342
|
-
await (0, Utils_1.sleep)(this.delay * 1000);
|
|
343
|
-
messages.push({
|
|
344
|
-
address: jettonWalletAddress,
|
|
345
|
-
value: crossChainTonAmount + feeTonAmount + Consts_1.TRANSACTION_TON_AMOUNT,
|
|
346
|
-
payload,
|
|
347
|
-
});
|
|
348
|
-
crossChainTonAmount = 0n;
|
|
349
|
-
feeTonAmount = 0n;
|
|
350
|
-
currentFeeParams = undefined;
|
|
351
|
-
}
|
|
352
|
-
for (const nft of aggregatedData.nfts) {
|
|
353
|
-
const payload = await this.generateNFTPayload(nft, caller, evmData, crossChainTonAmount, feeTonAmount, currentFeeParams);
|
|
354
|
-
await (0, Utils_1.sleep)(this.delay * 1000);
|
|
355
|
-
messages.push({
|
|
356
|
-
address: nft.address,
|
|
357
|
-
value: crossChainTonAmount + feeTonAmount + Consts_1.TRANSACTION_TON_AMOUNT,
|
|
358
|
-
payload,
|
|
359
|
-
});
|
|
360
|
-
crossChainTonAmount = 0n;
|
|
361
|
-
feeTonAmount = 0n;
|
|
362
|
-
currentFeeParams = undefined;
|
|
363
|
-
}
|
|
364
|
-
return messages;
|
|
365
|
-
}
|
|
366
|
-
async getRawAmount(asset, precalculatedAddress) {
|
|
367
|
-
if ('rawAmount' in asset) {
|
|
368
|
-
// User specified raw format amount
|
|
369
|
-
return asset.rawAmount;
|
|
370
|
-
}
|
|
371
|
-
if (!precalculatedAddress) {
|
|
372
|
-
// User specified TON Coin
|
|
373
|
-
return (0, ton_1.toNano)(asset.amount);
|
|
374
|
-
}
|
|
375
|
-
if (typeof asset.decimals === 'number') {
|
|
376
|
-
// User manually set decimals
|
|
377
|
-
return (0, Utils_1.calculateRawAmount)(asset.amount, asset.decimals);
|
|
378
|
-
}
|
|
379
|
-
// Get decimals from chain
|
|
380
|
-
(0, Utils_1.validateTVMAddress)(precalculatedAddress);
|
|
381
|
-
const contract = this.TONParams.contractOpener.open(new JettonMaster_1.JettonMaster((0, ton_1.address)(precalculatedAddress)));
|
|
382
|
-
const { content } = await contract.getJettonData();
|
|
383
|
-
await (0, Utils_1.sleep)(this.delay * 1000);
|
|
384
|
-
if (!content.metadata.decimals) {
|
|
385
|
-
// if decimals not specified use default value 9
|
|
386
|
-
return (0, ton_1.toNano)(asset.amount);
|
|
387
|
-
}
|
|
388
|
-
return (0, Utils_1.calculateRawAmount)(asset.amount, Number(content.metadata.decimals));
|
|
389
|
-
}
|
|
390
|
-
async convertAssetsToRawFormat(assets) {
|
|
391
|
-
return await Promise.all((assets ?? []).map(async (asset) => {
|
|
392
|
-
if (asset.type === Struct_1.AssetType.FT) {
|
|
393
|
-
const address = (0, ethers_1.isAddress)(asset.address)
|
|
394
|
-
? await this.getTVMTokenAddress(asset.address)
|
|
395
|
-
: asset.address;
|
|
396
|
-
return {
|
|
397
|
-
address,
|
|
398
|
-
rawAmount: await this.getRawAmount(asset, address),
|
|
399
|
-
type: asset.type,
|
|
400
|
-
};
|
|
401
|
-
}
|
|
402
|
-
if (asset.type === Struct_1.AssetType.NFT) {
|
|
403
|
-
if ('collectionAddress' in asset) {
|
|
404
|
-
const address = (0, ethers_1.isAddress)(asset.collectionAddress)
|
|
405
|
-
? await this.getTVMNFTAddress(asset.collectionAddress, asset.itemIndex)
|
|
406
|
-
: await this.getNFTItemAddressTON(asset.collectionAddress, asset.itemIndex);
|
|
407
|
-
await (0, Utils_1.sleep)(this.delay * 1000);
|
|
408
|
-
return {
|
|
409
|
-
address,
|
|
410
|
-
rawAmount: 1n,
|
|
411
|
-
type: asset.type,
|
|
412
|
-
};
|
|
413
|
-
}
|
|
414
|
-
(0, Utils_1.validateTVMAddress)(asset.address);
|
|
415
|
-
return {
|
|
416
|
-
address: asset.address,
|
|
417
|
-
rawAmount: 1n,
|
|
418
|
-
type: asset.type,
|
|
419
|
-
};
|
|
420
|
-
}
|
|
421
|
-
throw instances_1.invalidAssetType;
|
|
422
|
-
}));
|
|
70
|
+
get getTrustedTACExecutors() {
|
|
71
|
+
return this.config.getTrustedTACExecutors;
|
|
423
72
|
}
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
const fullStateCCL = await crossChainLayer.getFullData();
|
|
427
|
-
const tacSimulationBody = {
|
|
428
|
-
tacCallParams: {
|
|
429
|
-
arguments: evmProxyMsg.encodedParameters ?? '0x',
|
|
430
|
-
methodName: (0, Utils_1.formatSolidityMethodName)(evmProxyMsg.methodName),
|
|
431
|
-
target: evmProxyMsg.evmTargetAddress,
|
|
432
|
-
},
|
|
433
|
-
evmValidExecutors: evmValidExecutors,
|
|
434
|
-
extraData: '0x',
|
|
435
|
-
shardsKey: transactionLinker.shardsKey,
|
|
436
|
-
tonAssets: rawAssets.map((asset) => ({
|
|
437
|
-
amount: asset.rawAmount.toString(),
|
|
438
|
-
tokenAddress: asset.address || '',
|
|
439
|
-
assetType: asset.type,
|
|
440
|
-
})),
|
|
441
|
-
tonCaller: transactionLinker.caller,
|
|
442
|
-
};
|
|
443
|
-
isRoundTrip = isRoundTrip ?? (rawAssets.length != 0);
|
|
444
|
-
const tacSimulationResult = await this.simulateTACMessage(tacSimulationBody);
|
|
445
|
-
if (!tacSimulationResult.simulationStatus) {
|
|
446
|
-
if (forceSend) {
|
|
447
|
-
return {
|
|
448
|
-
feeParams: {
|
|
449
|
-
isRoundTrip,
|
|
450
|
-
gasLimit: 0n,
|
|
451
|
-
protocolFee: BigInt((0, ton_1.toNano)(fullStateCCL.tacProtocolFee)) +
|
|
452
|
-
BigInt(isRoundTrip) * BigInt((0, ton_1.toNano)(fullStateCCL.tonProtocolFee)),
|
|
453
|
-
evmExecutorFee: BigInt(tacSimulationResult.suggestedTacExecutionFee),
|
|
454
|
-
tvmExecutorFee: BigInt(tacSimulationResult.suggestedTonExecutionFee) * BigInt(isRoundTrip),
|
|
455
|
-
},
|
|
456
|
-
simulation: tacSimulationResult,
|
|
457
|
-
};
|
|
458
|
-
}
|
|
459
|
-
throw tacSimulationResult;
|
|
460
|
-
}
|
|
461
|
-
const protocolFee = BigInt((0, ton_1.toNano)(fullStateCCL.tacProtocolFee)) +
|
|
462
|
-
BigInt(isRoundTrip) * BigInt((0, ton_1.toNano)(fullStateCCL.tonProtocolFee));
|
|
463
|
-
const feeParams = {
|
|
464
|
-
isRoundTrip: isRoundTrip,
|
|
465
|
-
gasLimit: tacSimulationResult.estimatedGas,
|
|
466
|
-
protocolFee: protocolFee,
|
|
467
|
-
evmExecutorFee: BigInt(tacSimulationResult.suggestedTacExecutionFee),
|
|
468
|
-
tvmExecutorFee: BigInt(tacSimulationResult.suggestedTonExecutionFee) * BigInt(isRoundTrip),
|
|
469
|
-
};
|
|
470
|
-
return { feeParams: feeParams, simulation: tacSimulationResult };
|
|
73
|
+
get getTrustedTONExecutors() {
|
|
74
|
+
return this.config.getTrustedTONExecutors;
|
|
471
75
|
}
|
|
472
76
|
async getTransactionSimulationInfo(evmProxyMsg, sender, assets) {
|
|
473
|
-
|
|
474
|
-
const aggregatedData = await this.aggregateTokens(rawAssets);
|
|
475
|
-
const transactionLinkerShardCount = aggregatedData.jettons.length == 0 ? 1 : aggregatedData.jettons.length;
|
|
476
|
-
const transactionLinker = (0, Utils_1.generateTransactionLinker)(sender.getSenderAddress(), transactionLinkerShardCount);
|
|
477
|
-
return await this.getFeeInfo(evmProxyMsg, transactionLinker, rawAssets);
|
|
77
|
+
return this.simulator.getTransactionSimulationInfo(evmProxyMsg, sender, assets);
|
|
478
78
|
}
|
|
479
79
|
async getTVMExecutorFeeInfo(assets, feeSymbol) {
|
|
480
|
-
|
|
481
|
-
const requestBody = {
|
|
482
|
-
tonAssets: rawAssets.map((asset) => ({
|
|
483
|
-
amount: asset.rawAmount.toString(),
|
|
484
|
-
tokenAddress: asset.address || '',
|
|
485
|
-
assetType: asset.type,
|
|
486
|
-
})),
|
|
487
|
-
feeSymbol: feeSymbol,
|
|
488
|
-
};
|
|
489
|
-
let lastError;
|
|
490
|
-
for (const endpoint of this.liteSequencerEndpoints) {
|
|
491
|
-
try {
|
|
492
|
-
const response = await axios_1.default.post(`${endpoint}/ton/calculator/ton-executor-fee`, requestBody);
|
|
493
|
-
return response.data.response;
|
|
494
|
-
}
|
|
495
|
-
catch (error) {
|
|
496
|
-
console.error(`Error while calculating tvm executor fee ${endpoint}:`, error);
|
|
497
|
-
lastError = error;
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
throw (0, errors_1.simulationError)(lastError);
|
|
501
|
-
}
|
|
502
|
-
async prepareCrossChainTransaction(evmProxyMsg, caller, assets, options) {
|
|
503
|
-
let { forceSend = false, isRoundTrip = undefined, protocolFee = undefined, evmValidExecutors = [], evmExecutorFee = undefined, tvmValidExecutors = [], tvmExecutorFee = undefined, } = options || {};
|
|
504
|
-
const rawAssets = await this.convertAssetsToRawFormat(assets);
|
|
505
|
-
const aggregatedData = await this.aggregateTokens(rawAssets);
|
|
506
|
-
const tokensLength = aggregatedData.jettons.length + aggregatedData.nfts.length;
|
|
507
|
-
let transactionLinkerShardCount = tokensLength == 0 ? 1 : tokensLength;
|
|
508
|
-
const transactionLinker = (0, Utils_1.generateTransactionLinker)(caller, transactionLinkerShardCount);
|
|
509
|
-
if (evmValidExecutors.length == 0) {
|
|
510
|
-
evmValidExecutors = this.TACParams.trustedTACExecutors;
|
|
511
|
-
}
|
|
512
|
-
if (tvmValidExecutors.length == 0) {
|
|
513
|
-
tvmValidExecutors = this.TACParams.trustedTONExecutors;
|
|
514
|
-
}
|
|
515
|
-
const { feeParams } = await this.getFeeInfo(evmProxyMsg, transactionLinker, rawAssets, forceSend, isRoundTrip, evmValidExecutors);
|
|
516
|
-
if (evmProxyMsg.gasLimit == undefined) {
|
|
517
|
-
evmProxyMsg.gasLimit = feeParams.gasLimit;
|
|
518
|
-
}
|
|
519
|
-
if (evmExecutorFee != undefined) {
|
|
520
|
-
feeParams.evmExecutorFee = evmExecutorFee;
|
|
521
|
-
}
|
|
522
|
-
if (feeParams.isRoundTrip && tvmExecutorFee != undefined) {
|
|
523
|
-
feeParams.tvmExecutorFee = tvmExecutorFee;
|
|
524
|
-
}
|
|
525
|
-
if (protocolFee != undefined) {
|
|
526
|
-
feeParams.protocolFee = protocolFee;
|
|
527
|
-
}
|
|
528
|
-
const validExecutors = {
|
|
529
|
-
tac: evmValidExecutors,
|
|
530
|
-
ton: tvmValidExecutors,
|
|
531
|
-
};
|
|
532
|
-
const evmData = (0, Utils_1.buildEvmDataCell)(transactionLinker, evmProxyMsg, validExecutors);
|
|
533
|
-
const messages = await this.generateCrossChainMessages(caller, evmData, aggregatedData, feeParams);
|
|
534
|
-
await (0, Utils_1.sleep)(this.delay * 1000);
|
|
535
|
-
const transaction = {
|
|
536
|
-
validUntil: +new Date() + 15 * 60 * 1000,
|
|
537
|
-
messages,
|
|
538
|
-
network: this.network,
|
|
539
|
-
};
|
|
540
|
-
return { transaction, transactionLinker };
|
|
80
|
+
return this.simulator.getTVMExecutorFeeInfo(assets, feeSymbol);
|
|
541
81
|
}
|
|
542
|
-
async sendCrossChainTransaction(evmProxyMsg, sender, assets, options) {
|
|
543
|
-
|
|
544
|
-
const { transaction, transactionLinker } = await this.prepareCrossChainTransaction(evmProxyMsg, caller, assets, options);
|
|
545
|
-
console.log('*****Sending transaction: ', transaction);
|
|
546
|
-
const sendTransactionResult = await sender.sendShardTransaction(transaction, this.delay, this.network, this.TONParams.contractOpener);
|
|
547
|
-
return { sendTransactionResult, ...transactionLinker };
|
|
82
|
+
async sendCrossChainTransaction(evmProxyMsg, sender, assets, options, waitOptions) {
|
|
83
|
+
return this.transactionManager.sendCrossChainTransaction(evmProxyMsg, sender, assets, options, waitOptions);
|
|
548
84
|
}
|
|
549
|
-
async sendCrossChainTransactions(sender, txs) {
|
|
550
|
-
|
|
551
|
-
const transactionLinkers = [];
|
|
552
|
-
const caller = sender.getSenderAddress();
|
|
553
|
-
for (const { options, assets, evmProxyMsg } of txs) {
|
|
554
|
-
const { transaction, transactionLinker } = await this.prepareCrossChainTransaction(evmProxyMsg, caller, assets, options);
|
|
555
|
-
transactions.push(transaction);
|
|
556
|
-
transactionLinkers.push(transactionLinker);
|
|
557
|
-
}
|
|
558
|
-
console.log('*****Sending transactions: ', transactions);
|
|
559
|
-
await sender.sendShardTransactions(transactions, this.delay, this.network, this.TONParams.contractOpener);
|
|
560
|
-
return transactionLinkers;
|
|
85
|
+
async sendCrossChainTransactions(sender, txs, waitOptions) {
|
|
86
|
+
return this.transactionManager.sendCrossChainTransactions(sender, txs, waitOptions);
|
|
561
87
|
}
|
|
562
|
-
// TODO move to sdk.TAC, sdk.TON
|
|
563
88
|
async bridgeTokensToTON(signer, value, tonTarget, assets, tvmExecutorFee) {
|
|
564
|
-
|
|
565
|
-
assets = [];
|
|
566
|
-
}
|
|
567
|
-
let tonAssets = [];
|
|
568
|
-
for (const asset of assets) {
|
|
569
|
-
if (asset.type == Struct_1.AssetType.FT) {
|
|
570
|
-
const tvmAddress = await this.getTVMTokenAddress(asset.address);
|
|
571
|
-
tonAssets.push({
|
|
572
|
-
address: tvmAddress,
|
|
573
|
-
rawAmount: asset.rawAmount,
|
|
574
|
-
type: Struct_1.AssetType.FT,
|
|
575
|
-
});
|
|
576
|
-
}
|
|
577
|
-
else {
|
|
578
|
-
const nftItemAddress = await this.getTVMNFTAddress(asset.collectionAddress, asset.itemIndex);
|
|
579
|
-
tonAssets.push({
|
|
580
|
-
address: nftItemAddress,
|
|
581
|
-
amount: 1,
|
|
582
|
-
type: Struct_1.AssetType.NFT,
|
|
583
|
-
});
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
if (value > 0) {
|
|
587
|
-
const tvmAddress = await this.getTVMTokenAddress(await this.nativeTACAddress());
|
|
588
|
-
tonAssets.push({
|
|
589
|
-
address: tvmAddress,
|
|
590
|
-
rawAmount: value,
|
|
591
|
-
type: Struct_1.AssetType.FT,
|
|
592
|
-
});
|
|
593
|
-
}
|
|
594
|
-
const suggestedTONExecutorFee = await this.getTVMExecutorFeeInfo(tonAssets, Consts_1.TAC_SYMBOL);
|
|
595
|
-
const crossChainLayerAddress = await this.TACParams.crossChainLayer.getAddress();
|
|
596
|
-
for (const asset of assets) {
|
|
597
|
-
if (asset.type == Struct_1.AssetType.FT) {
|
|
598
|
-
const tokenContract = this.artifacts.tac.wrappers.ERC20FactoryTAC.connect(asset.address, this.TACParams.provider);
|
|
599
|
-
const tx = await tokenContract.connect(signer).approve(crossChainLayerAddress, asset.rawAmount);
|
|
600
|
-
await tx.wait();
|
|
601
|
-
}
|
|
602
|
-
if (asset.type == Struct_1.AssetType.NFT) {
|
|
603
|
-
const tokenContract = this.artifacts.tac.wrappers.ERC721FactoryTAC.connect(asset.collectionAddress, this.TACParams.provider);
|
|
604
|
-
const tx = await tokenContract.connect(signer).approve(crossChainLayerAddress, asset.itemIndex);
|
|
605
|
-
await tx.wait();
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
const shardsKey = BigInt(Math.round(Math.random() * 1e18));
|
|
609
|
-
const protocolFee = await this.TACParams.crossChainLayer.getProtocolFee();
|
|
610
|
-
const outMessage = {
|
|
611
|
-
shardsKey: shardsKey,
|
|
612
|
-
tvmTarget: tonTarget,
|
|
613
|
-
tvmPayload: '',
|
|
614
|
-
tvmProtocolFee: protocolFee,
|
|
615
|
-
tvmExecutorFee: tvmExecutorFee ?? BigInt(suggestedTONExecutorFee.inTAC),
|
|
616
|
-
tvmValidExecutors: this.TACParams.trustedTONExecutors,
|
|
617
|
-
toBridge: assets
|
|
618
|
-
.filter((asset) => asset.type === Struct_1.AssetType.FT)
|
|
619
|
-
.map((asset) => ({
|
|
620
|
-
evmAddress: asset.address,
|
|
621
|
-
amount: asset.rawAmount,
|
|
622
|
-
})),
|
|
623
|
-
toBridgeNFT: assets
|
|
624
|
-
.filter((asset) => asset.type === Struct_1.AssetType.NFT)
|
|
625
|
-
.map((asset) => ({
|
|
626
|
-
evmAddress: asset.collectionAddress,
|
|
627
|
-
amount: 1n,
|
|
628
|
-
tokenId: asset.itemIndex,
|
|
629
|
-
})),
|
|
630
|
-
};
|
|
631
|
-
const encodedOutMessage = this.artifacts.tac.utils.encodeOutMessageV1(outMessage);
|
|
632
|
-
const outMsgVersion = 1n;
|
|
633
|
-
const totalValue = value + BigInt(outMessage.tvmProtocolFee) + BigInt(outMessage.tvmExecutorFee);
|
|
634
|
-
const tx = await this.TACParams.crossChainLayer
|
|
635
|
-
.connect(signer)
|
|
636
|
-
.sendMessage(outMsgVersion, encodedOutMessage, { value: totalValue });
|
|
637
|
-
await tx.wait();
|
|
638
|
-
return tx.hash;
|
|
639
|
-
}
|
|
640
|
-
get getTrustedTACExecutors() {
|
|
641
|
-
return this.TACParams.trustedTACExecutors;
|
|
642
|
-
}
|
|
643
|
-
get getTrustedTONExecutors() {
|
|
644
|
-
return this.TACParams.trustedTONExecutors;
|
|
645
|
-
}
|
|
646
|
-
async getEVMTokenAddress(tvmTokenAddress) {
|
|
647
|
-
if (tvmTokenAddress !== this.nativeTONAddress) {
|
|
648
|
-
(0, Utils_1.validateTVMAddress)(tvmTokenAddress);
|
|
649
|
-
tvmTokenAddress = ton_1.Address.parse(tvmTokenAddress).toString({ bounceable: true });
|
|
650
|
-
const { code: givenMinterCodeBOC } = await this.TONParams.contractOpener.getContractState((0, ton_1.address)(tvmTokenAddress));
|
|
651
|
-
await (0, Utils_1.sleep)(this.delay * 1000);
|
|
652
|
-
if (givenMinterCodeBOC && this.TONParams.jettonMinterCode.equals(ton_1.Cell.fromBoc(givenMinterCodeBOC)[0])) {
|
|
653
|
-
const givenMinter = this.TONParams.contractOpener.open(new JettonMaster_1.JettonMaster((0, ton_1.address)(tvmTokenAddress)));
|
|
654
|
-
const evmAddress = await givenMinter.getEVMAddress();
|
|
655
|
-
await (0, Utils_1.sleep)(this.delay * 1000);
|
|
656
|
-
return evmAddress;
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
return this.TACParams.tokenUtils.computeAddress(tvmTokenAddress);
|
|
660
|
-
}
|
|
661
|
-
async getTVMTokenAddress(evmTokenAddress) {
|
|
662
|
-
(0, Utils_1.validateEVMAddress)(evmTokenAddress);
|
|
663
|
-
const exists = await this.TACParams.tokenUtils['exists(address)'](evmTokenAddress);
|
|
664
|
-
if (exists) {
|
|
665
|
-
const erc721Token = this.artifacts.tac.wrappers.CrossChainLayerERC20FactoryTAC.connect(evmTokenAddress, this.TACParams.provider);
|
|
666
|
-
const info = await erc721Token.getInfo();
|
|
667
|
-
return info.tvmAddress;
|
|
668
|
-
}
|
|
669
|
-
const jettonMaster = JettonMaster_1.JettonMaster.createFromConfig({
|
|
670
|
-
evmTokenAddress,
|
|
671
|
-
crossChainLayerAddress: (0, ton_1.address)(this.TONParams.crossChainLayerAddress),
|
|
672
|
-
code: this.TONParams.jettonMinterCode,
|
|
673
|
-
walletCode: this.TONParams.jettonWalletCode,
|
|
674
|
-
});
|
|
675
|
-
return jettonMaster.address.toString();
|
|
676
|
-
}
|
|
677
|
-
async getTVMNFTAddress(evmNFTAddress, tokenId) {
|
|
678
|
-
(0, Utils_1.validateEVMAddress)(evmNFTAddress);
|
|
679
|
-
let nftCollection;
|
|
680
|
-
const exists = await this.TACParams.tokenUtils['exists(address)'](evmNFTAddress);
|
|
681
|
-
if (exists) {
|
|
682
|
-
const erc721Token = this.artifacts.tac.wrappers.CrossChainLayerERC721FactoryTAC.connect(evmNFTAddress, this.TACParams.provider);
|
|
683
|
-
const info = await erc721Token.getInfo();
|
|
684
|
-
nftCollection = this.TONParams.contractOpener.open(wrappers_1.NFTCollection.createFromAddress((0, ton_1.address)(info.tvmAddress)));
|
|
685
|
-
return tokenId == undefined
|
|
686
|
-
? nftCollection.address.toString()
|
|
687
|
-
: (await nftCollection.getNFTAddressByIndex(tokenId)).toString();
|
|
688
|
-
}
|
|
689
|
-
else {
|
|
690
|
-
nftCollection = this.TONParams.contractOpener.open(wrappers_1.NFTCollection.createFromConfig({
|
|
691
|
-
ownerAddress: (0, ton_1.address)(this.TONParams.crossChainLayerAddress),
|
|
692
|
-
content: (0, ton_1.beginCell)().endCell(),
|
|
693
|
-
nftItemCode: this.TONParams.nftItemCode,
|
|
694
|
-
originalAddress: evmNFTAddress,
|
|
695
|
-
}, this.TONParams.nftCollectionCode));
|
|
696
|
-
return tokenId == undefined
|
|
697
|
-
? nftCollection.address.toString()
|
|
698
|
-
: wrappers_1.NFTItem.createFromConfig({
|
|
699
|
-
collectionAddress: nftCollection.address,
|
|
700
|
-
cclAddress: (0, ton_1.address)(this.TONParams.crossChainLayerAddress),
|
|
701
|
-
// @ts-ignore // bigint can be used, wrapper is not typed properly
|
|
702
|
-
index: tokenId,
|
|
703
|
-
}, this.TONParams.nftItemCode).address.toString();
|
|
704
|
-
}
|
|
705
|
-
}
|
|
706
|
-
async getEVMNFTAddress(tvmNFTAddress, addressType) {
|
|
707
|
-
(0, Utils_1.validateTVMAddress)(tvmNFTAddress);
|
|
708
|
-
tvmNFTAddress = ton_1.Address.parse(tvmNFTAddress).toString({ bounceable: true });
|
|
709
|
-
if (addressType == Struct_1.NFTAddressType.ITEM) {
|
|
710
|
-
tvmNFTAddress = (await this.getNFTItemData(tvmNFTAddress)).collectionAddress.toString();
|
|
711
|
-
addressType = Struct_1.NFTAddressType.COLLECTION;
|
|
712
|
-
await (0, Utils_1.sleep)(this.delay * 1000);
|
|
713
|
-
}
|
|
714
|
-
const { code: givenNFTCollection } = await this.TONParams.contractOpener.getContractState((0, ton_1.address)(tvmNFTAddress));
|
|
715
|
-
await (0, Utils_1.sleep)(this.delay * 1000);
|
|
716
|
-
if (givenNFTCollection && this.TONParams.nftCollectionCode.equals(ton_1.Cell.fromBoc(givenNFTCollection)[0])) {
|
|
717
|
-
const nftCollection = this.TONParams.contractOpener.open(wrappers_1.NFTCollection.createFromAddress((0, ton_1.address)(tvmNFTAddress)));
|
|
718
|
-
const evmAddress = await nftCollection.getOriginalAddress();
|
|
719
|
-
await (0, Utils_1.sleep)(this.delay * 1000);
|
|
720
|
-
return evmAddress.toString();
|
|
721
|
-
}
|
|
722
|
-
return this.TACParams.tokenUtils.computeAddressERC721(tvmNFTAddress);
|
|
89
|
+
return this.transactionManager.bridgeTokensToTON(signer, value, tonTarget, assets, tvmExecutorFee);
|
|
723
90
|
}
|
|
724
91
|
async isContractDeployedOnTVM(address) {
|
|
725
|
-
return
|
|
92
|
+
return this.config.isContractDeployedOnTVM(address);
|
|
726
93
|
}
|
|
727
94
|
async simulateTACMessage(req) {
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
transformResponse: [Utils_1.toCamelCaseTransformer],
|
|
733
|
-
});
|
|
734
|
-
return response.data.response;
|
|
735
|
-
}
|
|
736
|
-
catch (error) {
|
|
737
|
-
console.error(`Error while simulating with ${endpoint}:`, error);
|
|
738
|
-
lastError = error;
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
throw (0, errors_1.simulationError)(lastError);
|
|
95
|
+
return this.simulator.simulateTACMessage(req);
|
|
96
|
+
}
|
|
97
|
+
async simulateTransactions(sender, txs) {
|
|
98
|
+
return this.simulator.simulateTransactions(sender, txs);
|
|
742
99
|
}
|
|
743
100
|
}
|
|
744
101
|
exports.TacSdk = TacSdk;
|