tronprotocol / tronweb

Javascript API Library for interacting with the TRON Network
MIT License
423 stars 271 forks source link

Add possibility to extend the expiration in transaction creation parameters #414

Closed VladLypovyi closed 12 months ago

VladLypovyi commented 1 year ago

By default, expiration is created for 1 minute.

In order to change it you need to make a separate call to the extendExpiration method (which under the hood makes a request to the network to build a new transaction using the newTxID method).

    async newTxID(transaction, options, callback) {
        if (utils.isFunction(options)) {
            callback = options;
            options = {};
        }

        if (!callback)
            return this.injectPromise(this.newTxID, transaction, options);

        if (options?.txLocal) {
            const contract = transaction.raw_data.contract[0];
            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,
            }).then((tx) => {
                tx.signature = transaction.signature;
                tx.visible = transaction.visible;
                callback(null, tx);
            }).catch((err) => callback('Error generating a new transaction id.'));
            return;
        }
        ...
    }

    async alterTransaction(transaction, options = {}, callback = false) {
        if (!callback)
            return this.injectPromise(this.alterTransaction, transaction, options);

        if (transaction.signature)
            return callback('You can not extend the expiration of a signed transaction.')

        if (options.data) {
            if (options.dataFormat !== 'hex')
                options.data = this.tronWeb.toHex(options.data);
            options.data = options.data.replace(/^0x/, '')
            if (options.data.length === 0)
                return callback('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)
                return callback('Invalid extension provided');
            transaction.raw_data.expiration += options.extension;
        }

        this.newTxID(transaction, { txLocal: options.txLocal }, callback)
    }

    async extendExpiration(transaction, extension, options, callback = false) {
        if (utils.isFunction(options)) {
            callback = options;
            options = {};
        }

        if (!callback)
            return this.injectPromise(this.extendExpiration, transaction, extension, options);

        this.alterTransaction(transaction, {extension, txLocal: options?.txLocal}, callback);
    }

Why not add the ability to pass expiration with other method-specific parameters to the createTransaction method?

      async function createTransaction(tronWeb, type, value, Permission_id, options = {}) {
          const metaData = await getHeaderInfo(tronWeb.fullNode);
          const tx = {
              visible: false,
              txID: '',
              raw_data_hex: '',
              raw_data: {
                  contract: [{
                      parameter: {
                          value,
                          type_url: `type.googleapis.com/protocol.${type}`,
                      },
                      type,
                  }],
                  ...metaData,
                  ...options,
              },
          };
          if (Permission_id) {
              tx.raw_data.contract[0].Permission_id = Permission_id;
          }
          const pb = txJsonToPb(tx);
          tx.txID = txPbToTxID(pb).replace(/^0x/, '');
          tx.raw_data_hex = txPbToRawDataHex(pb).toLowerCase();
          return tx;
      }
start940315 commented 1 year ago

Because we want to provide a common way to process the common procedure. Also, we don't want the options arguments to contain mixed parameters that some belong to api and some belongs to transaction object. Thus, we provide a method to do it.

DmytroShalaiev commented 12 months ago

Thanks for the reply, obviously it could help to use fewer requests to the network.