@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
JavaScript
;
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