{"size": 1965, "ext": "js", "max_stars_repo_path": "lib/utils/transaction/buildDocument.js", "max_stars_repo_name": "phys3/api", "max_stars_repo_stars_event_min_datetime": null, "max_stars_repo_stars_event_max_datetime": null, "max_issues_repo_path": "lib/utils/transaction/buildDocument.js", "max_issues_repo_name": "phys3/api", "max_issues_repo_issues_event_min_datetime": "2021-07-19T23:18:28.000Z", "max_issues_repo_issues_event_max_datetime": "2022-03-08T22:08:06.000Z", "max_forks_repo_path": "lib/utils/transaction/buildDocument.js", "max_forks_repo_name": "phys3/api", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": null, "max_issues_count": 4, "max_forks_count": null, "avg_line_length": 25.8552631579, "max_line_length": 77, "alphanum_fraction": 0.6575063613}
'use strict'

const crypto = require('crypto')
const stringify = require('json-stable-stringify')

const validateDocument = require('./validateDocument')
const convertMapToArray = require('../convertMapToArray')
const createHash = require('@webwallet/cryptools').hashing.create

class TransactionDocument {
  constructor({hash = {}, data = {}, meta = {}} = {}, params = {}) {
    let {inputs = [], outputs = []} = data
    let inputHashes = inputs.map(input => ({hash: input.hash.value}))
    outputs = outputs instanceof Array ? outputs : convertMapToArray(outputs)

    this.properties = {
      hash,
      data: {inputs: inputHashes, outputs},
      meta
    }
    this.properties.meta.inputs = inputs
    this.parameters = params
  }
  get id() {
    return this.properties.hash.value
  }
  set data(data) {
    this.properties.data = data
    return this.hash()
  }
  get data() {
    return this.properties.data
  }
  get meta() {
    return this.properties.meta
  }
  update(property, value) {
    this.properties.data[property] = value
    return this.hash()
  }
  validate() {
    return validateDocument.call(this)
  }
  hash({algorithms = 'sha256:sha256'} = {}) {
    let data = stringify(this.data)
    let encodings = ['utf8']

    this.properties.hash.types = algorithms
    this.properties.hash.steps = 'stringify:data'
    this.properties.hash.value = createHash({data, algorithms, encodings})

    return this
  }
  sign(keys = []) {
    this.properties.meta.signatures = []
    this.parameters.keys = keys
    for (let key of keys) {
      let signature = /*generate signature*/{}
      this.properties.meta.signatures.push(signature)
    }
    // Object.freeze(this.properties)
    return this
  }
  get content() {
    return this.properties
  }
}

function buildDocument(data = {}, params = {}) {
  let document = new TransactionDocument({data}, params)

  return document.hash(params.hash).sign(params.keys)
}

module.exports = buildDocument
