UNPKG

@siglesiasg/node-red-hyperledger-fabric-gateway

Version:

Hyperledger Fabric 2.x nodes for node-red with latest fabric-gateway library

234 lines 10.2 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.invokeChaincodeGeneric = exports.invokeChaincode = exports.closeConnection = exports.assertDefined = exports.getTransactionName = exports.buildGatewayConnection = exports.newIdentity = exports.newGrpcConnection = void 0; const grpc = __importStar(require("@grpc/grpc-js")); const fabric_gateway_1 = require("@hyperledger/fabric-gateway"); const buffer_1 = require("buffer"); const crypto = __importStar(require("crypto")); const fs_1 = require("fs"); const fabric_connection_pool_1 = require("./fabric-connection-pool"); const node_red_utils_1 = require("./node-red-utils"); async function newGrpcConnection(connectionConfig) { let tlsCredentials; if (connectionConfig.gateway.peer.tls) { const tlsRootCert = buffer_1.Buffer.from(buffer_1.Buffer.from(connectionConfig.gateway.peer.tls, 'base64').toString('utf8'), 'utf8'); tlsCredentials = grpc.credentials.createSsl(tlsRootCert); } else { tlsCredentials = grpc.credentials.createInsecure(); } return new grpc.Client(connectionConfig.gateway.peer.url, tlsCredentials, connectionConfig.gateway.peer.grpcOptions); } exports.newGrpcConnection = newGrpcConnection; async function newIdentity(connectionConfig) { let credentials; let privateKey; if (connectionConfig.identity.certType === 'embeded') { try { credentials = buffer_1.Buffer.from(buffer_1.Buffer.from(connectionConfig.identity.cert, 'base64').toString('utf8'), 'utf8'); const privateKeyPem = buffer_1.Buffer.from(connectionConfig.identity.privateKey, 'base64').toString('utf8'); privateKey = crypto.createPrivateKey(privateKeyPem); } catch (err) { throw new Error(`Unable to build identity from embeded cert. Are certs in base64?. ${err}`); } } else if (connectionConfig.identity.certType === 'files') { credentials = await fs_1.promises.readFile(connectionConfig.identity.certPath); const privateKeyPem = await fs_1.promises.readFile(connectionConfig.identity.privateKeyPath); privateKey = crypto.createPrivateKey(privateKeyPem); } else if (connectionConfig.identity.certType === 'microfab') { try { const dataufab = await fetch(connectionConfig.identity.microfabUrl + '/ak/api/v1/components'); const bodyJson = await dataufab.json(); const ufabIdentity = findCertById(bodyJson, connectionConfig.identity.microfabId); credentials = buffer_1.Buffer.from(buffer_1.Buffer.from(ufabIdentity.cert, 'base64').toString('utf8'), 'utf8'); const privateKeyPem = buffer_1.Buffer.from(ufabIdentity.private_key, 'base64').toString('utf8'); privateKey = crypto.createPrivateKey(privateKeyPem); } catch (err) { throw new Error(`Unable to build identity from microfab. ${err}`); } } else { throw new Error('Unable to get identity with cert type: ' + connectionConfig.identity.certType + '. Not implemented'); } return { identity: { mspId: connectionConfig.identity.mspId.mspId, credentials }, signer: fabric_gateway_1.signers.newPrivateKeySigner(privateKey) }; } exports.newIdentity = newIdentity; async function buildGatewayConnection(grpcClient, connectionConfig) { const identity = await newIdentity(connectionConfig); const options = { identity: identity.identity, signer: identity.signer, client: grpcClient, evaluateOptions: () => { return { deadline: Date.now() + 5000 }; }, endorseOptions: () => { return { deadline: Date.now() + 15000 }; }, submitOptions: () => { return { deadline: Date.now() + 5000 }; }, commitStatusOptions: () => { return { deadline: Date.now() + 60000 }; }, }; return (0, fabric_gateway_1.connect)(options); } exports.buildGatewayConnection = buildGatewayConnection; function getTransactionName(configTransaction, payload) { const payAsAny = payload; let transactionName; if (payAsAny && payAsAny.transactionName) { transactionName = payAsAny.transactionName; } else if (payAsAny && payAsAny.transaction?.name) { transactionName = payAsAny.transaction?.name; } else { transactionName = configTransaction; } if (!transactionName) { throw Error('Transaction name not defined in config nor payload'); } return transactionName; } exports.getTransactionName = getTransactionName; function assertDefined(value, message) { if (value === undefined) { throw new Error(message); } return value; } exports.assertDefined = assertDefined; async function closeConnection(connection, done) { try { await (0, fabric_connection_pool_1.closeGateway)(this, connection); this.status({ fill: 'grey', shape: 'dot', text: 'Closed' }); this.debug('Closed'); done(); } catch (error) { this.status({ fill: 'red', shape: 'dot', text: error }); done(); } } exports.closeConnection = closeConnection; async function invokeChaincode(RED, node, msg, decoder, actionType, connection, config) { const channelName = (0, node_red_utils_1.getConfigValidate)(RED, config.channelSelector).channel; const contractName = (0, node_red_utils_1.getConfigValidate)(RED, config.contractSelector).contract; const transactionName = getTransactionName(config.transaction, msg.payload); const proposal = getTransactionData(config.args, config.transientData, msg.payload); return await invokeChaincodeInternal(RED, node, msg, decoder, actionType, connection, channelName, contractName, transactionName, proposal); } exports.invokeChaincode = invokeChaincode; async function invokeChaincodeGeneric(RED, node, msg, decoder, actionType, connection, channelSelector, contractName, transactionName, args) { const fabricChannelDef = (0, node_red_utils_1.getConfigValidate)(RED, channelSelector); const proposal = { arguments: args }; return await invokeChaincodeInternal(RED, node, msg, decoder, actionType, connection, fabricChannelDef.channel, contractName, transactionName, proposal); } exports.invokeChaincodeGeneric = invokeChaincodeGeneric; async function invokeChaincodeInternal(RED, node, msg, decoder, actionType, connection, channelName, contractName, transactionName, proposal) { const gateway = await (0, fabric_connection_pool_1.getGateway)(node, connection); const network = gateway.getNetwork(channelName); const contract = network.getContract(contractName); let getResult; if (actionType === 'submit') { getResult = await contract.submit(transactionName, proposal); } else if (actionType === 'evaluate') { getResult = await contract.evaluate(transactionName, proposal); } else { throw new Error('Undefined action type: ' + actionType); } (0, node_red_utils_1.addResultToPayload)(RED, msg, transactionName, proposal, decoder(getResult)); } function getTransactionData(configArgs, configTransient, payload) { return { arguments: getTransactionArg(), transientData: getTransactionTransient() }; function getTransactionArg() { let transactionArgs; if (payload?.transaction?.args) { transactionArgs = payload.transaction.args; } else if (payload?.transaction) { transactionArgs = payload.transaction; } else if (configArgs) { try { transactionArgs = JSON.parse(configArgs); } catch (e) { throw new Error('Configuration Args is not an array! Check config'); } } else { transactionArgs = payload; } if (transactionArgs && !Array.isArray(transactionArgs)) { throw new Error('Configuration Args is not an array!. Check payload config.'); } return transactionArgs; } function getTransactionTransient() { let transientData; if (payload?.transaction?.transient) { transientData = payload.transaction.transient; } else if (configTransient) { try { transientData = JSON.parse(configTransient); } catch (e) { throw new Error('Transient args is not an object! Check config'); } } if (transientData && !Array.isArray(transientData)) { throw new Error('Transient args is not an array. Check payload.transaction.transient'); } return transientData; } } function findCertById(data, id) { try { for (const item of data) { if (item.id === id && item.type === 'identity') { return item; } } } catch (err) { throw new Error('Unable to get Identity from microfab. Id: ' + id + '. Error: ' + err); } throw new Error('Unable to get Identity from microfab. Id: ' + id); } //# sourceMappingURL=fabric-functions.js.map