@tonappchain/sdk 0.7.0-rc13 → 0.7.0-rc15
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/README.md +7 -7
- package/dist/adapters/contractOpener.js +33 -4
- package/dist/adapters/retryableContractOpener.js +1 -1
- package/dist/assets/AssetFactory.js +1 -1
- package/dist/assets/FT.d.ts +8 -12
- package/dist/assets/FT.js +69 -36
- package/dist/assets/NFT.d.ts +4 -2
- package/dist/assets/NFT.js +14 -2
- package/dist/assets/TON.d.ts +4 -10
- package/dist/assets/TON.js +17 -15
- package/dist/errors/index.d.ts +1 -1
- package/dist/errors/index.js +7 -2
- package/dist/errors/instances.d.ts +8 -1
- package/dist/errors/instances.js +22 -16
- package/dist/index.d.ts +2 -1
- package/dist/index.js +5 -3
- package/dist/interfaces/Asset.d.ts +22 -17
- package/dist/interfaces/ILiteSequencerClient.d.ts +14 -1
- package/dist/interfaces/IOperationTracker.d.ts +16 -1
- package/dist/interfaces/ISimulator.d.ts +7 -36
- package/dist/interfaces/ITACTransactionManager.d.ts +15 -0
- package/dist/interfaces/ITONTransactionManager.d.ts +21 -0
- package/dist/interfaces/ITONTransactionManager.js +2 -0
- package/dist/interfaces/ITacSDK.d.ts +51 -13
- package/dist/interfaces/index.d.ts +2 -1
- package/dist/interfaces/index.js +2 -1
- package/dist/sdk/Configuration.d.ts +1 -0
- package/dist/sdk/Configuration.js +67 -14
- package/dist/sdk/Consts.d.ts +1 -0
- package/dist/sdk/Consts.js +5 -4
- package/dist/sdk/LiteSequencerClient.d.ts +5 -3
- package/dist/sdk/LiteSequencerClient.js +27 -4
- package/dist/sdk/OperationTracker.d.ts +3 -1
- package/dist/sdk/OperationTracker.js +51 -11
- package/dist/sdk/Simulator.d.ts +6 -12
- package/dist/sdk/Simulator.js +30 -124
- package/dist/sdk/TACTransactionManager.d.ts +10 -0
- package/dist/sdk/TACTransactionManager.js +92 -0
- package/dist/sdk/TONTransactionManager.d.ts +17 -0
- package/dist/sdk/TONTransactionManager.js +209 -0
- package/dist/sdk/TacSdk.d.ts +16 -10
- package/dist/sdk/TacSdk.js +52 -19
- package/dist/sdk/TxFinalizer.d.ts +3 -2
- package/dist/sdk/TxFinalizer.js +8 -8
- package/dist/sdk/Utils.d.ts +9 -4
- package/dist/sdk/Utils.js +86 -12
- package/dist/sdk/Validator.d.ts +2 -2
- package/dist/sdk/Validator.js +1 -1
- package/dist/structs/InternalStruct.d.ts +6 -2
- package/dist/structs/Struct.d.ts +70 -16
- package/dist/wrappers/Settings.d.ts +5 -1
- package/dist/wrappers/Settings.js +17 -0
- package/package.json +4 -3
- package/dist/interfaces/ITransactionManager.d.ts +0 -35
- package/dist/sdk/TransactionManager.d.ts +0 -22
- package/dist/sdk/TransactionManager.js +0 -272
- /package/dist/interfaces/{ITransactionManager.js → ITACTransactionManager.js} +0 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TONTransactionManager = void 0;
|
|
4
|
+
const assets_1 = require("../assets");
|
|
5
|
+
const errors_1 = require("../errors");
|
|
6
|
+
const Consts_1 = require("./Consts");
|
|
7
|
+
const Logger_1 = require("./Logger");
|
|
8
|
+
const Utils_1 = require("./Utils");
|
|
9
|
+
const Validator_1 = require("./Validator");
|
|
10
|
+
class TONTransactionManager {
|
|
11
|
+
constructor(config, simulator, operationTracker, logger = new Logger_1.NoopLogger()) {
|
|
12
|
+
this.config = config;
|
|
13
|
+
this.simulator = simulator;
|
|
14
|
+
this.operationTracker = operationTracker;
|
|
15
|
+
this.logger = logger;
|
|
16
|
+
}
|
|
17
|
+
async buildFeeParams(options, evmProxyMsg, sender, tx) {
|
|
18
|
+
const { withoutSimulation, protocolFee, evmExecutorFee, tvmExecutorFee, isRoundTrip } = options;
|
|
19
|
+
if (withoutSimulation) {
|
|
20
|
+
if (protocolFee === undefined || evmExecutorFee === undefined) {
|
|
21
|
+
throw errors_1.missingFeeParamsError;
|
|
22
|
+
}
|
|
23
|
+
if (isRoundTrip && tvmExecutorFee === undefined) {
|
|
24
|
+
throw errors_1.missingTvmExecutorFeeError;
|
|
25
|
+
}
|
|
26
|
+
if (!evmProxyMsg.gasLimit) {
|
|
27
|
+
throw errors_1.missingGasLimitError;
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
protocolFee,
|
|
31
|
+
evmExecutorFee,
|
|
32
|
+
tvmExecutorFee: tvmExecutorFee || 0n,
|
|
33
|
+
gasLimit: evmProxyMsg.gasLimit,
|
|
34
|
+
isRoundTrip: isRoundTrip || false,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
const simulationResult = await this.simulator.getSimulationInfo(sender, tx);
|
|
38
|
+
if (!evmProxyMsg.gasLimit)
|
|
39
|
+
evmProxyMsg.gasLimit = simulationResult.feeParams.gasLimit;
|
|
40
|
+
return {
|
|
41
|
+
protocolFee: protocolFee ?? simulationResult.feeParams.protocolFee,
|
|
42
|
+
evmExecutorFee: evmExecutorFee ?? simulationResult.feeParams.evmExecutorFee,
|
|
43
|
+
tvmExecutorFee: simulationResult.feeParams.isRoundTrip && tvmExecutorFee !== undefined
|
|
44
|
+
? tvmExecutorFee
|
|
45
|
+
: simulationResult.feeParams.tvmExecutorFee,
|
|
46
|
+
gasLimit: evmProxyMsg.gasLimit ?? simulationResult.feeParams.gasLimit,
|
|
47
|
+
isRoundTrip: isRoundTrip ?? simulationResult.feeParams.isRoundTrip,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
async prepareCrossChainTransaction(evmProxyMsg, sender, assets, options, skipAssetsBalanceValidation = false) {
|
|
51
|
+
this.logger.debug('Preparing cross-chain transaction');
|
|
52
|
+
const caller = sender.getSenderAddress();
|
|
53
|
+
const { allowSimulationError = false, isRoundTrip = undefined, calculateRollbackFee = true, validateAssetsBalance = true } = options || {};
|
|
54
|
+
const { evmValidExecutors = [], tvmValidExecutors = [] } = options || {};
|
|
55
|
+
Validator_1.Validator.validateEVMAddress(evmProxyMsg.evmTargetAddress);
|
|
56
|
+
const aggregatedData = await (0, Utils_1.aggregateTokens)(assets);
|
|
57
|
+
Validator_1.Validator.validateEVMAddresses(evmValidExecutors);
|
|
58
|
+
Validator_1.Validator.validateTVMAddresses(tvmValidExecutors);
|
|
59
|
+
const shouldValidateAssets = validateAssetsBalance && !skipAssetsBalanceValidation;
|
|
60
|
+
if (shouldValidateAssets) {
|
|
61
|
+
await Promise.all([
|
|
62
|
+
...aggregatedData.jettons.map((jetton) => jetton.checkCanBeTransferredBy(caller)),
|
|
63
|
+
...aggregatedData.nfts.map((nft) => nft.checkCanBeTransferredBy(caller)),
|
|
64
|
+
aggregatedData.ton?.checkCanBeTransferredBy(caller),
|
|
65
|
+
].filter(Boolean));
|
|
66
|
+
}
|
|
67
|
+
const tokensLength = aggregatedData.jettons.length + aggregatedData.nfts.length;
|
|
68
|
+
const transactionLinker = (0, Utils_1.generateTransactionLinker)(caller, tokensLength || 1);
|
|
69
|
+
this.logger.debug(`Generated transaction linker: ${(0, Utils_1.formatObjectForLogging)(transactionLinker)}`);
|
|
70
|
+
const tacExecutors = evmValidExecutors.length ? evmValidExecutors : this.config.getTrustedTACExecutors;
|
|
71
|
+
const tonExecutors = tvmValidExecutors.length ? tvmValidExecutors : this.config.getTrustedTONExecutors;
|
|
72
|
+
const tx = {
|
|
73
|
+
evmProxyMsg,
|
|
74
|
+
assets: assets ?? [],
|
|
75
|
+
options: {
|
|
76
|
+
allowSimulationError,
|
|
77
|
+
isRoundTrip,
|
|
78
|
+
evmValidExecutors: tacExecutors,
|
|
79
|
+
tvmValidExecutors: tonExecutors,
|
|
80
|
+
calculateRollbackFee,
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
const feeParams = await this.buildFeeParams(options || {}, evmProxyMsg, sender, tx);
|
|
84
|
+
this.logger.debug(`Resulting fee params: ${(0, Utils_1.formatObjectForLogging)(feeParams)}`);
|
|
85
|
+
const validExecutors = {
|
|
86
|
+
tac: tacExecutors,
|
|
87
|
+
ton: tonExecutors,
|
|
88
|
+
};
|
|
89
|
+
const evmData = (0, Utils_1.buildEvmDataCell)(transactionLinker, evmProxyMsg, validExecutors);
|
|
90
|
+
const messages = await this.generateCrossChainMessages(caller, evmData, aggregatedData, feeParams);
|
|
91
|
+
return {
|
|
92
|
+
transaction: {
|
|
93
|
+
validUntil: Date.now() + Consts_1.FIFTEEN_MINUTES,
|
|
94
|
+
messages,
|
|
95
|
+
network: this.config.network,
|
|
96
|
+
},
|
|
97
|
+
transactionLinker,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
async generateCrossChainMessages(caller, evmData, aggregatedData, feeParams) {
|
|
101
|
+
this.logger.debug('Generating cross-chain messages');
|
|
102
|
+
const { jettons, nfts, ton = assets_1.TON.create(this.config) } = aggregatedData;
|
|
103
|
+
const totalAssets = [...jettons, ...nfts];
|
|
104
|
+
let crossChainTonAmount = ton.rawAmount;
|
|
105
|
+
let feeTonAmount = feeParams.protocolFee + feeParams.evmExecutorFee + feeParams.tvmExecutorFee;
|
|
106
|
+
this.logger.debug(`Crosschain ton amount: ${crossChainTonAmount}, Fee ton amount: ${feeTonAmount}`);
|
|
107
|
+
if (!totalAssets.length) {
|
|
108
|
+
return [
|
|
109
|
+
{
|
|
110
|
+
address: this.config.TONParams.crossChainLayerAddress,
|
|
111
|
+
value: crossChainTonAmount + feeTonAmount + Consts_1.TRANSACTION_TON_AMOUNT,
|
|
112
|
+
payload: await ton.generatePayload({ excessReceiver: caller, evmData, feeParams }),
|
|
113
|
+
},
|
|
114
|
+
];
|
|
115
|
+
}
|
|
116
|
+
const messages = [];
|
|
117
|
+
let currentFeeParams = feeParams;
|
|
118
|
+
for (const asset of totalAssets) {
|
|
119
|
+
const payload = await asset.generatePayload({
|
|
120
|
+
excessReceiver: caller,
|
|
121
|
+
evmData,
|
|
122
|
+
crossChainTonAmount,
|
|
123
|
+
forwardFeeTonAmount: feeTonAmount,
|
|
124
|
+
feeParams: currentFeeParams,
|
|
125
|
+
});
|
|
126
|
+
const address = asset instanceof assets_1.FT ? await asset.getUserWalletAddress(caller) : asset.address;
|
|
127
|
+
messages.push({
|
|
128
|
+
address,
|
|
129
|
+
value: crossChainTonAmount + feeTonAmount + Consts_1.TRANSACTION_TON_AMOUNT,
|
|
130
|
+
payload,
|
|
131
|
+
});
|
|
132
|
+
crossChainTonAmount = 0n;
|
|
133
|
+
feeTonAmount = 0n;
|
|
134
|
+
currentFeeParams = undefined;
|
|
135
|
+
}
|
|
136
|
+
this.logger.debug('Cross-chain messages generated successfully');
|
|
137
|
+
return messages;
|
|
138
|
+
}
|
|
139
|
+
async sendCrossChainTransaction(evmProxyMsg, sender, tx, waitOptions) {
|
|
140
|
+
const { transaction, transactionLinker } = await this.prepareCrossChainTransaction(evmProxyMsg, sender, tx.assets, tx.options);
|
|
141
|
+
await assets_1.TON.checkBalance(sender, this.config, [transaction]);
|
|
142
|
+
this.logger.debug(`Sending transaction: ${(0, Utils_1.formatObjectForLogging)(transactionLinker)}`);
|
|
143
|
+
const sendTransactionResult = await sender.sendShardTransaction(transaction, this.config.network, this.config.TONParams.contractOpener);
|
|
144
|
+
if (!waitOptions) {
|
|
145
|
+
return { sendTransactionResult, ...transactionLinker };
|
|
146
|
+
}
|
|
147
|
+
const operationId = await this.operationTracker.getOperationId(transactionLinker, {
|
|
148
|
+
...waitOptions,
|
|
149
|
+
successCheck: (id) => !!id,
|
|
150
|
+
logger: this.logger,
|
|
151
|
+
})
|
|
152
|
+
.catch((error) => {
|
|
153
|
+
this.logger.error(`Error while waiting for operation ID: ${error}`);
|
|
154
|
+
return undefined;
|
|
155
|
+
});
|
|
156
|
+
return { sendTransactionResult, operationId, ...transactionLinker };
|
|
157
|
+
}
|
|
158
|
+
async sendCrossChainTransactions(sender, txs, waitOptions) {
|
|
159
|
+
const caller = sender.getSenderAddress();
|
|
160
|
+
this.logger.debug(`Preparing ${txs.length} cross-chain transactions for ${caller}`);
|
|
161
|
+
const { transactions, transactionLinkers } = await this.prepareBatchTransactions(txs, sender);
|
|
162
|
+
await assets_1.TON.checkBalance(sender, this.config, transactions);
|
|
163
|
+
this.logger.debug(`Sending transactions: ${(0, Utils_1.formatObjectForLogging)(transactionLinkers)}`);
|
|
164
|
+
await sender.sendShardTransactions(transactions, this.config.network, this.config.TONParams.contractOpener);
|
|
165
|
+
return waitOptions
|
|
166
|
+
? await this.waitForOperationIds(transactionLinkers, caller, waitOptions)
|
|
167
|
+
: transactionLinkers;
|
|
168
|
+
}
|
|
169
|
+
async prepareBatchTransactions(txs, sender) {
|
|
170
|
+
const caller = sender.getSenderAddress();
|
|
171
|
+
const txsRequiringValidation = txs.filter((tx) => tx.options?.validateAssetsBalance ?? true);
|
|
172
|
+
if (txsRequiringValidation.length) {
|
|
173
|
+
// Aggregate only assets from txs that require validation and validate once per unique asset
|
|
174
|
+
const assetsToValidate = txsRequiringValidation.flatMap((tx) => tx.assets ?? []);
|
|
175
|
+
const aggregatedData = await (0, Utils_1.aggregateTokens)(assetsToValidate);
|
|
176
|
+
await Promise.all([
|
|
177
|
+
...aggregatedData.jettons.map((jetton) => jetton.checkCanBeTransferredBy(caller)),
|
|
178
|
+
...aggregatedData.nfts.map((nft) => nft.checkCanBeTransferredBy(caller)),
|
|
179
|
+
aggregatedData.ton?.checkCanBeTransferredBy(caller),
|
|
180
|
+
].filter(Boolean));
|
|
181
|
+
}
|
|
182
|
+
const results = await Promise.all(txs.map(({ evmProxyMsg, assets, options }) => this.prepareCrossChainTransaction(evmProxyMsg, sender, assets, options, true)));
|
|
183
|
+
return {
|
|
184
|
+
transactions: results.map((r) => r.transaction),
|
|
185
|
+
transactionLinkers: results.map((r) => r.transactionLinker),
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
async waitForOperationIds(transactionLinkers, caller, waitOptions) {
|
|
189
|
+
this.logger.debug(`Waiting for operation IDs`);
|
|
190
|
+
try {
|
|
191
|
+
const operationIds = await this.operationTracker.getOperationIdsByShardsKeys(transactionLinkers.map((linker) => linker.shardsKey), caller, {
|
|
192
|
+
...waitOptions,
|
|
193
|
+
logger: this.logger,
|
|
194
|
+
successCheck: (operationIds) => Object.keys(operationIds).length == transactionLinkers.length &&
|
|
195
|
+
Object.values(operationIds).every((ids) => ids.operationIds.length > 0),
|
|
196
|
+
});
|
|
197
|
+
this.logger.debug(`Operation IDs: ${(0, Utils_1.formatObjectForLogging)(operationIds)}`);
|
|
198
|
+
return transactionLinkers.map((linker) => ({
|
|
199
|
+
...linker,
|
|
200
|
+
operationId: operationIds[linker.shardsKey].operationIds.at(0),
|
|
201
|
+
}));
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
this.logger.error(`Error while waiting for operation IDs: ${error}`);
|
|
205
|
+
return transactionLinkers;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
exports.TONTransactionManager = TONTransactionManager;
|
package/dist/sdk/TacSdk.d.ts
CHANGED
|
@@ -1,28 +1,33 @@
|
|
|
1
|
+
import { AgnosticProxySDK } from '@tonappchain/agnostic-sdk';
|
|
1
2
|
import { Wallet } from 'ethers';
|
|
2
3
|
import { FT, NFT } from '../assets';
|
|
3
|
-
import {
|
|
4
|
+
import { IConfiguration, ILogger, IOperationTracker, ITacSDK } from '../interfaces';
|
|
4
5
|
import type { SenderAbstraction } from '../sender';
|
|
5
|
-
import { AssetFromFTArg, AssetFromNFTCollectionArg, AssetFromNFTItemArg, CrossChainTransactionOptions, CrosschainTx, EVMAddress, EvmProxyMsg, ExecutionFeeEstimationResult, NFTAddressType, NFTItemData, OperationIdsByShardsKey, SDKParams,
|
|
6
|
+
import { AssetFromFTArg, AssetFromNFTCollectionArg, AssetFromNFTItemArg, AssetLike, CrossChainTransactionOptions, CrosschainTx, CrosschainTxWithAssetLike, EVMAddress, EvmProxyMsg, ExecutionFeeEstimationResult, NFTAddressType, NFTItemData, OperationIdsByShardsKey, SDKParams, SuggestedTVMExecutorFee, TACSimulationParams, TACSimulationResult, TransactionLinkerWithOperationId, TVMAddress, UserWalletBalanceExtended, WaitOptions } from '../structs/Struct';
|
|
6
7
|
import { JettonMasterData } from '../wrappers/JettonMaster';
|
|
7
8
|
export declare class TacSdk implements ITacSDK {
|
|
8
9
|
readonly config: IConfiguration;
|
|
10
|
+
readonly operationTracker: IOperationTracker;
|
|
9
11
|
private readonly simulator;
|
|
10
|
-
private readonly
|
|
12
|
+
private readonly tonTransactionManager;
|
|
13
|
+
private readonly tacTransactionManager;
|
|
11
14
|
private constructor();
|
|
12
15
|
static create(sdkParams: SDKParams, logger?: ILogger): Promise<TacSdk>;
|
|
13
16
|
closeConnections(): unknown;
|
|
14
17
|
get nativeTONAddress(): string;
|
|
18
|
+
getAgnosticProxySDK(agnosticProxyAddress?: string, smartAccountFactoryAddress?: string): AgnosticProxySDK;
|
|
19
|
+
getSmartAccountAddressForTvmWallet(tvmWallet: string, applicationAddress: string): Promise<string>;
|
|
15
20
|
nativeTACAddress(): Promise<string>;
|
|
16
21
|
get getTrustedTACExecutors(): string[];
|
|
17
22
|
get getTrustedTONExecutors(): string[];
|
|
18
|
-
|
|
19
|
-
getTVMExecutorFeeInfo(assets:
|
|
20
|
-
sendCrossChainTransaction(evmProxyMsg: EvmProxyMsg, sender: SenderAbstraction, assets?:
|
|
21
|
-
sendCrossChainTransactions(sender: SenderAbstraction, txs:
|
|
22
|
-
bridgeTokensToTON(signer: Wallet, value: bigint, tonTarget: string, assets?:
|
|
23
|
+
getSimulationInfo(evmProxyMsg: EvmProxyMsg, sender: SenderAbstraction, assets?: AssetLike[], options?: CrossChainTransactionOptions): Promise<ExecutionFeeEstimationResult>;
|
|
24
|
+
getTVMExecutorFeeInfo(assets: AssetLike[], feeSymbol: string, tvmValidExecutors?: string[]): Promise<SuggestedTVMExecutorFee>;
|
|
25
|
+
sendCrossChainTransaction(evmProxyMsg: EvmProxyMsg, sender: SenderAbstraction, assets?: AssetLike[], options?: CrossChainTransactionOptions, waitOptions?: WaitOptions<string>): Promise<TransactionLinkerWithOperationId>;
|
|
26
|
+
sendCrossChainTransactions(sender: SenderAbstraction, txs: CrosschainTxWithAssetLike[], waitOptions?: WaitOptions<OperationIdsByShardsKey>): Promise<TransactionLinkerWithOperationId[]>;
|
|
27
|
+
bridgeTokensToTON(signer: Wallet, value: bigint, tonTarget: string, assets?: AssetLike[], tvmExecutorFee?: bigint, tvmValidExecutors?: string[]): Promise<string>;
|
|
23
28
|
isContractDeployedOnTVM(address: string): Promise<boolean>;
|
|
24
|
-
simulateTACMessage(req:
|
|
25
|
-
simulateTransactions(sender: SenderAbstraction, txs: CrosschainTx[]): Promise<
|
|
29
|
+
simulateTACMessage(req: TACSimulationParams): Promise<TACSimulationResult>;
|
|
30
|
+
simulateTransactions(sender: SenderAbstraction, txs: CrosschainTx[]): Promise<ExecutionFeeEstimationResult[]>;
|
|
26
31
|
getAsset(args: AssetFromFTArg): Promise<FT>;
|
|
27
32
|
getAsset(args: AssetFromNFTCollectionArg): Promise<NFT>;
|
|
28
33
|
getAsset(args: AssetFromNFTItemArg): Promise<NFT>;
|
|
@@ -37,4 +42,5 @@ export declare class TacSdk implements ITacSDK {
|
|
|
37
42
|
getTVMTokenAddress(evmTokenAddress: string): Promise<string>;
|
|
38
43
|
getTVMNFTAddress(evmNFTAddress: string, tokenId?: number | bigint): Promise<string>;
|
|
39
44
|
getEVMNFTAddress(tvmNFTAddress: string, addressType: NFTAddressType): Promise<string>;
|
|
45
|
+
getOperationTracker(): IOperationTracker;
|
|
40
46
|
}
|
package/dist/sdk/TacSdk.js
CHANGED
|
@@ -34,6 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.TacSdk = void 0;
|
|
37
|
+
const agnostic_sdk_1 = require("@tonappchain/agnostic-sdk");
|
|
37
38
|
const assets_1 = require("../assets");
|
|
38
39
|
const Struct_1 = require("../structs/Struct");
|
|
39
40
|
const Configuration_1 = require("./Configuration");
|
|
@@ -41,12 +42,16 @@ const Consts_1 = require("./Consts");
|
|
|
41
42
|
const Logger_1 = require("./Logger");
|
|
42
43
|
const OperationTracker_1 = require("./OperationTracker");
|
|
43
44
|
const Simulator_1 = require("./Simulator");
|
|
44
|
-
const
|
|
45
|
+
const TACTransactionManager_1 = require("./TACTransactionManager");
|
|
46
|
+
const TONTransactionManager_1 = require("./TONTransactionManager");
|
|
47
|
+
const Utils_1 = require("./Utils");
|
|
45
48
|
class TacSdk {
|
|
46
|
-
constructor(config, simulator,
|
|
49
|
+
constructor(config, simulator, tonTransactionManager, tacTransactionManager, operationTracker) {
|
|
47
50
|
this.config = config;
|
|
48
51
|
this.simulator = simulator;
|
|
49
|
-
this.
|
|
52
|
+
this.tonTransactionManager = tonTransactionManager;
|
|
53
|
+
this.tacTransactionManager = tacTransactionManager;
|
|
54
|
+
this.operationTracker = operationTracker;
|
|
50
55
|
}
|
|
51
56
|
static async create(sdkParams, logger = new Logger_1.NoopLogger()) {
|
|
52
57
|
const network = sdkParams.network;
|
|
@@ -54,10 +59,11 @@ class TacSdk {
|
|
|
54
59
|
const { testnet, mainnet } = await Promise.resolve().then(() => __importStar(require('@tonappchain/artifacts')));
|
|
55
60
|
const artifacts = network === Struct_1.Network.TESTNET ? testnet : mainnet;
|
|
56
61
|
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
62
|
const operationTracker = new OperationTracker_1.OperationTracker(network, config.liteSequencerEndpoints);
|
|
59
|
-
const
|
|
60
|
-
|
|
63
|
+
const simulator = new Simulator_1.Simulator(config, operationTracker, logger);
|
|
64
|
+
const tonTransactionManager = new TONTransactionManager_1.TONTransactionManager(config, simulator, operationTracker, logger);
|
|
65
|
+
const tacTransactionManager = new TACTransactionManager_1.TACTransactionManager(config, operationTracker, logger);
|
|
66
|
+
return new TacSdk(config, simulator, tonTransactionManager, tacTransactionManager, operationTracker);
|
|
61
67
|
}
|
|
62
68
|
closeConnections() {
|
|
63
69
|
return this.config.closeConnections();
|
|
@@ -65,6 +71,13 @@ class TacSdk {
|
|
|
65
71
|
get nativeTONAddress() {
|
|
66
72
|
return this.config.nativeTONAddress;
|
|
67
73
|
}
|
|
74
|
+
getAgnosticProxySDK(agnosticProxyAddress, smartAccountFactoryAddress) {
|
|
75
|
+
return new agnostic_sdk_1.AgnosticProxySDK(smartAccountFactoryAddress ?? this.config.artifacts.TAC_SMART_ACCOUNT_FACTORY_ADDRESS, this.config.TACParams.provider, agnosticProxyAddress ?? this.config.artifacts.AGNOSTIC_PROXY_ADDRESS);
|
|
76
|
+
}
|
|
77
|
+
async getSmartAccountAddressForTvmWallet(tvmWallet, applicationAddress) {
|
|
78
|
+
const bouncedAddress = (0, Utils_1.getBouncedAddress)(tvmWallet);
|
|
79
|
+
return await this.config.TACParams.smartAccountFactory.getSmartAccountForApplication(bouncedAddress, applicationAddress);
|
|
80
|
+
}
|
|
68
81
|
async nativeTACAddress() {
|
|
69
82
|
return this.config.nativeTACAddress();
|
|
70
83
|
}
|
|
@@ -74,29 +87,45 @@ class TacSdk {
|
|
|
74
87
|
get getTrustedTONExecutors() {
|
|
75
88
|
return this.config.getTrustedTONExecutors;
|
|
76
89
|
}
|
|
77
|
-
async
|
|
78
|
-
|
|
90
|
+
async getSimulationInfo(evmProxyMsg, sender, assets, options) {
|
|
91
|
+
const normalizedAssets = await (0, Utils_1.normalizeAssets)(this.config, assets);
|
|
92
|
+
const tx = { evmProxyMsg, assets: normalizedAssets, options };
|
|
93
|
+
return this.simulator.getSimulationInfo(sender, tx);
|
|
79
94
|
}
|
|
80
95
|
async getTVMExecutorFeeInfo(assets, feeSymbol, tvmValidExecutors) {
|
|
81
|
-
|
|
96
|
+
const normalized = await (0, Utils_1.normalizeAssets)(this.config, assets);
|
|
97
|
+
const params = {
|
|
98
|
+
tonAssets: (0, Utils_1.mapAssetsToTonAssets)(normalized),
|
|
99
|
+
feeSymbol: feeSymbol,
|
|
100
|
+
tvmValidExecutors: tvmValidExecutors ?? [],
|
|
101
|
+
};
|
|
102
|
+
return this.operationTracker.getTVMExecutorFee(params);
|
|
82
103
|
}
|
|
83
|
-
async sendCrossChainTransaction(evmProxyMsg, sender, assets, options, waitOptions) {
|
|
84
|
-
|
|
104
|
+
async sendCrossChainTransaction(evmProxyMsg, sender, assets = [], options, waitOptions) {
|
|
105
|
+
const normalizedAssets = await (0, Utils_1.normalizeAssets)(this.config, assets);
|
|
106
|
+
const tx = { evmProxyMsg, assets: normalizedAssets, options };
|
|
107
|
+
return this.tonTransactionManager.sendCrossChainTransaction(evmProxyMsg, sender, tx, waitOptions);
|
|
85
108
|
}
|
|
86
109
|
async sendCrossChainTransactions(sender, txs, waitOptions) {
|
|
87
|
-
|
|
110
|
+
const normalizedTxs = await Promise.all(txs.map(async (tx) => ({
|
|
111
|
+
evmProxyMsg: tx.evmProxyMsg,
|
|
112
|
+
options: tx.options,
|
|
113
|
+
assets: await (0, Utils_1.normalizeAssets)(this.config, tx.assets),
|
|
114
|
+
})));
|
|
115
|
+
return this.tonTransactionManager.sendCrossChainTransactions(sender, normalizedTxs, waitOptions);
|
|
88
116
|
}
|
|
89
117
|
async bridgeTokensToTON(signer, value, tonTarget, assets, tvmExecutorFee, tvmValidExecutors) {
|
|
90
|
-
|
|
118
|
+
const normalizedAssets = await (0, Utils_1.normalizeAssets)(this.config, assets);
|
|
119
|
+
return this.tacTransactionManager.bridgeTokensToTON(signer, value, tonTarget, normalizedAssets, tvmExecutorFee, tvmValidExecutors);
|
|
91
120
|
}
|
|
92
121
|
async isContractDeployedOnTVM(address) {
|
|
93
122
|
return this.config.isContractDeployedOnTVM(address);
|
|
94
123
|
}
|
|
95
124
|
async simulateTACMessage(req) {
|
|
96
|
-
return this.
|
|
125
|
+
return this.operationTracker.simulateTACMessage(req);
|
|
97
126
|
}
|
|
98
127
|
async simulateTransactions(sender, txs) {
|
|
99
|
-
return this.simulator.
|
|
128
|
+
return this.simulator.getSimulationsInfo(sender, txs);
|
|
100
129
|
}
|
|
101
130
|
async getAsset(args) {
|
|
102
131
|
return await assets_1.AssetFactory.from(this.config, args);
|
|
@@ -147,10 +176,11 @@ class TacSdk {
|
|
|
147
176
|
}
|
|
148
177
|
// Address conversion methods
|
|
149
178
|
async getEVMTokenAddress(tvmTokenAddress) {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
179
|
+
const asset = await assets_1.AssetFactory.from(this.config, {
|
|
180
|
+
address: tvmTokenAddress,
|
|
181
|
+
tokenType: Struct_1.AssetType.FT,
|
|
182
|
+
});
|
|
183
|
+
return asset.getEVMAddress();
|
|
154
184
|
}
|
|
155
185
|
async getTVMTokenAddress(evmTokenAddress) {
|
|
156
186
|
return assets_1.FT.getTVMAddress(this.config, evmTokenAddress);
|
|
@@ -168,5 +198,8 @@ class TacSdk {
|
|
|
168
198
|
return nftCollection.getEVMAddress();
|
|
169
199
|
}
|
|
170
200
|
}
|
|
201
|
+
getOperationTracker() {
|
|
202
|
+
return this.operationTracker;
|
|
203
|
+
}
|
|
171
204
|
}
|
|
172
205
|
exports.TacSdk = TacSdk;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { ILogger } from '../interfaces';
|
|
1
|
+
import { IHttpClient, ILogger } from '../interfaces';
|
|
2
2
|
import { TxFinalizerConfig } from '../structs/InternalStruct';
|
|
3
3
|
export declare class TonTxFinalizer {
|
|
4
4
|
private logger;
|
|
5
5
|
private apiConfig;
|
|
6
|
-
|
|
6
|
+
private readonly httpClient;
|
|
7
|
+
constructor(apiConfig: TxFinalizerConfig, logger?: ILogger, httpClient?: IHttpClient);
|
|
7
8
|
private logHashFormats;
|
|
8
9
|
private fetchAdjacentTransactions;
|
|
9
10
|
trackTransactionTree(hash: string, maxDepth?: number): Promise<void>;
|
package/dist/sdk/TxFinalizer.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.TonTxFinalizer = void 0;
|
|
7
|
-
const
|
|
4
|
+
const AxiosHttpClient_1 = require("./AxiosHttpClient");
|
|
8
5
|
const Logger_1 = require("./Logger");
|
|
9
6
|
const Utils_1 = require("./Utils");
|
|
10
7
|
const IGNORE_OPCODE = [
|
|
@@ -12,9 +9,10 @@ const IGNORE_OPCODE = [
|
|
|
12
9
|
'0x7362d09c', // Jetton Notify
|
|
13
10
|
];
|
|
14
11
|
class TonTxFinalizer {
|
|
15
|
-
constructor(apiConfig, logger = new Logger_1.NoopLogger()) {
|
|
12
|
+
constructor(apiConfig, logger = new Logger_1.NoopLogger(), httpClient = new AxiosHttpClient_1.AxiosHttpClient()) {
|
|
16
13
|
this.apiConfig = apiConfig;
|
|
17
14
|
this.logger = logger;
|
|
15
|
+
this.httpClient = httpClient;
|
|
18
16
|
}
|
|
19
17
|
logHashFormats(hash) {
|
|
20
18
|
let hex, base64;
|
|
@@ -34,10 +32,9 @@ class TonTxFinalizer {
|
|
|
34
32
|
// Fetches adjacent transactions from toncenter
|
|
35
33
|
async fetchAdjacentTransactions(hash, retries = 5, delay = 1000) {
|
|
36
34
|
for (let i = retries; i >= 0; i--) {
|
|
37
|
-
await (0, Utils_1.sleep)(delay);
|
|
38
35
|
try {
|
|
39
36
|
const url = this.apiConfig.urlBuilder(hash);
|
|
40
|
-
const response = await
|
|
37
|
+
const response = await this.httpClient.get(url, {
|
|
41
38
|
headers: {
|
|
42
39
|
[this.apiConfig.authorization.header]: this.apiConfig.authorization.value,
|
|
43
40
|
},
|
|
@@ -57,6 +54,7 @@ class TonTxFinalizer {
|
|
|
57
54
|
console.warn(`Failed to fetch adjacent transactions for ${hash}:`, logMessage);
|
|
58
55
|
}
|
|
59
56
|
}
|
|
57
|
+
await (0, Utils_1.sleep)(delay);
|
|
60
58
|
}
|
|
61
59
|
return [];
|
|
62
60
|
}
|
|
@@ -91,7 +89,9 @@ class TonTxFinalizer {
|
|
|
91
89
|
`action.result_code = ${action.resultCode}`);
|
|
92
90
|
}
|
|
93
91
|
if (currentDepth + 1 < maxDepth) {
|
|
94
|
-
|
|
92
|
+
if (tx.outMsgs.length > 0) {
|
|
93
|
+
queue.push({ hash: tx.hash, depth: currentDepth + 1 });
|
|
94
|
+
}
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
else {
|
package/dist/sdk/Utils.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Address, Cell } from '@ton/ton';
|
|
2
2
|
import { AbiCoder } from 'ethers';
|
|
3
|
-
import { FT, NFT, TON } from '../assets';
|
|
4
|
-
import { Asset } from '../interfaces';
|
|
3
|
+
import type { FT, NFT, TON } from '../assets';
|
|
4
|
+
import { Asset, IConfiguration } from '../interfaces';
|
|
5
5
|
import { RandomNumberByTimestamp } from '../structs/InternalStruct';
|
|
6
|
-
import { EvmProxyMsg, FeeParams, TransactionLinker, ValidExecutors, WaitOptions } from '../structs/Struct';
|
|
6
|
+
import { AssetLike, EvmProxyMsg, FeeParams, TONAsset, TransactionLinker, ValidExecutors, WaitOptions } from '../structs/Struct';
|
|
7
7
|
export declare const sleep: (ms: number) => Promise<unknown>;
|
|
8
8
|
export declare function generateRandomNumber(interval: number): number;
|
|
9
9
|
export declare function generateRandomNumberByTimestamp(): RandomNumberByTimestamp;
|
|
@@ -17,10 +17,15 @@ export declare const calculateRawAmount: (amount: number, decimals: number) => b
|
|
|
17
17
|
export declare const calculateAmount: (rawAmount: bigint, decimals: number) => number;
|
|
18
18
|
export declare const toCamelCaseTransformer: (data: string) => any;
|
|
19
19
|
export declare const generateFeeData: (feeParams?: FeeParams) => Cell | undefined;
|
|
20
|
-
export declare function waitUntilSuccess<T, A extends unknown[]>(options: WaitOptions<T> | undefined, operation: (...args: A) => Promise<T>, ...args: A): Promise<T>;
|
|
20
|
+
export declare function waitUntilSuccess<T, TContext = unknown, A extends unknown[] = unknown[]>(options: WaitOptions<T, TContext> | undefined, operation: (...args: A) => Promise<T>, operationDescription?: string, ...args: A): Promise<T>;
|
|
21
21
|
export declare function formatObjectForLogging(obj: unknown): string;
|
|
22
|
+
export declare function getBouncedAddress(tvmAddress: string): string;
|
|
22
23
|
export declare function aggregateTokens(assets?: Asset[]): Promise<{
|
|
23
24
|
jettons: FT[];
|
|
24
25
|
nfts: NFT[];
|
|
25
26
|
ton?: TON;
|
|
26
27
|
}>;
|
|
28
|
+
export declare function sha256toBigInt(ContractName: string): bigint;
|
|
29
|
+
export declare function mapAssetsToTonAssets(assets: Asset[]): TONAsset[];
|
|
30
|
+
export declare function normalizeAsset(config: IConfiguration, input: AssetLike): Promise<Asset>;
|
|
31
|
+
export declare function normalizeAssets(config: IConfiguration, assets?: AssetLike[]): Promise<Asset[]>;
|
package/dist/sdk/Utils.js
CHANGED
|
@@ -10,9 +10,16 @@ exports.generateTransactionLinker = generateTransactionLinker;
|
|
|
10
10
|
exports.calculateEVMTokenAddress = calculateEVMTokenAddress;
|
|
11
11
|
exports.waitUntilSuccess = waitUntilSuccess;
|
|
12
12
|
exports.formatObjectForLogging = formatObjectForLogging;
|
|
13
|
+
exports.getBouncedAddress = getBouncedAddress;
|
|
13
14
|
exports.aggregateTokens = aggregateTokens;
|
|
15
|
+
exports.sha256toBigInt = sha256toBigInt;
|
|
16
|
+
exports.mapAssetsToTonAssets = mapAssetsToTonAssets;
|
|
17
|
+
exports.normalizeAsset = normalizeAsset;
|
|
18
|
+
exports.normalizeAssets = normalizeAssets;
|
|
14
19
|
const ton_1 = require("@ton/ton");
|
|
15
20
|
const ethers_1 = require("ethers");
|
|
21
|
+
const ton_crypto_1 = require("ton-crypto");
|
|
22
|
+
const assets_1 = require("../assets");
|
|
16
23
|
const errors_1 = require("../errors");
|
|
17
24
|
const Struct_1 = require("../structs/Struct");
|
|
18
25
|
const Consts_1 = require("./Consts");
|
|
@@ -131,12 +138,14 @@ const generateFeeData = (feeParams) => {
|
|
|
131
138
|
}
|
|
132
139
|
};
|
|
133
140
|
exports.generateFeeData = generateFeeData;
|
|
134
|
-
async function waitUntilSuccess(options = {}, operation, ...args) {
|
|
141
|
+
async function waitUntilSuccess(options = {}, operation, operationDescription, ...args) {
|
|
135
142
|
const timeout = options.timeout ?? 300000;
|
|
136
143
|
const maxAttempts = options.maxAttempts ?? 30;
|
|
137
144
|
const delay = options.delay ?? 10000;
|
|
138
145
|
const successCheck = options.successCheck;
|
|
139
|
-
|
|
146
|
+
const context = options.context;
|
|
147
|
+
const contextPrefix = operationDescription ? `[${operationDescription}] ` : '';
|
|
148
|
+
options.logger?.debug(`${contextPrefix}Starting wait for success with timeout=${timeout}ms, maxAttempts=${maxAttempts}, delay=${delay}ms`);
|
|
140
149
|
const startTime = Date.now();
|
|
141
150
|
let attempt = 1;
|
|
142
151
|
while (true) {
|
|
@@ -144,27 +153,36 @@ async function waitUntilSuccess(options = {}, operation, ...args) {
|
|
|
144
153
|
const elapsedTime = currentTime - startTime;
|
|
145
154
|
try {
|
|
146
155
|
const result = await operation(...args);
|
|
147
|
-
if (
|
|
156
|
+
if (result === undefined || result === null) {
|
|
148
157
|
throw new Error(`Empty result`);
|
|
149
158
|
}
|
|
150
|
-
options.logger?.debug(
|
|
151
|
-
if (successCheck && !successCheck(result)) {
|
|
159
|
+
options.logger?.debug(`${contextPrefix}Result: ${formatObjectForLogging(result)}`);
|
|
160
|
+
if (successCheck && !successCheck(result, context)) {
|
|
152
161
|
throw new Error(`Result is not successful`);
|
|
153
162
|
}
|
|
154
|
-
options.logger?.debug(
|
|
163
|
+
options.logger?.debug(`${contextPrefix}Attempt ${attempt} successful`);
|
|
164
|
+
// Execute custom onSuccess callback if provided
|
|
165
|
+
if (options.onSuccess) {
|
|
166
|
+
try {
|
|
167
|
+
await options.onSuccess(result, context);
|
|
168
|
+
}
|
|
169
|
+
catch (callbackError) {
|
|
170
|
+
options.logger?.warn(`${contextPrefix}onSuccess callback error: ${callbackError}`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
155
173
|
return result;
|
|
156
174
|
}
|
|
157
175
|
catch (error) {
|
|
158
176
|
if (elapsedTime >= timeout) {
|
|
159
|
-
options.logger?.debug(
|
|
177
|
+
options.logger?.debug(`${contextPrefix}Timeout after ${elapsedTime}ms`);
|
|
160
178
|
throw error;
|
|
161
179
|
}
|
|
162
180
|
if (attempt >= maxAttempts) {
|
|
163
|
-
options.logger?.debug(
|
|
181
|
+
options.logger?.debug(`${contextPrefix}Max attempts (${maxAttempts}) reached`);
|
|
164
182
|
throw error;
|
|
165
183
|
}
|
|
166
|
-
options.logger?.debug(
|
|
167
|
-
options.logger?.debug(
|
|
184
|
+
options.logger?.debug(`${contextPrefix}Error on attempt ${attempt}: ${error}`);
|
|
185
|
+
options.logger?.debug(`${contextPrefix}Waiting ${delay}ms before next attempt`);
|
|
168
186
|
await (0, exports.sleep)(delay);
|
|
169
187
|
attempt++;
|
|
170
188
|
}
|
|
@@ -173,6 +191,11 @@ async function waitUntilSuccess(options = {}, operation, ...args) {
|
|
|
173
191
|
function formatObjectForLogging(obj) {
|
|
174
192
|
return JSON.stringify(obj, (key, value) => (typeof value === 'bigint' ? value.toString() : value));
|
|
175
193
|
}
|
|
194
|
+
function getBouncedAddress(tvmAddress) {
|
|
195
|
+
return ton_1.Address.parse(tvmAddress).toString({
|
|
196
|
+
bounceable: true,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
176
199
|
async function aggregateTokens(assets) {
|
|
177
200
|
const uniqueAssetsMap = new Map();
|
|
178
201
|
let ton;
|
|
@@ -180,7 +203,7 @@ async function aggregateTokens(assets) {
|
|
|
180
203
|
if (asset.type !== Struct_1.AssetType.FT)
|
|
181
204
|
continue;
|
|
182
205
|
if (!asset.address) {
|
|
183
|
-
ton = ton ?
|
|
206
|
+
ton = ton ? ton.addRawAmount(asset.rawAmount) : asset.clone;
|
|
184
207
|
continue;
|
|
185
208
|
}
|
|
186
209
|
let jetton = uniqueAssetsMap.get(asset.address);
|
|
@@ -188,7 +211,7 @@ async function aggregateTokens(assets) {
|
|
|
188
211
|
jetton = asset.clone;
|
|
189
212
|
}
|
|
190
213
|
else {
|
|
191
|
-
jetton =
|
|
214
|
+
jetton = jetton.addRawAmount(asset.rawAmount);
|
|
192
215
|
}
|
|
193
216
|
uniqueAssetsMap.set(asset.address, jetton);
|
|
194
217
|
}
|
|
@@ -206,3 +229,54 @@ async function aggregateTokens(assets) {
|
|
|
206
229
|
ton,
|
|
207
230
|
};
|
|
208
231
|
}
|
|
232
|
+
function sha256toBigInt(ContractName) {
|
|
233
|
+
const hash = (0, ton_crypto_1.sha256_sync)(ContractName);
|
|
234
|
+
return BigInt('0x' + hash.toString('hex'));
|
|
235
|
+
}
|
|
236
|
+
function mapAssetsToTonAssets(assets) {
|
|
237
|
+
return assets.map((asset) => ({
|
|
238
|
+
amount: asset.rawAmount.toString(),
|
|
239
|
+
tokenAddress: asset.address || '',
|
|
240
|
+
assetType: asset.type,
|
|
241
|
+
}));
|
|
242
|
+
}
|
|
243
|
+
async function normalizeAsset(config, input) {
|
|
244
|
+
if (typeof input.generatePayload === 'function') {
|
|
245
|
+
return input;
|
|
246
|
+
}
|
|
247
|
+
const address = 'address' in input && input.address ? input.address : '';
|
|
248
|
+
if ('itemIndex' in input) {
|
|
249
|
+
const args = {
|
|
250
|
+
address,
|
|
251
|
+
tokenType: Struct_1.AssetType.NFT,
|
|
252
|
+
addressType: Struct_1.NFTAddressType.COLLECTION,
|
|
253
|
+
index: BigInt(input.itemIndex),
|
|
254
|
+
};
|
|
255
|
+
return await assets_1.AssetFactory.from(config, args);
|
|
256
|
+
}
|
|
257
|
+
if ('rawAmount' in input || 'amount' in input) {
|
|
258
|
+
const ftArgs = {
|
|
259
|
+
address,
|
|
260
|
+
tokenType: Struct_1.AssetType.FT,
|
|
261
|
+
};
|
|
262
|
+
const asset = await assets_1.AssetFactory.from(config, ftArgs);
|
|
263
|
+
return 'rawAmount' in input
|
|
264
|
+
? asset.withRawAmount(input.rawAmount)
|
|
265
|
+
: asset.withAmount(input.amount);
|
|
266
|
+
}
|
|
267
|
+
const itemArgs = {
|
|
268
|
+
address,
|
|
269
|
+
tokenType: Struct_1.AssetType.NFT,
|
|
270
|
+
addressType: Struct_1.NFTAddressType.ITEM,
|
|
271
|
+
};
|
|
272
|
+
return await assets_1.AssetFactory.from(config, itemArgs);
|
|
273
|
+
}
|
|
274
|
+
async function normalizeAssets(config, assets) {
|
|
275
|
+
if (!assets || assets.length === 0)
|
|
276
|
+
return [];
|
|
277
|
+
const normalized = [];
|
|
278
|
+
for (const a of assets) {
|
|
279
|
+
normalized.push(await normalizeAsset(config, a));
|
|
280
|
+
}
|
|
281
|
+
return normalized;
|
|
282
|
+
}
|