diff --git a/packages/cactus-plugin-ledger-connector-fabric/src/main/json/openapi.json b/packages/cactus-plugin-ledger-connector-fabric/src/main/json/openapi.json index 3b058acea20..793826836a4 100644 --- a/packages/cactus-plugin-ledger-connector-fabric/src/main/json/openapi.json +++ b/packages/cactus-plugin-ledger-connector-fabric/src/main/json/openapi.json @@ -331,6 +331,16 @@ "params" ], "properties": { + "endorsingPeers": { + "description": "An array of MSP IDs to set as the list of endorsing peers for the transaction.", + "type": "array", + "items": { + "type": "string", + "minLength": 1, + "maxLength": 4096, + "nullable": false + } + }, "transientData": { "type": "object", "nullable": true diff --git a/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/generated/openapi/typescript-axios/api.ts b/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/generated/openapi/typescript-axios/api.ts index 7572dcd8c7b..a29c68fcf20 100644 --- a/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/generated/openapi/typescript-axios/api.ts +++ b/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/generated/openapi/typescript-axios/api.ts @@ -680,6 +680,12 @@ export interface InlineResponse501 { * @interface RunTransactionRequest */ export interface RunTransactionRequest { + /** + * An array of MSP IDs to set as the list of endorsing peers for the transaction. + * @type {Array} + * @memberof RunTransactionRequest + */ + endorsingPeers?: Array; /** * * @type {object} diff --git a/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/plugin-ledger-connector-fabric.ts b/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/plugin-ledger-connector-fabric.ts index 8a1b4a64c4b..85cae565132 100644 --- a/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/plugin-ledger-connector-fabric.ts +++ b/packages/cactus-plugin-ledger-connector-fabric/src/main/typescript/plugin-ledger-connector-fabric.ts @@ -3,6 +3,7 @@ import path from "path"; import { Server } from "http"; import { Server as SecureServer } from "https"; +import { Certificate } from "@fidm/x509"; import { Express } from "express"; import "multer"; import temp from "temp"; @@ -88,6 +89,7 @@ import { import { sourceLangToRuntimeLang } from "./peer/source-lang-to-runtime-lang"; import FabricCAServices from "fabric-ca-client"; import { createGateway } from "./common/create-gateway"; +import { Endorser } from "fabric-common"; /** * Constant value holding the default $GOPATH in the Fabric CLI container as @@ -916,7 +918,37 @@ export class PluginLedgerConnectorFabric break; } case FabricContractInvocationType.Send: { - out = await contract.submitTransaction(fnName, ...params); + const tx = contract.createTransaction(fnName); + if (req.endorsingPeers) { + const { endorsingPeers } = req; + const channel = network.getChannel(); + + const allChannelEndorsers = (channel.getEndorsers() as unknown) as Array< + Endorser & { options: { pem: string } } + >; + + const endorsers = allChannelEndorsers + .map((endorser) => { + const certificate = Certificate.fromPEM( + (endorser.options.pem as unknown) as Buffer, + ); + return { certificate, endorser }; + }) + .filter( + ({ endorser, certificate }) => + endorsingPeers.includes(endorser.mspid) || + endorsingPeers.includes(certificate.issuer.organizationName), + ) + .map((it) => it.endorser); + + this.log.debug( + "%o endorsers: %o", + endorsers.length, + endorsers.map((it) => `${it.mspid}:${it.name}`), + ); + tx.setEndorsingPeers(endorsers); + } + out = await tx.submit(...params); success = true; break; } diff --git a/packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/run-transaction-endpoint-v1.test.ts b/packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/run-transaction-endpoint-v1.test.ts index 47a66a6c229..aafca696fe5 100644 --- a/packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/run-transaction-endpoint-v1.test.ts +++ b/packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/run-transaction-endpoint-v1.test.ts @@ -231,6 +231,29 @@ test(testCase, async (t: Test) => { ); } + { + const req: RunTransactionRequest = { + signingCredential, + gatewayOptions: { + identity: keychainEntryKey, + wallet: { + json: keychainEntryValue, + }, + }, + channelName, + invocationType: FabricContractInvocationType.Send, + contractName, + methodName: "CreateAsset", + params: ["asset388", "green", "111", assetOwner, "299"], + endorsingPeers: ["org1.example.com", "Org2MSP"], + }; + + const res = await apiClient.runTransactionV1(req); + t.ok(res, "Create green asset response truthy OK"); + t.ok(res.data, "Create green asset response.data truthy OK"); + t.equal(res.status, 200, "Create green asset response.status=200 OK"); + } + { const res = await apiClient.runTransactionV1({ gatewayOptions: {