Source: index.js

const Web3 = require("web3");
const { encrypt, decrypt } = require("./lib/encryption");
const signMsg = require("./lib/sign");

/**
 * This function decodes json string to json object
 * @param  {String} str
 */
const decode = str => JSON.parse(str);

/**
 * This function encodes json object to json string
 * @param  {Any} data
 */
const encode = data => (typeof data == "string" ? data : JSON.stringify(data));

/**
 * This function generates symmetric key based
 * @param  {web3.providers} web3 Web3 provider
 * @param  {web3.account} account Web3 account object
 * @param  {Int} salt Integer for more randomness
 */
function getSymmetricKey(web3, account, salt) {
  return signMsg(web3, account, salt);
}

/**
 * This function encrypts and signs the message
 * @param  {web3.providers} web3 Web3 provider
 * @param  {web3.account} account Web3 account object
 * @param  {String} msg Message to send
 * @param  {Int} salt Integer for more randomness
 * @return {} cipher TODO: Confirm type here
 */
async function sigEncrypt(web3, account, msg, salt) {
  let key = await getSymmetricKey(web3, account, salt);
  key = key.signature;
  const data = encode(msg);
  const cipher = encrypt(data, key);
  return cipher;
}

/**
 * This function decrypts encrypted and signed message
 * @param  {web3.providers} web3 Web3 provider
 * @param  {web3.account} account Web3 account object
 * @param  {Int} cipher Shared symmetric key
 * @param  {Int} salt Integer for more randomness
 * @return {} result TODO: Confirm type here
 */
async function sigDecrypt(web3, account, cipher, salt) {
  let key = await getSymmetricKey(web3, account, salt);
  key = key.signature;
  const data = decrypt(cipher, key);
  let result;
  try {
    result = decode(data);
  } catch (e) {
    result = data;
  }
  return result;
}

/**
 * This function constructs Web3 http provider
 * @param  {Web3.HttpProvider} newWeb3.providers.HttpProvider(providerUrl
 */
const constructWeb3 = providerUrl =>
  new Web3(new Web3.providers.HttpProvider(providerUrl));

/**
 * This class is the message encryption/decryption engine
 */
class EthSigEncryption {
  constructor(web3, account, salt) {
    if (typeof web3 == "string") this.web3 = constructWeb3(web3);
    else this.web3 = web3;
    this.account = account;
    this.salt = salt;
  }

  /**
   * This function encrypts a message
   * @param {String} message Message to send
   * @param {Object} options Options for encrypting the message
   * @return {} TODO: confirm type sigEncrypt Encrypted message
   */
  async encrypt(message, options) {
    const { web3, account, salt } = options ? options : this;
    return sigEncrypt(web3, account, message, salt);
  }

  /**
   * This function decrypts a message
   * @param {Int} cipher Shared Symmetric key
   * @param {Object} options Options for decrypying the message
   * @return {} TODO: confirm type sigDecrypt Decrypted message
   */
  async decrypt(cipher, options) {
    const { web3, account, salt } = options ? options : this;
    return sigDecrypt(web3, account, cipher, salt);
  }
}

module.exports = {
  EthSigEncryption,
  sigEncrypt,
  sigDecrypt,
  getSymmetricKey,
  signMsg,
  encrypt,
  decrypt,
  constructWeb3
};