{"id":25716335,"url":"https://github.com/interledgerjs/five-bells-condition","last_synced_at":"2025-08-21T18:23:07.455Z","repository":{"id":43866856,"uuid":"42370565","full_name":"interledgerjs/five-bells-condition","owner":"interledgerjs","description":"JavaScript implementation of Crypto Conditions validation and fulfillment","archived":false,"fork":false,"pushed_at":"2022-02-15T11:41:11.000Z","size":1533,"stargazers_count":31,"open_issues_count":14,"forks_count":21,"subscribers_count":14,"default_branch":"master","last_synced_at":"2025-04-28T23:08:21.045Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://github.com/rfcs/crypto-conditions","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/interledgerjs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-09-12T19:42:57.000Z","updated_at":"2024-04-09T19:46:47.000Z","dependencies_parsed_at":"2022-09-05T02:51:43.541Z","dependency_job_id":null,"html_url":"https://github.com/interledgerjs/five-bells-condition","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/interledgerjs%2Ffive-bells-condition","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/interledgerjs%2Ffive-bells-condition/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/interledgerjs%2Ffive-bells-condition/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/interledgerjs%2Ffive-bells-condition/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/interledgerjs","download_url":"https://codeload.github.com/interledgerjs/five-bells-condition/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252575802,"owners_count":21770628,"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":"2025-02-25T14:53:01.742Z","updated_at":"2025-05-05T20:49:51.620Z","avatar_url":"https://github.com/interledgerjs.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Crypto Conditions\n\n[![npm][npm-image]][npm-url] [![circle][circle-image]][circle-url] [![codecov][codecov-image]][codecov-url]\n\n[npm-image]: https://img.shields.io/npm/v/five-bells-condition.svg?style=flat\n[npm-url]: https://npmjs.org/package/five-bells-condition\n[circle-image]: https://circleci.com/gh/interledgerjs/five-bells-condition.svg?style=shield\n[circle-url]: https://circleci.com/gh/interledgerjs/five-bells-condition\n[codecov-image]: https://codecov.io/gh/interledgerjs/five-bells-condition/branch/master/graph/badge.svg\n[codecov-url]: https://codecov.io/gh/interledgerjs/five-bells-condition\n\n\u003e Implementation of crypto-conditions in JavaScript for Node.js and the browser\n\n## Specification\n\nEditor's Draft: [**draft-thomas-crypto-conditions-02**](https://tools.ietf.org/html/draft-thomas-crypto-conditions-02)\n\nThis specification is only a draft at this stage and has not been submitted.\n\n## Table of Contents\n\n- [Crypto Conditions](#crypto-conditions)\n    - [Specification](#specification)\n    - [Table of Contents](#table-of-contents)\n    - [API Documentation](#api-documentation)\n    - [Usage](#usage)\n        - [Validate a Condition](#validate-a-condition)\n        - [Validate a Fulfillment (No Message)](#validate-a-fulfillment-no-message)\n        - [Get Condition from Fulfillment And Validate](#get-condition-from-fulfillment-and-validate)\n        - [Create a PREIMAGE-SHA-256 Condition (Hashlock)](#create-a-preimage-sha-256-condition-hashlock)\n        - [Create a PREIMAGE-SHA-256 Fullfillment (Hashlock)](#create-a-preimage-sha-256-fullfillment-hashlock)\n        - [Parse a Fulfillment](#parse-a-fulfillment)\n        - [Create an ED25519 Condition](#create-an-ed25519-condition)\n        - [Fulfill an ED25519 Condition](#fulfill-an-ed25519-condition)\n        - [Verify a Fulfillment (with Message)](#verify-a-fulfillment-with-message)\n        - [Create a THRESHOLD-SHA-256 Condition](#create-a-threshold-sha-256-condition)\n        - [Create a THRESHOLD-SHA-256 Fulfillment](#create-a-threshold-sha-256-fulfillment)\n        - [Create a PREFIX-SHA-256 Condition](#create-a-prefix-sha-256-condition)\n        - [Create a PREFIX-SHA-256 Fulfillment](#create-a-prefix-sha-256-fulfillment)\n        - [Create an RSA-SHA-256 Condition](#create-an-rsa-sha-256-condition)\n        - [Create an RSA-SHA-256 Fulfillment](#create-an-rsa-sha-256-fulfillment)\n        - [Advanced: Parse a Condition](#advanced-parse-a-condition)\n        - [Advanced: Parse and Reserialize a THRESHOLD-SHA-256 Fulfillment](#advanced-parse-and-reserialize-a-threshold-sha-256-fulfillment)\n        - [Advanced: Manually Create a Condition](#advanced-manually-create-a-condition)\n\n## API Documentation\n\n**[API Docs](https://interledger.org/five-bells-condition/jsdoc/)**\n\n## Usage\n\n### Validate a Condition\n\n``` js\nconst cc = require('five-bells-condition')\n\n// Check a condition for validity\nconst condition = 'ni:///sha-256;47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU?fpt=preimage-sha-256\u0026cost=0'\nconst validationResult = cc.validateCondition(condition)\n// validationResult === true\n```\n\nThis will ensure that the requested type, features and fulfillment length are\nall accepted by the current implementation.\n\n### Validate a Fulfillment (No Message)\n\n``` js\nconst cc = require('five-bells-condition')\n\nconst condition = 'ni:///sha-256;47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU?fpt=preimage-sha-256\u0026cost=0'\nconst fulfillment = 'oAKAAA'\nconst validationResult = cc.validateFulfillment(fulfillment, condition)\n// validationResult === true\n```\n\nThis validates the fulfillment and ensures that it matches the given condition.\n\n### Get Condition from Fulfillment And Validate\n\n``` js\nconst cc = require('five-bells-condition')\n\nconst fulfillment = 'oAKAAA'\nconst condition = cc.fulfillmentToCondition(fulfillment)\n\n// You could now look up this condition in your database etc.\n\nconst validationResult = cc.validateFulfillment(fulfillment, condition)\n// validationResult === true\n```\n\n### Create a PREIMAGE-SHA-256 Condition (Hashlock)\n\n``` js\nconst cc = require('five-bells-condition')\n\nconst myFulfillment = new cc.PreimageSha256()\nmyFulfillment.setPreimage(new Buffer(''))\nconsole.log(myFulfillment.getConditionUri())\n// prints 'ni:///sha-256;47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU?fpt=preimage-sha-256\u0026cost=0'\n```\n\n### Create a PREIMAGE-SHA-256 Fullfillment (Hashlock)\n\n``` js\nconst cc = require('five-bells-condition')\n\nconst myFulfillment = new cc.PreimageSha256()\nmyFulfillment.setPreimage(new Buffer(''))\nconsole.log(myFulfillment.serializeUri())\n// prints 'oAKAAA'\n```\n\n### Parse a Fulfillment\n\n``` js\nconst cc = require('five-bells-condition')\n\nconst parsedFulfillment = cc.fromFulfillmentUri('oAKAAA')\n// parsedFulfillment instanceof cc.PreimageSha256 === true\n// Note: Merely parsing a fulfillment DOES NOT validate it.\n\n// Validate a fulfillment\nparsedFulfillment.validate()\n```\n\n### Create an ED25519 Condition\n\n``` js\nconst cc = require('five-bells-condition')\n\nconst ed25519Fulfillment = new cc.Ed25519Sha256()\ned25519Fulfillment.setPublicKey(new Buffer('ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf', 'hex'))\nconsole.log(ed25519Fulfillment.getConditionUri())\n// prints 'ni:///sha-256;U1YhFdW0lOI-SVF3PbDP4t_lVefj_-tB5P11yvfBaoE?fpt=ed25519-sha-256\u0026cost=131072'\n```\n\n### Fulfill an ED25519 Condition\n\n``` js\nconst cc = require('five-bells-condition')\n\nconst edPrivateKey = new Buffer('833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42', 'hex')\n\nconst ed25519Fulfillment = new cc.Ed25519Sha256()\n// ed25519Fulfillment.setPublicKey(new Buffer('...'))\n// ed25519Fulfillment.setSignature(new Buffer('...'))\n// -- or --\ned25519Fulfillment.sign(new Buffer('Hello World! Conditions are here!'), edPrivateKey)\nconsole.log(ed25519Fulfillment.getConditionUri())\n// prints 'ni:///sha-256;U1YhFdW0lOI-SVF3PbDP4t_lVefj_-tB5P11yvfBaoE?fpt=ed25519-sha-256\u0026cost=131072'\nconsole.log(ed25519Fulfillment.serializeUri())\n// prints 'pGSAIOwXK5OtXlY79JMscOEkUDTDVGfvLv1NZOv4GWg0Z-K_gUC2IpH62UMvjymLnEpIldvik_b_2hpo2t8Mze9fR6DHISpf6jzal6P0wD6p8uisHOyGpR1FISer26CdG28zHAcK'\n```\n\n### Verify a Fulfillment (with Message)\n\n``` js\nconst cc = require('five-bells-condition')\n\nconst fulfillment = 'pGSAIOwXK5OtXlY79JMscOEkUDTDVGfvLv1NZOv4GWg0Z-K_gUC2IpH62UMvjymLnEpIldvik_b_2hpo2t8Mze9fR6DHISpf6jzal6P0wD6p8uisHOyGpR1FISer26CdG28zHAcK'\nconst condition = 'ni:///sha-256;U1YhFdW0lOI-SVF3PbDP4t_lVefj_-tB5P11yvfBaoE?fpt=ed25519-sha-256\u0026cost=131072'\nconst message = new Buffer('Hello World! Conditions are here!')\n\nconst result = cc.validateFulfillment(fulfillment, condition, message)\n// result === true\n```\n\n### Create a THRESHOLD-SHA-256 Condition\n``` js\nconst cc = require('five-bells-condition')\n\nconst thresholdFulfillment = new cc.ThresholdSha256()\nthresholdFulfillment.addSubconditionUri('ni:///sha-256;U1YhFdW0lOI-SVF3PbDP4t_lVefj_-tB5P11yvfBaoE?fpt=ed25519-sha-256\u0026cost=131072')\nthresholdFulfillment.addSubfulfillmentUri('oAKAAA')\nthresholdFulfillment.setThreshold(1) // defaults to subconditions.length\nconsole.log(thresholdFulfillment.getConditionUri())\n// prints 'ni:///sha-256;l-wuy18t5Ic2GfCbVb9yAiTJ_gJbN2x34fk3eHOz5kY?fpt=threshold-sha-256\u0026cost=133120\u0026subtypes=ed25519-sha-256,preimage-sha-256'\n```\n\n### Create a THRESHOLD-SHA-256 Fulfillment\n\n``` js\nconst cc = require('five-bells-condition')\n\nconst thresholdFulfillment = new cc.ThresholdSha256()\nthresholdFulfillment.addSubfulfillmentUri('pGSAIOwXK5OtXlY79JMscOEkUDTDVGfvLv1NZOv4GWg0Z-K_gUC2IpH62UMvjymLnEpIldvik_b_2hpo2t8Mze9fR6DHISpf6jzal6P0wD6p8uisHOyGpR1FISer26CdG28zHAcK')\nthresholdFulfillment.addSubfulfillmentUri('oAKAAA')\nthresholdFulfillment.setThreshold(1) // defaults to subconditions.length\nconsole.log(thresholdFulfillment.getConditionUri())\n// prints 'ni:///sha-256;l-wuy18t5Ic2GfCbVb9yAiTJ_gJbN2x34fk3eHOz5kY?fpt=threshold-sha-256\u0026cost=133120\u0026subtypes=ed25519-sha-256,preimage-sha-256'\nconst thresholdFulfillmentUri = thresholdFulfillment.serializeUri()\n// Note: If there are more than enough fulfilled subconditions, shorter\n// fulfillments will be chosen over longer ones.\n// thresholdFulfillmentUri.length === 68\nconsole.log(thresholdFulfillmentUri)\n// prints 'ojGgBKACgAChKaQngCBTViEV1bSU4j5JUXc9sM_i3-VV5-P_60Hk_XXK98FqgYEDAgAA'\n```\n\n### Create a PREFIX-SHA-256 Condition\n\n``` js\nconst cc = require('five-bells-condition')\n\nconst prefix = new cc.PrefixSha256()\nprefix.setPrefix(new Buffer('2016:'))\nprefix.setMaxMessageLength(65536)\nprefix.setSubconditionUri('ni:///sha-256;U1YhFdW0lOI-SVF3PbDP4t_lVefj_-tB5P11yvfBaoE?fpt=ed25519-sha-256\u0026cost=131072')\nconsole.log(prefix.getConditionUri())\n// prints 'ni:///sha-256;3Q87-ZwAaOH3KKkRD-wAuTiA3g7T8idCir2Gie6hkoI?fpt=prefix-sha-256\u0026cost=197637\u0026subtypes=ed25519-sha-256'\n```\n\n### Create a PREFIX-SHA-256 Fulfillment\n\n``` js\nconst cc = require('five-bells-condition')\n\nconst prefix = new cc.PrefixSha256()\nprefix.setPrefix(new Buffer('Hello World! '))\nprefix.setMaxMessageLength(16384)\nprefix.setSubfulfillmentUri('pGSAIOwXK5OtXlY79JMscOEkUDTDVGfvLv1NZOv4GWg0Z-K_gUC2IpH62UMvjymLnEpIldvik_b_2hpo2t8Mze9fR6DHISpf6jzal6P0wD6p8uisHOyGpR1FISer26CdG28zHAcK')\nconst fulfillmentUri = prefix.serializeUri()\nconsole.log(fulfillmentUri)\n// prints 'oXuADUhlbGxvIFdvcmxkISCBAkAAomakZIAg7Bcrk61eVjv0kyxw4SRQNMNUZ-8u_U1k6_gZaDRn4r-BQLYikfrZQy-PKYucSkiV2-KT9v_aGmja3wzN719HoMchKl_qPNqXo_TAPqny6Kwc7IalHUUhJ6vboJ0bbzMcBwo'\n\nconst conditionUri = prefix.getConditionUri()\nconst message = new Buffer('Conditions are here!')\ncc.validateFulfillment(fulfillmentUri, conditionUri, message)\n```\n\n### Create an RSA-SHA-256 Condition\n\n``` js\nconst cc = require('five-bells-condition')\n\nconst rsaFulfillment = new cc.RsaSha256()\nrsaFulfillment.setPublicModulus(new Buffer('b30e7a938783babf836850ff49e14f87e3f92d5c46e33feca3e4f0b22358580b11765995f4b8eea7fb4712c2e1e316f7f775a953d232216a169d9a64ddc007120a400b37f2afc077b62fe304de74de6a119ec4076b529c4f6096b0baad4f533df0173b9b822fd85d65fa4befa92d8f524f69cbca0136bd80d095c169aec0e095', 'hex'))\nconsole.log(rsaFulfillment.getConditionUri())\n// prints 'ni:///sha-256;j2luKLUjz-Ilu0jdDQO-Eg5Srmu06lEs4dsZHHVxcdc?fpt=rsa-sha-256\u0026cost=16384'\n```\n\n### Create an RSA-SHA-256 Fulfillment\n\n``` js\nconst cc = require('five-bells-condition')\n\nconst exampleMessage = new Buffer('Hello World! Conditions are here!')\nconst privateKey =\n'-----BEGIN RSA PRIVATE KEY-----\\n' +\n'MIICXAIBAAKBgQCzDnqTh4O6v4NoUP9J4U+H4/ktXEbjP+yj5PCyI1hYCxF2WZX0\\n' +\n'uO6n+0cSwuHjFvf3dalT0jIhahadmmTdwAcSCkALN/KvwHe2L+ME3nTeahGexAdr\\n' +\n'UpxPYJawuq1PUz3wFzubgi/YXWX6S++pLY9ST2nLygE2vYDQlcFprsDglQIDAQAB\\n' +\n'AoGAB7Rjyd1W6b475U027vLm/S3uFumVk0m44QSE5uVmc8NmKPWJ4lHi0w+Y61G/\\n' +\n'booaeWdytcyho5ZxCq8OEAynQSkJiBNtzBg+xCGcO6GPOf+dFBYZFQsXiG/EbwrA\\n' +\n'pT0cv+AqiGzLIAh2WtNI6cr5/ZEMScNhMcQ4AZ1kRyUdpIECQQDbRtFz0dSMMvS/\\n' +\n'1KtDZxej9HqC5xOEuCDEZuLvk4bW4mC02OP/H/VV5qqclz0LIvMWK6TDtoFRpkvD\\n' +\n'UYiYoc85AkEA0QtH1zQlGGlliLcWoPeqjkbtf3ocmYy2exBSCwnOf87xV//k9pNC\\n' +\n'7jmoIzRgKVef8kQR/mXWszo3WbWMt0aAPQJBAMtoRD/GM/7h/fw9Uamy5lEnJsZr\\n' +\n'iMWi8HKAZp+LIJgRY1gfolA12yWWVknwWaYNA6ZbUfpjQE73jmxfI/FCmLECQBmF\\n' +\n'WAr06cZ2L5gmShPyyJbAIASdItq4LBsQHgQM+XHvENXeftR/m/87eMR7g3XopbVN\\n' +\n'DClTw4d0Bwfjuz8w0z0CQFG7RmgPqsTEGfojpRgLZnec87R6XhuUY5ZoGgpnx7r9\\n' +\n'/zGekAwjBZDKpc+H0jC14JjMzRRKeWVEpDU3k2cfBH0=\\n' +\n'-----END RSA PRIVATE KEY-----\\n'\n\nconst rsaFulfillment = new cc.RsaSha256()\n// rsaFulfillment.setPublicModulus(new Buffer('...'))\n// rsaFulfillment.setSignature(new Buffer('...'))\n// -- or --\nrsaFulfillment.sign(exampleMessage, privateKey)\nconsole.log(rsaFulfillment.serializeUri().length)\n// prints '355'\n\n// Verify RSA-SHA256 condition\nconst rsaFulfillmentUri = rsaFulfillment.serializeUri()\nconst rsaConditionUri = rsaFulfillment.getConditionUri()\ncc.validateFulfillment(rsaFulfillmentUri, rsaConditionUri, exampleMessage)\n```\n\n### Advanced: Parse a Condition\n``` js\nconst cc = require('five-bells-condition')\n\n// Parse a condition\nconst condition = 'ni:///sha-256;47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU?fpt=preimage-sha-256\u0026cost=0'\nconst parsedCondition = cc.fromConditionUri(condition)\nconsole.log(parsedCondition.constructor.name)\n// prints 'Condition'\n\n// Compile to a condition\nconsole.log(parsedCondition.serializeUri())\n// prints condition\n```\n### Advanced: Parse and Reserialize a THRESHOLD-SHA-256 Fulfillment\n\n``` js\nconst cc = require('five-bells-condition')\n\nconst thresholdFulfillmentUri = 'oi-gBKACgAChJ6AlgCB_g7Flf_H8U7ktwYFIodZd_C1LH6PWdyhK3dIAEm2QaYEBDA'\nconst reparsedFulfillment = cc.fromFulfillmentUri(thresholdFulfillmentUri)\n\nconst reserializedFulfillment = reparsedFulfillment.serializeUri()\nconsole.log(reserializedFulfillment)\n// prints thresholdFulfillmentUri\n```\n\n### Advanced: Manually Create a Condition\n\n``` js\nconst cc = require('five-bells-condition')\n\nconst myCondition = new cc.Condition()\nmyCondition.setTypeId(cc.PreimageSha256.TYPE_ID)\nmyCondition.setSubtypes(new Set('preimage-sha-256'))\nmyCondition.setHash(new Buffer('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', 'hex'))\nmyCondition.setCost(0)\nconsole.log(myCondition.serializeUri())\n// prints 'ni:///sha-256;47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU?fpt=preimage-sha-256\u0026cost=0'\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finterledgerjs%2Ffive-bells-condition","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finterledgerjs%2Ffive-bells-condition","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finterledgerjs%2Ffive-bells-condition/lists"}