{"id":23236749,"url":"https://github.com/pratikpc/fabric-contract-client","last_synced_at":"2025-07-14T09:08:26.208Z","repository":{"id":57137929,"uuid":"450991443","full_name":"pratikpc/fabric-contract-client","owner":"pratikpc","description":null,"archived":false,"fork":false,"pushed_at":"2022-08-15T04:42:23.000Z","size":69,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"develop","last_synced_at":"2025-06-11T09:57:00.565Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pratikpc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-01-23T03:07:30.000Z","updated_at":"2022-01-23T13:52:57.000Z","dependencies_parsed_at":"2022-08-22T20:50:39.911Z","dependency_job_id":null,"html_url":"https://github.com/pratikpc/fabric-contract-client","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/pratikpc/fabric-contract-client","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pratikpc%2Ffabric-contract-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pratikpc%2Ffabric-contract-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pratikpc%2Ffabric-contract-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pratikpc%2Ffabric-contract-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pratikpc","download_url":"https://codeload.github.com/pratikpc/fabric-contract-client/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pratikpc%2Ffabric-contract-client/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265265780,"owners_count":23737103,"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-12-19T04:12:37.543Z","updated_at":"2025-07-14T09:08:25.886Z","avatar_url":"https://github.com/pratikpc.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Fabric Contract Client\n\nContract's should be written in a way that is clean, simple and easy to maintain.  \nFor this, I was a big fan of [Convector](https://github.com/hyperledger-labs/convector)  \nBut given Convector is not likely to be maintained or [support Fabric 2.0](https://github.com/hyperledger-labs/convector/issues/117), I needed to find and maintain a replacement which allows me to write cleaner code.\n\nI noticed that the [`fabric-contract-api`](https://www.npmjs.com/package/fabric-contract-api) exists to write Chaincode but it has no client support.\n\nThis leverages your [fabric-contract-api](https://www.npmjs.com/package/fabric-contract-api) Chaincodes to extend and support them for usage at the Client end thus helping you write cleaner and easy to maintain code.\n\n## Usage\n\nInclude the library first\n```typescript\nimport ContractClient from '@pratikpc/fabric-contract-client';\n```\nYou need to connect to the network first. This code remains same and is fairly simple.  \nChainCodeContract is the type of the contract that you have deployed. \n\n1. My ChainCodeContract's actual name is `CarContract`\n2. So you don't even need to know the actual name.\n3. The extraction is handled by the code.\n4. As long as you annotate via Info parameter which you should be doing anyways\n5. If not, you can pass the name of the contract as the 3rd parameter\n```typescript\n// Use Library\nconst client = ContractClient(ChainCodeContract, network);\n```\n\n```typescript\n// Modern way to communicate with the library\nconst time = await client.returnCurrentTime();\nconsole.log(\n    'Chaincode test result: Time is ',\n    time\n);\n\n// See how simple passing args can be\nconsole.log(\n    `Chaincode says ${await client.sayHi('Pratik')}`\n);\n\nconsole.log('Transaction has been submitted');\n```\n## Intellisense\n\nWhen using Typescript or JavaScript, does this support Intellisense?\n\nYes of course it does.\n\n![Intellisense working](docs/intellisense-contract-client.png)\n\n\n## Typescript Type Checks\n\nYes of course.\n\n## Older way\n\nFor those interested how it looked before this API was around\n\n```typescript\nconst contract =\n    network.getContract('chaincode');\nconsole.log(\n    'Using traditional approach to query Hyperledger Fabric',\n    Number(\n        (\n            await contract.evaluateTransaction(\n                'returnCurrentTime'\n            )\n        ).toString()\n    )\n);\nconsole.log(\n    'Using traditional approach to say hi to Hyperledger Fabric',\n    (\n        await contract.evaluateTransaction(\n            'sayHi',\n            'Pratik'\n        )\n    ).toString()\n);\n```\n\nThis code:- \n1. Readability is less\n2. Expects every argument to be a String unlike ours\n3. Needs to convert Output from String unlike ours  \nOurs uses the value of your return argument\n4. Needs you to know whether a transaction is submit or evaluate\n5. Requires you to remember the name of the Chaincode. Mine extracts it from the Info annotation.\n\n## Support for executing new and old way in the same code\n\nYes this support exists!\n\n## What's the catch?\n\nThe catch is that we expect you to write the code with proper and corect annotations\n\n```typescript\n@Info({\n    title: 'CarContract',\n    DeployedChainCodeName: 'DeployedCarContract',\n    description: 'A sample Car Contract'\n})\nexport default class CarContract extends Contract {\n    @Transaction(false)\n    @Returns('boolean')\n    // eslint-disable-next-line class-methods-use-this\n    public async carExists(\n        ctx: Context,\n        carId: string\n    ): Promise\u003cboolean\u003e {\n        const data: Uint8Array = await ctx.stub.getState(\n            carId\n        );\n        return !!data \u0026\u0026 data.length \u003e 0;\n    }\n}\n```\n\n## Contact me\n\nYou can create an issue here or contact me [via LinkedIn](https://www.linkedin.com/in/pratik-chowdhury-889bb2183/)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpratikpc%2Ffabric-contract-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpratikpc%2Ffabric-contract-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpratikpc%2Ffabric-contract-client/lists"}