ptm.js

const rp = require("request-promise-native");
const { URL } = require("url");
const { hexToBase64, base64toHex } = require("./util");

/**
 * For more details about the {@link https://consensys.github.io/tessera/ Private Transaction manager}
 * @module ptm
 */
function ptm(web3, { ipcPath, privateUrl, tlsSettings }) {
  const socketRoot = `http://unix:${ipcPath}:`;
  const privateEndpoint = ipcPath ? socketRoot : privateUrl;
  const publicEndpoint = ipcPath ? socketRoot : privateUrl;
  const tlsOptions = {};
  // eslint-disable-next-line no-param-reassign
  web3.ptm = {};

  // tls settings fot https connections
  if (ipcPath === undefined && privateEndpoint) {
    const { protocol } = new URL(privateEndpoint);
    if (protocol === "https:" && tlsSettings) {
      if (tlsSettings.key) {
        tlsOptions.clientKey = tlsSettings.key;
      }
      if (tlsSettings.clcert) {
        tlsOptions.clientCert = tlsSettings.clcert;
      }
      if (tlsSettings.cacert) {
        tlsOptions.ca = tlsSettings.cacert;
      }
      if (tlsSettings.allowInsecure) {
        tlsOptions.rejectInsecure = tlsSettings.allowInsecure;
      }
    }
  }

  /**
   * Calls Tessera’s ThirdParty /send API to encrypts a payload, stores result in database, and publishes result to recipients.
   * @function send
   * @param {Object} options
   * @param {String} options.data        Hex encoded private transaction data (value of data/input field in the transaction)
   * @param {String} options.privateFrom Sending party’s base64-encoded public key
   * @param {String} options.privateFor  public keys identifying the recipients of the payload
   * @returns   A promise that resolves to the hex-encoded hash of the encrypted data (key field) that should be used to replace the data field of a transaction if externally signing.
   */
  const send = async ({ data, privateFrom, privateFor }) => {
    const response = await rp({
      method: "POST",
      uri: `${privateEndpoint}/send`,
      json: true,
      body: {
        payload: hexToBase64(data.substring(2)),
        from: privateFrom,
        to: privateFor,
      },
      ...tlsOptions,
    });
    return base64toHex(response.key);
  };

  /**
   * Calls Tessera’s ThirdParty /storeraw API to encrypt the provided data and store in preparation for a eth_sendRawPrivateTransaction.
   * @function storeRaw
   * @param {Object} options
   * @param {String} options.data        Hex encoded private transaction data (value of data/input field in the transaction)
   * @param {String} options.privateFrom Sending party’s base64-encoded public key
   * @returns   A promise that resolves to the hex-encoded hash of the encrypted data (key field) that should be used to replace the data field of a transaction if externally signing.
   */
  const storeRaw = async ({ data, privateFrom }) => {
    const response = await rp({
      method: "POST",
      uri: `${privateEndpoint}/storeraw`,
      json: true,
      body: {
        payload: hexToBase64(data.substring(2)),
        from: privateFrom,
      },
      ...tlsOptions,
    });
    return base64toHex(response.key);
  };

  /**
   * @function keys
   * @returns all public keys managed by the server's enclave
   */
  const keys = () => {
    return rp({
      method: "GET",
      uri: `${publicEndpoint}/keys`,
      ...tlsOptions,
    });
  };

  /**
   * @function partyInfoKeys
   * @return public keys of all known nodes in the network, including the server's own keys
   */
  const partyInfoKeys = () => {
    return rp({
      method: "GET",
      uri: `${publicEndpoint}/partyinfo/keys`,
      ...tlsOptions,
    });
  };

  /**
   * @function upCheck
   * @return "I'm up!"
   */
  const upCheck = () => {
    return rp({
      method: "GET",
      uri: `${publicEndpoint}/upcheck`,
      ...tlsOptions,
    });
  };

  Object.assign(web3.ptm, {
    send,
    storeRaw,
    keys,
    partyInfoKeys,
    upCheck,
  });
  return web3;
}
module.exports = ptm;