123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963 |
- import { TronWeb } from '../tronweb.js';
- import utils from '../utils/index.js';
- import { keccak256, toUtf8Bytes, recoverAddress, SigningKey, Signature } from '../utils/ethersUtils.js';
- import { ADDRESS_PREFIX } from '../utils/address.js';
- import { Validator } from '../paramValidator/index.js';
- import { txCheck } from '../utils/transaction.js';
- import { ecRecover } from '../utils/crypto.js';
- const TRX_MESSAGE_HEADER = '\x19TRON Signed Message:\n32';
- // it should be: '\x15TRON Signed Message:\n32';
- const ETH_MESSAGE_HEADER = '\x19Ethereum Signed Message:\n32';
- function toHex(value) {
- return TronWeb.address.toHex(value);
- }
- export class Trx {
- tronWeb;
- cache;
- validator;
- signMessage;
- sendAsset;
- send;
- sendTrx;
- broadcast;
- broadcastHex;
- signTransaction;
- constructor(tronWeb) {
- this.tronWeb = tronWeb;
- this.cache = {
- contracts: {},
- };
- this.validator = new Validator();
- this.signMessage = this.sign;
- this.sendAsset = this.sendToken;
- this.send = this.sendTransaction;
- this.sendTrx = this.sendTransaction;
- this.broadcast = this.sendRawTransaction;
- this.broadcastHex = this.sendHexTransaction;
- this.signTransaction = this.sign;
- }
- _parseToken(token) {
- return {
- ...token,
- name: this.tronWeb.toUtf8(token.name),
- abbr: token.abbr && this.tronWeb.toUtf8(token.abbr),
- description: token.description && this.tronWeb.toUtf8(token.description),
- url: token.url && this.tronWeb.toUtf8(token.url),
- };
- }
- getCurrentBlock() {
- return this.tronWeb.fullNode.request('wallet/getnowblock');
- }
- getConfirmedCurrentBlock() {
- return this.tronWeb.solidityNode.request('walletsolidity/getnowblock');
- }
- async getBlock(block = this.tronWeb.defaultBlock) {
- if (block === false) {
- throw new Error('No block identifier provided');
- }
- if (block == 'earliest')
- block = 0;
- if (block == 'latest')
- return this.getCurrentBlock();
- if (isNaN(+block) && utils.isHex(block.toString()))
- return this.getBlockByHash(block);
- return this.getBlockByNumber(block);
- }
- async getBlockByHash(blockHash) {
- const block = await this.tronWeb.fullNode.request('wallet/getblockbyid', {
- value: blockHash,
- }, 'post');
- if (!Object.keys(block).length) {
- throw new Error('Block not found');
- }
- return block;
- }
- async getBlockByNumber(blockID) {
- if (!utils.isInteger(blockID) || blockID < 0) {
- throw new Error('Invalid block number provided');
- }
- return this.tronWeb.fullNode
- .request('wallet/getblockbynum', {
- num: parseInt(blockID),
- }, 'post')
- .then((block) => {
- if (!Object.keys(block).length) {
- throw new Error('Block not found');
- }
- return block;
- });
- }
- async getBlockTransactionCount(block = this.tronWeb.defaultBlock) {
- const { transactions = [] } = await this.getBlock(block);
- return transactions.length;
- }
- async getTransactionFromBlock(block = this.tronWeb.defaultBlock, index) {
- const { transactions } = await this.getBlock(block);
- if (!transactions) {
- throw new Error('Transaction not found in block');
- }
- if (index >= 0 && index < transactions.length)
- return transactions[index];
- else
- throw new Error('Invalid transaction index provided');
- }
- async getTransactionsFromBlock(block = this.tronWeb.defaultBlock) {
- const { transactions } = await this.getBlock(block);
- if (!transactions) {
- throw new Error('Transaction not found in block');
- }
- return transactions;
- }
- async getTransaction(transactionID) {
- const transaction = await this.tronWeb.fullNode.request('wallet/gettransactionbyid', {
- value: transactionID,
- }, 'post');
- if (!Object.keys(transaction).length) {
- throw new Error('Transaction not found');
- }
- return transaction;
- }
- async getConfirmedTransaction(transactionID) {
- const transaction = await this.tronWeb.solidityNode.request('walletsolidity/gettransactionbyid', {
- value: transactionID,
- }, 'post');
- if (!Object.keys(transaction).length) {
- throw new Error('Transaction not found');
- }
- return transaction;
- }
- getUnconfirmedTransactionInfo(transactionID) {
- return this.tronWeb.fullNode.request('wallet/gettransactioninfobyid', { value: transactionID }, 'post');
- }
- getTransactionInfo(transactionID) {
- return this.tronWeb.solidityNode.request('walletsolidity/gettransactioninfobyid', { value: transactionID }, 'post');
- }
- getTransactionsToAddress(address = this.tronWeb.defaultAddress.hex, limit = 30, offset = 0) {
- return this.getTransactionsRelated(this.tronWeb.address.toHex(address), 'to', limit, offset);
- }
- getTransactionsFromAddress(address = this.tronWeb.defaultAddress.hex, limit = 30, offset = 0) {
- return this.getTransactionsRelated(this.tronWeb.address.toHex(address), 'from', limit, offset);
- }
- async getTransactionsRelated(address = this.tronWeb.defaultAddress.hex, direction = 'all', limit = 30, offset = 0) {
- if (this.tronWeb.fullnodeSatisfies('>=4.1.1')) {
- throw new Error('This api is not supported any more');
- }
- if (!['to', 'from', 'all'].includes(direction)) {
- throw new Error('Invalid direction provided: Expected "to", "from" or "all"');
- }
- if (direction == 'all') {
- const [from, to] = await Promise.all([
- this.getTransactionsRelated(address, 'from', limit, offset),
- this.getTransactionsRelated(address, 'to', limit, offset),
- ]);
- return [
- ...from.map((tx) => ((tx.direction = 'from'), tx)),
- ...to.map((tx) => ((tx.direction = 'to'), tx)),
- ].sort((a, b) => {
- return b.raw_data.timestamp - a.raw_data.timestamp;
- });
- }
- if (!this.tronWeb.isAddress(address)) {
- throw new Error('Invalid address provided');
- }
- if (!utils.isInteger(limit) || limit < 0 || (offset && limit < 1)) {
- throw new Error('Invalid limit provided');
- }
- if (!utils.isInteger(offset) || offset < 0) {
- throw new Error('Invalid offset provided');
- }
- address = this.tronWeb.address.toHex(address);
- return this.tronWeb.solidityNode
- .request(`walletextension/gettransactions${direction}this`, {
- account: {
- address,
- },
- offset,
- limit,
- }, 'post')
- .then(({ transaction }) => {
- return transaction;
- });
- }
- async getAccount(address = this.tronWeb.defaultAddress.hex) {
- if (!this.tronWeb.isAddress(address)) {
- throw new Error('Invalid address provided');
- }
- address = this.tronWeb.address.toHex(address);
- return this.tronWeb.solidityNode.request('walletsolidity/getaccount', {
- address,
- }, 'post');
- }
- getAccountById(id) {
- return this.getAccountInfoById(id, { confirmed: true });
- }
- async getAccountInfoById(id, options) {
- this.validator.notValid([
- {
- name: 'accountId',
- type: 'hex',
- value: id,
- },
- {
- name: 'accountId',
- type: 'string',
- lte: 32,
- gte: 8,
- value: id,
- },
- ]);
- if (id.startsWith('0x')) {
- id = id.slice(2);
- }
- return this.tronWeb[options.confirmed ? 'solidityNode' : 'fullNode'].request(`wallet${options.confirmed ? 'solidity' : ''}/getaccountbyid`, {
- account_id: id,
- }, 'post');
- }
- async getBalance(address = this.tronWeb.defaultAddress.hex) {
- const { balance = 0 } = await this.getAccount(address);
- return balance;
- }
- async getUnconfirmedAccount(address = this.tronWeb.defaultAddress.hex) {
- if (!this.tronWeb.isAddress(address)) {
- throw new Error('Invalid address provided');
- }
- address = this.tronWeb.address.toHex(address);
- return this.tronWeb.fullNode.request('wallet/getaccount', {
- address,
- }, 'post');
- }
- getUnconfirmedAccountById(id) {
- return this.getAccountInfoById(id, { confirmed: false });
- }
- async getUnconfirmedBalance(address = this.tronWeb.defaultAddress.hex) {
- const { balance = 0 } = await this.getUnconfirmedAccount(address);
- return balance;
- }
- async getBandwidth(address = this.tronWeb.defaultAddress.hex) {
- if (!this.tronWeb.isAddress(address)) {
- throw new Error('Invalid address provided');
- }
- address = this.tronWeb.address.toHex(address);
- return this.tronWeb.fullNode
- .request('wallet/getaccountnet', {
- address,
- }, 'post')
- .then(({ freeNetUsed = 0, freeNetLimit = 0, NetUsed = 0, NetLimit = 0 }) => {
- return freeNetLimit - freeNetUsed + (NetLimit - NetUsed);
- });
- }
- async getTokensIssuedByAddress(address = this.tronWeb.defaultAddress.hex) {
- if (!this.tronWeb.isAddress(address)) {
- throw new Error('Invalid address provided');
- }
- address = this.tronWeb.address.toHex(address);
- return this.tronWeb.fullNode
- .request('wallet/getassetissuebyaccount', {
- address,
- }, 'post')
- .then(({ assetIssue }) => {
- if (!assetIssue)
- return {};
- const tokens = assetIssue
- .map((token) => {
- return this._parseToken(token);
- })
- .reduce((tokens, token) => {
- return (tokens[token.name] = token), tokens;
- }, {});
- return tokens;
- });
- }
- async getTokenFromID(tokenID) {
- if (utils.isInteger(tokenID))
- tokenID = tokenID.toString();
- if (!utils.isString(tokenID) || !tokenID.length) {
- throw new Error('Invalid token ID provided');
- }
- return this.tronWeb.fullNode
- .request('wallet/getassetissuebyname', {
- value: this.tronWeb.fromUtf8(tokenID),
- }, 'post')
- .then((token) => {
- if (!token.name) {
- throw new Error('Token does not exist');
- }
- return this._parseToken(token);
- });
- }
- async listNodes() {
- const { nodes = [] } = await this.tronWeb.fullNode.request('wallet/listnodes');
- return nodes.map(({ address: { host, port } }) => `${this.tronWeb.toUtf8(host)}:${port}`);
- }
- async getBlockRange(start = 0, end = 30) {
- if (!utils.isInteger(start) || start < 0) {
- throw new Error('Invalid start of range provided');
- }
- if (!utils.isInteger(end) || end < start) {
- throw new Error('Invalid end of range provided');
- }
- if (end + 1 - start > 100) {
- throw new Error('Invalid range size, which should be no more than 100.');
- }
- return this.tronWeb.fullNode
- .request('wallet/getblockbylimitnext', {
- startNum: parseInt(start),
- endNum: parseInt(end) + 1,
- }, 'post')
- .then(({ block = [] }) => block);
- }
- async listSuperRepresentatives() {
- const { witnesses = [] } = await this.tronWeb.fullNode.request('wallet/listwitnesses');
- return witnesses;
- }
- async listTokens(limit = 0, offset = 0) {
- if (!utils.isInteger(limit) || limit < 0 || (offset && limit < 1)) {
- throw new Error('Invalid limit provided');
- }
- if (!utils.isInteger(offset) || offset < 0) {
- throw new Error('Invalid offset provided');
- }
- if (!limit) {
- return this.tronWeb.fullNode
- .request('wallet/getassetissuelist')
- .then(({ assetIssue = [] }) => assetIssue.map((token) => this._parseToken(token)));
- }
- return this.tronWeb.fullNode
- .request('wallet/getpaginatedassetissuelist', {
- offset: parseInt(offset),
- limit: parseInt(limit),
- }, 'post')
- .then(({ assetIssue = [] }) => assetIssue.map((token) => this._parseToken(token)));
- }
- async timeUntilNextVoteCycle() {
- const { num = -1 } = await this.tronWeb.fullNode.request('wallet/getnextmaintenancetime');
- if (num == -1) {
- throw new Error('Failed to get time until next vote cycle');
- }
- return Math.floor(num / 1000);
- }
- async getContract(contractAddress) {
- if (!this.tronWeb.isAddress(contractAddress)) {
- throw new Error('Invalid contract address provided');
- }
- if (this.cache.contracts[contractAddress]) {
- return this.cache.contracts[contractAddress];
- }
- contractAddress = this.tronWeb.address.toHex(contractAddress);
- const contract = await this.tronWeb.fullNode.request('wallet/getcontract', {
- value: contractAddress,
- });
- if (contract.Error) {
- throw new Error('Contract does not exist');
- }
- this.cache.contracts[contractAddress] = contract;
- return contract;
- }
- ecRecover(transaction) {
- return Trx.ecRecover(transaction);
- }
- static ecRecover(transaction) {
- if (!txCheck(transaction)) {
- throw new Error('Invalid transaction');
- }
- if (!transaction.signature?.length) {
- throw new Error('Transaction is not signed');
- }
- if (transaction.signature.length === 1) {
- const tronAddress = ecRecover(transaction.txID, transaction.signature[0]);
- return TronWeb.address.fromHex(tronAddress);
- }
- return transaction.signature.map((sig) => {
- const tronAddress = ecRecover(transaction.txID, sig);
- return TronWeb.address.fromHex(tronAddress);
- });
- }
- async verifyMessage(message, signature, address = this.tronWeb.defaultAddress.base58, useTronHeader = true) {
- if (!utils.isHex(message)) {
- throw new Error('Expected hex message input');
- }
- if (Trx.verifySignature(message, address, signature, useTronHeader)) {
- return true;
- }
- throw new Error('Signature does not match');
- }
- static verifySignature(message, address, signature, useTronHeader = true) {
- message = message.replace(/^0x/, '');
- const messageBytes = [
- ...toUtf8Bytes(useTronHeader ? TRX_MESSAGE_HEADER : ETH_MESSAGE_HEADER),
- ...utils.code.hexStr2byteArray(message),
- ];
- const messageDigest = keccak256(new Uint8Array(messageBytes));
- const recovered = recoverAddress(messageDigest, Signature.from(`0x${signature.replace(/^0x/, '')}`));
- const tronAddress = ADDRESS_PREFIX + recovered.substr(2);
- const base58Address = TronWeb.address.fromHex(tronAddress);
- return base58Address == TronWeb.address.fromHex(address);
- }
- async verifyMessageV2(message, signature) {
- return Trx.verifyMessageV2(message, signature);
- }
- static verifyMessageV2(message, signature) {
- return utils.message.verifyMessage(message, signature);
- }
- verifyTypedData(domain, types, value, signature, address = this.tronWeb.defaultAddress.base58) {
- if (Trx.verifyTypedData(domain, types, value, signature, address))
- return true;
- throw new Error('Signature does not match');
- }
- static verifyTypedData(domain, types, value, signature, address) {
- const messageDigest = utils._TypedDataEncoder.hash(domain, types, value);
- const recovered = recoverAddress(messageDigest, Signature.from(`0x${signature.replace(/^0x/, '')}`));
- const tronAddress = ADDRESS_PREFIX + recovered.substr(2);
- const base58Address = TronWeb.address.fromHex(tronAddress);
- return base58Address == TronWeb.address.fromHex(address);
- }
- async sign(transaction, privateKey = this.tronWeb.defaultPrivateKey, useTronHeader = true, multisig = false) {
- // Message signing
- if (utils.isString(transaction)) {
- if (!utils.isHex(transaction)) {
- throw new Error('Expected hex message input');
- }
- return Trx.signString(transaction, privateKey, useTronHeader);
- }
- if (!utils.isObject(transaction)) {
- throw new Error('Invalid transaction provided');
- }
- if (!multisig && transaction.signature) {
- throw new Error('Transaction is already signed');
- }
- if (!multisig) {
- const address = this.tronWeb.address
- .toHex(this.tronWeb.address.fromPrivateKey(privateKey))
- .toLowerCase();
- if (address !== this.tronWeb.address.toHex(transaction.raw_data.contract[0].parameter.value.owner_address)) {
- throw new Error('Private key does not match address in transaction');
- }
- if (!txCheck(transaction)) {
- throw new Error('Invalid transaction');
- }
- }
- return utils.crypto.signTransaction(privateKey, transaction);
- }
- static signString(message, privateKey, useTronHeader = true) {
- message = message.replace(/^0x/, '');
- const value = `0x${privateKey.replace(/^0x/, '')}`;
- const signingKey = new SigningKey(value);
- const messageBytes = [
- ...toUtf8Bytes(useTronHeader ? TRX_MESSAGE_HEADER : ETH_MESSAGE_HEADER),
- ...utils.code.hexStr2byteArray(message),
- ];
- const messageDigest = keccak256(new Uint8Array(messageBytes));
- const signature = signingKey.sign(messageDigest);
- const signatureHex = ['0x', signature.r.substring(2), signature.s.substring(2), Number(signature.v).toString(16)].join('');
- return signatureHex;
- }
- /**
- * sign message v2 for verified header length
- *
- * @param {message to be signed, should be Bytes or string} message
- * @param {privateKey for signature} privateKey
- * @param {reserved} options
- */
- signMessageV2(message, privateKey = this.tronWeb.defaultPrivateKey) {
- return Trx.signMessageV2(message, privateKey);
- }
- static signMessageV2(message, privateKey) {
- return utils.message.signMessage(message, privateKey);
- }
- _signTypedData(domain, types, value, privateKey = this.tronWeb.defaultPrivateKey) {
- return Trx._signTypedData(domain, types, value, privateKey);
- }
- static _signTypedData(domain, types, value, privateKey) {
- return utils.crypto._signTypedData(domain, types, value, privateKey);
- }
- async multiSign(transaction, privateKey = this.tronWeb.defaultPrivateKey, permissionId = 0) {
- if (!utils.isObject(transaction) || !transaction.raw_data || !transaction.raw_data.contract) {
- throw new Error('Invalid transaction provided');
- }
- // If owner permission or permission id exists in transaction, do sign directly
- // If no permission id inside transaction or user passes permission id, use old way to reset permission id
- if (!transaction.raw_data.contract[0].Permission_id && permissionId > 0) {
- // set permission id
- transaction.raw_data.contract[0].Permission_id = permissionId;
- // check if private key insides permission list
- const address = this.tronWeb.address
- .toHex(this.tronWeb.address.fromPrivateKey(privateKey))
- .toLowerCase();
- const signWeight = await this.getSignWeight(transaction, permissionId);
- if (signWeight.result.code === 'PERMISSION_ERROR') {
- throw new Error(signWeight.result.message);
- }
- let foundKey = false;
- signWeight.permission.keys.map((key) => {
- if (key.address === address)
- foundKey = true;
- });
- if (!foundKey) {
- throw new Error(privateKey + ' has no permission to sign');
- }
- if (signWeight.approved_list && signWeight.approved_list.indexOf(address) != -1) {
- throw new Error(privateKey + ' already sign transaction');
- }
- // reset transaction
- if (signWeight.transaction && signWeight.transaction.transaction) {
- transaction = signWeight.transaction.transaction;
- if (permissionId > 0) {
- transaction.raw_data.contract[0].Permission_id = permissionId;
- }
- }
- else {
- throw new Error('Invalid transaction provided');
- }
- }
- // sign
- if (!txCheck(transaction)) {
- throw new Error('Invalid transaction');
- }
- return utils.crypto.signTransaction(privateKey, transaction);
- }
- async getApprovedList(transaction) {
- if (!utils.isObject(transaction)) {
- throw new Error('Invalid transaction provided');
- }
- return this.tronWeb.fullNode.request('wallet/getapprovedlist', transaction, 'post');
- }
- async getSignWeight(transaction, permissionId) {
- if (!utils.isObject(transaction) || !transaction.raw_data || !transaction.raw_data.contract)
- throw new Error('Invalid transaction provided');
- if (utils.isInteger(permissionId)) {
- transaction.raw_data.contract[0].Permission_id = parseInt(permissionId);
- }
- else if (typeof transaction.raw_data.contract[0].Permission_id !== 'number') {
- transaction.raw_data.contract[0].Permission_id = 0;
- }
- return this.tronWeb.fullNode.request('wallet/getsignweight', transaction, 'post');
- }
- async sendRawTransaction(signedTransaction) {
- if (!utils.isObject(signedTransaction)) {
- throw new Error('Invalid transaction provided');
- }
- if (!signedTransaction.signature || !utils.isArray(signedTransaction.signature)) {
- throw new Error('Transaction is not signed');
- }
- const result = await this.tronWeb.fullNode.request('wallet/broadcasttransaction', signedTransaction, 'post');
- return {
- ...result,
- transaction: signedTransaction,
- };
- }
- async sendHexTransaction(signedHexTransaction) {
- if (!utils.isHex(signedHexTransaction)) {
- throw new Error('Invalid hex transaction provided');
- }
- const params = {
- transaction: signedHexTransaction,
- };
- const result = await this.tronWeb.fullNode.request('wallet/broadcasthex', params, 'post');
- if (result.result) {
- return {
- ...result,
- transaction: JSON.parse(result.transaction),
- hexTransaction: signedHexTransaction,
- };
- }
- return result;
- }
- async sendTransaction(to, amount, options = {}) {
- if (typeof options === 'string')
- options = { privateKey: options };
- if (!this.tronWeb.isAddress(to)) {
- throw new Error('Invalid recipient provided');
- }
- if (!utils.isInteger(amount) || amount <= 0) {
- throw new Error('Invalid amount provided');
- }
- options = {
- privateKey: this.tronWeb.defaultPrivateKey,
- address: this.tronWeb.defaultAddress.hex,
- ...options,
- };
- if (!options.privateKey && !options.address) {
- throw new Error('Function requires either a private key or address to be set');
- }
- const address = options.privateKey ? this.tronWeb.address.fromPrivateKey(options.privateKey) : options.address;
- const transaction = await this.tronWeb.transactionBuilder.sendTrx(to, amount, address);
- const signedTransaction = await this.sign(transaction, options.privateKey);
- const result = await this.sendRawTransaction(signedTransaction);
- return result;
- }
- async sendToken(to, amount, tokenID, options = {}) {
- if (typeof options === 'string')
- options = { privateKey: options };
- if (!this.tronWeb.isAddress(to)) {
- throw new Error('Invalid recipient provided');
- }
- if (!utils.isInteger(amount) || amount <= 0) {
- throw new Error('Invalid amount provided');
- }
- if (utils.isInteger(tokenID))
- tokenID = tokenID.toString();
- if (!utils.isString(tokenID)) {
- throw new Error('Invalid token ID provided');
- }
- options = {
- privateKey: this.tronWeb.defaultPrivateKey,
- address: this.tronWeb.defaultAddress.hex,
- ...options,
- };
- if (!options.privateKey && !options.address) {
- throw new Error('Function requires either a private key or address to be set');
- }
- const address = options.privateKey ? this.tronWeb.address.fromPrivateKey(options.privateKey) : options.address;
- const transaction = await this.tronWeb.transactionBuilder.sendToken(to, amount, tokenID, address);
- const signedTransaction = await this.sign(transaction, options.privateKey);
- const result = await this.sendRawTransaction(signedTransaction);
- return result;
- }
- /**
- * Freezes an amount of TRX.
- * Will give bandwidth OR Energy and TRON Power(voting rights)
- * to the owner of the frozen tokens.
- *
- * @param amount - is the number of frozen trx
- * @param duration - is the duration in days to be frozen
- * @param resource - is the type, must be either "ENERGY" or "BANDWIDTH"
- * @param options
- */
- async freezeBalance(amount = 0, duration = 3, resource = 'BANDWIDTH', options = {}, receiverAddress) {
- if (typeof options === 'string')
- options = { privateKey: options };
- if (!['BANDWIDTH', 'ENERGY'].includes(resource)) {
- throw new Error('Invalid resource provided: Expected "BANDWIDTH" or "ENERGY"');
- }
- if (!utils.isInteger(amount) || amount <= 0) {
- throw new Error('Invalid amount provided');
- }
- if (!utils.isInteger(duration) || duration < 3) {
- throw new Error('Invalid duration provided, minimum of 3 days');
- }
- options = {
- privateKey: this.tronWeb.defaultPrivateKey,
- address: this.tronWeb.defaultAddress.hex,
- ...options,
- };
- if (!options.privateKey && !options.address) {
- throw new Error('Function requires either a private key or address to be set');
- }
- const address = options.privateKey ? this.tronWeb.address.fromPrivateKey(options.privateKey) : options.address;
- const freezeBalance = await this.tronWeb.transactionBuilder.freezeBalance(amount, duration, resource, address, receiverAddress);
- const signedTransaction = await this.sign(freezeBalance, options.privateKey);
- const result = await this.sendRawTransaction(signedTransaction);
- return result;
- }
- /**
- * Unfreeze TRX that has passed the minimum freeze duration.
- * Unfreezing will remove bandwidth and TRON Power.
- *
- * @param resource - is the type, must be either "ENERGY" or "BANDWIDTH"
- * @param options
- */
- async unfreezeBalance(resource = 'BANDWIDTH', options = {}, receiverAddress) {
- if (typeof options === 'string')
- options = { privateKey: options };
- if (!['BANDWIDTH', 'ENERGY'].includes(resource)) {
- throw new Error('Invalid resource provided: Expected "BANDWIDTH" or "ENERGY"');
- }
- options = {
- privateKey: this.tronWeb.defaultPrivateKey,
- address: this.tronWeb.defaultAddress.hex,
- ...options,
- };
- if (!options.privateKey && !options.address) {
- throw new Error('Function requires either a private key or address to be set');
- }
- const address = options.privateKey ? this.tronWeb.address.fromPrivateKey(options.privateKey) : options.address;
- const unfreezeBalance = await this.tronWeb.transactionBuilder.unfreezeBalance(resource, address, receiverAddress);
- const signedTransaction = await this.sign(unfreezeBalance, options.privateKey);
- const result = await this.sendRawTransaction(signedTransaction);
- return result;
- }
- /**
- * Modify account name
- * Note: Username is allowed to edit only once.
- *
- * @param privateKey - Account private Key
- * @param accountName - name of the account
- *
- * @return modified Transaction Object
- */
- async updateAccount(accountName, options = {}) {
- if (typeof options === 'string')
- options = { privateKey: options };
- if (!utils.isString(accountName) || !accountName.length) {
- throw new Error('Name must be a string');
- }
- options = {
- privateKey: this.tronWeb.defaultPrivateKey,
- address: this.tronWeb.defaultAddress.hex,
- ...options,
- };
- if (!options.privateKey && !options.address)
- throw Error('Function requires either a private key or address to be set');
- const address = options.privateKey ? this.tronWeb.address.fromPrivateKey(options.privateKey) : options.address;
- const updateAccount = await this.tronWeb.transactionBuilder.updateAccount(accountName, address);
- const signedTransaction = await this.sign(updateAccount, options.privateKey);
- const result = await this.sendRawTransaction(signedTransaction);
- return result;
- }
- /**
- * Gets a network modification proposal by ID.
- */
- async getProposal(proposalID) {
- if (!utils.isInteger(proposalID) || proposalID < 0) {
- throw new Error('Invalid proposalID provided');
- }
- return this.tronWeb.fullNode.request('wallet/getproposalbyid', {
- id: parseInt(proposalID),
- }, 'post');
- }
- /**
- * Lists all network modification proposals.
- */
- async listProposals() {
- const { proposals = [] } = await this.tronWeb.fullNode.request('wallet/listproposals', {}, 'post');
- return proposals;
- }
- /**
- * Lists all parameters available for network modification proposals.
- */
- async getChainParameters() {
- const { chainParameter = [] } = await this.tronWeb.fullNode.request('wallet/getchainparameters', {}, 'post');
- return chainParameter;
- }
- /**
- * Get the account resources
- */
- async getAccountResources(address = this.tronWeb.defaultAddress.hex) {
- if (!this.tronWeb.isAddress(address)) {
- throw new Error('Invalid address provided');
- }
- return this.tronWeb.fullNode.request('wallet/getaccountresource', {
- address: this.tronWeb.address.toHex(address),
- }, 'post');
- }
- /**
- * Query the amount of resources of a specific resourceType delegated by fromAddress to toAddress
- */
- async getDelegatedResourceV2(fromAddress = this.tronWeb.defaultAddress.hex, toAddress = this.tronWeb.defaultAddress.hex, options = { confirmed: true }) {
- if (!this.tronWeb.isAddress(fromAddress)) {
- throw new Error('Invalid address provided');
- }
- if (!this.tronWeb.isAddress(toAddress)) {
- throw new Error('Invalid address provided');
- }
- return this.tronWeb[options.confirmed ? 'solidityNode' : 'fullNode'].request(`wallet${options.confirmed ? 'solidity' : ''}/getdelegatedresourcev2`, {
- fromAddress: toHex(fromAddress),
- toAddress: toHex(toAddress),
- }, 'post');
- }
- /**
- * Query the resource delegation index by an account
- */
- async getDelegatedResourceAccountIndexV2(address = this.tronWeb.defaultAddress.hex, options = { confirmed: true }) {
- if (!this.tronWeb.isAddress(address)) {
- throw new Error('Invalid address provided');
- }
- return this.tronWeb[options.confirmed ? 'solidityNode' : 'fullNode'].request(`wallet${options.confirmed ? 'solidity' : ''}/getdelegatedresourceaccountindexv2`, {
- value: toHex(address),
- }, 'post');
- }
- /**
- * Query the amount of delegatable resources of the specified resource Type for target address, unit is sun.
- */
- async getCanDelegatedMaxSize(address = this.tronWeb.defaultAddress.hex, resource = 'BANDWIDTH', options = { confirmed: true }) {
- if (!this.tronWeb.isAddress(address)) {
- throw new Error('Invalid address provided');
- }
- this.validator.notValid([
- {
- name: 'resource',
- type: 'resource',
- value: resource,
- msg: 'Invalid resource provided: Expected "BANDWIDTH" or "ENERGY"',
- },
- ]);
- return this.tronWeb[options.confirmed ? 'solidityNode' : 'fullNode'].request(`wallet${options.confirmed ? 'solidity' : ''}/getcandelegatedmaxsize`, {
- owner_address: toHex(address),
- type: resource === 'ENERGY' ? 1 : 0,
- }, 'post');
- }
- /**
- * Remaining times of available unstaking API
- */
- async getAvailableUnfreezeCount(address = this.tronWeb.defaultAddress.hex, options = { confirmed: true }) {
- if (!this.tronWeb.isAddress(address)) {
- throw new Error('Invalid address provided');
- }
- return this.tronWeb[options.confirmed ? 'solidityNode' : 'fullNode'].request(`wallet${options.confirmed ? 'solidity' : ''}/getavailableunfreezecount`, {
- owner_address: toHex(address),
- }, 'post');
- }
- /**
- * Query the withdrawable balance at the specified timestamp
- */
- async getCanWithdrawUnfreezeAmount(address = this.tronWeb.defaultAddress.hex, timestamp = Date.now(), options = { confirmed: true }) {
- if (!this.tronWeb.isAddress(address)) {
- throw new Error('Invalid address provided');
- }
- if (!utils.isInteger(timestamp) || timestamp < 0) {
- throw new Error('Invalid timestamp provided');
- }
- return this.tronWeb[options.confirmed ? 'solidityNode' : 'fullNode'].request(`wallet${options.confirmed ? 'solidity' : ''}/getcanwithdrawunfreezeamount`, {
- owner_address: toHex(address),
- timestamp: timestamp,
- }, 'post');
- }
- /**
- * Get the exchange ID.
- */
- async getExchangeByID(exchangeID) {
- if (!utils.isInteger(exchangeID) || exchangeID < 0) {
- throw new Error('Invalid exchangeID provided');
- }
- return this.tronWeb.fullNode.request('wallet/getexchangebyid', {
- id: exchangeID,
- }, 'post');
- }
- /**
- * Lists the exchanges
- */
- async listExchanges() {
- return this.tronWeb.fullNode
- .request('wallet/listexchanges', {}, 'post')
- .then(({ exchanges = [] }) => exchanges);
- }
- /**
- * Lists all network modification proposals.
- */
- async listExchangesPaginated(limit = 10, offset = 0) {
- return this.tronWeb.fullNode
- .request('wallet/getpaginatedexchangelist', {
- limit,
- offset,
- }, 'post')
- .then(({ exchanges = [] }) => exchanges);
- }
- /**
- * Get info about thre node
- */
- async getNodeInfo() {
- return this.tronWeb.fullNode.request('wallet/getnodeinfo', {}, 'post');
- }
- async getTokenListByName(tokenID) {
- if (utils.isInteger(tokenID))
- tokenID = tokenID.toString();
- if (!utils.isString(tokenID) || !tokenID.length) {
- throw new Error('Invalid token ID provided');
- }
- return this.tronWeb.fullNode
- .request('wallet/getassetissuelistbyname', {
- value: this.tronWeb.fromUtf8(tokenID),
- }, 'post')
- .then((token) => {
- if (Array.isArray(token.assetIssue)) {
- return token.assetIssue.map((t) => this._parseToken(t));
- }
- else if (!token.name) {
- throw new Error('Token does not exist');
- }
- return this._parseToken(token);
- });
- }
- getTokenByID(tokenID) {
- if (utils.isInteger(tokenID))
- tokenID = tokenID.toString();
- if (!utils.isString(tokenID) || !tokenID.length) {
- throw new Error('Invalid token ID provided');
- }
- return this.tronWeb.fullNode
- .request('wallet/getassetissuebyid', {
- value: tokenID,
- }, 'post')
- .then((token) => {
- if (!token.name) {
- throw new Error('Token does not exist');
- }
- return this._parseToken(token);
- });
- }
- async getReward(address, options = {}) {
- options.confirmed = true;
- return this._getReward(address, options);
- }
- async getUnconfirmedReward(address, options = {}) {
- options.confirmed = false;
- return this._getReward(address, options);
- }
- async getBrokerage(address, options = {}) {
- options.confirmed = true;
- return this._getBrokerage(address, options);
- }
- async getUnconfirmedBrokerage(address, options = {}) {
- options.confirmed = false;
- return this._getBrokerage(address, options);
- }
- async _getReward(address = this.tronWeb.defaultAddress.hex, options) {
- this.validator.notValid([
- {
- name: 'origin',
- type: 'address',
- value: address,
- },
- ]);
- const data = {
- address: toHex(address),
- };
- return this.tronWeb[options.confirmed ? 'solidityNode' : 'fullNode']
- .request(`wallet${options.confirmed ? 'solidity' : ''}/getReward`, data, 'post')
- .then((result = { reward: undefined }) => {
- if (typeof result.reward === 'undefined') {
- throw new Error('Not found.');
- }
- return result.reward;
- });
- }
- async _getBrokerage(address = this.tronWeb.defaultAddress.hex, options) {
- this.validator.notValid([
- {
- name: 'origin',
- type: 'address',
- value: address,
- },
- ]);
- const data = {
- address: toHex(address),
- };
- return this.tronWeb[options.confirmed ? 'solidityNode' : 'fullNode']
- .request(`wallet${options.confirmed ? 'solidity' : ''}/getBrokerage`, data, 'post')
- .then((result = {}) => {
- if (typeof result.brokerage === 'undefined') {
- throw new Error('Not found.');
- }
- return result.brokerage;
- });
- }
- async getBandwidthPrices() {
- return this.tronWeb.fullNode.request('wallet/getbandwidthprices', {}, 'post')
- .then((result = {}) => {
- if (typeof result.prices === 'undefined') {
- throw new Error('Not found.');
- }
- return result.prices;
- });
- }
- async getEnergyPrices() {
- return this.tronWeb.fullNode.request('wallet/getenergyprices', {}, 'post')
- .then((result = {}) => {
- if (typeof result.prices === 'undefined') {
- throw new Error('Not found.');
- }
- return result.prices;
- });
- }
- }
- //# sourceMappingURL=trx.js.map
|