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)