{"id":19901914,"url":"https://github.com/hyperledger/firefly-cordaconnect","last_synced_at":"2025-09-11T16:46:38.321Z","repository":{"id":44900624,"uuid":"367469041","full_name":"hyperledger/firefly-cordaconnect","owner":"hyperledger","description":null,"archived":false,"fork":false,"pushed_at":"2024-07-15T14:47:28.000Z","size":109,"stargazers_count":8,"open_issues_count":4,"forks_count":4,"subscribers_count":14,"default_branch":"main","last_synced_at":"2025-05-01T09:05:25.843Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hyperledger.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-05-14T20:08:42.000Z","updated_at":"2024-07-15T14:47:32.000Z","dependencies_parsed_at":"2024-07-15T17:53:32.836Z","dependency_job_id":null,"html_url":"https://github.com/hyperledger/firefly-cordaconnect","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperledger%2Ffirefly-cordaconnect","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperledger%2Ffirefly-cordaconnect/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperledger%2Ffirefly-cordaconnect/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperledger%2Ffirefly-cordaconnect/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hyperledger","download_url":"https://codeload.github.com/hyperledger/firefly-cordaconnect/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252122302,"owners_count":21698305,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-12T20:16:35.687Z","updated_at":"2025-05-02T23:32:02.017Z","avatar_url":"https://github.com/hyperledger.png","language":"Java","readme":"# Blockchain connector for corda\n- FireFly Cordapp\n- Connector springboot application\n  - Exposes REST endpoint to interact with firefly cordapp\n  - Exposes REST endpoints to manage eventstreams and subscriptions\n  - Exposes Websocket endpoint to consume events from corda ledger \n## PRE-REQS\n- JDK 11 (such as from [https://adoptopenjdk.net/](https://gradle.org/install/))\n- gradle ([https://gradle.org/install/](https://gradle.org/install/))\n\n## BUILD\n```\n./gradlew build\n```\n\nThe outputs are in these folders:\n\n- Cordapp jars\n  - `cordapp/firefly-contracts/build/libs/firefly-contracts.jar`\n  - `cordapp/firefly-flows/build/libs/firefly-flows.jar`\n- Connector springboot application\n  - `connector/build/libs/connector.jar`\n  \n## Running locally\n\n### Prerequisites\n\n- Install above cordapps on corda nodes in your corda network\n\n### Running connector locally\n\n- Run following command to run the connector springboot application\n\n```\n./gradlew bootRun --args='--rpc.host=\u003crpc host for corda node\u003e --rpc.username=test --rpc.password=client123!'\n```\n\n- Open `http://localhost:8080/swagger-ui/index.html` to view rest endpoints available.\n- Create an eventstream using `POST /eventstream`, example request body\n\n```\n{\n  \"data\": {\n    \"name\": \"eventstream-0\",\n    \"batchSize\": 10,\n    \"batchTimeoutMS\": 5000,\n    \"blockedRetryDelaySec\": 20,\n    \"errorHandling\": \"BLOCK\",\n    \"websocket\": {\n      \"topic\": \"eventstream-0-topic\"\n    }\n  }\n}\n```\n\n- Note the eventstream id from the response\n\n```\n{\n  \"statusCode\": 200,\n  \"status\": true,\n  \"message\": \"SUCCESS\",\n  \"data\": {\n    \"id\": \"es-622a2ff8-b688-46b2-874b-de7c5cd4e8dc\",\n    \"name\": \"eventstream-0\",\n    \"batchSize\": 10,\n    \"batchTimeoutMs\": 5000,\n    \"batchRetryDelaySec\": 20,\n    \"errorHandling\": \"BLOCK\",\n    \"websocketTopic\": \"eventstream-0-topic\",\n    \"suspended\": false,\n    \"created\": \"2021-06-24T19:49:53.775Z\",\n    \"updated\": null\n  }\n}\n```\n\n- Create an subscription using `POST /subscriptions`, example request body using id of eventstream created in previous step\n\n```\n{\n  \"data\": {\n    \"fromTime\": \"2021-06-24T19:54:17.776Z\",\n    \"stream\": \"es-622a2ff8-b688-46b2-874b-de7c5cd4e8dc\",\n    \"filter\": {\n      \"stateType\": \"io.kaleido.firefly.cordapp.states.BroadcastBatch\",\n      \"stateStatus\": \"UNCONSUMED\",\n      \"relevancyStatus\": \"RELEVANT\"\n    },\n    \"name\": \"subscription-0\"\n  }\n}\n```\n\n- response \n\n```\n{\n  \"statusCode\": 200,\n  \"status\": true,\n  \"message\": \"SUCCESS\",\n  \"data\": {\n    \"id\": \"sb-6dd6e475-b2ed-4109-9831-b259e9b08ef2\",\n    \"name\": \"subscription-0\",\n    \"stream\": {\n      \"id\": \"es-622a2ff8-b688-46b2-874b-de7c5cd4e8dc\",\n      \"name\": \"eventstream-0\",\n      \"batchSize\": 10,\n      \"batchTimeoutMs\": 5000,\n      \"batchRetryDelaySec\": 20,\n      \"errorHandling\": \"BLOCK\",\n      \"websocketTopic\": \"eventstream-0-topic\",\n      \"suspended\": false,\n      \"created\": \"2021-06-24T19:49:53.775Z\",\n      \"updated\": null\n    },\n    \"stateType\": \"io.kaleido.firefly.cordapp.states.BroadcastBatch\",\n    \"stateStatus\": \"UNCONSUMED\",\n    \"relevancyStatus\": \"RELEVANT\",\n    \"fromTime\": \"2021-06-24T19:54:17.776Z\",\n    \"lastCheckpoint\": null,\n    \"created\": \"2021-06-24T19:56:15.845Z\",\n    \"updated\": null\n  }\n}\n```\n\n- setup websocket client to listen to corda events, you can use following node sample\n\n```\nconst WebSocket = require('ws')\nconst ws = new WebSocket(`ws://localhost:8080/ws`);\nlet lastAck = null;\nlet heartBeatTimeout = setTimeout(() =\u003e {\n  console.error('Event stream ping timeout');\n  ws.terminate();\n}, 10000);\nconst heartBeat = () =\u003e {\n  ws.ping();\n  clearTimeout(heartBeatTimeout);\n  heartBeatTimeout = setTimeout(() =\u003e {\n    console.error('Event stream ping timeout');\n    ws.terminate();\n  }, 2000);\n}\n\nws.on('open', () =\u003e {\n  ws.send(JSON.stringify({\n    type: 'listen',\n    topic: 'eventstream-0-topic'\n  }));\n  heartBeat();\n}).on('close', () =\u003e {\n  console.error(`Event stream websocket disconnected`);\n}).on('message', async (message) =\u003e {\n  const data = JSON.parse(message);\n  for(var i=0; i\u003cdata.length; i++) { \n    console.log(JSON.stringify(data[i]));\n  }\n  ws.send(JSON.stringify({\n    type: 'ack',\n    topic: 'eventstream-0-topic'\n  }));\n}).on('pong', () =\u003e {\n  heartBeat();\n}).on('error', err =\u003e {\n  console.error(`Event stream websocket error. ${err}`);\n});\n```\n\n- send a firefly transaction using `POST /broadcastBatch`, request body\n\n```\n{\n  \"data\": {\n    \"batchId\": \"batch-id-0\",\n    \"payloadRef\": \"some-payload-ref-0\",\n    \"observers\": [\n      \"CN=Node of u0xrgv6atc for u0fifdgpl8, O=Kaleido, L=Raleigh, C=US\"\n    ],\n    \"groupId\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\"\n  }\n}\n```\n\n- you would receive transaction hash as response \n```\n{\n  \"statusCode\": 200,\n  \"status\": true,\n  \"message\": \"SUCCESS\",\n  \"data\": \"891F8893DB10130413C4D504F42395C9D8C788684074C325DCE115E8DBF915CE\"\n}\n```\n\n- On websocket client you would receive the event message from corda\n\n```\n{\n    \"data\":\n    {\n        \"data\":\n            {\n                \"@class\":\"io.kaleido.firefly.cordapp.states.BroadcastBatch\",\n                \"author\":\"CN=Node of u0jh5fc7yc for u0fifdgpl8, O=Kaleido, L=Raleigh, C=US\",\n                \"batchId\":\"batch-id-0\",\n                \"payloadRef\":\"some-payload-ref-0\",\n                \"participants\":[\"CN=Node of u0xrgv6atc for u0fifdgpl8, O=Kaleido, L=Raleigh, C=US\",\"CN=Node of u0jh5fc7yc for u0fifdgpl8, O=Kaleido, L=Raleigh, C=US\"]\n            },\n            \"contract\":\"io.kaleido.firefly.cordapp.contracts.FireflyContract\",\n            \"notary\":\"CN=Node of u0congcs2l for u0fifdgpl8, O=Kaleido, L=Raleigh, C=US\",\n            \"encumbrance\":null,\n            \"constraint\":\n            {\n                \"@class\":\"net.corda.core.contracts.SignatureAttachmentConstraint\",\n                \"key\":\"3mviYCPz42wQCX8yUe3fdhFKHg7ZDA1dthqUQF946tgfUC43hosoa8Ef98JXufsSVMW8C6L3UEHhh4kdKr1xashDNWuacM5F43dL9Btzs534H2iEksEDX3aWWAMgXBMj88jiEmQi7orS2VSrpB29QNGYTKWZrcKrK4oJm3bYNKiv4Smrkd5zWoZQ8Tzz2HKamvSXqQ2s3MxTYXZrJ6zTz2rEMjXBF3s1d8tPqV3LBhvpDwG4MaVhg3UREzKkZGe58T8x1QJ4GEu6TGU43T3VJ295dyZSEguXj6v1g6HVqTPE8CnLvszy31E3xSBGU2sQFNeC\"\n            }\n        },\n        \"subId\":\"sb-6dd6e475-b2ed-4109-9831-b259e9b08ef2\",\n        \"signature\":\"io.kaleido.firefly.cordapp.states.BroadcastBatch\",\n        \"stateRef\":\n        {\n            \"txhash\":\"891F8893DB10130413C4D504F42395C9D8C788684074C325DCE115E8DBF915CE\",\n            \"index\":0\n        },\n        \"recordedTime\":\"2021-06-24T20:04:30.361398Z\",\n        \"consumedTime\":null\n}\n```\n\n## TODOS\n- Solve broadcast problem for corda\n    - All communication is corda is point to point, and there is no concept of global blockchain state in corda.\n    - We currently solve it by passing a list of observers (list of corda nodes)\n    - This solution has a late join problem\n- add support for async requests \n- add support for request retries similaer to ethconnect\n- e2e integration with firefly\n- Add unit/integration tests and coverage \n- Add acceptance tests\n\n\n\n\n\n \n\n\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyperledger%2Ffirefly-cordaconnect","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhyperledger%2Ffirefly-cordaconnect","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyperledger%2Ffirefly-cordaconnect/lists"}