From ad241ba2f9c0dd7f3e566f7b24cca5694725b1ac Mon Sep 17 00:00:00 2001 From: Eduardo Vasques Date: Wed, 27 Nov 2024 17:04:23 +0000 Subject: [PATCH] fix(satp): make satp a cacti plugin * changed cbdc example to use cacti api-server * added test to test the compatibility * TODO: check OAS (detailed comment in main plugin) Signed-off-by: Eduardo Vasques --- .../process.env | 4 +- .../src/main/typescript/cbdc-bridging-app.ts | 147 +-- .../cbdc-bridging-app-dummy-infrastructure.ts | 18 +- .../package.json | 2 +- .../src/api-calls/gateway-api.tsx | 3 +- .../cactus-plugin-satp-hermes/package.json | 1 + .../typescript/plugin-satp-hermes-gateway.ts | 42 +- .../integration/gateway-init-startup.test.ts | 57 +- ...-end-transfer-1-gateway-api-server.test.ts | 1139 +++++++++++++++++ yarn.lock | 520 +------- 10 files changed, 1324 insertions(+), 609 deletions(-) create mode 100644 packages/cactus-plugin-satp-hermes/src/test/typescript/integration/satp-end-to-end-transfer-1-gateway-api-server.test.ts diff --git a/examples/cactus-example-cbdc-bridging-backend/process.env b/examples/cactus-example-cbdc-bridging-backend/process.env index 1e16235f2a..d27777e61a 100644 --- a/examples/cactus-example-cbdc-bridging-backend/process.env +++ b/examples/cactus-example-cbdc-bridging-backend/process.env @@ -1,8 +1,8 @@ API_HOST=localhost API_SERVER_1_PORT=4000 API_SERVER_2_PORT=4100 -API_GATEWAY_1_BLO_PORT=4010 -API_GATEWAY_2_BLO_PORT=4110 +API_GATEWAY_1_BLO_PORT=4000 +API_GATEWAY_2_BLO_PORT=4100 API_GATEWAY_1_CLIENT_PORT=3011 API_GATEWAY_2_CLIENT_PORT=3111 API_GATEWAY_1_SERVER_PORT=3010 diff --git a/examples/cactus-example-cbdc-bridging-backend/src/main/typescript/cbdc-bridging-app.ts b/examples/cactus-example-cbdc-bridging-backend/src/main/typescript/cbdc-bridging-app.ts index 56b80a015a..2592a754a4 100644 --- a/examples/cactus-example-cbdc-bridging-backend/src/main/typescript/cbdc-bridging-app.ts +++ b/examples/cactus-example-cbdc-bridging-backend/src/main/typescript/cbdc-bridging-app.ts @@ -1,8 +1,10 @@ import { AddressInfo } from "net"; import exitHook, { IAsyncExitHookDoneCallback } from "async-exit-hook"; import { PluginRegistry } from "@hyperledger/cactus-core"; +import { v4 as uuidv4 } from "uuid"; +import CryptoMaterial from "../../crypto-material/crypto-material.json"; + import { - IListenOptions, LogLevelDesc, Logger, LoggerProvider, @@ -21,13 +23,9 @@ import { import { CbdcBridgingAppDummyInfrastructure } from "./infrastructure/cbdc-bridging-app-dummy-infrastructure"; import { DefaultApi as FabricApi } from "@hyperledger/cactus-plugin-ledger-connector-fabric"; import { DefaultApi as BesuApi } from "@hyperledger/cactus-plugin-ledger-connector-besu"; -import express from "express"; -import bodyParser from "body-parser"; -import http, { Server } from "http"; -import { Constants } from "@hyperledger/cactus-core-api"; -import cors from "cors"; +import { Server } from "http"; -import { Server as SocketIoServer } from "socket.io"; +import { PluginKeychainMemory } from "@hyperledger/cactus-plugin-keychain-memory"; export interface ICbdcBridgingApp { apiHost: string; @@ -92,49 +90,57 @@ export class CbdcBridgingApp { await this.infrastructure.createFabricLedgerConnector(); this.log.info("Creating Besu Connector"); const besuPlugin = await this.infrastructure.createBesuLedgerConnector(); + const gatways = await this.infrastructure.createSATPGateways(); - let addressInfoA: AddressInfo; - let addressInfoB: AddressInfo; + this.log.info(`SATP Gateways started.`); // Reserve the ports where the API Servers will run - { - const expressApp = express(); - expressApp.use(cors()); - expressApp.use(bodyParser.json({ limit: "250mb" })); - const fabricServer = http.createServer(expressApp); - - const listenOptions: IListenOptions = { - hostname: this.options.apiHost, - port: this.options.apiServer1Port, - server: fabricServer, - }; - addressInfoA = (await Servers.listen(listenOptions)) as AddressInfo; - - await fabricPlugin.getOrCreateWebServices(); - await fabricPlugin.registerWebServices(expressApp); - } - - { - const expressApp = express(); - expressApp.use(bodyParser.json({ limit: "250mb" })); - expressApp.use(cors()); - const besuServer = http.createServer(expressApp); - const listenOptions: IListenOptions = { - hostname: this.options.apiHost, - port: this.options.apiServer2Port, - server: besuServer, - }; - addressInfoB = (await Servers.listen(listenOptions)) as AddressInfo; - await besuPlugin.getOrCreateWebServices(); - const wsApi = new SocketIoServer(besuServer, { - path: Constants.SocketIoConnectionPathV1, - }); - await besuPlugin.registerWebServices(expressApp, wsApi); - } - + const httpApiA = await Servers.startOnPort( + this.options.apiServer1Port, + this.options.apiHost, + ); + const httpApiB = await Servers.startOnPort( + this.options.apiServer2Port, + this.options.apiHost, + ); + const addressInfoA = httpApiA.address() as AddressInfo; const nodeApiHostA = `http://${this.options.apiHost}:${addressInfoA.port}`; + + const addressInfoB = httpApiB.address() as AddressInfo; const nodeApiHostB = `http://${this.options.apiHost}:${addressInfoB.port}`; + const clientPluginRegistry = new PluginRegistry({ + plugins: [ + new PluginKeychainMemory({ + keychainId: CryptoMaterial.keychains.keychain1.id, + instanceId: uuidv4(), + logLevel: "INFO", + }), + ], + }); + const serverPluginRegistry = new PluginRegistry({ + plugins: [ + new PluginKeychainMemory({ + keychainId: CryptoMaterial.keychains.keychain2.id, + instanceId: uuidv4(), + logLevel: "INFO", + }), + ], + }); + + clientPluginRegistry.add(fabricPlugin); + clientPluginRegistry.add(gatways[0]); + await gatways[0].onPluginInit(); + serverPluginRegistry.add(besuPlugin); + serverPluginRegistry.add(gatways[1]); + await gatways[1].onPluginInit(); + + const crpcOptionsServer1 = {host: 'localhost', port: 6000}; + const apiServer1 = await this.startNode(httpApiA, clientPluginRegistry, crpcOptionsServer1, 5101); + const crpcOptionsServer2 = {host: 'localhost', port: 6001}; + + const apiServer2 = await this.startNode(httpApiB, serverPluginRegistry,crpcOptionsServer2, 5100); + const fabricApiClient = new FabricApi( new Configuration({ basePath: nodeApiHostA }), ); @@ -158,13 +164,7 @@ export class CbdcBridgingApp { this.log.info(`Chaincode and smart Contracts deployed.`); - const gatways = await this.infrastructure.createSATPGateways(); - - for (const gateway of gatways) { - await gateway.startup(); - } - - this.log.info(`SATP Gateways started.`); + return { fabricApiClient, @@ -186,33 +186,36 @@ export class CbdcBridgingApp { httpServerApi: Server, pluginRegistry: PluginRegistry, crpcOptions: ICrpcOptions, + grpcPort: number, ): Promise { this.log.info(`Starting API Server node...`); const addressInfoApi = httpServerApi.address() as AddressInfo; - let config; - if (this.options.apiServerOptions) { - config = this.options.apiServerOptions; - } else { - const configService = new ConfigService(); - const convictConfig = await configService.getOrCreate(); - config = convictConfig.getProperties(); - config.configFile = ""; - config.apiCorsDomainCsv = `http://${process.env.API_HOST_FRONTEND}:${process.env.API_PORT_FRONTEND}`; - config.cockpitCorsDomainCsv = `http://${process.env.API_HOST_FRONTEND}:${process.env.API_PORT_FRONTEND}`; - config.apiPort = addressInfoApi.port; - config.apiHost = addressInfoApi.address; - config.grpcPort = 0; - config.logLevel = this.options.logLevel || "INFO"; - config.authorizationProtocol = AuthorizationProtocol.NONE; - config.crpcHost = crpcOptions.host; - config.crpcPort = crpcOptions.port; - } - + + + const configService = new ConfigService(); + const apiServerOptions = await configService.newExampleConfig(); + apiServerOptions.authorizationProtocol = AuthorizationProtocol.NONE; + apiServerOptions.configFile = ""; + apiServerOptions.apiCorsDomainCsv = "*"; + apiServerOptions.apiPort = addressInfoApi.port; + apiServerOptions.apiHost = addressInfoApi.address; + apiServerOptions.logLevel = this.options.logLevel || "INFO"; + apiServerOptions.apiTlsEnabled = false; + apiServerOptions.grpcPort = grpcPort; + apiServerOptions.crpcHost = crpcOptions.host; + apiServerOptions.crpcPort = crpcOptions.port; + const config = + await configService.newExampleConfigConvict(apiServerOptions); + const prop = config.getProperties(); + prop.grpcPort = grpcPort + prop.apiPort = addressInfoApi.port; + prop.crpcPort = crpcOptions.port; + this.log.info(prop); const apiServer = new ApiServer({ - config, - httpServerApi, + httpServerApi: httpServerApi, + config: prop, pluginRegistry, }); diff --git a/examples/cactus-example-cbdc-bridging-backend/src/main/typescript/infrastructure/cbdc-bridging-app-dummy-infrastructure.ts b/examples/cactus-example-cbdc-bridging-backend/src/main/typescript/infrastructure/cbdc-bridging-app-dummy-infrastructure.ts index b8e2543ab6..bb5b045f67 100644 --- a/examples/cactus-example-cbdc-bridging-backend/src/main/typescript/infrastructure/cbdc-bridging-app-dummy-infrastructure.ts +++ b/examples/cactus-example-cbdc-bridging-backend/src/main/typescript/infrastructure/cbdc-bridging-app-dummy-infrastructure.ts @@ -75,6 +75,7 @@ import { GetAmountApprovedEndpointV1 } from "../web-services/get-amount-approved import { AdminApi, TransactionApi, + TransactRequest, } from "@hyperledger/cactus-plugin-satp-hermes/src/main/typescript/generated/gateway-client/typescript-axios/api"; import { ClaimFormat } from "@hyperledger/cactus-plugin-satp-hermes/src/main/typescript/generated/proto/cacti/satp/v02/common/message_pb"; @@ -399,7 +400,7 @@ export class CbdcBridgingAppDummyInfrastructure { address: `http://localhost`, gatewayServerPort: 3010, gatewayClientPort: 3011, - gatewayOpenAPIPort: 4010, + gatewayOpenAPIPort: 4000, } as GatewayIdentity; const besuGatewayIdentity = { @@ -411,7 +412,7 @@ export class CbdcBridgingAppDummyInfrastructure { address: `http://localhost`, gatewayServerPort: 3110, gatewayClientPort: 3111, - gatewayOpenAPIPort: 4110, + gatewayOpenAPIPort: 4100, } as GatewayIdentity; const pluginBungeeFabricOptions = { @@ -472,7 +473,7 @@ export class CbdcBridgingAppDummyInfrastructure { address: `http://localhost`, gatewayServerPort: 3010, gatewayClientPort: 3011, - gatewayOpenAPIPort: 4010, + gatewayOpenAPIPort: 4000, pubKey: bufArray2HexStr(fabricGatewayKeyPair.publicKey), } as GatewayIdentity, ], @@ -494,7 +495,7 @@ export class CbdcBridgingAppDummyInfrastructure { address: `http://localhost`, gatewayServerPort: 3110, gatewayClientPort: 3111, - gatewayOpenAPIPort: 4110, + gatewayOpenAPIPort: 4100, pubKey: bufArray2HexStr(besuGatewayKeyPair.publicKey), } as GatewayIdentity, ], @@ -1256,7 +1257,7 @@ export class CbdcBridgingAppDummyInfrastructure { } try { - await api.transact({ + const request: TransactRequest = { contextID: "MockID", fromDLTNetworkID, toDLTNetworkID, @@ -1265,11 +1266,12 @@ export class CbdcBridgingAppDummyInfrastructure { originatorPubkey: senderAddress, beneficiaryPubkey: receiverAddress, sourceAsset, - receiverAsset: receiverAsset, - }); + receiverAsset, + } + await api.transact(request); } catch (error) { this.log.error( - `Error bridging tokens from ${sourceChain} to ${receiverAsset}`, + `Error bridging tokens from ${sourceChain} to ${destinationChain}`, ); throw error; } diff --git a/examples/cactus-example-cbdc-bridging-frontend/package.json b/examples/cactus-example-cbdc-bridging-frontend/package.json index 6d2465c180..59000daed0 100644 --- a/examples/cactus-example-cbdc-bridging-frontend/package.json +++ b/examples/cactus-example-cbdc-bridging-frontend/package.json @@ -38,7 +38,7 @@ "dependencies": { "@emotion/react": "11.11.1", "@emotion/styled": "11.11.0", - "@hyperledger/cactus-example-cbdc-bridging-backend": "2.0.0-rc.7", + "@hyperledger/cactus-example-cbdc-bridging-backend": "2.0.0", "@mui/icons-material": "6.1.1", "@mui/material": "6.1.1", "@testing-library/jest-dom": "5.17.0", diff --git a/examples/cactus-example-cbdc-bridging-frontend/src/api-calls/gateway-api.tsx b/examples/cactus-example-cbdc-bridging-frontend/src/api-calls/gateway-api.tsx index ed45477537..43557e205a 100644 --- a/examples/cactus-example-cbdc-bridging-frontend/src/api-calls/gateway-api.tsx +++ b/examples/cactus-example-cbdc-bridging-frontend/src/api-calls/gateway-api.tsx @@ -3,6 +3,7 @@ import { SessionReference } from "@hyperledger/cactus-example-cbdc-bridging-back import { GetSessionsReferencesApi, TransactApi, + TransactRequest, } from "@hyperledger/cactus-example-cbdc-bridging-backend/src/main/typescript/generated/openapi/typescript-axios/api"; import { Configuration } from "@hyperledger/cactus-example-cbdc-bridging-backend/src/main/typescript/generated/openapi/typescript-axios/configuration"; @@ -55,7 +56,7 @@ export async function transactTokens( assetType: receiverChain, }, amount, - }); + } as TransactRequest); if (response.status !== 200) { throw Error(response.status + " :" + response.data); diff --git a/packages/cactus-plugin-satp-hermes/package.json b/packages/cactus-plugin-satp-hermes/package.json index 244474a1ed..9065632979 100644 --- a/packages/cactus-plugin-satp-hermes/package.json +++ b/packages/cactus-plugin-satp-hermes/package.json @@ -153,6 +153,7 @@ "@bufbuild/buf": "^1.47.2", "@bufbuild/protoc-gen-es": "2.2.2", "@grpc/proto-loader": "0.7.13", + "@hyperledger/cactus-api-client": "2.0.0", "@hyperledger/cactus-test-geth-ledger": "2.0.0-rc.7", "@quobix/vacuum": "0.9.16", "@types/body-parser": "1.19.4", diff --git a/packages/cactus-plugin-satp-hermes/src/main/typescript/plugin-satp-hermes-gateway.ts b/packages/cactus-plugin-satp-hermes/src/main/typescript/plugin-satp-hermes-gateway.ts index 520311b98c..4b2cda6d96 100644 --- a/packages/cactus-plugin-satp-hermes/src/main/typescript/plugin-satp-hermes-gateway.ts +++ b/packages/cactus-plugin-satp-hermes/src/main/typescript/plugin-satp-hermes-gateway.ts @@ -206,11 +206,11 @@ export class SATPGateway implements IPluginWebService, ICactusPlugin { return this.BLOApplication; } - public async onPluginInit(): Promise { + public async onPluginInit(): Promise { const fnTag = `${this.className}#onPluginInit()`; this.logger.trace(`Entering ${fnTag}`); // resolve gateways on init - throw new Error("Not implemented"); + await Promise.all([this.startupGOLServer()]); } /* IPluginWebService methods */ @@ -220,6 +220,7 @@ export class SATPGateway implements IPluginWebService, ICactusPlugin { this.logger.debug(`Registering service ${ws.getPath()}`); ws.registerExpress(app); }); + this.BLOApplication = app; return webServices; } @@ -229,7 +230,13 @@ export class SATPGateway implements IPluginWebService, ICactusPlugin { if (!this.BLODispatcher) { throw new Error(`Cannot ${fnTag} because BLODispatcher is erroneous`); } - return this.BLODispatcher?.getOrCreateWebServices(); + let webServices = await this.BLODispatcher?.getOrCreateWebServices(); + if (this.OAPIServerEnabled) { + webServices = webServices.concat( + await this.BLODispatcher?.getOrCreateOAPIWebServices(), + ); + } + return webServices; } /* Getters */ @@ -251,7 +258,13 @@ export class SATPGateway implements IPluginWebService, ICactusPlugin { } public getOpenApiSpec(): unknown { - return this.OAS; + return undefined; //this.OAS; + + /* + This needs to be fixed. api-server installs some validation middleware using this + and it was breaking the integration of the plugin with the api-server. + Error: 404 not found - on all api requests when the middleware is installed. + */ } // TODO: keep getter; add an admin endpoint to get identity of connected gateway to BLO @@ -535,7 +548,7 @@ export class SATPGateway implements IPluginWebService, ICactusPlugin { this.logger.info("Shutting down Node server - BOL"); await this.shutdownBLOServer(); - + await this.shutdownGOLServer(); this.logger.debug("Running shutdown hooks"); for (const hook of this.shutdownHooks) { this.logger.debug(`Running shutdown hook: ${hook.name}`); @@ -555,7 +568,6 @@ export class SATPGateway implements IPluginWebService, ICactusPlugin { this.logger.debug(`Entering ${fnTag}`); if (this.BLOServer) { try { - await this.GOLServer?.close(); await this.BLOServer.closeAllConnections(); await this.BLOServer.close(); this.BLOServer = undefined; @@ -569,4 +581,22 @@ export class SATPGateway implements IPluginWebService, ICactusPlugin { this.logger.warn("Server is not running."); } } + + private async shutdownGOLServer(): Promise { + const fnTag = `${this.className}#shutdownBLOServer()`; + this.logger.debug(`Entering ${fnTag}`); + if (this.GOLServer) { + try { + await this.GOLServer?.close(); + await this.GOLServer?.closeAllConnections(); + this.logger.info("GOL server shut down"); + } catch (error) { + this.logger.error( + `Error shutting down the gatewayApplication: ${error}`, + ); + } + } else { + this.logger.warn("Server is not running."); + } + } } diff --git a/packages/cactus-plugin-satp-hermes/src/test/typescript/integration/gateway-init-startup.test.ts b/packages/cactus-plugin-satp-hermes/src/test/typescript/integration/gateway-init-startup.test.ts index 085a2644c5..eb3987c989 100644 --- a/packages/cactus-plugin-satp-hermes/src/test/typescript/integration/gateway-init-startup.test.ts +++ b/packages/cactus-plugin-satp-hermes/src/test/typescript/integration/gateway-init-startup.test.ts @@ -3,7 +3,18 @@ import { Containers, pruneDockerAllIfGithubAction, } from "@hyperledger/cactus-test-tooling"; -import { LogLevelDesc, LoggerProvider } from "@hyperledger/cactus-common"; +import { + LogLevelDesc, + LoggerProvider, + Servers, +} from "@hyperledger/cactus-common"; +import { + ApiServer, + AuthorizationProtocol, + ConfigService, +} from "@hyperledger/cactus-cmd-api-server"; +import { ApiClient } from "@hyperledger/cactus-api-client"; + // import coordinator factory, coordinator and coordinator options import { SATPGateway, @@ -11,6 +22,7 @@ import { } from "../../../main/typescript/plugin-satp-hermes-gateway"; import { PluginFactorySATPGateway } from "../../../main/typescript/factory/plugin-factory-gateway-orchestrator"; import { + Configuration, IPluginFactoryOptions, PluginImportType, } from "@hyperledger/cactus-core-api"; @@ -26,6 +38,9 @@ import { SATP_CORE_VERSION, SATP_CRASH_VERSION, } from "../../../main/typescript/core/constants"; +import { AddressInfo } from "net"; +import { PluginRegistry } from "@hyperledger/cactus-core"; +import { AdminApi } from "../../../main/typescript"; const logLevel: LogLevelDesc = "DEBUG"; const logger = LoggerProvider.getOrCreate({ @@ -290,6 +305,7 @@ describe("SATPGateway startup", () => { gatewayOpenAPIPort: 4010, address: "http://localhost", }, + enableOpenAPI: true, }; const gateway = await factory.create(options); expect(gateway).toBeInstanceOf(SATPGateway); @@ -298,8 +314,43 @@ describe("SATPGateway startup", () => { expect(identity.gatewayServerPort).toBe(13010); expect(identity.gatewayClientPort).toBe(13011); expect(identity.address).toBe("http://localhost"); - await gateway.startup(); - await gateway.shutdown(); + const httpServer2 = await Servers.startOnPreferredPort( + DEFAULT_PORT_GATEWAY_API, + ); + const addressInfo1 = httpServer2.address() as AddressInfo; + const node1Host = `http://${addressInfo1.address}:${addressInfo1.port}`; + const pluginRegistry = new PluginRegistry({ plugins: [] }); + + const configService = new ConfigService(); + const apiServerOptions = await configService.newExampleConfig(); + apiServerOptions.authorizationProtocol = AuthorizationProtocol.NONE; + apiServerOptions.configFile = ""; + apiServerOptions.apiCorsDomainCsv = "*"; + apiServerOptions.apiPort = addressInfo1.port; + apiServerOptions.cockpitPort = 0; + apiServerOptions.grpcPort = 0; + apiServerOptions.crpcPort = 0; + apiServerOptions.apiTlsEnabled = false; + const config = + await configService.newExampleConfigConvict(apiServerOptions); + pluginRegistry.add(gateway); + await gateway.onPluginInit(); + const apiServer1 = new ApiServer({ + httpServerApi: httpServer2, + config: config.getProperties(), + pluginRegistry, + }); + + await apiServer1.start(); + const config1 = new Configuration({ basePath: node1Host }); + const mainApiClient = new ApiClient(config1); + const admin = mainApiClient.extendWith(AdminApi); + + const result = await admin.getSessionIds(); + expect(result).toBeDefined(); + expect(result.status).toBe(200); + apiServer1.shutdown(); + httpServer2.close(); }); }); diff --git a/packages/cactus-plugin-satp-hermes/src/test/typescript/integration/satp-end-to-end-transfer-1-gateway-api-server.test.ts b/packages/cactus-plugin-satp-hermes/src/test/typescript/integration/satp-end-to-end-transfer-1-gateway-api-server.test.ts new file mode 100644 index 0000000000..66da8720ab --- /dev/null +++ b/packages/cactus-plugin-satp-hermes/src/test/typescript/integration/satp-end-to-end-transfer-1-gateway-api-server.test.ts @@ -0,0 +1,1139 @@ +import "jest-extended"; + +import { + IListenOptions, + LogLevelDesc, + LoggerProvider, + Secp256k1Keys, + Servers, +} from "@hyperledger/cactus-common"; +import { v4 as uuidv4 } from "uuid"; + +import { PluginRegistry } from "@hyperledger/cactus-core"; +import { PluginKeychainMemory } from "@hyperledger/cactus-plugin-keychain-memory"; +import { + ChainCodeProgrammingLanguage, + Configuration, + DefaultEventHandlerStrategy, + FabricSigningCredential, + FileBase64, + IPluginLedgerConnectorFabricOptions, + PluginLedgerConnectorFabric, + DefaultApi as FabricApi, + FabricContractInvocationType, +} from "@hyperledger/cactus-plugin-ledger-connector-fabric"; +import http, { Server } from "http"; +import fs from "fs-extra"; + +import { + pruneDockerAllIfGithubAction, + Containers, + FabricTestLedgerV1, + BesuTestLedger, + FABRIC_25_LTS_AIO_FABRIC_VERSION, + FABRIC_25_LTS_AIO_IMAGE_VERSION, + FABRIC_25_LTS_FABRIC_SAMPLES_ENV_INFO_ORG_1, + FABRIC_25_LTS_FABRIC_SAMPLES_ENV_INFO_ORG_2, +} from "@hyperledger/cactus-test-tooling"; +import bodyParser from "body-parser"; +import express from "express"; +import { DiscoveryOptions, X509Identity } from "fabric-network"; +import { AddressInfo } from "net"; +import path from "path"; +import { + BesuConfig, + FabricConfig, +} from "../../../main/typescript/types/blockchain-interaction"; +import { IPluginBungeeHermesOptions } from "@hyperledger/cactus-plugin-bungee-hermes"; +import { Account } from "web3-core"; +import { + EthContractInvocationType, + IPluginLedgerConnectorBesuOptions, + PluginLedgerConnectorBesu, + ReceiptType, + Web3SigningCredentialType, +} from "@hyperledger/cactus-plugin-ledger-connector-besu"; +import Web3 from "web3"; +import SATPContract from "../../solidity/generated/satp-erc20.sol/SATPContract.json"; +import SATPWrapperContract from "../../../solidity/generated/satp-wrapper.sol/SATPWrapperContract.json"; +import { + SATPGatewayConfig, + SATPGateway, + PluginFactorySATPGateway, + TransactRequest, + Asset, + TransactionApi, +} from "../../../main/typescript"; +import { + Address, + GatewayIdentity, + SupportedChain, +} from "../../../main/typescript/core/types"; +import { + IPluginFactoryOptions, + PluginImportType, +} from "@hyperledger/cactus-core-api"; +import FabricSATPInteraction from "../../../test/typescript/fabric/satp-erc20-interact.json"; +import BesuSATPInteraction from "../../solidity/satp-erc20-interact.json"; +import { ClaimFormat } from "../../../main/typescript/generated/proto/cacti/satp/v02/common/message_pb"; +import { + ApiServer, + AuthorizationProtocol, + ConfigService, +} from "@hyperledger/cactus-cmd-api-server"; + +const logLevel: LogLevelDesc = "DEBUG"; +const log = LoggerProvider.getOrCreate({ + level: logLevel, + label: "BUNGEE - Hermes", +}); + +let fabricServer: Server; + +let besuLedger: BesuTestLedger; + +let fabricLedger: FabricTestLedgerV1; +let fabricSigningCredential: FabricSigningCredential; +let bridgeFabricSigningCredential: FabricSigningCredential; +let configFabric: Configuration; +let fabricChannelName: string; + +const FABRIC_ASSET_ID = uuidv4(); + +const BRIDGE_ID = + "x509::/OU=org2/OU=client/OU=department1/CN=bridge::/C=UK/ST=Hampshire/L=Hursley/O=org2.example.com/CN=ca.org2.example.com"; + +let clientId: string; +let fabricConfig: FabricConfig; +let pluginBungeeFabricOptions: IPluginBungeeHermesOptions; + +let erc20TokenContract: string; +let contractNameWrapper: string; + +let rpcApiHttpHost: string; +let rpcApiWsHost: string; +let web3: Web3; +let firstHighNetWorthAccount: string; +let testing_connector: PluginLedgerConnectorBesu; +let besuKeyPair: { privateKey: string }; +let bridgeEthAccount: Account; +let assigneeEthAccount: Account; +const BESU_ASSET_ID = uuidv4(); +let assetContractAddress: string; +let wrapperContractAddress: string; +let satpContractName: string; + +let pluginBungeeBesuOptions: IPluginBungeeHermesOptions; + +let besuConfig: BesuConfig; +let besuOptions: IPluginLedgerConnectorBesuOptions; +let apiServer: ApiServer; +let keychainPlugin1: PluginKeychainMemory; +let keychainPlugin2: PluginKeychainMemory; +let fabricUser: X509Identity; + +let apiClient: FabricApi; + +afterAll(async () => { + await besuLedger.stop(); + await besuLedger.destroy(); + await fabricLedger.stop(); + await fabricLedger.destroy(); + await apiServer.shutdown(); + await Servers.shutdown(fabricServer); + + await pruneDockerAllIfGithubAction({ logLevel }) + .then(() => { + log.info("Pruning throw OK"); + }) + .catch(async () => { + await Containers.logDiagnostics({ logLevel }); + fail("Pruning didn't throw OK"); + }); +}); + +beforeAll(async () => { + pruneDockerAllIfGithubAction({ logLevel }) + .then(() => { + log.info("Pruning throw OK"); + }) + .catch(async () => { + await Containers.logDiagnostics({ logLevel }); + fail("Pruning didn't throw OK"); + }); + { + besuLedger = new BesuTestLedger({ + logLevel, + emitContainerLogs: true, + envVars: ["BESU_NETWORK=dev"], + }); + await besuLedger.start(); + + // Fabric ledger connection + const channelId = "mychannel"; + fabricChannelName = channelId; + + fabricLedger = new FabricTestLedgerV1({ + emitContainerLogs: true, + publishAllPorts: true, + imageName: "ghcr.io/hyperledger/cactus-fabric2-all-in-one", + imageVersion: FABRIC_25_LTS_AIO_IMAGE_VERSION, + envVars: new Map([["FABRIC_VERSION", FABRIC_25_LTS_AIO_FABRIC_VERSION]]), + logLevel: "INFO", + }); + + await fabricLedger.start(); + + log.info("Both Ledgers started successfully"); + } + + { + // setup fabric ledger + const connectionProfile = await fabricLedger.getConnectionProfileOrg1(); + expect(connectionProfile).not.toBeUndefined(); + + const bridgeProfile = await fabricLedger.getConnectionProfileOrgX("org2"); + expect(bridgeProfile).not.toBeUndefined(); + + const enrollAdminOut = await fabricLedger.enrollAdmin(); + const adminWallet = enrollAdminOut[1]; + + const enrollAdminBridgeOut = await fabricLedger.enrollAdminV2({ + organization: "org2", + }); + const bridgeWallet = enrollAdminBridgeOut[1]; + + const [userIdentity] = await fabricLedger.enrollUser(adminWallet); + fabricUser = userIdentity; + const opts = { + enrollmentID: "bridge", + organization: "org2", + wallet: bridgeWallet, + }; + + const [bridgeIdentity] = await fabricLedger.enrollUserV2(opts); + + const sshConfig = await fabricLedger.getSshConfig(); + + log.info("enrolled admin"); + + const keychainInstanceId = uuidv4(); + const keychainId = uuidv4(); + const keychainEntryKey = "user1"; + const keychainEntryValue = JSON.stringify(userIdentity); + + console.log("keychainEntryValue: ", keychainEntryValue); + + const keychainInstanceIdBridge = uuidv4(); + const keychainIdBridge = uuidv4(); + const keychainEntryKeyBridge = "bridge1"; + const keychainEntryValueBridge = JSON.stringify(bridgeIdentity); + + console.log("keychainEntryValue: ", keychainEntryValueBridge); + + const keychainPlugin = new PluginKeychainMemory({ + instanceId: keychainInstanceId, + keychainId, + logLevel, + backend: new Map([ + [keychainEntryKey, keychainEntryValue], + ["some-other-entry-key", "some-other-entry-value"], + ]), + }); + + const keychainPluginBridge = new PluginKeychainMemory({ + instanceId: keychainInstanceIdBridge, + keychainId: keychainIdBridge, + logLevel, + backend: new Map([ + [keychainEntryKeyBridge, keychainEntryValueBridge], + ["some-other-entry-key", "some-other-entry-value"], + ]), + }); + + const pluginRegistry = new PluginRegistry({ plugins: [keychainPlugin] }); + + const pluginRegistryBridge = new PluginRegistry({ + plugins: [keychainPluginBridge], + }); + + const discoveryOptions: DiscoveryOptions = { + enabled: true, + asLocalhost: true, + }; + + const pluginOptions: IPluginLedgerConnectorFabricOptions = { + instanceId: uuidv4(), + dockerBinary: "/usr/local/bin/docker", + peerBinary: "/fabric-samples/bin/peer", + goBinary: "/usr/local/go/bin/go", + pluginRegistry, + cliContainerEnv: FABRIC_25_LTS_FABRIC_SAMPLES_ENV_INFO_ORG_1, + sshConfig, + logLevel: "DEBUG", + connectionProfile, + discoveryOptions, + eventHandlerOptions: { + strategy: DefaultEventHandlerStrategy.NetworkScopeAllfortx, + commitTimeout: 300, + }, + }; + + const fabricConnector = new PluginLedgerConnectorFabric(pluginOptions); + + const expressApp = express(); + expressApp.use(bodyParser.json({ limit: "250mb" })); + fabricServer = http.createServer(expressApp); + const listenOptions: IListenOptions = { + hostname: "127.0.0.1", + port: 3000, + server: fabricServer, + }; + const addressInfo = (await Servers.listen(listenOptions)) as AddressInfo; + const { address, port } = addressInfo; + + await fabricConnector.getOrCreateWebServices(); + await fabricConnector.registerWebServices(expressApp); + + log.info("Fabric Ledger connector check"); + + const apiUrl = `http://${address}:${port}`; + + configFabric = new Configuration({ basePath: apiUrl }); + + apiClient = new FabricApi(configFabric); + + // deploy contracts ... + satpContractName = "satp-contract"; + const satpWrapperContractName = "satp-wrapper-contract"; + const satpContractRelPath = + "../../../test/typescript/fabric/contracts/satp-contract/chaincode-typescript"; + const wrapperSatpContractRelPath = + "../../../main/typescript/fabric-contracts/satp-wrapper/chaincode-typescript"; + const satpContractDir = path.join(__dirname, satpContractRelPath); + + // ├── package.json + // ├── src + // │ ├── index.ts + // │ ├── ITraceableContract.ts + // │ ├── satp-contract-interface.ts + // │ ├── satp-contract.ts + // ├── tsconfig.json + // ├── lib + // │ └── tokenERC20.js + // -------- + const satpSourceFiles: FileBase64[] = []; + { + const filename = "./tsconfig.json"; + const relativePath = "./"; + const filePath = path.join(satpContractDir, relativePath, filename); + const buffer = await fs.readFile(filePath); + satpSourceFiles.push({ + body: buffer.toString("base64"), + filepath: relativePath, + filename, + }); + } + { + const filename = "./package.json"; + const relativePath = "./"; + const filePath = path.join(satpContractDir, relativePath, filename); + const buffer = await fs.readFile(filePath); + satpSourceFiles.push({ + body: buffer.toString("base64"), + filepath: relativePath, + filename, + }); + } + { + const filename = "./index.ts"; + const relativePath = "./src/"; + const filePath = path.join(satpContractDir, relativePath, filename); + const buffer = await fs.readFile(filePath); + satpSourceFiles.push({ + body: buffer.toString("base64"), + filepath: relativePath, + filename, + }); + } + { + const filename = "./ITraceableContract.ts"; + const relativePath = "./src/"; + const filePath = path.join(satpContractDir, relativePath, filename); + const buffer = await fs.readFile(filePath); + satpSourceFiles.push({ + body: buffer.toString("base64"), + filepath: relativePath, + filename, + }); + } + { + const filename = "./satp-contract-interface.ts"; + const relativePath = "./src/"; + const filePath = path.join(satpContractDir, relativePath, filename); + const buffer = await fs.readFile(filePath); + satpSourceFiles.push({ + body: buffer.toString("base64"), + filepath: relativePath, + filename, + }); + } + { + const filename = "./satp-contract.ts"; + const relativePath = "./src/"; + const filePath = path.join(satpContractDir, relativePath, filename); + const buffer = await fs.readFile(filePath); + satpSourceFiles.push({ + body: buffer.toString("base64"), + filepath: relativePath, + filename, + }); + } + { + const filename = "./tokenERC20.ts"; + const relativePath = "./src/"; + const filePath = path.join(satpContractDir, relativePath, filename); + const buffer = await fs.readFile(filePath); + satpSourceFiles.push({ + body: buffer.toString("base64"), + filepath: relativePath, + filename, + }); + } + + const wrapperSatpContractDir = path.join( + __dirname, + wrapperSatpContractRelPath, + ); + + // ├── package.json + // ├── src + // │ ├── index.ts + // │ ├── interaction-signature.ts + // │ ├── ITraceableContract.ts + // │ ├── satp-wrapper.ts + // │ └── token.ts + // ├── tsconfig.json + // -------- + const wrapperSourceFiles: FileBase64[] = []; + { + const filename = "./tsconfig.json"; + const relativePath = "./"; + const filePath = path.join( + wrapperSatpContractDir, + relativePath, + filename, + ); + const buffer = await fs.readFile(filePath); + wrapperSourceFiles.push({ + body: buffer.toString("base64"), + filepath: relativePath, + filename, + }); + } + { + const filename = "./package.json"; + const relativePath = "./"; + const filePath = path.join( + wrapperSatpContractDir, + relativePath, + filename, + ); + const buffer = await fs.readFile(filePath); + wrapperSourceFiles.push({ + body: buffer.toString("base64"), + filepath: relativePath, + filename, + }); + } + { + const filename = "./index.ts"; + const relativePath = "./src/"; + const filePath = path.join( + wrapperSatpContractDir, + relativePath, + filename, + ); + const buffer = await fs.readFile(filePath); + wrapperSourceFiles.push({ + body: buffer.toString("base64"), + filepath: relativePath, + filename, + }); + } + { + const filename = "./interaction-signature.ts"; + const relativePath = "./src/"; + const filePath = path.join( + wrapperSatpContractDir, + relativePath, + filename, + ); + const buffer = await fs.readFile(filePath); + wrapperSourceFiles.push({ + body: buffer.toString("base64"), + filepath: relativePath, + filename, + }); + } + { + const filename = "./ITraceableContract.ts"; + const relativePath = "./src/"; + const filePath = path.join( + wrapperSatpContractDir, + relativePath, + filename, + ); + const buffer = await fs.readFile(filePath); + wrapperSourceFiles.push({ + body: buffer.toString("base64"), + filepath: relativePath, + filename, + }); + } + { + const filename = "./satp-wrapper.ts"; + const relativePath = "./src/"; + const filePath = path.join( + wrapperSatpContractDir, + relativePath, + filename, + ); + const buffer = await fs.readFile(filePath); + wrapperSourceFiles.push({ + body: buffer.toString("base64"), + filepath: relativePath, + filename, + }); + } + { + const filename = "./token.ts"; + const relativePath = "./src/"; + const filePath = path.join( + wrapperSatpContractDir, + relativePath, + filename, + ); + const buffer = await fs.readFile(filePath); + wrapperSourceFiles.push({ + body: buffer.toString("base64"), + filepath: relativePath, + filename, + }); + } + + const res = await apiClient.deployContractV1({ + channelId: fabricChannelName, + ccVersion: "1.0.0", + sourceFiles: satpSourceFiles, + ccName: satpContractName, + targetOrganizations: [ + FABRIC_25_LTS_FABRIC_SAMPLES_ENV_INFO_ORG_1, + FABRIC_25_LTS_FABRIC_SAMPLES_ENV_INFO_ORG_2, + ], + caFile: + FABRIC_25_LTS_FABRIC_SAMPLES_ENV_INFO_ORG_1.ORDERER_TLS_ROOTCERT_FILE, + ccLabel: "satp-contract", + ccLang: ChainCodeProgrammingLanguage.Typescript, + ccSequence: 1, + orderer: "orderer.example.com:7050", + ordererTLSHostnameOverride: "orderer.example.com", + connTimeout: 60, + }); + + const { packageIds, lifecycle, success } = res.data; + expect(res.status).toBe(200); + expect(success).toBe(true); + expect(lifecycle).not.toBeUndefined(); + + const { + approveForMyOrgList, + installList, + queryInstalledList, + commit, + packaging, + queryCommitted, + } = lifecycle; + + expect(packageIds).toBeTruthy(); + expect(packageIds).toBeArray(); + + expect(approveForMyOrgList).toBeTruthy(); + expect(approveForMyOrgList).toBeArray(); + + expect(installList).toBeTruthy(); + expect(installList).toBeArray(); + expect(queryInstalledList).toBeTruthy(); + expect(queryInstalledList).toBeArray(); + + expect(commit).toBeTruthy(); + expect(packaging).toBeTruthy(); + expect(queryCommitted).toBeTruthy(); + log.info("SATP Contract deployed"); + + const res2 = await apiClient.deployContractV1({ + channelId: fabricChannelName, + ccVersion: "1.0.0", + sourceFiles: wrapperSourceFiles, + ccName: satpWrapperContractName, + targetOrganizations: [ + FABRIC_25_LTS_FABRIC_SAMPLES_ENV_INFO_ORG_1, + FABRIC_25_LTS_FABRIC_SAMPLES_ENV_INFO_ORG_2, + ], + caFile: + FABRIC_25_LTS_FABRIC_SAMPLES_ENV_INFO_ORG_2.ORDERER_TLS_ROOTCERT_FILE, + ccLabel: "satp-wrapper-contract", + ccLang: ChainCodeProgrammingLanguage.Typescript, + ccSequence: 1, + orderer: "orderer.example.com:7050", + ordererTLSHostnameOverride: "orderer.example.com", + connTimeout: 60, + }); + + const { + packageIds: packageIds2, + lifecycle: lifecycle2, + success: success2, + } = res2.data; + expect(res2.status).toBe(200); + expect(success2).toBe(true); + + const { + approveForMyOrgList: approveForMyOrgList2, + installList: installList2, + queryInstalledList: queryInstalledList2, + commit: commit2, + packaging: packaging2, + queryCommitted: queryCommitted2, + } = lifecycle2; + + expect(packageIds2).toBeTruthy(); + expect(packageIds2).toBeArray(); + + expect(approveForMyOrgList2).toBeTruthy(); + expect(approveForMyOrgList2).toBeArray(); + + expect(installList2).toBeTruthy(); + expect(installList2).toBeArray(); + expect(queryInstalledList2).toBeTruthy(); + expect(queryInstalledList2).toBeArray(); + + expect(commit2).toBeTruthy(); + expect(packaging2).toBeTruthy(); + expect(queryCommitted2).toBeTruthy(); + + log.info("SATP Wrapper Contract deployed"); + + fabricSigningCredential = { + keychainId, + keychainRef: keychainEntryKey, + }; + + bridgeFabricSigningCredential = { + keychainId: keychainIdBridge, + keychainRef: keychainEntryKeyBridge, + }; + const mspId: string = userIdentity.mspId; + + const initializeResponse = await apiClient.runTransactionV1({ + contractName: satpContractName, + channelName: fabricChannelName, + params: [mspId, FABRIC_ASSET_ID], + methodName: "InitToken", + invocationType: FabricContractInvocationType.Send, + signingCredential: fabricSigningCredential, + }); + + expect(initializeResponse).not.toBeUndefined(); + expect(initializeResponse.status).toBeGreaterThan(199); + expect(initializeResponse.status).toBeLessThan(300); + + log.info( + `SATPContract.InitToken(): ${JSON.stringify(initializeResponse.data)}`, + ); + + const initializeResponse2 = await apiClient.runTransactionV1({ + contractName: satpWrapperContractName, + channelName: fabricChannelName, + params: [mspId], + methodName: "Initialize", + invocationType: FabricContractInvocationType.Send, + signingCredential: fabricSigningCredential, + }); + + expect(initializeResponse2).not.toBeUndefined(); + expect(initializeResponse2.status).toBeGreaterThan(199); + expect(initializeResponse2.status).toBeLessThan(300); + + log.info( + `SATPWrapper.Initialize(): ${JSON.stringify(initializeResponse2.data)}`, + ); + + const setBridgeResponse = await apiClient.runTransactionV1({ + contractName: satpContractName, + channelName: fabricChannelName, + params: ["Org2MSP"], + methodName: "setBridge", + invocationType: FabricContractInvocationType.Send, + signingCredential: fabricSigningCredential, + }); + + const setBridgeResponse2 = await apiClient.runTransactionV1({ + contractName: satpWrapperContractName, + channelName: fabricChannelName, + params: ["Org2MSP", BRIDGE_ID], + methodName: "setBridge", + invocationType: FabricContractInvocationType.Send, + signingCredential: fabricSigningCredential, + }); + + expect(setBridgeResponse2).not.toBeUndefined(); + expect(setBridgeResponse2.status).toBeGreaterThan(199); + expect(setBridgeResponse2.status).toBeLessThan(300); + + log.info( + `SATPWrapper.setBridge(): ${JSON.stringify(setBridgeResponse.data)}`, + ); + + const responseClientId = await apiClient.runTransactionV1({ + contractName: satpWrapperContractName, + channelName: fabricChannelName, + params: [], + methodName: "ClientAccountID", + invocationType: FabricContractInvocationType.Send, + signingCredential: fabricSigningCredential, + }); + + clientId = responseClientId.data.functionOutput.toString(); + + pluginBungeeFabricOptions = { + keyPair: Secp256k1Keys.generateKeyPairsBuffer(), + instanceId: uuidv4(), + pluginRegistry: new PluginRegistry(), + logLevel, + }; + + const pluginOptionsFabricBridge: IPluginLedgerConnectorFabricOptions = { + instanceId: uuidv4(), + dockerBinary: "/usr/local/bin/docker", + peerBinary: "/fabric-samples/bin/peer", + goBinary: "/usr/local/go/bin/go", + pluginRegistry: pluginRegistryBridge, + cliContainerEnv: FABRIC_25_LTS_FABRIC_SAMPLES_ENV_INFO_ORG_2, + sshConfig, + logLevel: "DEBUG", + connectionProfile: bridgeProfile, + discoveryOptions, + eventHandlerOptions: { + strategy: DefaultEventHandlerStrategy.NetworkScopeAllfortx, + commitTimeout: 300, + }, + }; + + fabricConfig = { + network: SupportedChain.FABRIC, + signingCredential: bridgeFabricSigningCredential, + channelName: fabricChannelName, + contractName: satpWrapperContractName, + options: pluginOptionsFabricBridge, + bungeeOptions: pluginBungeeFabricOptions, + claimFormat: ClaimFormat.DEFAULT, + } as FabricConfig; + + // networkDetails = { + // connectorApiPath: fabricPath, + // signingCredential: fabricSigningCredential, + // channelName: fabricChannelName, + // contractName: satpContractName, + // participant: "Org1MSP", + // }; + } + + { + //setup besu ledger + rpcApiHttpHost = await besuLedger.getRpcApiHttpHost(); + rpcApiWsHost = await besuLedger.getRpcApiWsHost(); + web3 = new Web3(rpcApiHttpHost); + firstHighNetWorthAccount = besuLedger.getGenesisAccountPubKey(); + + bridgeEthAccount = await besuLedger.createEthTestAccount(); + + assigneeEthAccount = await besuLedger.createEthTestAccount(); + + besuKeyPair = { + privateKey: besuLedger.getGenesisAccountPrivKey(), + }; + + erc20TokenContract = "SATPContract"; + contractNameWrapper = "SATPWrapperContract"; + + const keychainEntryValue = besuKeyPair.privateKey; + const keychainEntryKey = uuidv4(); + keychainPlugin1 = new PluginKeychainMemory({ + instanceId: uuidv4(), + keychainId: uuidv4(), + + backend: new Map([[keychainEntryKey, keychainEntryValue]]), + logLevel, + }); + + keychainPlugin2 = new PluginKeychainMemory({ + instanceId: uuidv4(), + keychainId: uuidv4(), + + backend: new Map([[keychainEntryKey, keychainEntryValue]]), + logLevel, + }); + + keychainPlugin1.set(erc20TokenContract, JSON.stringify(SATPContract)); + keychainPlugin2.set( + contractNameWrapper, + JSON.stringify(SATPWrapperContract), + ); + + const pluginRegistry = new PluginRegistry({ + plugins: [keychainPlugin1, keychainPlugin2], + }); + + besuOptions = { + instanceId: uuidv4(), + rpcApiHttpHost, + rpcApiWsHost, + pluginRegistry, + logLevel, + }; + testing_connector = new PluginLedgerConnectorBesu(besuOptions); + pluginRegistry.add(testing_connector); + + await testing_connector.transact({ + web3SigningCredential: { + ethAccount: firstHighNetWorthAccount, + secret: besuKeyPair.privateKey, + type: Web3SigningCredentialType.PrivateKeyHex, + }, + consistencyStrategy: { + blockConfirmations: 0, + receiptType: ReceiptType.NodeTxPoolAck, + }, + transactionConfig: { + from: firstHighNetWorthAccount, + to: bridgeEthAccount.address, + value: 10e9, + gas: 1000000, + }, + }); + + const balance = await web3.eth.getBalance(bridgeEthAccount.address); + expect(balance).toBeTruthy(); + expect(parseInt(balance, 10)).toBeGreaterThan(10e9); + log.info("Connector initialized"); + + const deployOutSATPContract = await testing_connector.deployContract({ + keychainId: keychainPlugin1.getKeychainId(), + contractName: erc20TokenContract, + contractAbi: SATPContract.abi, + constructorArgs: [firstHighNetWorthAccount, BESU_ASSET_ID], + web3SigningCredential: { + ethAccount: firstHighNetWorthAccount, + secret: besuKeyPair.privateKey, + type: Web3SigningCredentialType.PrivateKeyHex, + }, + bytecode: SATPContract.bytecode.object, + gas: 999999999999999, + }); + expect(deployOutSATPContract).toBeTruthy(); + expect(deployOutSATPContract.transactionReceipt).toBeTruthy(); + expect( + deployOutSATPContract.transactionReceipt.contractAddress, + ).toBeTruthy(); + + assetContractAddress = + deployOutSATPContract.transactionReceipt.contractAddress ?? ""; + + log.info("SATPContract Deployed successfully"); + + const deployOutWrapperContract = await testing_connector.deployContract({ + keychainId: keychainPlugin2.getKeychainId(), + contractName: contractNameWrapper, + contractAbi: SATPWrapperContract.abi, + constructorArgs: [bridgeEthAccount.address], + web3SigningCredential: { + ethAccount: bridgeEthAccount.address, + secret: bridgeEthAccount.privateKey, + type: Web3SigningCredentialType.PrivateKeyHex, + }, + bytecode: SATPWrapperContract.bytecode.object, + gas: 999999999999999, + }); + expect(deployOutWrapperContract).toBeTruthy(); + expect(deployOutWrapperContract.transactionReceipt).toBeTruthy(); + expect( + deployOutWrapperContract.transactionReceipt.contractAddress, + ).toBeTruthy(); + log.info("SATPWrapperContract Deployed successfully"); + + wrapperContractAddress = + deployOutWrapperContract.transactionReceipt.contractAddress ?? ""; + + pluginBungeeBesuOptions = { + keyPair: Secp256k1Keys.generateKeyPairsBuffer(), + instanceId: uuidv4(), + pluginRegistry: new PluginRegistry(), + logLevel, + }; + + besuConfig = { + network: SupportedChain.BESU, + keychainId: keychainPlugin2.getKeychainId(), + signingCredential: { + ethAccount: bridgeEthAccount.address, + secret: bridgeEthAccount.privateKey, + type: Web3SigningCredentialType.PrivateKeyHex, + }, + contractName: contractNameWrapper, + contractAddress: wrapperContractAddress, + options: besuOptions, + bungeeOptions: pluginBungeeBesuOptions, + gas: 999999999999999, + claimFormat: ClaimFormat.DEFAULT, + }; + + const giveRoleRes = await testing_connector.invokeContract({ + contractName: erc20TokenContract, + keychainId: keychainPlugin1.getKeychainId(), + invocationType: EthContractInvocationType.Send, + methodName: "giveRole", + params: [wrapperContractAddress], + signingCredential: { + ethAccount: firstHighNetWorthAccount, + secret: besuKeyPair.privateKey, + type: Web3SigningCredentialType.PrivateKeyHex, + }, + gas: 1000000, + }); + + expect(giveRoleRes).toBeTruthy(); + expect(giveRoleRes.success).toBeTruthy(); + log.info("BRIDGE_ROLE given to SATPWrapperContract successfully"); + } + + const responseMint = await testing_connector.invokeContract({ + contractName: erc20TokenContract, + keychainId: keychainPlugin1.getKeychainId(), + invocationType: EthContractInvocationType.Send, + methodName: "mint", + params: [firstHighNetWorthAccount, "100"], + signingCredential: { + ethAccount: firstHighNetWorthAccount, + secret: besuKeyPair.privateKey, + type: Web3SigningCredentialType.PrivateKeyHex, + }, + gas: 999999999, + }); + expect(responseMint).toBeTruthy(); + expect(responseMint.success).toBeTruthy(); + log.info("Minted 100 tokens to firstHighNetWorthAccount"); + + const responseApprove = await testing_connector.invokeContract({ + contractName: erc20TokenContract, + keychainId: keychainPlugin1.getKeychainId(), + invocationType: EthContractInvocationType.Send, + methodName: "approve", + params: [wrapperContractAddress, "100"], + signingCredential: { + ethAccount: firstHighNetWorthAccount, + secret: besuKeyPair.privateKey, + type: Web3SigningCredentialType.PrivateKeyHex, + }, + gas: 999999999, + }); + expect(responseApprove).toBeTruthy(); + expect(responseApprove.success).toBeTruthy(); + log.info("Approved 100 tokens to SATPWrapperContract"); +}); +describe("SATPGateway sending a token from Besu to Fabric", () => { + it("should realize a transfer", async () => { + //setup satp gateway + const factoryOptions: IPluginFactoryOptions = { + pluginImportType: PluginImportType.Local, + }; + const factory = new PluginFactorySATPGateway(factoryOptions); + + const gatewayIdentity = { + id: "mockID", + name: "CustomGateway", + version: [ + { + Core: "v02", + Architecture: "v02", + Crash: "v02", + }, + ], + supportedDLTs: [SupportedChain.FABRIC, SupportedChain.BESU], + proofID: "mockProofID10", + address: "http://localhost" as Address, + gatewayOpenAPIPort: 4111, + } as GatewayIdentity; + + const options: SATPGatewayConfig = { + logLevel: "DEBUG", + gid: gatewayIdentity, + counterPartyGateways: [], //only knows itself + bridgesConfig: [besuConfig, fabricConfig], + enableOpenAPI: true, + }; + const gateway = await factory.create(options); + expect(gateway).toBeInstanceOf(SATPGateway); + await gateway.onPluginInit(); + + const identity = gateway.Identity; + // default servers + expect(identity.gatewayServerPort).toBe(3010); + expect(identity.gatewayClientPort).toBe(3011); + expect(identity.address).toBe("http://localhost"); + //await gateway.startup(); + + const httpApiA = await Servers.startOnPort(4111, "localhost"); + const addressInfoA = httpApiA.address() as AddressInfo; + const nodeApiHostA = `http://localhost:${addressInfoA.port}`; + const clientPluginRegistry = new PluginRegistry({ + plugins: [ + new PluginKeychainMemory({ + keychainId: uuidv4(), + instanceId: uuidv4(), + logLevel: "INFO", + }), + ], + }); + + clientPluginRegistry.add(gateway); + + const addressInfoApi = httpApiA.address() as AddressInfo; + + const configService = new ConfigService(); + const apiServerOptions = await configService.newExampleConfig(); + apiServerOptions.authorizationProtocol = AuthorizationProtocol.NONE; + apiServerOptions.configFile = ""; + apiServerOptions.apiCorsDomainCsv = "*"; + apiServerOptions.apiPort = addressInfoApi.port; + apiServerOptions.apiHost = addressInfoApi.address; + apiServerOptions.logLevel = logLevel || "INFO"; + apiServerOptions.apiTlsEnabled = false; + apiServerOptions.grpcPort = 0; + apiServerOptions.crpcPort = 0; + const config = + await configService.newExampleConfigConvict(apiServerOptions); + const prop = config.getProperties(); + apiServer = new ApiServer({ + httpServerApi: httpApiA, + config: prop, + pluginRegistry: clientPluginRegistry, + }); + await apiServer.start(); + + const satpApi = new TransactionApi( + new Configuration({ basePath: nodeApiHostA }), + ); + + const dispatcher = gateway.getBLODispatcher(); + + expect(dispatcher).toBeTruthy(); + const sourceAsset: Asset = { + owner: firstHighNetWorthAccount, + ontology: JSON.stringify(BesuSATPInteraction), + contractName: erc20TokenContract, + contractAddress: assetContractAddress, + }; + const receiverAsset: Asset = { + owner: clientId, + ontology: JSON.stringify(FabricSATPInteraction), + contractName: satpContractName, + mspId: fabricUser.mspId, + channelName: fabricChannelName, + }; + const req: TransactRequest = { + contextID: "mockContext", + fromDLTNetworkID: SupportedChain.BESU, + toDLTNetworkID: SupportedChain.FABRIC, + fromAmount: "100", + toAmount: "1", + originatorPubkey: assigneeEthAccount.address, + beneficiaryPubkey: fabricUser.credentials.certificate, + sourceAsset, + receiverAsset, + }; + + const res = await satpApi.transact(req); + log.info(res?.status); + log.info(res.data.statusResponse); + + const responseBalanceOwner = await testing_connector.invokeContract({ + contractName: erc20TokenContract, + keychainId: keychainPlugin1.getKeychainId(), + invocationType: EthContractInvocationType.Call, + methodName: "checkBalance", + params: [firstHighNetWorthAccount], + signingCredential: { + ethAccount: firstHighNetWorthAccount, + secret: besuKeyPair.privateKey, + type: Web3SigningCredentialType.PrivateKeyHex, + }, + gas: 999999999, + }); + expect(responseBalanceOwner).toBeTruthy(); + expect(responseBalanceOwner.success).toBeTruthy(); + expect(responseBalanceOwner.callOutput).toBe("0"); + log.info("Amount was transfer correctly from the Owner account"); + + const responseBalanceBridge = await testing_connector.invokeContract({ + contractName: erc20TokenContract, + keychainId: keychainPlugin1.getKeychainId(), + invocationType: EthContractInvocationType.Call, + methodName: "checkBalance", + params: [wrapperContractAddress], + signingCredential: { + ethAccount: firstHighNetWorthAccount, + secret: besuKeyPair.privateKey, + type: Web3SigningCredentialType.PrivateKeyHex, + }, + gas: 999999999, + }); + expect(responseBalanceBridge).toBeTruthy(); + expect(responseBalanceBridge.success).toBeTruthy(); + expect(responseBalanceBridge.callOutput).toBe("0"); + log.info("Amount was transfer correctly to the Wrapper account"); + + const responseBalance1 = await apiClient.runTransactionV1({ + contractName: satpContractName, + channelName: fabricChannelName, + params: [BRIDGE_ID], + methodName: "ClientIDAccountBalance", + invocationType: FabricContractInvocationType.Send, + signingCredential: fabricSigningCredential, + }); + + expect(responseBalance1).not.toBeUndefined(); + expect(responseBalance1.status).toBeGreaterThan(199); + expect(responseBalance1.status).toBeLessThan(300); + expect(responseBalance1.data).not.toBeUndefined(); + expect(responseBalance1.data.functionOutput).toBe("0"); + log.info("Amount was transfer correctly from the Bridge account"); + + const responseBalance2 = await apiClient.runTransactionV1({ + contractName: satpContractName, + channelName: fabricChannelName, + params: [clientId], + methodName: "ClientIDAccountBalance", + invocationType: FabricContractInvocationType.Send, + signingCredential: fabricSigningCredential, + }); + expect(responseBalance2).not.toBeUndefined(); + expect(responseBalance2.status).toBeGreaterThan(199); + expect(responseBalance2.status).toBeLessThan(300); + expect(responseBalance2.data).not.toBeUndefined(); + expect(responseBalance2.data.functionOutput).toBe("1"); + log.info("Amount was transfer correctly to the Owner account"); + log.info(res?.data.statusResponse); + await gateway.shutdown(); + }); +}); diff --git a/yarn.lock b/yarn.lock index 2402ef4c55..4e03bbca31 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7035,16 +7035,6 @@ __metadata: languageName: node linkType: hard -"@grpc/grpc-js@npm:1.11.2": - version: 1.11.2 - resolution: "@grpc/grpc-js@npm:1.11.2" - dependencies: - "@grpc/proto-loader": "npm:^0.7.13" - "@js-sdsl/ordered-map": "npm:^4.4.2" - checksum: 10/05bc4bbc9907017e723de7c3a776a07155b522c1a56f68cc89655eeee3f72f00f4c31584e908c250495344f384d9528c18a44db0976783fd17e338a563df6f84 - languageName: node - linkType: hard - "@grpc/grpc-js@npm:1.11.3": version: 1.11.3 resolution: "@grpc/grpc-js@npm:1.11.3" @@ -7262,7 +7252,7 @@ __metadata: dependencies: "@emotion/react": "npm:11.11.1" "@emotion/styled": "npm:11.11.0" - "@hyperledger/cactus-example-cbdc-bridging-backend": "npm:2.0.0-rc.7" + "@hyperledger/cactus-example-cbdc-bridging-backend": "npm:2.0.0" "@mui/icons-material": "npm:6.1.1" "@mui/material": "npm:6.1.1" "@testing-library/jest-dom": "npm:5.17.0" @@ -7617,21 +7607,6 @@ __metadata: languageName: unknown linkType: soft -"@hyperledger/cactus-api-client@npm:2.0.0-rc.7": - version: 2.0.0-rc.7 - resolution: "@hyperledger/cactus-api-client@npm:2.0.0-rc.7" - dependencies: - "@hyperledger/cactus-common": "npm:2.0.0-rc.7" - "@hyperledger/cactus-core": "npm:2.0.0-rc.7" - "@hyperledger/cactus-core-api": "npm:2.0.0-rc.7" - "@hyperledger/cactus-plugin-consortium-manual": "npm:2.0.0-rc.7" - jsonwebtoken: "npm:9.0.0" - rxjs: "npm:7.8.1" - socket.io-client-fixed-types: "npm:4.5.4" - checksum: 10/5af636a87238d7ecbc4da0e19f71354f33e0545858f1af99b94756523da4bbbe2c417c718b7d4d1145b3c44c88e6b5b82af531a1bea348c9407e5978935a2965 - languageName: node - linkType: hard - "@hyperledger/cactus-cmd-api-server@npm:2.0.0, @hyperledger/cactus-cmd-api-server@workspace:packages/cactus-cmd-api-server": version: 0.0.0-use.local resolution: "@hyperledger/cactus-cmd-api-server@workspace:packages/cactus-cmd-api-server" @@ -7711,54 +7686,6 @@ __metadata: languageName: unknown linkType: soft -"@hyperledger/cactus-cmd-api-server@npm:2.0.0-rc.7": - version: 2.0.0-rc.7 - resolution: "@hyperledger/cactus-cmd-api-server@npm:2.0.0-rc.7" - dependencies: - "@bufbuild/protobuf": "npm:1.10.0" - "@connectrpc/connect": "npm:1.4.0" - "@connectrpc/connect-express": "npm:1.4.0" - "@connectrpc/connect-fastify": "npm:1.4.0" - "@connectrpc/connect-node": "npm:1.4.0" - "@grpc/grpc-js": "npm:1.11.2" - "@grpc/proto-loader": "npm:0.7.13" - "@hyperledger/cactus-common": "npm:2.0.0-rc.7" - "@hyperledger/cactus-core": "npm:2.0.0-rc.7" - "@hyperledger/cactus-core-api": "npm:2.0.0-rc.7" - "@thream/socketio-jwt": "npm:2.1.1" - async-exit-hook: "npm:2.0.1" - axios: "npm:1.7.7" - bluebird: "npm:3.7.2" - body-parser: "npm:1.20.3" - compression: "npm:1.7.4" - convict: "npm:6.2.4" - convict-format-with-validator: "npm:6.2.0" - cors: "npm:2.8.5" - express: "npm:4.20.0" - express-http-proxy: "npm:1.6.2" - express-jwt: "npm:8.4.1" - express-openapi-validator: "npm:5.2.0" - express-rate-limit: "npm:6.7.0" - fastify: "npm:4.26.2" - fs-extra: "npm:11.2.0" - google-protobuf: "npm:3.21.4" - jose: "npm:4.15.5" - json-stable-stringify: "npm:1.0.2" - lmify: "npm:0.3.0" - node-forge: "npm:1.3.0" - prom-client: "npm:15.1.3" - run-time-error-cjs: "npm:1.4.0" - rxjs: "npm:7.8.1" - safe-stable-stringify: "npm:2.4.3" - semver: "npm:7.6.2" - socket.io: "npm:4.6.2" - socket.io-client-fixed-types: "npm:4.5.4" - typescript-optional: "npm:2.0.1" - uuid: "npm:10.0.0" - checksum: 10/b2da3c309ce21b72790de8d22243f29cff81b00bddb7393c5bbcf573382f19ce16aa08496b751c8460640291bb6d043644df8c129b7da57f55aa24a4560f2f89 - languageName: node - linkType: hard - "@hyperledger/cactus-common-example-server@npm:2.0.0, @hyperledger/cactus-common-example-server@workspace:examples/cactus-common-example-server": version: 0.0.0-use.local resolution: "@hyperledger/cactus-common-example-server@workspace:examples/cactus-common-example-server" @@ -7882,21 +7809,6 @@ __metadata: languageName: unknown linkType: soft -"@hyperledger/cactus-core-api@npm:2.0.0-rc.7": - version: 2.0.0-rc.7 - resolution: "@hyperledger/cactus-core-api@npm:2.0.0-rc.7" - dependencies: - "@grpc/grpc-js": "npm:1.11.2" - "@hyperledger/cactus-common": "npm:2.0.0-rc.7" - ajv: "npm:8.17.1" - ajv-draft-04: "npm:1.0.0" - ajv-formats: "npm:3.0.1" - axios: "npm:1.7.7" - google-protobuf: "npm:3.21.4" - checksum: 10/12bb6d9eb77a7ca0b80aefec6f740672e172e6c02b840c9ad1756b8411be8b2cd0ee63fd5d2a3c5699f6ef7ecc3b3ec9eec854659ebec507362646131836e0e0 - languageName: node - linkType: hard - "@hyperledger/cactus-core@npm:2.0.0, @hyperledger/cactus-core@workspace:packages/cactus-core": version: 0.0.0-use.local resolution: "@hyperledger/cactus-core@workspace:packages/cactus-core" @@ -7920,25 +7832,6 @@ __metadata: languageName: unknown linkType: soft -"@hyperledger/cactus-core@npm:2.0.0-rc.7": - version: 2.0.0-rc.7 - resolution: "@hyperledger/cactus-core@npm:2.0.0-rc.7" - dependencies: - "@hyperledger/cactus-common": "npm:2.0.0-rc.7" - "@hyperledger/cactus-core-api": "npm:2.0.0-rc.7" - body-parser: "npm:1.20.3" - express: "npm:4.20.0" - express-jwt-authz: "npm:2.4.1" - express-openapi-validator: "npm:5.2.0" - http-errors: "npm:2.0.0" - http-errors-enhanced-cjs: "npm:2.0.1" - run-time-error-cjs: "npm:1.4.0" - safe-stable-stringify: "npm:2.4.3" - typescript-optional: "npm:2.0.1" - checksum: 10/adf674bc37907c2b1adad5090b4cee5bbfd5ddcf0d9bcc80560793a667033b636a4ad06a991c86a0f10109995da51289724db06a669348270cf528002632e418 - languageName: node - linkType: hard - "@hyperledger/cactus-example-carbon-accounting-backend@workspace:examples/cactus-example-carbon-accounting-backend": version: 0.0.0-use.local resolution: "@hyperledger/cactus-example-carbon-accounting-backend@workspace:examples/cactus-example-carbon-accounting-backend" @@ -8042,44 +7935,7 @@ __metadata: languageName: unknown linkType: soft -"@hyperledger/cactus-example-cbdc-bridging-backend@npm:2.0.0-rc.7": - version: 2.0.0-rc.7 - resolution: "@hyperledger/cactus-example-cbdc-bridging-backend@npm:2.0.0-rc.7" - dependencies: - "@hyperledger/cactus-api-client": "npm:2.0.0-rc.7" - "@hyperledger/cactus-cmd-api-server": "npm:2.0.0-rc.7" - "@hyperledger/cactus-common": "npm:2.0.0-rc.7" - "@hyperledger/cactus-core": "npm:2.0.0-rc.7" - "@hyperledger/cactus-core-api": "npm:2.0.0-rc.7" - "@hyperledger/cactus-plugin-keychain-memory": "npm:2.0.0-rc.7" - "@hyperledger/cactus-plugin-ledger-connector-besu": "npm:2.0.0-rc.7" - "@hyperledger/cactus-plugin-ledger-connector-fabric": "npm:2.0.0-rc.7" - "@hyperledger/cactus-plugin-ledger-connector-xdai": "npm:2.0.0-rc.7" - "@hyperledger/cactus-plugin-object-store-ipfs": "npm:2.0.0-rc.7" - "@hyperledger/cactus-plugin-satp-hermes": "npm:2.0.0-rc.7" - "@hyperledger/cactus-test-tooling": "npm:2.0.0-rc.7" - "@openzeppelin/contracts": "npm:4.9.6" - "@openzeppelin/contracts-upgradeable": "npm:4.9.6" - async-exit-hook: "npm:2.0.1" - axios: "npm:1.7.7" - crypto-js: "npm:4.2.0" - dotenv: "npm:16.0.1" - fabric-network: "npm:2.2.20" - fs-extra: "npm:11.2.0" - knex: "npm:2.5.1" - kubo-rpc-client: "npm:3.0.1" - nyc: "npm:13.1.0" - openapi-types: "npm:12.1.3" - sqlite3: "npm:5.1.5" - typescript-optional: "npm:2.0.1" - uuid: "npm:10.0.0" - web3-core: "npm:1.10.1" - web3-utils: "npm:1.10.1" - checksum: 10/fd62bf56f3c323d67f9a1558cf51a28d47720d5a5a2be62a40ff9b6e9e1926da6a92311c3cad8c6feceb2989ec765a9c76a9e32fcca936c8411f89631967482b - languageName: node - linkType: hard - -"@hyperledger/cactus-example-cbdc-bridging-backend@workspace:examples/cactus-example-cbdc-bridging-backend": +"@hyperledger/cactus-example-cbdc-bridging-backend@npm:2.0.0, @hyperledger/cactus-example-cbdc-bridging-backend@workspace:examples/cactus-example-cbdc-bridging-backend": version: 0.0.0-use.local resolution: "@hyperledger/cactus-example-cbdc-bridging-backend@workspace:examples/cactus-example-cbdc-bridging-backend" dependencies: @@ -8436,25 +8292,6 @@ __metadata: languageName: unknown linkType: soft -"@hyperledger/cactus-plugin-consortium-manual@npm:2.0.0-rc.7": - version: 2.0.0-rc.7 - resolution: "@hyperledger/cactus-plugin-consortium-manual@npm:2.0.0-rc.7" - dependencies: - "@hyperledger/cactus-common": "npm:2.0.0-rc.7" - "@hyperledger/cactus-core": "npm:2.0.0-rc.7" - "@hyperledger/cactus-core-api": "npm:2.0.0-rc.7" - axios: "npm:1.7.7" - body-parser: "npm:1.20.3" - express: "npm:4.20.0" - jose: "npm:4.15.5" - json-stable-stringify: "npm:1.0.1" - prom-client: "npm:15.1.3" - typescript-optional: "npm:2.0.1" - uuid: "npm:10.0.0" - checksum: 10/ebca6b107897ef321322415ecbe7173f0294db6ff09575c8a148a44fe53182c0cc794ca584836e4998d27634f35f4b4fd762fe2ae02fd952f63755b92445e5fa - languageName: node - linkType: hard - "@hyperledger/cactus-plugin-htlc-coordinator-besu@workspace:extensions/cactus-plugin-htlc-coordinator-besu": version: 0.0.0-use.local resolution: "@hyperledger/cactus-plugin-htlc-coordinator-besu@workspace:extensions/cactus-plugin-htlc-coordinator-besu" @@ -8646,24 +8483,6 @@ __metadata: languageName: unknown linkType: soft -"@hyperledger/cactus-plugin-keychain-memory@npm:2.0.0-rc.7": - version: 2.0.0-rc.7 - resolution: "@hyperledger/cactus-plugin-keychain-memory@npm:2.0.0-rc.7" - dependencies: - "@bufbuild/protobuf": "npm:1.10.0" - "@connectrpc/connect": "npm:1.4.0" - "@hyperledger/cactus-common": "npm:2.0.0-rc.7" - "@hyperledger/cactus-core": "npm:2.0.0-rc.7" - "@hyperledger/cactus-core-api": "npm:2.0.0-rc.7" - axios: "npm:1.7.7" - express: "npm:4.20.0" - prom-client: "npm:15.1.3" - rxjs: "npm:7.8.1" - uuid: "npm:10.0.0" - checksum: 10/bc644527271a60de8d9227274129423fd77c30d3dfb71c55f644b2621ba2f56ea13b7c722931889b13223d1da9e390b172196c254d4409ba45689d2c4c9af085 - languageName: node - linkType: hard - "@hyperledger/cactus-plugin-keychain-vault@npm:2.0.0, @hyperledger/cactus-plugin-keychain-vault@workspace:packages/cactus-plugin-keychain-vault": version: 0.0.0-use.local resolution: "@hyperledger/cactus-plugin-keychain-vault@workspace:packages/cactus-plugin-keychain-vault" @@ -8773,36 +8592,6 @@ __metadata: languageName: unknown linkType: soft -"@hyperledger/cactus-plugin-ledger-connector-besu@npm:2.0.0-rc.7": - version: 2.0.0-rc.7 - resolution: "@hyperledger/cactus-plugin-ledger-connector-besu@npm:2.0.0-rc.7" - dependencies: - "@grpc/grpc-js": "npm:1.11.2" - "@hyperledger/cactus-common": "npm:2.0.0-rc.7" - "@hyperledger/cactus-core": "npm:2.0.0-rc.7" - "@hyperledger/cactus-core-api": "npm:2.0.0-rc.7" - axios: "npm:1.7.7" - express: "npm:4.20.0" - google-protobuf: "npm:3.21.4" - http-errors: "npm:2.0.0" - http-errors-enhanced-cjs: "npm:2.0.1" - joi: "npm:17.13.3" - openapi-types: "npm:12.1.3" - prom-client: "npm:15.1.3" - run-time-error-cjs: "npm:1.4.0" - rxjs: "npm:7.8.1" - socket.io-client-fixed-types: "npm:4.5.4" - typescript-optional: "npm:2.0.1" - web3: "npm:1.6.1" - web3-core: "npm:1.6.1" - web3-eth: "npm:1.6.1" - web3-eth-contract: "npm:1.6.1" - web3-utils: "npm:1.6.1" - web3js-quorum: "npm:22.4.0" - checksum: 10/44a8002558abc6d1d54179b30ca6e7c10efe9d143d45aff7958a1d2ff8c242c24725a7ad85d3eaf9be8d3d0a0f6f6e6fbf882f2fecb81a48e7b82cda924e7571 - languageName: node - linkType: hard - "@hyperledger/cactus-plugin-ledger-connector-cdl@workspace:packages/cactus-plugin-ledger-connector-cdl": version: 0.0.0-use.local resolution: "@hyperledger/cactus-plugin-ledger-connector-cdl@workspace:packages/cactus-plugin-ledger-connector-cdl" @@ -8955,48 +8744,6 @@ __metadata: languageName: unknown linkType: soft -"@hyperledger/cactus-plugin-ledger-connector-fabric@npm:2.0.0-rc.7": - version: 2.0.0-rc.7 - resolution: "@hyperledger/cactus-plugin-ledger-connector-fabric@npm:2.0.0-rc.7" - dependencies: - "@fidm/x509": "npm:1.2.1" - "@hyperledger/cactus-common": "npm:2.0.0-rc.7" - "@hyperledger/cactus-core": "npm:2.0.0-rc.7" - "@hyperledger/cactus-core-api": "npm:2.0.0-rc.7" - axios: "npm:1.7.7" - bl: "npm:6.0.14" - bn.js: "npm:4.12.0" - elliptic: "npm:6.5.7" - express: "npm:4.20.0" - fabric-ca-client: "npm:2.5.0-snapshot.23" - fabric-common: "npm:2.5.0-snapshot.23" - fabric-network: "npm:2.5.0-snapshot.23" - fabric-protos: "npm:2.5.0-snapshot.23" - fast-safe-stringify: "npm:2.1.1" - form-data: "npm:4.0.0" - http-status-codes: "npm:2.1.4" - jsrsasign: "npm:11.0.0" - long: "npm:5.2.3" - multer: "npm:1.4.5-lts.1" - ngo: "npm:2.7.0" - node-ssh: "npm:13.1.0" - node-vault: "npm:0.9.22" - openapi-types: "npm:12.1.3" - prom-client: "npm:15.1.3" - run-time-error-cjs: "npm:1.4.0" - rxjs: "npm:7.8.1" - sanitize-filename: "npm:1.6.3" - sanitize-html: "npm:2.12.1" - secp256k1: "npm:4.0.3" - socket.io-client-fixed-types: "npm:4.5.4" - temp: "npm:0.9.4" - typescript-optional: "npm:2.0.1" - uuid: "npm:10.0.0" - ws-identity-client: "npm:1.0.2" - checksum: 10/a21c55cb8cf12f5c40a9272028d9208c1f8273a6411c6465dd2a3c6d298318f4c69912ffe2c6256dd5cc9882f51e37d84bc68904e312d396b9f4dcea29c34ce4 - languageName: node - linkType: hard - "@hyperledger/cactus-plugin-ledger-connector-iroha2@npm:2.0.0, @hyperledger/cactus-plugin-ledger-connector-iroha2@workspace:packages/cactus-plugin-ledger-connector-iroha2": version: 0.0.0-use.local resolution: "@hyperledger/cactus-plugin-ledger-connector-iroha2@workspace:packages/cactus-plugin-ledger-connector-iroha2" @@ -9120,28 +8867,6 @@ __metadata: languageName: unknown linkType: soft -"@hyperledger/cactus-plugin-ledger-connector-xdai@npm:2.0.0-rc.7": - version: 2.0.0-rc.7 - resolution: "@hyperledger/cactus-plugin-ledger-connector-xdai@npm:2.0.0-rc.7" - dependencies: - "@hyperledger/cactus-common": "npm:2.0.0-rc.7" - "@hyperledger/cactus-core": "npm:2.0.0-rc.7" - "@hyperledger/cactus-core-api": "npm:2.0.0-rc.7" - axios: "npm:1.7.7" - express: "npm:4.20.0" - joi: "npm:17.13.3" - openapi-types: "npm:12.1.3" - prom-client: "npm:15.1.3" - run-time-error-cjs: "npm:1.4.0" - typescript-optional: "npm:2.0.1" - uuid: "npm:10.0.0" - web3: "npm:1.6.1" - web3-eth-contract: "npm:1.6.1" - web3-utils: "npm:1.6.1" - checksum: 10/ba33fc5d8d92c7eb8947334c46c2a17e5e0232e920b19325f353c8fb882580ea7cba1d2036aff7fb1ad1c88437e9958bd87a0980bfb2d4d2f6fc8953ec0edbf5 - languageName: node - linkType: hard - "@hyperledger/cactus-plugin-object-store-ipfs@npm:2.0.0, @hyperledger/cactus-plugin-object-store-ipfs@workspace:extensions/cactus-plugin-object-store-ipfs": version: 0.0.0-use.local resolution: "@hyperledger/cactus-plugin-object-store-ipfs@workspace:extensions/cactus-plugin-object-store-ipfs" @@ -9167,21 +8892,6 @@ __metadata: languageName: unknown linkType: soft -"@hyperledger/cactus-plugin-object-store-ipfs@npm:2.0.0-rc.7": - version: 2.0.0-rc.7 - resolution: "@hyperledger/cactus-plugin-object-store-ipfs@npm:2.0.0-rc.7" - dependencies: - "@hyperledger/cactus-common": "npm:2.0.0-rc.7" - "@hyperledger/cactus-core": "npm:2.0.0-rc.7" - "@hyperledger/cactus-core-api": "npm:2.0.0-rc.7" - axios: "npm:1.7.7" - run-time-error-cjs: "npm:1.4.0" - typescript-optional: "npm:2.0.1" - uuid: "npm:10.0.0" - checksum: 10/d1e171d2ba7fefe37801c74d7f40be442f6c079348753ebe633065d222aa0daa385923b2003ef1d3e1351549cde16d2f64c04d94ac49bbe0e905fbdea889156a - languageName: node - linkType: hard - "@hyperledger/cactus-plugin-persistence-ethereum@workspace:packages/cactus-plugin-persistence-ethereum": version: 0.0.0-use.local resolution: "@hyperledger/cactus-plugin-persistence-ethereum@workspace:packages/cactus-plugin-persistence-ethereum" @@ -9259,6 +8969,7 @@ __metadata: "@foundry-rs/hardhat-forge": "npm:0.1.17" "@grpc/grpc-js": "npm:1.12.4" "@grpc/proto-loader": "npm:0.7.13" + "@hyperledger/cactus-api-client": "npm:2.0.0" "@hyperledger/cactus-cmd-api-server": "npm:2.0.0" "@hyperledger/cactus-common": "npm:2.0.0" "@hyperledger/cactus-core": "npm:2.0.0" @@ -9326,34 +9037,6 @@ __metadata: languageName: unknown linkType: soft -"@hyperledger/cactus-plugin-satp-hermes@npm:2.0.0-rc.7": - version: 2.0.0-rc.7 - resolution: "@hyperledger/cactus-plugin-satp-hermes@npm:2.0.0-rc.7" - dependencies: - "@hyperledger/cactus-cmd-api-server": "npm:2.0.0-rc.7" - "@hyperledger/cactus-common": "npm:2.0.0-rc.7" - "@hyperledger/cactus-core": "npm:2.0.0-rc.7" - "@hyperledger/cactus-core-api": "npm:2.0.0-rc.7" - "@hyperledger/cactus-plugin-keychain-memory": "npm:2.0.0-rc.7" - "@hyperledger/cactus-plugin-ledger-connector-besu": "npm:2.0.0-rc.7" - "@hyperledger/cactus-plugin-ledger-connector-fabric": "npm:2.0.0-rc.7" - "@hyperledger/cactus-plugin-object-store-ipfs": "npm:2.0.0-rc.7" - "@hyperledger/cactus-test-tooling": "npm:2.0.0-rc.7" - axios: "npm:1.7.7" - crypto-js: "npm:4.2.0" - fs-extra: "npm:11.2.0" - knex: "npm:2.4.0" - secp256k1: "npm:4.0.3" - socket.io: "npm:4.6.2" - sqlite3: "npm:5.1.5" - typescript-optional: "npm:2.0.1" - uuid: "npm:10.0.0" - web3: "npm:1.6.1" - web3-utils: "npm:1.6.1" - checksum: 10/e9e9f93c1387b7f2d7d66008b52a85f935379f4286d9a243443def2900e061b694241302fbcfa75081a885dc239f68903667a1937c049454fd1cd54a4b0b6908 - languageName: node - linkType: hard - "@hyperledger/cactus-test-api-client@workspace:packages/cactus-test-api-client": version: 0.0.0-use.local resolution: "@hyperledger/cactus-test-api-client@workspace:packages/cactus-test-api-client" @@ -19909,18 +19592,6 @@ __metadata: languageName: node linkType: hard -"bl@npm:6.0.14": - version: 6.0.14 - resolution: "bl@npm:6.0.14" - dependencies: - "@types/readable-stream": "npm:^4.0.0" - buffer: "npm:^6.0.3" - inherits: "npm:^2.0.4" - readable-stream: "npm:^4.2.0" - checksum: 10/36e96324729b056fc9763121e3688912d465bc7afec2e13a53b858658cbddf4e8a9f6d8ffc4a684a930f3b4e544424ed65c181a3044b3ad49411f6d92e4fe953 - languageName: node - linkType: hard - "bl@npm:6.0.16": version: 6.0.16 resolution: "bl@npm:6.0.16" @@ -24854,13 +24525,6 @@ __metadata: languageName: node linkType: hard -"dotenv@npm:16.0.1": - version: 16.0.1 - resolution: "dotenv@npm:16.0.1" - checksum: 10/4b530b0cc1ecfbff93ce4641fb7bbcd5731a54c3acfbdbd00283073ec3f0cbff8e93946a68eaa6fa8ece33d442555e6a61a01da8fffb553d20838ba079bf1a20 - languageName: node - linkType: hard - "dotenv@npm:16.0.3": version: 16.0.3 resolution: "dotenv@npm:16.0.3" @@ -27556,45 +27220,6 @@ __metadata: languageName: node linkType: hard -"express@npm:4.20.0": - version: 4.20.0 - resolution: "express@npm:4.20.0" - dependencies: - accepts: "npm:~1.3.8" - array-flatten: "npm:1.1.1" - body-parser: "npm:1.20.3" - content-disposition: "npm:0.5.4" - content-type: "npm:~1.0.4" - cookie: "npm:0.6.0" - cookie-signature: "npm:1.0.6" - debug: "npm:2.6.9" - depd: "npm:2.0.0" - encodeurl: "npm:~2.0.0" - escape-html: "npm:~1.0.3" - etag: "npm:~1.8.1" - finalhandler: "npm:1.2.0" - fresh: "npm:0.5.2" - http-errors: "npm:2.0.0" - merge-descriptors: "npm:1.0.3" - methods: "npm:~1.1.2" - on-finished: "npm:2.4.1" - parseurl: "npm:~1.3.3" - path-to-regexp: "npm:0.1.10" - proxy-addr: "npm:~2.0.7" - qs: "npm:6.11.0" - range-parser: "npm:~1.2.1" - safe-buffer: "npm:5.2.1" - send: "npm:0.19.0" - serve-static: "npm:1.16.0" - setprototypeof: "npm:1.2.0" - statuses: "npm:2.0.1" - type-is: "npm:~1.6.18" - utils-merge: "npm:1.0.1" - vary: "npm:~1.1.2" - checksum: 10/4131f566cf8f6d1611475d5ff5d0dbc5c628ad8b525aa2aa2b3da9a23a041efcce09ede10b8a31315b0258ac4e53208a009fd7669ee1eb385936a0d54adb3cde - languageName: node - linkType: hard - "express@npm:4.21.0": version: 4.21.0 resolution: "express@npm:4.21.0" @@ -28073,30 +27698,6 @@ __metadata: languageName: node linkType: hard -"fastify@npm:4.26.2": - version: 4.26.2 - resolution: "fastify@npm:4.26.2" - dependencies: - "@fastify/ajv-compiler": "npm:^3.5.0" - "@fastify/error": "npm:^3.4.0" - "@fastify/fast-json-stringify-compiler": "npm:^4.3.0" - abstract-logging: "npm:^2.0.1" - avvio: "npm:^8.3.0" - fast-content-type-parse: "npm:^1.1.0" - fast-json-stringify: "npm:^5.8.0" - find-my-way: "npm:^8.0.0" - light-my-request: "npm:^5.11.0" - pino: "npm:^8.17.0" - process-warning: "npm:^3.0.0" - proxy-addr: "npm:^2.0.7" - rfdc: "npm:^1.3.0" - secure-json-parse: "npm:^2.7.0" - semver: "npm:^7.5.4" - toad-cache: "npm:^3.3.0" - checksum: 10/24ee6b1496bf0c3b6b266edef6654c547ea54ffe3a17a98afd0f2a8e7a69e0fea2b58eaebb81388fa36d20032e239e656fbfdfac539b4758483a438250f791ff - languageName: node - linkType: hard - "fastify@npm:4.28.1": version: 4.28.1 resolution: "fastify@npm:4.28.1" @@ -28364,21 +27965,6 @@ __metadata: languageName: node linkType: hard -"finalhandler@npm:1.2.0": - version: 1.2.0 - resolution: "finalhandler@npm:1.2.0" - dependencies: - debug: "npm:2.6.9" - encodeurl: "npm:~1.0.2" - escape-html: "npm:~1.0.3" - on-finished: "npm:2.4.1" - parseurl: "npm:~1.3.3" - statuses: "npm:2.0.1" - unpipe: "npm:~1.0.0" - checksum: 10/635718cb203c6d18e6b48dfbb6c54ccb08ea470e4f474ddcef38c47edcf3227feec316f886dd701235997d8af35240cae49856721ce18f539ad038665ebbf163 - languageName: node - linkType: hard - "finalhandler@npm:1.3.1": version: 1.3.1 resolution: "finalhandler@npm:1.3.1" @@ -41042,16 +40628,6 @@ __metadata: languageName: node linkType: hard -"pino-abstract-transport@npm:^1.2.0": - version: 1.2.0 - resolution: "pino-abstract-transport@npm:1.2.0" - dependencies: - readable-stream: "npm:^4.0.0" - split2: "npm:^4.0.0" - checksum: 10/6ec1d19a7ff3347fd21576f744c31c3e38ca4463ae638818408f43698c936f96be6a0bc750af5f7c1ae81873183bfcb062b7a0d12dc159a1813ea900c388c693 - languageName: node - linkType: hard - "pino-abstract-transport@npm:^2.0.0": version: 2.0.0 resolution: "pino-abstract-transport@npm:2.0.0" @@ -41061,13 +40637,6 @@ __metadata: languageName: node linkType: hard -"pino-std-serializers@npm:^6.0.0": - version: 6.2.2 - resolution: "pino-std-serializers@npm:6.2.2" - checksum: 10/a00cdff4e1fbc206da9bed047e6dc400b065f43e8b4cef1635b0192feab0e8f932cdeb0faaa38a5d93d2e777ba4cda939c2ed4c1a70f6839ff25f9aef97c27ff - languageName: node - linkType: hard - "pino-std-serializers@npm:^7.0.0": version: 7.0.0 resolution: "pino-std-serializers@npm:7.0.0" @@ -41075,27 +40644,6 @@ __metadata: languageName: node linkType: hard -"pino@npm:^8.17.0": - version: 8.21.0 - resolution: "pino@npm:8.21.0" - dependencies: - atomic-sleep: "npm:^1.0.0" - fast-redact: "npm:^3.1.1" - on-exit-leak-free: "npm:^2.1.0" - pino-abstract-transport: "npm:^1.2.0" - pino-std-serializers: "npm:^6.0.0" - process-warning: "npm:^3.0.0" - quick-format-unescaped: "npm:^4.0.3" - real-require: "npm:^0.2.0" - safe-stable-stringify: "npm:^2.3.1" - sonic-boom: "npm:^3.7.0" - thread-stream: "npm:^2.6.0" - bin: - pino: bin.js - checksum: 10/5a054eab533ab91b20f63497b86070f0a6b40e4688cde9de66d23e03d6046c4e95d69c3f526dea9f30bcbc5874c7fbf0f91660cded4753946fd02261ca8ac340 - languageName: node - linkType: hard - "pino@npm:^9.0.0": version: 9.5.0 resolution: "pino@npm:9.5.0" @@ -43081,15 +42629,6 @@ __metadata: languageName: node linkType: hard -"qs@npm:6.11.0": - version: 6.11.0 - resolution: "qs@npm:6.11.0" - dependencies: - side-channel: "npm:^1.0.4" - checksum: 10/5a3bfea3e2f359ede1bfa5d2f0dbe54001aa55e40e27dc3e60fab814362d83a9b30758db057c2011b6f53a2d4e4e5150194b5bac45372652aecb3e3c0d4b256e - languageName: node - linkType: hard - "qs@npm:6.13.0, qs@npm:^6.12.3, qs@npm:^6.13.0, qs@npm:^6.9.4": version: 6.13.0 resolution: "qs@npm:6.13.0" @@ -43801,7 +43340,7 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^4.0.0, readable-stream@npm:^4.2.0, readable-stream@npm:^4.5.2": +"readable-stream@npm:^4.2.0, readable-stream@npm:^4.5.2": version: 4.5.2 resolution: "readable-stream@npm:4.5.2" dependencies: @@ -45592,27 +45131,6 @@ __metadata: languageName: node linkType: hard -"send@npm:0.18.0": - version: 0.18.0 - resolution: "send@npm:0.18.0" - dependencies: - debug: "npm:2.6.9" - depd: "npm:2.0.0" - destroy: "npm:1.2.0" - encodeurl: "npm:~1.0.2" - escape-html: "npm:~1.0.3" - etag: "npm:~1.8.1" - fresh: "npm:0.5.2" - http-errors: "npm:2.0.0" - mime: "npm:1.6.0" - ms: "npm:2.1.3" - on-finished: "npm:2.4.1" - range-parser: "npm:~1.2.1" - statuses: "npm:2.0.1" - checksum: 10/ec66c0ad109680ad8141d507677cfd8b4e40b9559de23191871803ed241718e99026faa46c398dcfb9250676076573bd6bfe5d0ec347f88f4b7b8533d1d391cb - languageName: node - linkType: hard - "send@npm:0.19.0": version: 0.19.0 resolution: "send@npm:0.19.0" @@ -45713,18 +45231,6 @@ __metadata: languageName: node linkType: hard -"serve-static@npm:1.16.0": - version: 1.16.0 - resolution: "serve-static@npm:1.16.0" - dependencies: - encodeurl: "npm:~1.0.2" - escape-html: "npm:~1.0.3" - parseurl: "npm:~1.3.3" - send: "npm:0.18.0" - checksum: 10/29a01f67e8c64a359d49dd0c46bc95bb4aa99781f97845dccbf0c8cd0284c5fd79ad7fb9433a36fac4b6c58b577d3eab314a379142412413b8b5cd73be3cd551 - languageName: node - linkType: hard - "serve-static@npm:1.16.2": version: 1.16.2 resolution: "serve-static@npm:1.16.2" @@ -46439,15 +45945,6 @@ __metadata: languageName: node linkType: hard -"sonic-boom@npm:^3.7.0": - version: 3.8.1 - resolution: "sonic-boom@npm:3.8.1" - dependencies: - atomic-sleep: "npm:^1.0.0" - checksum: 10/e03c9611e43fa81132cd2ce0fe4eb7fbcf19db267e9dec20dc6c586f82465c9c906e91a02f72150c740463ad9335536ea2131850307aaa6686d1fb5d4cc4be3e - languageName: node - linkType: hard - "sonic-boom@npm:^4.0.1": version: 4.2.0 resolution: "sonic-boom@npm:4.2.0" @@ -48590,15 +48087,6 @@ __metadata: languageName: node linkType: hard -"thread-stream@npm:^2.6.0": - version: 2.7.0 - resolution: "thread-stream@npm:2.7.0" - dependencies: - real-require: "npm:^0.2.0" - checksum: 10/03e743a2ccb2af5fa695d2e4369113336ee9b9f09c4453d50a222cbb4ae3af321bff658e0e5bf8bfbce9d7f5a7bf6262d12a2a365e160f4e76380ec624d32e7b - languageName: node - linkType: hard - "thread-stream@npm:^3.0.0": version: 3.1.0 resolution: "thread-stream@npm:3.1.0"