UNPKG

@tatumio/tatum-v1

Version:

Tatum API client allows browsers and Node.js clients to interact with Tatum API.

840 lines 83.4 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.transferHexToBase58Address = exports.signTrxKMSTransaction = exports.prepareTronUpdateCashbackForAuthorTrc721SignedTransaction = exports.prepareTronMintMultipleTrc721SignedTransaction = exports.prepareTronBurnTrc721SignedTransaction = exports.prepareTronTransferTrc721SignedTransaction = exports.prepareTronMintTrc721SignedTransaction = exports.prepareTronMintCashbackTrc721SignedTransaction = exports.prepareTronDeployMarketplaceListingSignedTransaction = exports.prepareTronGenerateCustodialWalletSignedTransaction = exports.prepareTronDeployTrc721SignedTransaction = exports.prepareTronCreateTrc20SignedKMSTransaction = exports.prepareTronCreateTrc10SignedKMSTransaction = exports.prepareTronTrc20SignedKMSTransaction = exports.prepareTronTrc10SignedKMSTransaction = exports.prepareTronFreezeKMSTransaction = exports.prepareTronSignedKMSTransaction = exports.prepareTronCreateTrc20SignedTransaction = exports.prepareTronCreateTrc10SignedTransaction = exports.prepareTronTrc20SignedTransaction = exports.prepareTronCustodialTransferBatch = exports.prepareTronSmartContractInvocation = exports.getTronTrc20ContractDecimals = exports.tronGetAccountTrc20Address = exports.prepareTronTrc10SignedTransaction = exports.prepareTronFreezeTransaction = exports.prepareTronSignedTransaction = exports.sendTronUpdateCashbackForAuthorTrc721SignedTransaction = exports.sendTronMintMultipleTrc721SignedTransaction = exports.sendTronBurnTrc721SignedTransaction = exports.sendTronTransferTrc721SignedTransaction = exports.sendTronMintTrc721SignedTransaction = exports.sendTronMintCashbackTrc721SignedTransaction = exports.sendTronDeployMarketplaceListingSignedTransaction = exports.sendTronGenerateCustodialWalletSignedTransaction = exports.sendTronDeployTrc721SignedTransaction = exports.convertAddressToHex = exports.convertAddressFromHex = exports.signTronKMSTransaction = exports.createTronTrc20Transaction = exports.createTronTrc10Transaction = exports.sendTronTrc20Transaction = exports.sendTronTrc10Transaction = exports.freezeTronTransaction = exports.sendTronTransaction = void 0; const bignumber_js_1 = __importDefault(require("bignumber.js")); const blockchain_1 = require("../blockchain"); const tatum_1 = require("../connector/tatum"); const constants_1 = require("../constants"); const marketplace_1 = require("../contracts/marketplace"); const token_abi_1 = __importDefault(require("../contracts/trc20/token_abi")); const token_bytecode_1 = __importDefault(require("../contracts/trc20/token_bytecode")); const trc721_abi_1 = __importDefault(require("../contracts/trc721/trc721_abi")); const trc721_bytecode_1 = __importDefault(require("../contracts/trc721/trc721_bytecode")); const model_1 = require("../model"); const wallet_1 = require("../wallet"); // tslint:disable-next-line:no-var-requires const TronWeb = require('tronweb'); const prepareTronWeb = (testnet, provider) => { const HttpProvider = TronWeb.providers.HttpProvider; const url = provider || `${process.env.TATUM_API_URL || constants_1.TATUM_API_URL}/v3/tron/node/${process.env.TATUM_API_KEY}`; const fullNode = new HttpProvider(url); const solidityNode = new HttpProvider(url); const eventServer = new HttpProvider(url); const tronWeb = new TronWeb(fullNode, solidityNode, eventServer); tronWeb.setHeader({ 'TRON-PRO-API-KEY': process.env.TRON_PRO_API_KEY }); return tronWeb; }; /** * Send Tron transaction to the blockchain. This method broadcasts signed transaction to the blockchain. * This operation is irreversible. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @returns transaction id of the transaction in the blockchain */ const sendTronTransaction = async (testnet, body) => { return blockchain_1.tronBroadcast(await exports.prepareTronSignedTransaction(testnet, body), body.signatureId); }; exports.sendTronTransaction = sendTronTransaction; /** * Send Tron Freeze balance transaction to the blockchain. This method broadcasts signed transaction to the blockchain. * This operation is irreversible. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @returns transaction id of the transaction in the blockchain */ const freezeTronTransaction = async (testnet, body) => { return blockchain_1.tronBroadcast(await exports.prepareTronFreezeTransaction(testnet, body), body.signatureId); }; exports.freezeTronTransaction = freezeTronTransaction; /** * Send Tron TRC10 transaction to the blockchain. This method broadcasts signed transaction to the blockchain. * This operation is irreversible. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @returns transaction id of the transaction in the blockchain */ const sendTronTrc10Transaction = async (testnet, body) => { return blockchain_1.tronBroadcast(await exports.prepareTronTrc10SignedTransaction(testnet, body), body.signatureId); }; exports.sendTronTrc10Transaction = sendTronTrc10Transaction; /** * Send Tron TRC20 transaction to the blockchain. This method broadcasts signed transaction to the blockchain. * This operation is irreversible. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @returns transaction id of the transaction in the blockchain */ const sendTronTrc20Transaction = async (testnet, body) => { return blockchain_1.tronBroadcast(await exports.prepareTronTrc20SignedTransaction(testnet, body), body.signatureId); }; exports.sendTronTrc20Transaction = sendTronTrc20Transaction; /** * Create Tron TRC10 transaction to the blockchain. This method broadcasts signed transaction to the blockchain. * This operation is irreversible. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @returns transaction id of the transaction in the blockchain */ const createTronTrc10Transaction = async (testnet, body) => { return blockchain_1.tronBroadcast(await exports.prepareTronCreateTrc10SignedTransaction(testnet, body), body.signatureId); }; exports.createTronTrc10Transaction = createTronTrc10Transaction; /** * Create Tron TRC20 transaction to the blockchain. This method broadcasts signed transaction to the blockchain. * This operation is irreversible. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @returns transaction id of the transaction in the blockchain */ const createTronTrc20Transaction = async (testnet, body) => { return blockchain_1.tronBroadcast(await exports.prepareTronCreateTrc20SignedTransaction(testnet, body), body.signatureId); }; exports.createTronTrc20Transaction = createTronTrc20Transaction; /** * Sign Tron pending transaction from Tatum KMS * @param tx pending transaction from KMS * @param fromPrivateKey private key to sign transaction with. * @param testnet mainnet or testnet version * @returns transaction data to be broadcast to blockchain. */ const signTronKMSTransaction = async (tx, fromPrivateKey, testnet) => { if (tx.chain !== model_1.Currency.TRON) { throw Error('Unsupported chain.'); } const tronWeb = prepareTronWeb(testnet); const transactionConfig = JSON.parse(tx.serializedTransaction); return JSON.stringify(await tronWeb.trx.sign(transactionConfig, fromPrivateKey)); }; exports.signTronKMSTransaction = signTronKMSTransaction; const convertAddressFromHex = (address) => TronWeb.address.fromHex(address); exports.convertAddressFromHex = convertAddressFromHex; const convertAddressToHex = (address) => TronWeb.address.toHex(address); exports.convertAddressToHex = convertAddressToHex; /** * Send Tron deploy trc721 transaction to the blockchain. This method broadcasts signed transaction to the blockchain. * This operation is irreversible. * @param testnet * @param body content of the transaction to broadcast * @returns transaction id of the transaction in the blockchain */ const sendTronDeployTrc721SignedTransaction = async (testnet, body) => await blockchain_1.tronBroadcast(await exports.prepareTronDeployTrc721SignedTransaction(testnet, body), body.signatureId); exports.sendTronDeployTrc721SignedTransaction = sendTronDeployTrc721SignedTransaction; /** * Send Tron generate custodial wallet transaction to the blockchain. This method broadcasts signed transaction to the blockchain. * This operation is irreversible. * @param testnet * @param body content of the transaction to broadcast * @returns transaction id of the transaction in the blockchain */ const sendTronGenerateCustodialWalletSignedTransaction = async (testnet, body, provider) => await blockchain_1.tronBroadcast(await exports.prepareTronGenerateCustodialWalletSignedTransaction(testnet, body, provider), body.signatureId); exports.sendTronGenerateCustodialWalletSignedTransaction = sendTronGenerateCustodialWalletSignedTransaction; /** * Deploy new smart contract for NFT marketplace logic. Smart contract enables marketplace operator to create new listing for NFT (ERC-721/1155). * @param testnet chain to work with * @param body request data * @param provider optional provider to enter. if not present, Tatum provider will be used. * @returns {txId: string} Transaction ID of the operation, or signatureID in case of Tatum KMS */ const sendTronDeployMarketplaceListingSignedTransaction = async (testnet, body, provider) => await blockchain_1.tronBroadcast(await exports.prepareTronDeployMarketplaceListingSignedTransaction(testnet, body, provider), body.signatureId); exports.sendTronDeployMarketplaceListingSignedTransaction = sendTronDeployMarketplaceListingSignedTransaction; /** * Send Tron mint cashback trc721 transaction to the blockchain. This method broadcasts signed transaction to the blockchain. * This operation is irreversible. * @param testnet * @param body content of the transaction to broadcast * @returns transaction id of the transaction in the blockchain */ const sendTronMintCashbackTrc721SignedTransaction = async (testnet, body) => await blockchain_1.tronBroadcast(await exports.prepareTronMintCashbackTrc721SignedTransaction(testnet, body), body.signatureId); exports.sendTronMintCashbackTrc721SignedTransaction = sendTronMintCashbackTrc721SignedTransaction; /** * Send Tron mint trc721 transaction to the blockchain. This method broadcasts signed transaction to the blockchain. * This operation is irreversible. * @param testnet * @param body content of the transaction to broadcast * @returns transaction id of the transaction in the blockchain */ const sendTronMintTrc721SignedTransaction = async (testnet, body) => await blockchain_1.tronBroadcast(await exports.prepareTronMintTrc721SignedTransaction(testnet, body), body.signatureId); exports.sendTronMintTrc721SignedTransaction = sendTronMintTrc721SignedTransaction; /** * Send Tron transfer trc721 transaction to the blockchain. This method broadcasts signed transaction to the blockchain. * This operation is irreversible. * @param testnet * @param body content of the transaction to broadcast * @returns transaction id of the transaction in the blockchain */ const sendTronTransferTrc721SignedTransaction = async (testnet, body) => await blockchain_1.tronBroadcast(await exports.prepareTronTransferTrc721SignedTransaction(testnet, body), body.signatureId); exports.sendTronTransferTrc721SignedTransaction = sendTronTransferTrc721SignedTransaction; /** * Send Tron burn trc721 transaction to the blockchain. This method broadcasts signed transaction to the blockchain. * This operation is irreversible. * @param testnet * @param body content of the transaction to broadcast * @returns transaction id of the transaction in the blockchain */ const sendTronBurnTrc721SignedTransaction = async (testnet, body) => await blockchain_1.tronBroadcast(await exports.prepareTronBurnTrc721SignedTransaction(testnet, body), body.signatureId); exports.sendTronBurnTrc721SignedTransaction = sendTronBurnTrc721SignedTransaction; /** * Send Tron mint multiple trc721 transaction to the blockchain. This method broadcasts signed transaction to the blockchain. * This operation is irreversible. * @param testnet * @param body content of the transaction to broadcast * @returns transaction id of the transaction in the blockchain */ const sendTronMintMultipleTrc721SignedTransaction = async (testnet, body) => await blockchain_1.tronBroadcast(await exports.prepareTronMintMultipleTrc721SignedTransaction(testnet, body), body.signatureId); exports.sendTronMintMultipleTrc721SignedTransaction = sendTronMintMultipleTrc721SignedTransaction; /** * Send Tron update cashback for author trc721 transaction to the blockchain. This method broadcasts signed transaction to the blockchain. * This operation is irreversible. * @param testnet * @param body content of the transaction to broadcast * @returns transaction id of the transaction in the blockchain */ const sendTronUpdateCashbackForAuthorTrc721SignedTransaction = async (testnet, body) => await blockchain_1.tronBroadcast(await exports.prepareTronUpdateCashbackForAuthorTrc721SignedTransaction(testnet, body), body.signatureId); exports.sendTronUpdateCashbackForAuthorTrc721SignedTransaction = sendTronUpdateCashbackForAuthorTrc721SignedTransaction; /** * Sign Tron transaction with private keys locally. Nothing is broadcast to the blockchain. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @param provider * @returns transaction data to be broadcast to blockchain. */ const prepareTronSignedTransaction = async (testnet, body, provider) => { await tatum_1.validateBody(body, model_1.TransferTron); const { fromPrivateKey, to, amount, } = body; const tronWeb = prepareTronWeb(testnet, provider); const tx = await tronWeb.transactionBuilder.sendTrx(to, tronWeb.toSun(amount), tronWeb.address.fromHex(tronWeb.address.fromPrivateKey(fromPrivateKey))); return JSON.stringify(await tronWeb.trx.sign(tx, fromPrivateKey)); }; exports.prepareTronSignedTransaction = prepareTronSignedTransaction; /** * Sign Tron Freeze balance transaction with private keys locally. Nothing is broadcast to the blockchain. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @param provider optional provider to enter. if not present, Tatum provider will be used. * @returns transaction data to be broadcast to blockchain. */ const prepareTronFreezeTransaction = async (testnet, body, provider) => { await tatum_1.validateBody(body, model_1.FreezeTron); const { fromPrivateKey, receiver, amount, resource, duration, } = body; const tronWeb = prepareTronWeb(testnet, provider); const tx = await tronWeb.transactionBuilder.freezeBalance(tronWeb.toSun(parseFloat(amount)), duration, resource, tronWeb.address.fromHex(tronWeb.address.fromPrivateKey(fromPrivateKey)), receiver); return JSON.stringify(await tronWeb.trx.sign(tx, fromPrivateKey)); }; exports.prepareTronFreezeTransaction = prepareTronFreezeTransaction; /** * Sign Tron TRC10 transaction with private keys locally. Nothing is broadcast to the blockchain. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @param precision * @returns transaction data to be broadcast to blockchain. */ const prepareTronTrc10SignedTransaction = async (testnet, body, precision, provider) => { await tatum_1.validateBody(body, model_1.TransferTronTrc10); const { fromPrivateKey, to, tokenId, amount, } = body; const tronWeb = prepareTronWeb(testnet, provider); const tx = await tronWeb.transactionBuilder.sendToken(to, new bignumber_js_1.default(amount).multipliedBy(new bignumber_js_1.default(10).pow(precision || await getTrc10Precision(testnet, tokenId))), tokenId, tronWeb.address.fromHex(tronWeb.address.fromPrivateKey(fromPrivateKey))); return JSON.stringify(await tronWeb.trx.sign(tx, fromPrivateKey)); }; exports.prepareTronTrc10SignedTransaction = prepareTronTrc10SignedTransaction; /** * Get TRC20 balance for the given tron address. * @param testnet mainnet or testnet version * @param address the address whose balance is returned * @param contractAddress the TRC20 contract address * @param provider */ const tronGetAccountTrc20Address = async (testnet, address, contractAddress, provider) => { if (!contractAddress) { throw new Error('Contract address not set.'); } const tronWeb = prepareTronWeb(testnet, provider); tronWeb.setAddress(contractAddress); const contractInstance = await tronWeb.contract().at(contractAddress); return await contractInstance.balanceOf(address).call(); }; exports.tronGetAccountTrc20Address = tronGetAccountTrc20Address; const getTronTrc20ContractDecimals = async (testnet, contractAddress, provider) => { if (!contractAddress) { throw new Error('Contract address not set.'); } const tronWeb = prepareTronWeb(testnet, provider); tronWeb.setAddress(contractAddress); const contractInstance = await tronWeb.contract().at(contractAddress); const decimalsBigNum = await contractInstance.decimals().call(); return new bignumber_js_1.default(decimalsBigNum).toNumber(); }; exports.getTronTrc20ContractDecimals = getTronTrc20ContractDecimals; /** * Sign Tron custodial transfer transaction with private keys locally. Nothing is broadcast to the blockchain. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @param feeLimit * @param from * @param provider * @returns transaction data to be broadcast to blockchain. */ const prepareTronSmartContractInvocation = async (testnet, body, feeLimit, from, provider) => { const tronWeb = prepareTronWeb(testnet, provider); tronWeb.setAddress(body.contractAddress); const sender = from || tronWeb.address.fromHex(tronWeb.address.fromPrivateKey(body.fromPrivateKey)); const { transaction } = await tronWeb.transactionBuilder.triggerSmartContract(tronWeb.address.toHex(body.contractAddress), body.methodName, { feeLimit: tronWeb.toSun(feeLimit), from: sender, callValue: tronWeb.toSun(body.amount || 0), }, body.params, sender); if (body.signatureId) { return JSON.stringify(transaction); } return JSON.stringify(await tronWeb.trx.sign(transaction, body.fromPrivateKey)); }; exports.prepareTronSmartContractInvocation = prepareTronSmartContractInvocation; /** * Sign Tron custodial transfer batch transaction with private keys locally. Nothing is broadcast to the blockchain. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @param feeLimit * @param from * @param provider * @returns transaction data to be broadcast to blockchain. */ const prepareTronCustodialTransferBatch = async (testnet, body, feeLimit, from, provider) => { const tronWeb = prepareTronWeb(testnet, provider); tronWeb.setAddress(body.contractAddress); const sender = from || tronWeb.address.fromHex(tronWeb.address.fromPrivateKey(body.fromPrivateKey)); const { transaction } = await tronWeb.transactionBuilder.triggerSmartContract(tronWeb.address.toHex(body.contractAddress), 'transferBatch(address[],uint256[],address[],uint256[],uint256[])', { feeLimit: tronWeb.toSun(feeLimit), from: sender }, [ { type: 'address[]', value: body.params[0].map(tronWeb.address.toHex) }, { type: 'uint256[]', value: body.params[1] }, { type: 'address[]', value: body.params[2].map(tronWeb.address.toHex) }, { type: 'uint256[]', value: body.params[3] }, { type: 'uint256[]', value: body.params[4] }, ], sender); if (body.signatureId) { return JSON.stringify(transaction); } return JSON.stringify(await tronWeb.trx.sign(transaction, body.fromPrivateKey)); }; exports.prepareTronCustodialTransferBatch = prepareTronCustodialTransferBatch; /** * Sign Tron TRC20 transaction with private keys locally. Nothing is broadcast to the blockchain. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @param provider * @returns transaction data to be broadcast to blockchain. */ const prepareTronTrc20SignedTransaction = async (testnet, body, provider) => { var _a; await tatum_1.validateBody(body, model_1.TransferTronTrc20); const { fromPrivateKey, to, tokenAddress, amount, feeLimit, } = body; const tronWeb = prepareTronWeb(testnet, provider); tronWeb.setAddress(tokenAddress); const contractInstance = await tronWeb.contract().at(tokenAddress); const decimals = await contractInstance.decimals().call(); const from = 'signatureId' in body ? body.from : tronWeb.address.fromHex(tronWeb.address.fromPrivateKey(body.fromPrivateKey)); const balance = new bignumber_js_1.default(((_a = (await contractInstance.balanceOf(from).call())) === null || _a === void 0 ? void 0 : _a.toString()) || 0); const valueToSend = new bignumber_js_1.default(amount).multipliedBy(new bignumber_js_1.default(10).pow(decimals)); if (valueToSend.isGreaterThan(balance)) { const balanceInTrx = balance.dividedBy(new bignumber_js_1.default(10).pow(decimals)); throw new Error(`Not enough TRC20 tokens on address to perform this transaction. Balance: ${balanceInTrx}`); } const { transaction } = await tronWeb.transactionBuilder.triggerSmartContract(tronWeb.address.toHex(tokenAddress), 'transfer(address,uint256)', { feeLimit: tronWeb.toSun(feeLimit), from: tronWeb.address.fromHex(tronWeb.address.fromPrivateKey(fromPrivateKey)) }, [{ type: 'address', value: tronWeb.address.toHex(to) }, { type: 'uint256', value: `0x${new bignumber_js_1.default(amount).multipliedBy(new bignumber_js_1.default(10).pow(new bignumber_js_1.default(decimals))).toString(16)}` }], tronWeb.address.fromHex(tronWeb.address.fromPrivateKey(fromPrivateKey))); return JSON.stringify(await tronWeb.trx.sign(transaction, fromPrivateKey)); }; exports.prepareTronTrc20SignedTransaction = prepareTronTrc20SignedTransaction; /** * Sign create Tron TRC10 transaction with private keys locally. Nothing is broadcast to the blockchain. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @returns transaction data to be broadcast to blockchain. */ const prepareTronCreateTrc10SignedTransaction = async (testnet, body, provider) => { await tatum_1.validateBody(body, model_1.CreateTronTrc10); const { fromPrivateKey, name, abbreviation, description, url, totalSupply, decimals, } = body; const tronWeb = prepareTronWeb(testnet, provider); const tx = await tronWeb.transactionBuilder.createToken({ name, abbreviation, description, url, totalSupply: new bignumber_js_1.default(totalSupply).multipliedBy(new bignumber_js_1.default(10).pow(decimals)), trxRatio: 1, tokenRatio: 1, saleStart: Date.now() + 60000, saleEnd: Date.now() + 100000, freeBandwidth: 0, freeBandwidthLimit: 0, frozenAmount: 0, frozenDuration: 0, precision: decimals, }, tronWeb.address.fromPrivateKey(fromPrivateKey)); return JSON.stringify(await tronWeb.trx.sign(tx, fromPrivateKey)); }; exports.prepareTronCreateTrc10SignedTransaction = prepareTronCreateTrc10SignedTransaction; /** * Sign create Tron TRC20 transaction with private keys locally. Nothing is broadcast to the blockchain. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @returns transaction data to be broadcast to blockchain. */ const prepareTronCreateTrc20SignedTransaction = async (testnet, body, provider) => { await tatum_1.validateBody(body, model_1.CreateTronTrc20); const { fromPrivateKey, name, decimals, recipient, symbol, totalSupply, } = body; const tronWeb = prepareTronWeb(testnet, provider); const tx = await tronWeb.transactionBuilder.createSmartContract({ feeLimit: 1000000000, callValue: 0, userFeePercentage: 100, originEnergyLimit: 1, abi: JSON.stringify(token_abi_1.default), bytecode: token_bytecode_1.default, parameters: [ name, symbol, decimals, tronWeb.address.toHex(recipient), totalSupply, ], name, }, tronWeb.address.fromPrivateKey(fromPrivateKey)); return JSON.stringify(await tronWeb.trx.sign(tx, fromPrivateKey)); }; exports.prepareTronCreateTrc20SignedTransaction = prepareTronCreateTrc20SignedTransaction; /** * Prepare Tron transaction for KMS. Nothing is broadcast to the blockchain. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @param provider * @returns transaction data to be broadcast to blockchain. */ const prepareTronSignedKMSTransaction = async (testnet, body, provider) => { await tatum_1.validateBody(body, model_1.TransferTron); const { from, to, amount, } = body; const tronWeb = prepareTronWeb(testnet, provider); const tx = await tronWeb.transactionBuilder.sendTrx(to, tronWeb.toSun(amount), from); return JSON.stringify(tx); }; exports.prepareTronSignedKMSTransaction = prepareTronSignedKMSTransaction; /** * Prepare Tron Freeze balance transaction for KMS. Nothing is broadcast to the blockchain. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @param provider * @returns transaction data to be broadcast to blockchain. */ const prepareTronFreezeKMSTransaction = async (testnet, body, provider) => { await tatum_1.validateBody(body, model_1.FreezeTron); const { from, receiver, amount, resource, duration, } = body; const tronWeb = prepareTronWeb(testnet, provider); const tx = await tronWeb.transactionBuilder.freezeBalance(tronWeb.toSun(parseFloat(amount)), duration, resource, from, receiver); return JSON.stringify(tx); }; exports.prepareTronFreezeKMSTransaction = prepareTronFreezeKMSTransaction; /** * Prepare Tron TRC10 transaction for KMS. Nothing is broadcast to the blockchain. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @param precision * @param provider * @returns transaction data to be broadcast to blockchain. */ const prepareTronTrc10SignedKMSTransaction = async (testnet, body, precision, provider) => { await tatum_1.validateBody(body, model_1.TransferTronTrc10); const { from, to, tokenId, amount, } = body; const tronWeb = prepareTronWeb(testnet, provider); const tx = await tronWeb.transactionBuilder.sendToken(to, new bignumber_js_1.default(amount).multipliedBy(new bignumber_js_1.default(10).pow(precision || await getTrc10Precision(testnet, tokenId))), tokenId, from); return JSON.stringify(tx); }; exports.prepareTronTrc10SignedKMSTransaction = prepareTronTrc10SignedKMSTransaction; /** * Prepare Tron TRC20 transaction for KMS. Nothing is broadcast to the blockchain. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @param provider * @returns transaction data to be broadcast to blockchain. */ const prepareTronTrc20SignedKMSTransaction = async (testnet, body, provider) => { await tatum_1.validateBody(body, model_1.TransferTronTrc20); const { from, to, tokenAddress, amount, feeLimit, } = body; const tronWeb = prepareTronWeb(testnet, provider); tronWeb.setAddress(tokenAddress); const contractInstance = await tronWeb.contract().at(tokenAddress); const decimals = await contractInstance.decimals().call(); const { transaction } = await tronWeb.transactionBuilder.triggerSmartContract(tronWeb.address.toHex(tokenAddress), 'transfer(address,uint256)', { feeLimit: tronWeb.toSun(feeLimit), from }, [{ type: 'address', value: tronWeb.address.toHex(to) }, { type: 'uint256', value: `0x${new bignumber_js_1.default(amount).multipliedBy(new bignumber_js_1.default(10).pow(new bignumber_js_1.default(decimals))).toString(16)}` }], from); return JSON.stringify(transaction); }; exports.prepareTronTrc20SignedKMSTransaction = prepareTronTrc20SignedKMSTransaction; /** * Prepare create Tron TRC10 transaction for KMS. Nothing is broadcast to the blockchain. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @param provider * @returns transaction data to be broadcast to blockchain. */ const prepareTronCreateTrc10SignedKMSTransaction = async (testnet, body, provider) => { await tatum_1.validateBody(body, model_1.CreateTronTrc10); const { from, name, abbreviation, description, url, totalSupply, decimals, } = body; const tronWeb = prepareTronWeb(testnet, provider); const tx = await tronWeb.transactionBuilder.createToken({ name, abbreviation, description, url, totalSupply: new bignumber_js_1.default(totalSupply).multipliedBy(new bignumber_js_1.default(10).pow(decimals)), trxRatio: 1, tokenRatio: 1, saleStart: Date.now() + 60000, saleEnd: Date.now() + 100000, freeBandwidth: 0, freeBandwidthLimit: 0, frozenAmount: 0, frozenDuration: 0, precision: decimals, }, from); return JSON.stringify(tx); }; exports.prepareTronCreateTrc10SignedKMSTransaction = prepareTronCreateTrc10SignedKMSTransaction; /** * Prepare create Tron TRC20 transaction for KMS. Nothing is broadcast to the blockchain. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @param provider * @returns transaction data to be broadcast to blockchain. */ const prepareTronCreateTrc20SignedKMSTransaction = async (testnet, body, provider) => { await tatum_1.validateBody(body, model_1.CreateTronTrc20); const { from, name, decimals, recipient, symbol, totalSupply, } = body; const tronWeb = prepareTronWeb(testnet, provider); const tx = await tronWeb.transactionBuilder.createSmartContract({ feeLimit: 1000000000, callValue: 0, userFeePercentage: 100, originEnergyLimit: 1, abi: JSON.stringify(token_abi_1.default), bytecode: token_bytecode_1.default, parameters: [ name, symbol, decimals, tronWeb.address.toHex(recipient), totalSupply, ], name, }, from); return JSON.stringify(tx); }; exports.prepareTronCreateTrc20SignedKMSTransaction = prepareTronCreateTrc20SignedKMSTransaction; /** * Sign Tron deploy trc721 transaction with private keys locally. Nothing is broadcast to the blockchain. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @param provider * @returns transaction data to be broadcast to blockchain. */ const prepareTronDeployTrc721SignedTransaction = async (testnet, body, provider) => { await tatum_1.validateBody(body, model_1.TronDeployTrc721); const { fromPrivateKey, name, symbol, feeLimit, signatureId, from, } = body; const tronWeb = prepareTronWeb(testnet, provider); const tx = await tronWeb.transactionBuilder.createSmartContract({ feeLimit: tronWeb.toSun(feeLimit), callValue: 0, userFeePercentage: 100, originEnergyLimit: 1, abi: JSON.stringify(trc721_abi_1.default), bytecode: trc721_bytecode_1.default, parameters: [ name, symbol, ], name, }, from || tronWeb.address.fromPrivateKey(fromPrivateKey)); if (signatureId) { return JSON.stringify(tx); } return JSON.stringify(await tronWeb.trx.sign(tx, fromPrivateKey)); }; exports.prepareTronDeployTrc721SignedTransaction = prepareTronDeployTrc721SignedTransaction; /** * Sign Tron generate custodial wallet transaction with private keys locally. Nothing is broadcast to the blockchain. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @param provider * @returns transaction data to be broadcast to blockchain. */ const prepareTronGenerateCustodialWalletSignedTransaction = async (testnet, body, provider) => { await tatum_1.validateBody(body, model_1.GenerateTronCustodialAddress); const tronWeb = prepareTronWeb(testnet, provider); const { abi, code } = wallet_1.obtainCustodialAddressType(body); const tx = await tronWeb.transactionBuilder.createSmartContract({ feeLimit: tronWeb.toSun(body.feeLimit || 100), callValue: 0, userFeePercentage: 100, originEnergyLimit: 1, abi: JSON.stringify(abi), bytecode: code, parameters: [], name: 'CustodialWallet', }, body.from || tronWeb.address.fromPrivateKey(body.fromPrivateKey)); if (body.signatureId) { return JSON.stringify(tx); } return JSON.stringify(await tronWeb.trx.sign(tx, body.fromPrivateKey)); }; exports.prepareTronGenerateCustodialWalletSignedTransaction = prepareTronGenerateCustodialWalletSignedTransaction; /** * Sign TRON deploy new smart contract for NFT marketplace transaction. Smart contract enables marketplace operator to create new listing for NFT (ERC-721/1155). * @param testnet chain to work with * @param body request data * @param provider optional provider to enter. if not present, Tatum provider will be used. * @returns {txId: string} Transaction ID of the operation, or signatureID in case of Tatum KMS */ const prepareTronDeployMarketplaceListingSignedTransaction = async (testnet, body, provider) => { await tatum_1.validateBody(body, model_1.DeployTronMarketplaceListing); const tronWeb = prepareTronWeb(testnet, provider); const tx = await tronWeb.transactionBuilder.createSmartContract({ feeLimit: tronWeb.toSun(body.feeLimit || 300), callValue: 0, userFeePercentage: 100, originEnergyLimit: 1, abi: JSON.stringify(marketplace_1.listing.abi), bytecode: marketplace_1.listing.data, parameters: [ body.marketplaceFee, body.feeRecipient, ], name: 'CustodialWallet', }, body.from || tronWeb.address.fromPrivateKey(body.fromPrivateKey)); if (body.signatureId) { return JSON.stringify(tx); } return JSON.stringify(await tronWeb.trx.sign(tx, body.fromPrivateKey)); }; exports.prepareTronDeployMarketplaceListingSignedTransaction = prepareTronDeployMarketplaceListingSignedTransaction; /** * Sign Tron deploy trc721 transaction with private keys locally. Nothing is broadcast to the blockchain. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @param provider * @returns transaction data to be broadcast to blockchain. */ const prepareTronMintCashbackTrc721SignedTransaction = async (testnet, body, provider) => { await tatum_1.validateBody(body, model_1.TronMintTrc721); const { fromPrivateKey, url, to, tokenId, contractAddress, feeLimit, from, signatureId, authorAddresses, cashbackValues } = body; const tronWeb = prepareTronWeb(testnet, provider); tronWeb.setAddress(contractAddress); const sender = from || tronWeb.address.fromHex(tronWeb.address.fromPrivateKey(fromPrivateKey)); const cb = []; for (const c of cashbackValues) { cb.push(`0x${new bignumber_js_1.default(c).multipliedBy(1e6).toString(16)}`); } const { transaction } = await tronWeb.transactionBuilder.triggerSmartContract(tronWeb.address.toHex(contractAddress), 'mintWithCashback(address,uint256,string,address[],uint256[])', { feeLimit: tronWeb.toSun(feeLimit), from: sender }, [{ type: 'address', value: tronWeb.address.toHex(to) }, { type: 'uint256', value: `0x${new bignumber_js_1.default(tokenId).toString(16)}` }, { type: 'string', value: url, }, { type: 'address[]', value: authorAddresses === null || authorAddresses === void 0 ? void 0 : authorAddresses.map(a => tronWeb.address.toHex(a)), }, { type: 'uint256[]', value: cb, }], sender); return JSON.stringify(signatureId ? transaction : await tronWeb.trx.sign(transaction, fromPrivateKey)); }; exports.prepareTronMintCashbackTrc721SignedTransaction = prepareTronMintCashbackTrc721SignedTransaction; /** * Sign Tron mint trc721 transaction with private keys locally. Nothing is broadcast to the blockchain. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @param provider * @returns transaction data to be broadcast to blockchain. */ const prepareTronMintTrc721SignedTransaction = async (testnet, body, provider) => { await tatum_1.validateBody(body, model_1.TronMintTrc721); const { fromPrivateKey, url, to, tokenId, contractAddress, from, feeLimit, signatureId, } = body; const tronWeb = prepareTronWeb(testnet, provider); tronWeb.setAddress(contractAddress); const sender = from || tronWeb.address.fromHex(tronWeb.address.fromPrivateKey(fromPrivateKey)); const { transaction } = await tronWeb.transactionBuilder.triggerSmartContract(tronWeb.address.toHex(contractAddress), 'mintWithTokenURI(address,uint256,string)', { feeLimit: tronWeb.toSun(feeLimit), from: sender }, [{ type: 'address', value: tronWeb.address.toHex(to) }, { type: 'uint256', value: `0x${new bignumber_js_1.default(tokenId).toString(16)}` }, { type: 'string', value: url, }], sender); return JSON.stringify(signatureId ? transaction : await tronWeb.trx.sign(transaction, fromPrivateKey)); }; exports.prepareTronMintTrc721SignedTransaction = prepareTronMintTrc721SignedTransaction; /** * Sign Tron transfer trc721 transaction with private keys locally. Nothing is broadcast to the blockchain. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @param provider * @returns transaction data to be broadcast to blockchain. */ const prepareTronTransferTrc721SignedTransaction = async (testnet, body, provider) => { await tatum_1.validateBody(body, model_1.TronTransferTrc721); const { fromPrivateKey, to, tokenId, contractAddress, feeLimit, from, signatureId, value } = body; const tronWeb = prepareTronWeb(testnet, provider); tronWeb.setAddress(contractAddress); const sender = from || tronWeb.address.fromHex(tronWeb.address.fromPrivateKey(fromPrivateKey)); const { transaction } = await tronWeb.transactionBuilder.triggerSmartContract(tronWeb.address.toHex(contractAddress), 'safeTransfer(address,uint256)', { feeLimit: tronWeb.toSun(feeLimit), from: sender, callValue: value ? `0x${new bignumber_js_1.default(value).multipliedBy(1e6).toString(16)}` : 0, }, [{ type: 'address', value: tronWeb.address.toHex(to) }, { type: 'uint256', value: `0x${new bignumber_js_1.default(tokenId).toString(16)}` }], sender); return JSON.stringify(signatureId ? transaction : await tronWeb.trx.sign(transaction, fromPrivateKey)); }; exports.prepareTronTransferTrc721SignedTransaction = prepareTronTransferTrc721SignedTransaction; /** * Sign Tron burn trc721 transaction with private keys locally. Nothing is broadcast to the blockchain. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @param provider * @returns transaction data to be broadcast to blockchain. */ const prepareTronBurnTrc721SignedTransaction = async (testnet, body, provider) => { await tatum_1.validateBody(body, model_1.TronBurnTrc721); const { fromPrivateKey, tokenId, contractAddress, feeLimit, from, signatureId, } = body; const tronWeb = prepareTronWeb(testnet, provider); tronWeb.setAddress(contractAddress); const sender = from || tronWeb.address.fromHex(tronWeb.address.fromPrivateKey(fromPrivateKey)); const { transaction } = await tronWeb.transactionBuilder.triggerSmartContract(tronWeb.address.toHex(contractAddress), 'burn(uint256)', { feeLimit: tronWeb.toSun(feeLimit), from: sender, }, [{ type: 'uint256', value: `0x${new bignumber_js_1.default(tokenId).toString(16)}` }], sender); return JSON.stringify(signatureId ? transaction : await tronWeb.trx.sign(transaction, fromPrivateKey)); }; exports.prepareTronBurnTrc721SignedTransaction = prepareTronBurnTrc721SignedTransaction; /** * Sign Tron mint multiple trc721 transaction with private keys locally. Nothing is broadcast to the blockchain. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @param provider * @returns transaction data to be broadcast to blockchain. */ const prepareTronMintMultipleTrc721SignedTransaction = async (testnet, body, provider) => { await tatum_1.validateBody(body, model_1.TronMintMultipleTrc721); const { fromPrivateKey, to, tokenId, contractAddress, url, feeLimit, from, signatureId, } = body; const tronWeb = prepareTronWeb(testnet, provider); tronWeb.setAddress(contractAddress); const sender = from || tronWeb.address.fromHex(tronWeb.address.fromPrivateKey(fromPrivateKey)); const { transaction } = await tronWeb.transactionBuilder.triggerSmartContract(tronWeb.address.toHex(contractAddress), 'mintMultiple(address[],uint256[],string[])', { feeLimit: tronWeb.toSun(feeLimit), from: sender }, [{ type: 'address[]', value: to.map(a => tronWeb.address.toHex(a)), }, { type: 'uint256[]', value: tokenId.map(t => `0x${new bignumber_js_1.default(t).toString(16)}`) }, { type: 'string[]', value: url, }], sender); return JSON.stringify(signatureId ? transaction : await tronWeb.trx.sign(transaction, fromPrivateKey)); }; exports.prepareTronMintMultipleTrc721SignedTransaction = prepareTronMintMultipleTrc721SignedTransaction; /** * Sign Tron update cashback for author trc721 transaction with private keys locally. Nothing is broadcast to the blockchain. * @param testnet mainnet or testnet version * @param body content of the transaction to broadcast * @param provider * @returns transaction data to be broadcast to blockchain. */ const prepareTronUpdateCashbackForAuthorTrc721SignedTransaction = async (testnet, body, provider) => { await tatum_1.validateBody(body, model_1.TronUpdateCashbackTrc721); const { fromPrivateKey, cashbackValue, tokenId, contractAddress, feeLimit, from, signatureId, } = body; const tronWeb = prepareTronWeb(testnet, provider); tronWeb.setAddress(contractAddress); const sender = from || tronWeb.address.fromHex(tronWeb.address.fromPrivateKey(fromPrivateKey)); const { transaction } = await tronWeb.transactionBuilder.triggerSmartContract(tronWeb.address.toHex(contractAddress), 'updateCashbackForAuthor(uint256,uint256)', { feeLimit: tronWeb.toSun(feeLimit), from: sender }, [{ type: 'uint256', value: `0x${new bignumber_js_1.default(tokenId).toString(16)}` }, { type: 'uint256', value: `0x${new bignumber_js_1.default(cashbackValue).multipliedBy(1e6).toString(16)}` }], sender); return JSON.stringify(signatureId ? transaction : await tronWeb.trx.sign(transaction, fromPrivateKey)); }; exports.prepareTronUpdateCashbackForAuthorTrc721SignedTransaction = prepareTronUpdateCashbackForAuthorTrc721SignedTransaction; /** * Sign Tron pending transaction from Tatum KMS * @param tx pending transaction from KMS * @param fromPrivateKey private key to sign transaction with. * @param testnet mainnet or testnet version * @returns transaction data to be broadcast to blockchain. */ const signTrxKMSTransaction = async (tx, fromPrivateKey, testnet) => { if (tx.chain !== model_1.Currency.TRON) { throw Error('Unsupported chain.'); } const transactionConfig = JSON.parse(tx.serializedTransaction); const tronWeb = prepareTronWeb(testnet); return JSON.stringify(await tronWeb.trx.sign(transactionConfig, fromPrivateKey)); }; exports.signTrxKMSTransaction = signTrxKMSTransaction; const transferHexToBase58Address = (address) => TronWeb.address.fromHex(address); exports.transferHexToBase58Address = transferHexToBase58Address; const getTrc10Precision = async (testnet, tokenId) => { const config = { method: 'GET', url: `/v1/assets/${tokenId}`, baseURL: `${testnet ? 'https://api.shasta.trongrid.io' : 'https://api.trongrid.io'}`, headers: { 'content-type': 'application/json', 'TRON-PRO-API-KEY': process.env.TRON_PRO_API_KEY, }, }; const { data } = (await tatum_1.axios.request(config)).data; if (!(data === null || data === void 0 ? void 0 : data.length)) { throw new Error('No such asset.'); } return data[0].precision; throw new Error('Get TRC10 precision error.'); }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy90cmFuc2FjdGlvbi90cm9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUNBLGdFQUFxQztBQUNyQyw4Q0FBOEM7QUFDOUMsOENBQXlEO0FBQ3pELDRDQUE2QztBQUM3QywwREFBbUQ7QUFDbkQsNkVBQStDO0FBQy9DLHVGQUF5RDtBQUN6RCxnRkFBd0Q7QUFDeEQsMEZBQWtFO0FBQ2xFLG9DQWtCa0I7QUFDbEIsc0NBQXVEO0FBR3ZELDJDQUEyQztBQUMzQyxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7QUFFbkMsTUFBTSxjQUFjLEdBQUcsQ0FBQyxPQUFnQixFQUFFLFFBQWlCLEVBQUUsRUFBRTtJQUMzRCxNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQztJQUNwRCxNQUFNLEdBQUcsR0FBRyxRQUFRLElBQUksR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLGFBQWEsSUFBSSx5QkFBYSxpQkFBaUIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUNsSCxNQUFNLFFBQVEsR0FBRyxJQUFJLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUN2QyxNQUFNLFlBQVksR0FBRyxJQUFJLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUMzQyxNQUFNLFdBQVcsR0FBRyxJQUFJLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUMxQyxNQUFNLE9BQU8sR0FBRyxJQUFJLE9BQU8sQ0FBQyxRQUFRLEVBQUUsWUFBWSxFQUFFLFdBQVcsQ0FBQyxDQUFBO0lBQ2hFLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBQyxrQkFBa0IsRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLGdCQUFnQixFQUFDLENBQUMsQ0FBQTtJQUNyRSxPQUFPLE9BQU8sQ0FBQTtBQUNsQixDQUFDLENBQUE7QUFFRDs7Ozs7O0dB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