| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767 |
- import { TronWeb } from '../../tronweb.js';
- import { AbiCoder, keccak256 } from '../../utils/ethersUtils.js';
- import { ADDRESS_PREFIX_REGEX, toHex } from '../../utils/address.js';
- import { encodeParamsV2ByABI } from '../../utils/abi.js';
- import { Validator } from '../../paramValidator/index.js';
- import { isArray, isInteger, isNotNullOrUndefined, isObject, isString } from '../../utils/validations.js';
- import { ContractType, } from '../../types/Contract.js';
- import { createTransaction, deepCopyJson, fromUtf8, genContractAddress, resultManager, resultManagerTriggerSmartContract, getTransactionOptions, } from './helper.js';
- export class TransactionBuilder {
- tronWeb;
- validator;
- constructor(tronWeb) {
- if (!tronWeb || !(tronWeb instanceof TronWeb)) {
- throw new Error('Expected instance of TronWeb');
- }
- this.tronWeb = tronWeb;
- this.validator = new Validator();
- }
- async sendTrx(to, amount = 0, from = this.tronWeb.defaultAddress.hex, options = {}) {
- // accept amounts passed as strings
- amount = parseInt(amount);
- this.validator.notValid([
- {
- name: 'recipient',
- type: 'address',
- value: to,
- },
- {
- name: 'origin',
- type: 'address',
- value: from,
- },
- {
- names: ['recipient', 'origin'],
- type: 'notEqual',
- msg: 'Cannot transfer TRX to the same account',
- },
- {
- name: 'amount',
- type: 'integer',
- gt: 0,
- value: amount,
- },
- ]);
- const data = {
- to_address: toHex(to),
- owner_address: toHex(from),
- amount: amount,
- };
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.TransferContract, data, options?.permissionId, transactionOptions);
- }
- async sendToken(to, amount = 0, tokenId, from = this.tronWeb.defaultAddress.hex, options = {}) {
- amount = parseInt(amount);
- this.validator.notValid([
- {
- name: 'recipient',
- type: 'address',
- value: to,
- },
- {
- name: 'origin',
- type: 'address',
- value: from,
- },
- {
- names: ['recipient', 'origin'],
- type: 'notEqual',
- msg: 'Cannot transfer tokens to the same account',
- },
- {
- name: 'amount',
- type: 'integer',
- gt: 0,
- value: amount,
- },
- {
- name: 'token ID',
- type: 'tokenId',
- value: tokenId,
- },
- ]);
- const data = {
- to_address: toHex(to),
- owner_address: toHex(from),
- asset_name: fromUtf8(tokenId),
- amount,
- };
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.TransferAssetContract, data, options?.permissionId, transactionOptions);
- }
- async purchaseToken(issuerAddress, tokenId, amount = 0, buyer = this.tronWeb.defaultAddress.hex, options = {}) {
- this.validator.notValid([
- {
- name: 'buyer',
- type: 'address',
- value: buyer,
- },
- {
- name: 'issuer',
- type: 'address',
- value: issuerAddress,
- },
- {
- names: ['buyer', 'issuer'],
- type: 'notEqual',
- msg: 'Cannot purchase tokens from same account',
- },
- {
- name: 'amount',
- type: 'integer',
- gt: 0,
- value: amount,
- },
- {
- name: 'token ID',
- type: 'tokenId',
- value: tokenId,
- },
- ]);
- const data = {
- to_address: toHex(issuerAddress),
- owner_address: toHex(buyer),
- asset_name: fromUtf8(tokenId),
- amount: parseInt(amount),
- };
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.ParticipateAssetIssueContract, data, options?.permissionId, transactionOptions);
- }
- async freezeBalance(amount = 0, duration = 3, resource = 'BANDWIDTH', ownerAddress = this.tronWeb.defaultAddress.hex, receiverAddress, options = {}) {
- this.validator.notValid([
- {
- name: 'origin',
- type: 'address',
- value: ownerAddress,
- },
- {
- name: 'receiver',
- type: 'address',
- value: receiverAddress,
- optional: true,
- },
- {
- name: 'amount',
- type: 'integer',
- gt: 0,
- value: amount,
- },
- {
- name: 'duration',
- type: 'integer',
- gte: 3,
- value: duration,
- },
- {
- name: 'resource',
- type: 'resource',
- value: resource,
- msg: 'Invalid resource provided: Expected "BANDWIDTH" or "ENERGY"',
- },
- ]);
- const data = {
- owner_address: toHex(ownerAddress),
- frozen_balance: parseInt(amount),
- frozen_duration: parseInt(String(duration)),
- };
- if (resource !== 'BANDWIDTH') {
- data.resource = resource;
- }
- if (isNotNullOrUndefined(receiverAddress) && toHex(receiverAddress) !== toHex(ownerAddress)) {
- data.receiver_address = toHex(receiverAddress);
- }
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.FreezeBalanceContract, data, options?.permissionId, transactionOptions);
- }
- async unfreezeBalance(resource = 'BANDWIDTH', address = this.tronWeb.defaultAddress.hex, receiverAddress, options = {}) {
- this.validator.notValid([
- {
- name: 'origin',
- type: 'address',
- value: address,
- },
- {
- name: 'receiver',
- type: 'address',
- value: receiverAddress,
- optional: true,
- },
- {
- name: 'resource',
- type: 'resource',
- value: resource,
- msg: 'Invalid resource provided: Expected "BANDWIDTH" or "ENERGY"',
- },
- ]);
- const data = {
- owner_address: toHex(address),
- };
- if (resource !== 'BANDWIDTH') {
- data.resource = resource;
- }
- if (isNotNullOrUndefined(receiverAddress) && toHex(receiverAddress) !== toHex(address)) {
- data.receiver_address = toHex(receiverAddress);
- }
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.UnfreezeBalanceContract, data, options?.permissionId, transactionOptions);
- }
- async freezeBalanceV2(amount = 0, resource = 'BANDWIDTH', address = this.tronWeb.defaultAddress.hex, options = {}) {
- this.validator.notValid([
- {
- name: 'origin',
- type: 'address',
- value: address,
- },
- {
- name: 'amount',
- type: 'integer',
- gt: 0,
- value: amount,
- },
- {
- name: 'resource',
- type: 'resource',
- value: resource,
- msg: 'Invalid resource provided: Expected "BANDWIDTH" or "ENERGY"',
- },
- ]);
- const data = {
- owner_address: toHex(address),
- frozen_balance: parseInt(amount),
- };
- if (resource !== 'BANDWIDTH') {
- data.resource = resource;
- }
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.FreezeBalanceV2Contract, data, options?.permissionId, transactionOptions);
- }
- async unfreezeBalanceV2(amount = 0, resource = 'BANDWIDTH', address = this.tronWeb.defaultAddress.hex, options = {}) {
- this.validator.notValid([
- {
- name: 'origin',
- type: 'address',
- value: address,
- },
- {
- name: 'amount',
- type: 'integer',
- gt: 0,
- value: amount,
- },
- {
- name: 'resource',
- type: 'resource',
- value: resource,
- msg: 'Invalid resource provided: Expected "BANDWIDTH" or "ENERGY"',
- },
- ]);
- const data = {
- owner_address: toHex(address),
- unfreeze_balance: parseInt(amount),
- };
- if (resource !== 'BANDWIDTH') {
- data.resource = resource;
- }
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.UnfreezeBalanceV2Contract, data, options?.permissionId, transactionOptions);
- }
- async cancelUnfreezeBalanceV2(address = this.tronWeb.defaultAddress.hex, options = {}) {
- this.validator.notValid([
- {
- name: 'origin',
- type: 'address',
- value: address,
- },
- ]);
- const data = {
- owner_address: toHex(address),
- };
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.CancelAllUnfreezeV2Contract, data, options?.permissionId, transactionOptions);
- }
- async delegateResource(amount = 0, receiverAddress, resource = 'BANDWIDTH', address = this.tronWeb.defaultAddress.hex, lock = false, lockPeriod, options = {}) {
- this.validator.notValid([
- {
- name: 'amount',
- type: 'integer',
- gt: 0,
- value: amount,
- },
- {
- name: 'resource',
- type: 'resource',
- value: resource,
- msg: 'Invalid resource provided: Expected "BANDWIDTH" or "ENERGY"',
- },
- {
- name: 'receiver',
- type: 'address',
- value: receiverAddress,
- },
- {
- name: 'origin',
- type: 'address',
- value: address,
- },
- {
- name: 'lock',
- type: 'boolean',
- value: lock,
- },
- {
- name: 'lock period',
- type: 'integer',
- gte: 0,
- value: lockPeriod,
- optional: true,
- },
- ]);
- if (toHex(receiverAddress) === toHex(address)) {
- throw new Error('Receiver address must not be the same as owner address');
- }
- const data = {
- owner_address: toHex(address),
- receiver_address: toHex(receiverAddress),
- balance: parseInt(amount),
- };
- if (resource !== 'BANDWIDTH') {
- data.resource = resource;
- }
- if (lock) {
- data.lock = lock;
- if (isNotNullOrUndefined(lockPeriod)) {
- data.lock_period = lockPeriod;
- }
- }
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.DelegateResourceContract, data, options?.permissionId, transactionOptions);
- }
- async undelegateResource(amount = 0, receiverAddress, resource = 'BANDWIDTH', address = this.tronWeb.defaultAddress.hex, options = {}) {
- this.validator.notValid([
- {
- name: 'origin',
- type: 'address',
- value: address,
- },
- {
- name: 'receiver',
- type: 'address',
- value: receiverAddress,
- },
- {
- name: 'amount',
- type: 'integer',
- gt: 0,
- value: amount,
- },
- {
- name: 'resource',
- type: 'resource',
- value: resource,
- msg: 'Invalid resource provided: Expected "BANDWIDTH" or "ENERGY"',
- },
- ]);
- if (toHex(receiverAddress) === toHex(address)) {
- throw new Error('Receiver address must not be the same as owner address');
- }
- const data = {
- owner_address: toHex(address),
- receiver_address: toHex(receiverAddress),
- balance: parseInt(amount),
- };
- if (resource !== 'BANDWIDTH') {
- data.resource = resource;
- }
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.UnDelegateResourceContract, data, options?.permissionId, transactionOptions);
- }
- async withdrawExpireUnfreeze(address = this.tronWeb.defaultAddress.hex, options = {}) {
- this.validator.notValid([
- {
- name: 'origin',
- type: 'address',
- value: address,
- },
- ]);
- const data = {
- owner_address: toHex(address),
- };
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.WithdrawExpireUnfreezeContract, data, options?.permissionId, transactionOptions);
- }
- async withdrawBlockRewards(address = this.tronWeb.defaultAddress.hex, options = {}) {
- this.validator.notValid([
- {
- name: 'origin',
- type: 'address',
- value: address,
- },
- ]);
- const data = {
- owner_address: toHex(address),
- };
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.WithdrawBalanceContract, data, options?.permissionId, transactionOptions);
- }
- async applyForSR(address = this.tronWeb.defaultAddress.hex, url = '', options = {}) {
- this.validator.notValid([
- {
- name: 'origin',
- type: 'address',
- value: address,
- },
- {
- name: 'url',
- type: 'url',
- value: url,
- msg: 'Invalid url provided',
- },
- {
- name: 'url',
- type: 'string',
- value: url,
- lte: 256,
- msg: 'Invalid url provided',
- },
- ]);
- const data = {
- owner_address: toHex(address),
- url: fromUtf8(url),
- };
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.WitnessCreateContract, data, options?.permissionId, transactionOptions);
- }
- async vote(votes = {}, voterAddress = this.tronWeb.defaultAddress.hex, options = {}) {
- this.validator.notValid([
- {
- name: 'voter',
- type: 'address',
- value: voterAddress,
- },
- {
- name: 'votes',
- type: 'notEmptyObject',
- value: votes,
- },
- ]);
- const entries = Object.entries(votes);
- for (const [srAddress, voteCount] of entries) {
- this.validator.notValid([
- {
- name: 'SR',
- type: 'address',
- value: srAddress,
- },
- {
- name: 'vote count',
- type: 'integer',
- gt: 0,
- value: voteCount,
- msg: 'Invalid vote count provided for SR: ' + srAddress,
- },
- ]);
- }
- const voteList = entries.map(([srAddress, voteCount]) => {
- return {
- vote_address: toHex(srAddress),
- vote_count: parseInt(voteCount),
- };
- });
- const data = {
- owner_address: toHex(voterAddress),
- votes: voteList,
- };
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.VoteWitnessContract, data, options?.permissionId, transactionOptions);
- }
- async createSmartContract(options = {}, issuerAddress = this.tronWeb.defaultAddress.hex) {
- const feeLimit = options.feeLimit || this.tronWeb.feeLimit;
- let userFeePercentage = options.userFeePercentage;
- if (typeof userFeePercentage !== 'number' && !userFeePercentage) {
- userFeePercentage = 100;
- }
- const originEnergyLimit = options.originEnergyLimit || 10_000_000;
- const callValue = options.callValue || 0;
- const tokenValue = options.tokenValue;
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore
- const tokenId = options.tokenId || options.token_id;
- let { abi } = options;
- const { parameters = [] } = options;
- let parameter = '';
- const { bytecode = false, name = '' } = options;
- if (abi && isString(abi)) {
- try {
- abi = JSON.parse(abi);
- }
- catch {
- throw new Error('Invalid options.abi provided');
- }
- }
- const newAbi = abi;
- let entries = newAbi;
- if (newAbi.entrys) {
- entries = newAbi.entrys;
- }
- if (!isArray(entries))
- throw new Error('Invalid options.abi provided');
- const payable = entries.some((func) => {
- return func.type === 'constructor' && 'payable' === func.stateMutability.toLowerCase();
- });
- this.validator.notValid([
- {
- name: 'bytecode',
- type: 'hex',
- value: bytecode,
- },
- {
- name: 'feeLimit',
- type: 'integer',
- value: feeLimit,
- gt: 0,
- },
- {
- name: 'callValue',
- type: 'integer',
- value: callValue,
- gte: 0,
- },
- {
- name: 'userFeePercentage',
- type: 'integer',
- value: userFeePercentage,
- gte: 0,
- lte: 100,
- },
- {
- name: 'originEnergyLimit',
- type: 'integer',
- value: originEnergyLimit,
- gte: 0,
- lte: 10_000_000,
- },
- {
- name: 'parameters',
- type: 'array',
- value: parameters,
- },
- {
- name: 'issuer',
- type: 'address',
- value: issuerAddress,
- },
- {
- name: 'tokenValue',
- type: 'integer',
- value: tokenValue,
- gte: 0,
- optional: true,
- },
- {
- name: 'tokenId',
- type: 'integer',
- value: tokenId,
- gte: 0,
- optional: true,
- },
- ]);
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore
- if (!payable && (callValue > 0 || tokenValue > 0))
- throw new Error('When contract is not payable, options.callValue and options.tokenValue must be 0');
- const { rawParameter, funcABIV2, parametersV2 } = options;
- if (rawParameter && isString(rawParameter)) {
- parameter = rawParameter.replace(/^(0x)/, '');
- }
- else if (funcABIV2) {
- parameter = encodeParamsV2ByABI(funcABIV2, parametersV2).replace(/^(0x)/, '');
- }
- else {
- let constructorParams = entries.find((it) => {
- return it.type === 'constructor';
- });
- if (typeof constructorParams !== 'undefined' && constructorParams) {
- const abiCoder = new AbiCoder();
- const types = [];
- const values = [];
- constructorParams = constructorParams.inputs;
- if (parameters.length != constructorParams.length)
- throw new Error(`constructor needs ${constructorParams.length} but ${parameters.length} provided`);
- for (let i = 0; i < parameters.length; i++) {
- let type = constructorParams[i].type;
- let value = parameters[i];
- if (!type || !isString(type) || !type.length)
- throw new Error('Invalid parameter type provided: ' + type);
- const replaceAddressPrefix = (value) => {
- if (isArray(value)) {
- return value.map((v) => replaceAddressPrefix(v));
- }
- return toHex(value).replace(ADDRESS_PREFIX_REGEX, '0x');
- };
- if (type === 'address')
- value = replaceAddressPrefix(value);
- else if (type.match(/^([^\x5b]*)(\x5b|$)/)?.[0] === 'address[')
- value = replaceAddressPrefix(value);
- else if (/trcToken/.test(type)) {
- type = type.replace(/trcToken/, 'uint256');
- }
- types.push(type);
- values.push(value);
- }
- try {
- parameter = abiCoder.encode(types, values).replace(/^(0x)/, '');
- }
- catch (ex) {
- throw new Error(ex);
- }
- }
- else {
- parameter = '';
- }
- }
- const args = {
- owner_address: toHex(issuerAddress),
- fee_limit: parseInt(feeLimit),
- call_value: parseInt(callValue),
- consume_user_resource_percent: userFeePercentage,
- origin_energy_limit: originEnergyLimit,
- abi: JSON.stringify(entries),
- bytecode,
- parameter,
- name,
- };
- // tokenValue and tokenId can cause errors if provided when the trx10 proposal has not been approved yet. So we set them only if they are passed to the method.
- if (isNotNullOrUndefined(tokenValue)) {
- args.call_token_value = parseInt(tokenValue);
- }
- if (isNotNullOrUndefined(tokenId)) {
- args.token_id = parseInt(tokenId);
- }
- const contract = {};
- contract.owner_address = args.owner_address;
- if (isNotNullOrUndefined(args.call_token_value)) {
- contract.call_token_value = args.call_token_value;
- }
- if (isNotNullOrUndefined(args.token_id)) {
- contract.token_id = args.token_id;
- }
- const new_contract = (contract.new_contract = {});
- if (args.abi) {
- new_contract.abi = {
- entrys: JSON.parse(args.abi),
- };
- }
- else {
- new_contract.abi = {};
- }
- if (args.call_value) {
- new_contract.call_value = args.call_value;
- }
- new_contract.consume_user_resource_percent = args.consume_user_resource_percent;
- new_contract.origin_energy_limit = args.origin_energy_limit;
- new_contract.origin_address = args.origin_address ?? args.owner_address;
- if (args.bytecode + args.parameter) {
- new_contract.bytecode = (args.bytecode + args.parameter).replace(/^0x/, '');
- }
- if (isNotNullOrUndefined(args.name)) {
- new_contract.name = args.name;
- }
- const transactionOptions = getTransactionOptions(options);
- const tx = (await createTransaction(this.tronWeb, ContractType.CreateSmartContract, contract, options?.permissionId, {
- ...transactionOptions,
- fee_limit: args.fee_limit,
- }));
- tx.contract_address = genContractAddress(args.owner_address, tx.txID);
- return tx;
- }
- async triggerSmartContract(contractAddress, functionSelector, options, parameters, issuerAddress) {
- const params = [
- contractAddress,
- functionSelector,
- options,
- parameters,
- issuerAddress,
- ];
- if (typeof params[2] !== 'object') {
- params[2] = {
- feeLimit: params[2],
- callValue: params[3],
- };
- params.splice(3, 1);
- }
- if (params[2]?.txLocal) {
- return this._triggerSmartContractLocal(...params);
- }
- return this._triggerSmartContract(...params);
- }
- async triggerConstantContract(contractAddress, functionSelector, options = {}, parameters = [], issuerAddress = this.tronWeb.defaultAddress.hex) {
- options._isConstant = true;
- return this._triggerSmartContract(contractAddress, functionSelector, options, parameters, issuerAddress);
- }
- async triggerConfirmedConstantContract(contractAddress, functionSelector, options = {}, parameters = [], issuerAddress = this.tronWeb.defaultAddress.hex) {
- options._isConstant = true;
- options.confirmed = true;
- return this._triggerSmartContract(contractAddress, functionSelector, options, parameters, issuerAddress);
- }
- async estimateEnergy(contractAddress, functionSelector, options = {}, parameters = [], issuerAddress = this.tronWeb.defaultAddress.hex) {
- options.estimateEnergy = true;
- const result = await this._triggerSmartContract(contractAddress, functionSelector, options, parameters, issuerAddress);
- return result;
- }
- async deployConstantContract(options = { input: '', ownerAddress: '' }) {
- const { input, ownerAddress, tokenId, tokenValue, callValue = 0 } = options;
- this.validator.notValid([
- {
- name: 'input',
- type: 'not-empty-string',
- value: input,
- },
- {
- name: 'callValue',
- type: 'integer',
- value: callValue,
- gte: 0,
- },
- {
- name: 'owner',
- type: 'address',
- value: ownerAddress,
- },
- {
- name: 'tokenValue',
- type: 'integer',
- value: tokenValue,
- gte: 0,
- optional: true,
- },
- {
- name: 'tokenId',
- type: 'integer',
- value: tokenId,
- gte: 0,
- optional: true,
- },
- ]);
- const args = {
- data: input,
- owner_address: toHex(ownerAddress),
- call_value: callValue,
- };
- if (tokenId) {
- args.token_id = tokenId;
- }
- if (tokenValue) {
- args.call_token_value = tokenValue;
- }
- const pathInfo = `wallet${options.confirmed ? 'solidity' : ''}/estimateenergy`;
- const transaction = await this.tronWeb[options.confirmed ? 'solidityNode' : 'fullNode'].request(pathInfo, args, 'post');
- if (transaction.Error)
- throw new Error(transaction.Error);
- if (transaction.result && transaction.result.message) {
- throw new Error(this.tronWeb.toUtf8(transaction.result.message));
- }
- return transaction;
- }
- _getTriggerSmartContractArgs(contractAddress, functionSelector, options, parameters, issuerAddress, tokenValue, tokenId, callValue, feeLimit) {
- const args = {
- contract_address: toHex(contractAddress),
- owner_address: toHex(issuerAddress),
- };
- if (functionSelector && isString(functionSelector)) {
- functionSelector = functionSelector.replace(/\s*/g, '');
- let parameterStr;
- if (parameters.length) {
- const abiCoder = new AbiCoder();
- let types = [];
- const values = [];
- for (let i = 0; i < parameters.length; i++) {
- let { value } = parameters[i];
- const { type } = parameters[i];
- if (!type || !isString(type) || !type.length)
- throw new Error('Invalid parameter type provided: ' + type);
- const replaceAddressPrefix = (value) => {
- if (isArray(value)) {
- return value.map((v) => replaceAddressPrefix(v));
- }
- return toHex(value).replace(ADDRESS_PREFIX_REGEX, '0x');
- };
- if (type === 'address')
- value = replaceAddressPrefix(value);
- else if (type.match(/^([^\x5b]*)(\x5b|$)/)?.[0] === 'address[')
- value = replaceAddressPrefix(value);
- types.push(type);
- values.push(value);
- }
- try {
- // workaround for unsupported trcToken type
- types = types.map((type) => {
- if (/trcToken/.test(type)) {
- type = type.replace(/trcToken/, 'uint256');
- }
- return type;
- });
- parameterStr = abiCoder.encode(types, values).replace(/^(0x)/, '');
- }
- catch (ex) {
- throw new Error(ex);
- }
- }
- else
- parameterStr = '';
- // work for abiv2 if passed the function abi in options
- if (options.funcABIV2) {
- parameterStr = encodeParamsV2ByABI(options.funcABIV2, options.parametersV2).replace(/^(0x)/, '');
- }
- if (options.shieldedParameter && isString(options.shieldedParameter)) {
- parameterStr = options.shieldedParameter.replace(/^(0x)/, '');
- }
- if (options.rawParameter && isString(options.rawParameter)) {
- parameterStr = options.rawParameter.replace(/^(0x)/, '');
- }
- args.function_selector = functionSelector;
- args.parameter = parameterStr;
- }
- else if (options.input) {
- args.data = options.input;
- }
- args.call_value = parseInt(callValue);
- if (isNotNullOrUndefined(tokenValue))
- args.call_token_value = parseInt(tokenValue);
- if (isNotNullOrUndefined(tokenId))
- args.token_id = parseInt(tokenId);
- if (!(options._isConstant || options.estimateEnergy)) {
- args.fee_limit = parseInt(feeLimit);
- }
- if (options.permissionId) {
- args.Permission_id = options.permissionId;
- }
- return args;
- }
- async _triggerSmartContractLocal(contractAddress, functionSelector, options = {}, parameters = [], issuerAddress = this.tronWeb.defaultAddress.hex) {
- const { tokenValue, tokenId, callValue, feeLimit } = Object.assign({
- callValue: 0,
- feeLimit: this.tronWeb.feeLimit,
- }, options);
- this.validator.notValid([
- {
- name: 'feeLimit',
- type: 'integer',
- value: feeLimit,
- gt: 0,
- },
- {
- name: 'callValue',
- type: 'integer',
- value: callValue,
- gte: 0,
- },
- {
- name: 'parameters',
- type: 'array',
- value: parameters,
- },
- {
- name: 'contract',
- type: 'address',
- value: contractAddress,
- },
- {
- name: 'issuer',
- type: 'address',
- value: issuerAddress,
- optional: true,
- },
- {
- name: 'tokenValue',
- type: 'integer',
- value: tokenValue,
- gte: 0,
- optional: true,
- },
- {
- name: 'tokenId',
- type: 'integer',
- value: tokenId,
- gte: 0,
- optional: true,
- },
- ]);
- const args = this._getTriggerSmartContractArgs(contractAddress, functionSelector, options, parameters, issuerAddress, tokenValue, tokenId, callValue, feeLimit);
- if (args.function_selector) {
- args.data = keccak256(Buffer.from(args.function_selector, 'utf-8')).toString().substring(2, 10) + args.parameter;
- }
- const value = {
- data: args.data,
- owner_address: args.owner_address,
- contract_address: args.contract_address,
- };
- if (args.call_value) {
- value.call_value = args.call_value;
- }
- if (args.call_token_value) {
- value.call_token_value = args.call_token_value;
- }
- if (args.token_id) {
- value.token_id = args.token_id;
- }
- const transactionOptions = getTransactionOptions(options);
- const transaction = await createTransaction(this.tronWeb, ContractType.TriggerSmartContract, value, options.permissionId, {
- ...transactionOptions,
- fee_limit: args.fee_limit,
- });
- return {
- result: {
- result: true,
- },
- transaction,
- };
- }
- async _triggerSmartContract(contractAddress, functionSelector, options = {}, parameters = [], issuerAddress = this.tronWeb.defaultAddress.hex) {
- const { tokenValue, tokenId, callValue, feeLimit } = Object.assign({
- callValue: 0,
- feeLimit: this.tronWeb.feeLimit,
- }, options);
- this.validator.notValid([
- {
- name: 'feeLimit',
- type: 'integer',
- value: feeLimit,
- gt: 0,
- },
- {
- name: 'callValue',
- type: 'integer',
- value: callValue,
- gte: 0,
- },
- {
- name: 'parameters',
- type: 'array',
- value: parameters,
- },
- {
- name: 'contract',
- type: 'address',
- value: contractAddress,
- },
- {
- name: 'issuer',
- type: 'address',
- value: issuerAddress,
- optional: true,
- },
- {
- name: 'tokenValue',
- type: 'integer',
- value: tokenValue,
- gte: 0,
- optional: true,
- },
- {
- name: 'tokenId',
- type: 'integer',
- value: tokenId,
- gte: 0,
- optional: true,
- },
- ]);
- const args = this._getTriggerSmartContractArgs(contractAddress, functionSelector, options, parameters, issuerAddress, tokenValue, tokenId, callValue, feeLimit);
- let pathInfo = 'triggersmartcontract';
- if (options._isConstant) {
- pathInfo = 'triggerconstantcontract';
- }
- else if (options.estimateEnergy) {
- pathInfo = 'estimateenergy';
- }
- pathInfo = `wallet${options.confirmed ? 'solidity' : ''}/${pathInfo}`;
- const transaction = await this.tronWeb[options.confirmed ? 'solidityNode' : 'fullNode'].request(pathInfo, args, 'post');
- return resultManagerTriggerSmartContract(transaction, args, options);
- }
- async clearABI(contractAddress, ownerAddress = this.tronWeb.defaultAddress.hex, options = {}) {
- if (!TronWeb.isAddress(contractAddress))
- throw new Error('Invalid contract address provided');
- if (!TronWeb.isAddress(ownerAddress))
- throw new Error('Invalid owner address provided');
- const data = {
- contract_address: toHex(contractAddress),
- owner_address: toHex(ownerAddress),
- };
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore
- if (this.tronWeb.trx.cache.contracts[contractAddress]) {
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore
- delete this.tronWeb.trx.cache.contracts[contractAddress];
- }
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.ClearABIContract, data, options?.permissionId, transactionOptions);
- }
- async updateBrokerage(brokerage, ownerAddress = this.tronWeb.defaultAddress.hex, options = {}) {
- if (!isNotNullOrUndefined(brokerage))
- throw new Error('Invalid brokerage provided');
- if (!isInteger(brokerage) || brokerage < 0 || brokerage > 100)
- throw new Error('Brokerage must be an integer between 0 and 100');
- if (!TronWeb.isAddress(ownerAddress))
- throw new Error('Invalid owner address provided');
- const data = {
- brokerage: parseInt(brokerage),
- owner_address: toHex(ownerAddress),
- };
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.UpdateBrokerageContract, data, options?.permissionId, transactionOptions);
- }
- async createToken(options = {}, issuerAddress = this.tronWeb.defaultAddress.hex) {
- const { name = false, abbreviation = false, description = '', url = false, totalSupply = 0, trxRatio = 1, // How much TRX will `tokenRatio` cost
- tokenRatio = 1, // How many tokens will `trxRatio` afford
- saleStart = Date.now(), saleEnd = false, freeBandwidth = 0, // The creator's "donated" bandwidth for use by token holders
- freeBandwidthLimit = 0, // Out of `totalFreeBandwidth`, the amount each token holder get
- frozenAmount = 0, frozenDuration = 0,
- // for now there is no default for the following values
- voteScore, precision, } = options;
- this.validator.notValid([
- {
- name: 'Supply amount',
- type: 'positive-integer',
- value: totalSupply,
- },
- {
- name: 'TRX ratio',
- type: 'positive-integer',
- value: trxRatio,
- },
- {
- name: 'Token ratio',
- type: 'positive-integer',
- value: tokenRatio,
- },
- {
- name: 'token abbreviation',
- type: 'string',
- value: abbreviation,
- lte: 32,
- gt: 0,
- },
- {
- name: 'token name',
- type: 'not-empty-string',
- value: name,
- },
- {
- name: 'token description',
- type: 'string',
- value: description,
- lte: 200,
- },
- {
- name: 'token url',
- type: 'url',
- value: url,
- },
- {
- name: 'token url',
- type: 'string',
- value: url,
- lte: 256,
- },
- {
- name: 'issuer',
- type: 'address',
- value: issuerAddress,
- },
- {
- name: 'sale start timestamp',
- type: 'integer',
- value: saleStart,
- gte: Date.now(),
- },
- {
- name: 'sale end timestamp',
- type: 'integer',
- value: saleEnd,
- gt: saleStart,
- },
- {
- name: 'Frozen supply',
- type: 'integer',
- value: frozenAmount,
- gte: 0,
- },
- {
- name: 'Frozen duration',
- type: 'integer',
- value: frozenDuration,
- gte: 0,
- },
- ]);
- if (isNotNullOrUndefined(voteScore) && (!isInteger(voteScore) || voteScore <= 0))
- throw new Error('voteScore must be a positive integer greater than 0');
- if (isNotNullOrUndefined(precision) && (!isInteger(precision) || precision < 0 || precision > 6))
- throw new Error('precision must be a positive integer >= 0 and <= 6');
- const data = {
- owner_address: toHex(issuerAddress),
- name: fromUtf8(name),
- abbr: fromUtf8(abbreviation),
- description: fromUtf8(description),
- url: fromUtf8(url),
- total_supply: parseInt(totalSupply),
- trx_num: parseInt(trxRatio),
- num: parseInt(tokenRatio),
- start_time: parseInt(saleStart),
- end_time: parseInt(saleEnd),
- frozen_supply: [
- {
- frozen_amount: parseInt(frozenAmount),
- frozen_days: parseInt(frozenDuration),
- },
- ],
- };
- ['name', 'abbr', 'description', 'url'].forEach((key) => {
- if (!data[key]) {
- delete data[key];
- }
- });
- if (!(parseInt(frozenAmount) > 0)) {
- delete data.frozen_supply;
- }
- if (freeBandwidth && !isNaN(parseInt(freeBandwidth)) && parseInt(freeBandwidth) >= 0) {
- data.free_asset_net_limit = parseInt(freeBandwidth);
- }
- if (freeBandwidthLimit && !isNaN(parseInt(freeBandwidthLimit)) && parseInt(freeBandwidthLimit) >= 0) {
- data.public_free_asset_net_limit = parseInt(freeBandwidthLimit);
- }
- if (precision && !isNaN(parseInt(precision))) {
- data.precision = parseInt(precision);
- }
- if (voteScore && !isNaN(parseInt(voteScore))) {
- data.vote_score = parseInt(voteScore);
- }
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.AssetIssueContract, data, options?.permissionId, transactionOptions);
- }
- async createAccount(accountAddress, address = this.tronWeb.defaultAddress.hex, options = {}) {
- this.validator.notValid([
- {
- name: 'account',
- type: 'address',
- value: accountAddress,
- },
- {
- name: 'origin',
- type: 'address',
- value: address,
- },
- ]);
- const data = {
- owner_address: toHex(address),
- account_address: toHex(accountAddress),
- };
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.AccountCreateContract, data, options?.permissionId, transactionOptions);
- }
- async updateAccount(accountName, address = this.tronWeb.defaultAddress.hex, options = {}) {
- this.validator.notValid([
- {
- name: 'Name',
- type: 'string',
- lte: 200,
- gt: 0,
- value: accountName,
- msg: 'Invalid accountName',
- },
- {
- name: 'origin',
- type: 'address',
- value: address,
- },
- ]);
- const data = {
- account_name: fromUtf8(accountName),
- owner_address: toHex(address),
- };
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.AccountUpdateContract, data, options?.permissionId, transactionOptions);
- }
- async setAccountId(accountId, address = this.tronWeb.defaultAddress.hex, options = {}) {
- if (accountId && isString(accountId) && accountId.startsWith('0x')) {
- accountId = accountId.slice(2);
- }
- this.validator.notValid([
- {
- name: 'accountId',
- type: 'hex',
- value: accountId,
- },
- {
- name: 'accountId',
- type: 'string',
- lte: 32,
- gte: 8,
- value: accountId,
- },
- {
- name: 'origin',
- type: 'address',
- value: address,
- },
- ]);
- const data = {
- account_id: accountId,
- owner_address: toHex(address),
- };
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.SetAccountIdContract, data, options?.permissionId, transactionOptions);
- }
- async updateToken(options = {}, issuerAddress = this.tronWeb.defaultAddress.hex) {
- const { description = '', url = false, freeBandwidth = 0, // The creator's "donated" bandwidth for use by token holders
- freeBandwidthLimit = 0, // Out of `totalFreeBandwidth`, the amount each token holder get
- } = options;
- this.validator.notValid([
- {
- name: 'token description',
- type: 'string',
- value: description,
- lte: 200,
- },
- {
- name: 'token url',
- type: 'url',
- value: url,
- },
- {
- name: 'token url',
- type: 'string',
- value: url,
- lte: 256,
- },
- {
- name: 'issuer',
- type: 'address',
- value: issuerAddress,
- },
- ]);
- const data = {
- owner_address: toHex(issuerAddress),
- description: fromUtf8(description),
- url: fromUtf8(url),
- };
- if (freeBandwidth && !isNaN(parseInt(freeBandwidth)) && parseInt(freeBandwidth) >= 0) {
- data.new_limit = parseInt(freeBandwidth);
- }
- if (freeBandwidthLimit && !isNaN(parseInt(freeBandwidthLimit)) && parseInt(freeBandwidthLimit) >= 0) {
- data.new_public_limit = parseInt(freeBandwidthLimit);
- }
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.UpdateAssetContract, data, options?.permissionId, transactionOptions);
- }
- async sendAsset(to, amount = 0, tokenId, from = this.tronWeb.defaultAddress.hex, options = {}) {
- return this.sendToken(to, amount, tokenId, from, options);
- }
- async purchaseAsset(issuerAddress, tokenId, amount = 0, buyer = this.tronWeb.defaultAddress.hex, options = {}) {
- return this.purchaseToken(issuerAddress, tokenId, amount, buyer, options);
- }
- async createAsset(options, issuerAddress) {
- return this.createToken(options, issuerAddress);
- }
- async updateAsset(options = {}, issuerAddress = this.tronWeb.defaultAddress.hex) {
- return this.updateToken(options, issuerAddress);
- }
- /**
- * Creates a proposal to modify the network.
- * Can only be created by a current Super Representative.
- */
- async createProposal(parameters, issuerAddress = this.tronWeb.defaultAddress.hex, options = {}) {
- this.validator.notValid([
- {
- name: 'issuer',
- type: 'address',
- value: issuerAddress,
- },
- ]);
- const invalid = 'Invalid proposal parameters provided';
- if (!parameters)
- throw new Error(invalid);
- const newParams = isArray(parameters) ? parameters : [parameters];
- for (const parameter of newParams) {
- if (!isObject(parameter))
- throw new Error(invalid);
- }
- const data = {
- owner_address: toHex(issuerAddress),
- parameters: newParams,
- };
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.ProposalCreateContract, data, options?.permissionId, transactionOptions);
- }
- /**
- * Deletes a network modification proposal that the owner issued.
- * Only current Super Representative can vote on a proposal.
- */
- async deleteProposal(proposalID, issuerAddress = this.tronWeb.defaultAddress.hex, options = {}) {
- this.validator.notValid([
- {
- name: 'issuer',
- type: 'address',
- value: issuerAddress,
- },
- {
- name: 'proposalID',
- type: 'integer',
- value: proposalID,
- gte: 0,
- },
- ]);
- const data = {
- owner_address: toHex(issuerAddress),
- proposal_id: parseInt(proposalID),
- };
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.ProposalDeleteContract, data, options?.permissionId, transactionOptions);
- }
- /**
- * Adds a vote to an issued network modification proposal.
- * Only current Super Representative can vote on a proposal.
- */
- async voteProposal(proposalID, isApproval = false, voterAddress = this.tronWeb.defaultAddress.hex, options = {}) {
- this.validator.notValid([
- {
- name: 'voter',
- type: 'address',
- value: voterAddress,
- },
- {
- name: 'proposalID',
- type: 'integer',
- value: proposalID,
- gte: 0,
- },
- {
- name: 'has approval',
- type: 'boolean',
- value: isApproval,
- },
- ]);
- const data = {
- owner_address: toHex(voterAddress),
- proposal_id: parseInt(proposalID),
- is_add_approval: isApproval,
- };
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.ProposalApproveContract, data, options?.permissionId, transactionOptions);
- }
- /**
- * Create an exchange between a token and TRX.
- * Token Name should be a CASE SENSITIVE string.
- * PLEASE VERIFY THIS ON TRONSCAN.
- */
- async createTRXExchange(tokenName, tokenBalance, trxBalance, ownerAddress = this.tronWeb.defaultAddress.hex, options = {}) {
- this.validator.notValid([
- {
- name: 'owner',
- type: 'address',
- value: ownerAddress,
- },
- {
- name: 'token name',
- type: 'not-empty-string',
- value: tokenName,
- },
- {
- name: 'token balance',
- type: 'positive-integer',
- value: tokenBalance,
- },
- {
- name: 'trx balance',
- type: 'positive-integer',
- value: trxBalance,
- },
- ]);
- const data = {
- owner_address: toHex(ownerAddress),
- first_token_id: fromUtf8(tokenName),
- first_token_balance: tokenBalance,
- second_token_id: '5f', // Constant for TRX.
- second_token_balance: trxBalance,
- };
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.ExchangeCreateContract, data, options?.permissionId, transactionOptions);
- }
- /**
- * Create an exchange between a token and another token.
- * DO NOT USE THIS FOR TRX.
- * Token Names should be a CASE SENSITIVE string.
- * PLEASE VERIFY THIS ON TRONSCAN.
- */
- async createTokenExchange(firstTokenName, firstTokenBalance, secondTokenName, secondTokenBalance, ownerAddress = this.tronWeb.defaultAddress.hex, options = {}) {
- this.validator.notValid([
- {
- name: 'owner',
- type: 'address',
- value: ownerAddress,
- },
- {
- name: 'first token name',
- type: 'not-empty-string',
- value: firstTokenName,
- },
- {
- name: 'second token name',
- type: 'not-empty-string',
- value: secondTokenName,
- },
- {
- name: 'first token balance',
- type: 'positive-integer',
- value: firstTokenBalance,
- },
- {
- name: 'second token balance',
- type: 'positive-integer',
- value: secondTokenBalance,
- },
- ]);
- const data = {
- owner_address: toHex(ownerAddress),
- first_token_id: fromUtf8(firstTokenName),
- first_token_balance: firstTokenBalance,
- second_token_id: fromUtf8(secondTokenName),
- second_token_balance: secondTokenBalance,
- };
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.ExchangeCreateContract, data, options?.permissionId, transactionOptions);
- }
- /**
- * Adds tokens into a bancor style exchange.
- * Will add both tokens at market rate.
- * Use "_" for the constant value for TRX.
- */
- async injectExchangeTokens(exchangeID, tokenName, tokenAmount, ownerAddress = this.tronWeb.defaultAddress.hex, options = {}) {
- this.validator.notValid([
- {
- name: 'owner',
- type: 'address',
- value: ownerAddress,
- },
- {
- name: 'token name',
- type: 'not-empty-string',
- value: tokenName,
- },
- {
- name: 'token amount',
- type: 'integer',
- value: tokenAmount,
- gte: 1,
- },
- {
- name: 'exchangeID',
- type: 'integer',
- value: exchangeID,
- gte: 0,
- },
- ]);
- const data = {
- owner_address: toHex(ownerAddress),
- exchange_id: parseInt(exchangeID),
- token_id: fromUtf8(tokenName),
- quant: parseInt(tokenAmount),
- };
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.ExchangeInjectContract, data, options?.permissionId, transactionOptions);
- }
- /**
- * Withdraws tokens from a bancor style exchange.
- * Will withdraw at market rate both tokens.
- * Use "_" for the constant value for TRX.
- */
- async withdrawExchangeTokens(exchangeID, tokenName, tokenAmount, ownerAddress = this.tronWeb.defaultAddress.hex, options = {}) {
- this.validator.notValid([
- {
- name: 'owner',
- type: 'address',
- value: ownerAddress,
- },
- {
- name: 'token name',
- type: 'not-empty-string',
- value: tokenName,
- },
- {
- name: 'token amount',
- type: 'integer',
- value: tokenAmount,
- gte: 1,
- },
- {
- name: 'exchangeID',
- type: 'integer',
- value: exchangeID,
- gte: 0,
- },
- ]);
- const data = {
- owner_address: toHex(ownerAddress),
- exchange_id: parseInt(exchangeID),
- token_id: fromUtf8(tokenName),
- quant: parseInt(tokenAmount),
- };
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.ExchangeWithdrawContract, data, options?.permissionId, transactionOptions);
- }
- /**
- * Trade tokens on a bancor style exchange.
- * Expected value is a validation and used to cap the total amt of token 2 spent.
- * Use "_" for the constant value for TRX.
- */
- async tradeExchangeTokens(exchangeID, tokenName, tokenAmountSold, tokenAmountExpected, ownerAddress = this.tronWeb.defaultAddress.hex, options = {}) {
- this.validator.notValid([
- {
- name: 'owner',
- type: 'address',
- value: ownerAddress,
- },
- {
- name: 'token name',
- type: 'not-empty-string',
- value: tokenName,
- },
- {
- name: 'tokenAmountSold',
- type: 'integer',
- value: tokenAmountSold,
- gte: 1,
- },
- {
- name: 'tokenAmountExpected',
- type: 'integer',
- value: tokenAmountExpected,
- gte: 1,
- },
- {
- name: 'exchangeID',
- type: 'integer',
- value: exchangeID,
- gte: 0,
- },
- ]);
- const data = {
- owner_address: toHex(ownerAddress),
- exchange_id: parseInt(exchangeID),
- token_id: TronWeb.fromAscii(tokenName).replace(/^0x/, ''),
- quant: parseInt(tokenAmountSold),
- expected: parseInt(tokenAmountExpected),
- };
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.ExchangeTransactionContract, data, options?.permissionId, transactionOptions);
- }
- /**
- * Update userFeePercentage.
- */
- async updateSetting(contractAddress, userFeePercentage, ownerAddress = this.tronWeb.defaultAddress.hex, options = {}) {
- this.validator.notValid([
- {
- name: 'owner',
- type: 'address',
- value: ownerAddress,
- },
- {
- name: 'contract',
- type: 'address',
- value: contractAddress,
- },
- {
- name: 'userFeePercentage',
- type: 'integer',
- value: userFeePercentage,
- gte: 0,
- lte: 100,
- },
- ]);
- const data = {
- owner_address: toHex(ownerAddress),
- contract_address: toHex(contractAddress),
- consume_user_resource_percent: userFeePercentage,
- };
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.UpdateSettingContract, data, options?.permissionId, transactionOptions);
- }
- /**
- * Update energy limit.
- */
- async updateEnergyLimit(contractAddress, originEnergyLimit = 0, ownerAddress = this.tronWeb.defaultAddress.hex, options = {}) {
- this.validator.notValid([
- {
- name: 'owner',
- type: 'address',
- value: ownerAddress,
- },
- {
- name: 'contract',
- type: 'address',
- value: contractAddress,
- },
- {
- name: 'originEnergyLimit',
- type: 'integer',
- value: originEnergyLimit,
- gte: 0,
- lte: 10_000_000,
- },
- ]);
- const data = {
- owner_address: toHex(ownerAddress),
- contract_address: toHex(contractAddress),
- origin_energy_limit: originEnergyLimit,
- };
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.UpdateEnergyLimitContract, data, options?.permissionId, transactionOptions);
- }
- checkPermissions(permissions, type) {
- if (permissions) {
- if (permissions.type !== type ||
- !permissions.permission_name ||
- !isString(permissions.permission_name) ||
- !isInteger(permissions.threshold) ||
- permissions.threshold < 1 ||
- !permissions.keys) {
- return false;
- }
- for (const key of permissions.keys) {
- if (!TronWeb.isAddress(key.address) ||
- !isInteger(key.weight) ||
- key.weight > permissions.threshold ||
- key.weight < 1 ||
- (type === 2 && !permissions.operations)) {
- return false;
- }
- }
- }
- return true;
- }
- async updateAccountPermissions(ownerAddress = this.tronWeb.defaultAddress.hex, ownerPermission, witnessPermission, activesPermissions, options = {}) {
- if (!TronWeb.isAddress(ownerAddress))
- throw new Error('Invalid ownerAddress provided');
- if (!this.checkPermissions(ownerPermission, 0)) {
- throw new Error('Invalid ownerPermissions provided');
- }
- if (!this.checkPermissions(witnessPermission, 1)) {
- throw new Error('Invalid witnessPermissions provided');
- }
- if (!Array.isArray(activesPermissions)) {
- activesPermissions = [activesPermissions];
- }
- for (const activesPermission of activesPermissions) {
- if (!this.checkPermissions(activesPermission, 2)) {
- throw new Error('Invalid activesPermissions provided');
- }
- }
- const data = {
- owner_address: toHex(ownerAddress),
- };
- if (ownerPermission) {
- const _ownerPermissions = deepCopyJson(ownerPermission);
- // for compatible with old way of building transaction from chain which type prop is omitted
- if ('type' in _ownerPermissions) {
- delete _ownerPermissions.type;
- }
- _ownerPermissions.keys = _ownerPermissions.keys?.map(({ address, weight }) => ({
- address: this.tronWeb.address.toHex(address),
- weight,
- }));
- data.owner = _ownerPermissions;
- }
- if (witnessPermission) {
- const _witnessPermissions = deepCopyJson(witnessPermission);
- // for compatible with old way of building transaction from chain which type prop is Witness
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore
- _witnessPermissions.type = 'Witness';
- _witnessPermissions.keys = _witnessPermissions.keys.map(({ address, weight }) => ({
- address: this.tronWeb.address.toHex(address),
- weight,
- }));
- data.witness = _witnessPermissions;
- }
- if (activesPermissions) {
- const _activesPermissions = deepCopyJson(activesPermissions);
- // for compatible with old way of building transaction from chain which type prop is Active
- _activesPermissions.forEach((activePermissions) => {
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore
- activePermissions.type = 'Active';
- });
- _activesPermissions.forEach((_activesPermission) => {
- _activesPermission.keys = _activesPermission.keys.map(({ address, weight }) => ({
- address: this.tronWeb.address.toHex(address),
- weight,
- }));
- });
- data.actives = _activesPermissions;
- }
- const transactionOptions = getTransactionOptions(options);
- return createTransaction(this.tronWeb, ContractType.AccountPermissionUpdateContract, data, options?.permissionId, transactionOptions);
- }
- async newTxID(transaction, options = {}) {
- if (options?.txLocal) {
- const contract = transaction.raw_data.contract[0];
- try {
- const tx = await createTransaction(this.tronWeb, contract.type, contract.parameter.value, contract.Permission_id, {
- fee_limit: transaction.raw_data.fee_limit,
- data: transaction.raw_data.data,
- ref_block_bytes: transaction.raw_data.ref_block_bytes,
- ref_block_hash: transaction.raw_data.ref_block_hash,
- expiration: transaction.raw_data.expiration,
- timestamp: transaction.raw_data.timestamp,
- });
- tx.signature = transaction.signature;
- tx.visible = transaction.visible;
- return tx;
- }
- catch (e) {
- throw new Error('Error generating a new transaction id.');
- }
- }
- try {
- const res = await this.tronWeb.fullNode.request('wallet/getsignweight', transaction, 'post');
- if (typeof transaction.visible === 'boolean') {
- res.transaction.transaction.visible = transaction.visible;
- }
- return resultManager(res.transaction.transaction, {
- ...transaction.raw_data.contract[0].parameter.value,
- Permission_id: transaction.raw_data.contract[0].Permission_id,
- },
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- /* @ts-ignore */
- { data: transaction.raw_data.data, fee_limit: transaction.raw_data.fee_limit });
- }
- catch (e) {
- throw new Error('Error generating a new transaction id.');
- }
- }
- async alterTransaction(transaction, options = {}) {
- if (Reflect.has(transaction, 'signature'))
- throw new Error('You can not extend the expiration of a signed transaction.');
- if (options.data) {
- if (options.dataFormat !== 'hex')
- options.data = TronWeb.toHex(options.data);
- options.data = options.data.replace(/^0x/, '');
- if (options.data.length === 0)
- throw new Error('Invalid data provided');
- transaction.raw_data.data = options.data;
- }
- if (options.extension) {
- options.extension = parseInt(options.extension * 1000);
- if (isNaN(options.extension) || transaction.raw_data.expiration + options.extension <= Date.now() + 3000)
- throw new Error('Invalid extension provided');
- transaction.raw_data.expiration += options.extension;
- }
- return await this.newTxID(transaction, { txLocal: options.txLocal });
- }
- async extendExpiration(transaction, extension, options = {}) {
- return await this.alterTransaction(transaction, { extension, txLocal: options?.txLocal });
- }
- async addUpdateData(transaction, data, dataFormat = 'utf8', options = {}) {
- return this.alterTransaction(transaction, { data, dataFormat: dataFormat, txLocal: options?.txLocal });
- }
- }
- //# sourceMappingURL=TransactionBuilder.js.map
|