github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-supply-chain-master/fish_client/src/services/payloads.js (about)

     1  /**
     2   * Copyright 2017 Intel Corporation
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   * ----------------------------------------------------------------------------
    16   */
    17  'use strict'
    18  
    19  const _ = require('lodash')
    20  const protobuf = require('protobufjs')
    21  
    22  // Use the generated JSON to reference the .proto files in protos/
    23  const protoJson = require('../generated_protos.json')
    24  
    25  // Keys for payload actions
    26  const ACTIONS = [
    27    'CREATE_AGENT',
    28    'CREATE_RECORD',
    29    'FINALIZE_RECORD',
    30    'CREATE_RECORD_TYPE',
    31    'UPDATE_PROPERTIES',
    32    'CREATE_PROPOSAL',
    33    'ANSWER_PROPOSAL',
    34    'REVOKE_REPORTER'
    35  ]
    36  
    37  // Create dictionary with key, enum and class names
    38  const titleify = allCaps => {
    39    return allCaps
    40      .split('_')
    41      .map(word => word[0] + word.slice(1).toLowerCase())
    42      .join('')
    43  }
    44  
    45  const actionMap = ACTIONS.reduce((map, enumName) => {
    46    const key = enumName[0].toLowerCase() + titleify(enumName).slice(1)
    47    const className = titleify(enumName) + 'Action'
    48    return _.set(map, key, { enum: enumName, name: className })
    49  }, {})
    50  
    51  // Compile Protobufs
    52  const root = protobuf.Root.fromJSON(protoJson)
    53  const SCPayload = root.lookup('SCPayload')
    54  const PropertyValue = root.lookup('PropertyValue')
    55  const PropertySchema = root.lookup('PropertySchema')
    56  const Location = root.lookup('Location')
    57  const Proposal = root.lookup('Proposal')
    58  _.map(actionMap, action => {
    59    return _.set(action, 'proto', root.lookup(action.name))
    60  })
    61  
    62  // Create data xforms on an action by action basis
    63  const propertiesXformer = xform => data => {
    64    return _.set(data, 'properties', data.properties.map(xform))
    65  }
    66  const valueXform = propertiesXformer(prop => PropertyValue.create(prop))
    67  const schemaXform = propertiesXformer(prop => {
    68    if (prop.locationValue) {
    69      prop.locationValue = Location.create(prop.locationValue)
    70    }
    71    return PropertySchema.create(prop)
    72  })
    73  
    74  _.map(actionMap, action => _.set(action, 'xform', x => x))
    75  actionMap.createRecord.xform = valueXform
    76  actionMap.createRecordType.xform = schemaXform
    77  actionMap.updateProperties.xform = valueXform
    78  
    79  /**
    80   * Encodes a new SCPayload with the specified action
    81   */
    82  const encode = (actionKey, actionData) => {
    83    const action = actionMap[actionKey]
    84    if (!action) {
    85      throw new Error('There is no payload action with that key')
    86    }
    87  
    88    return SCPayload.encode({
    89      action: SCPayload.Action[action.enum],
    90      timestamp: Math.floor(Date.now() / 1000),
    91      [actionKey]: action.proto.create(action.xform(actionData))
    92    }).finish()
    93  }
    94  
    95  /**
    96   * Particular encode methods can be called directly with their key name
    97   * For example: payloads.createAgent({name: 'Susan'})
    98   */
    99  const actionMethods = _.reduce(actionMap, (methods, value, key) => {
   100    return _.set(methods, key, _.partial(encode, key))
   101  }, {})
   102  
   103  // Add enums on an action by action basis
   104  actionMethods.createRecord.enum = PropertySchema.DataType
   105  actionMethods.createRecordType.enum = PropertySchema.DataType
   106  actionMethods.updateProperties.enum = PropertySchema.DataType
   107  actionMethods.createProposal.enum = Proposal.Role
   108  actionMethods.answerProposal.enum = actionMap.answerProposal.proto.Response
   109  
   110  module.exports = _.assign({
   111    encode,
   112    FLOAT_PRECISION: 1000000
   113  }, actionMethods)