{"id":22756582,"url":"https://github.com/bitcoinerlab/miniscript","last_synced_at":"2025-04-14T16:43:41.455Z","repository":{"id":65103915,"uuid":"581749364","full_name":"bitcoinerlab/miniscript","owner":"bitcoinerlab","description":"A Bitcoin Miniscript compiler and an explicit Satisfier decoupled from the tx signer.","archived":false,"fork":false,"pushed_at":"2023-09-13T07:31:54.000Z","size":431,"stargazers_count":13,"open_issues_count":2,"forks_count":6,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-03-15T11:22:50.283Z","etag":null,"topics":["asm","bitcoin","descriptors","miniscript","policy","satisfier"],"latest_commit_sha":null,"homepage":"https://bitcoinerlab.com/modules/miniscript","language":"JavaScript","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/bitcoinerlab.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-12-24T07:13:48.000Z","updated_at":"2024-06-19T22:47:08.904Z","dependencies_parsed_at":"2024-06-19T22:58:32.526Z","dependency_job_id":null,"html_url":"https://github.com/bitcoinerlab/miniscript","commit_stats":{"total_commits":31,"total_committers":1,"mean_commits":31.0,"dds":0.0,"last_synced_commit":"d420729aa46d8ea785e69e6d0548386bda6774d0"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitcoinerlab%2Fminiscript","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitcoinerlab%2Fminiscript/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitcoinerlab%2Fminiscript/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitcoinerlab%2Fminiscript/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bitcoinerlab","download_url":"https://codeload.github.com/bitcoinerlab/miniscript/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248914126,"owners_count":21182361,"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":["asm","bitcoin","descriptors","miniscript","policy","satisfier"],"created_at":"2024-12-11T07:14:22.999Z","updated_at":"2025-04-14T16:43:41.433Z","avatar_url":"https://github.com/bitcoinerlab.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Bitcoin Miniscript\n\nThis project is a JavaScript implementation of [Bitcoin Miniscript](https://bitcoin.sipa.be/miniscript/), a high-level language for describing Bitcoin spending conditions.\n\nIt includes a novel Miniscript Satisfier for generating explicit script witnesses that are decoupled from the tx signer, as well as a transpilation of [Peter Wuille's C++ code](https://github.com/sipa/miniscript) for compiling spending policies into Miniscript and Bitcoin scripts.\n\n## Features\n\n- Compile Policies into Miniscript and Bitcoin scripts.\n- A Miniscript Satisfier that discards malleable solutions.\n- The Miniscript Satisfier is able to generate explicit script witnesses from Miniscript expressions using variables, such as `pk(key)`.\n\n  For example, Miniscript `and_v(v:pk(key),after(10))` can be satisfied with `[{ asm: '\u003csig(key)\u003e', nLockTime: 10 }]`.\n\n- The ability to generate different satisfactions depending on the presence of `unknowns` (or complimentary `knowns`).\n\n  For example, Miniscript `c:and_v(or_c(pk(key1),v:ripemd160(H)),pk_k(key2))` can be satisfied with: `[{ asm: '\u003csig(key2)\u003e \u003cripemd160_preimage(H)\u003e 0' }]`.\n\n  However, if `unknowns: ['\u003cripemd160_preimage(H)\u003e']` is set, then the Miniscript can be satisfied with: `[{ asm: '\u003csig(key2)\u003e \u003csig(key1)\u003e' }]` because this solution can no longer be considered malleable, given then assumption that an attacker does not have access to the preimage.\n\n- Thoroughly tested.\n\n## Installation\n\nTo install the package, use npm:\n\n```\nnpm install @bitcoinerlab/miniscript\n```\n\n## Usage\n\nYou can test the examples in this section using the online playground demo available at https://bitcoinerlab.com/modules/miniscript.\n\n### Compiling Policies into Miniscript and Bitcoin script\n\nTo compile a Policy into a Miniscript and Bitcoin ASM, you can use the `compilePolicy` function:\n\n```javascript\nconst { compilePolicy } = require('@bitcoinerlab/miniscript');\n\nconst policy = 'or(and(pk(A),older(8640)),pk(B))';\n\nconst { miniscript, asm, issane } = compilePolicy(policy);\n```\n\n`issane` is a boolean that indicates whether the Miniscript is valid and follows the consensus and standardness rules for Bitcoin scripts. A sane Miniscript should have non-malleable solutions, not mix different timelock units on a single branch of the script, and not contain duplicate keys. In other words, it should be a well-formed and standards-compliant script that can be safely used in transactions.\n\n### Compiling Miniscript into Bitcoin script\n\nTo compile a Miniscript into Bitcoin ASM you can use the `compileMiniscript` function:\n\n```javascript\nconst { compileMiniscript } = require('@bitcoinerlab/miniscript');\n\nconst miniscript = 'and_v(v:pk(key),or_b(l:after(100),al:after(200)))';\n\nconst { asm, issane } = compileMiniscript(miniscript);\n```\n\n### Generating explicit script witnesses\n\nTo generate explicit script witnesses from a Miniscript, you can use the `satisfier` function:\n\n```javascript\nconst { satisfier } = require('@bitcoinerlab/miniscript');\n\nconst miniscript =\n  'c:or_i(andor(c:pk_h(key1),pk_h(key2),pk_h(key3)),pk_k(key4))';\n\nconst { nonMalleableSats, malleableSats } = satisfier(miniscript);\n```\n\n`satisfier` makes sure that output `satisfactions` are non-malleable and that the `miniscript` is sane by itself and it returns an object with keys:\n\n- `nonMalleableSats`: an array of objects representing good, non-malleable witnesses.\n- `malleableSats`: an array of objects representing malleable witnesses that should not be used.\n\nIn the example above `nonMalleableSats` is:\n\n```javascript\nnonMalleableSats: [\n  {asm: \"\u003csig(key4)\u003e 0\"}\n  {asm: \"\u003csig(key3)\u003e \u003ckey3\u003e 0 \u003ckey1\u003e 1\"}\n  {asm: \"\u003csig(key2)\u003e \u003ckey2\u003e \u003csig(key1)\u003e \u003ckey1\u003e 1\"}\n]\n```\n\nWhere satisfactions are ordered in ascending Weight Unit size.\n\nIn addition, `unknowns` can be set with the pieces of information the user does not have, f.ex., `\u003csig(key)\u003e` or `\u003cripemd160_preimage(H)\u003e`:\n\n```javascript\nconst { satisfier } = require('@bitcoinerlab/miniscript');\n\nconst miniscript =\n  'c:or_i(andor(c:pk_h(key1),pk_h(key2),pk_h(key3)),pk_k(key4))';\nconst unknowns = ['\u003csig(key1)\u003e', '\u003csig(key2)\u003e'];\n\nconst { nonMalleableSats, malleableSats, unknownSats } = satisfier(\n  miniscript,\n  { unknowns }\n);\n```\n\nWhen passing `unknowns`, `satisfier` returns an additional object: `{ unknownSats }` with an array of objects representing satisfactions that containt some of the `unknown` pieces of information:\n\n```javascript\nnonMalleableSats: [\n  {asm: \"\u003csig(key4)\u003e 0\"}\n  {asm: \"\u003csig(key3)\u003e \u003ckey3\u003e 0 \u003ckey1\u003e 1\"}\n]\nunknownSats: [ {asm: \"\u003csig(key2)\u003e \u003ckey2\u003e \u003csig(key1)\u003e \u003ckey1\u003e 1\"} ]\n```\n\nInstead of `unknowns`, the user has the option to provide the complementary argument `knowns`: `satisfier( miniscript, { knowns })`. This argument corresponds to the only pieces of information that are known. For instance, in the example above, `knowns` would be `['\u003csig(key3)\u003e', '\u003csig(key4)\u003e']`. It's important to note that either `knowns` or `unknowns` must be provided, but not both. If neither argument is provided, it's assumed that all signatures and preimages are known.\n\nThe objects returned in the `nonMalleableSats`, `malleableSats` and `unknownSats` arrays consist of the following properties:\n\n- `asm`: a string with the script witness.\n- `nSequence`: an integer representing the nSequence value, if needed.\n- `nLockTime`: an integer representing the nLockTime value, if needed.\n\n## Authors and Contributors\n\nThe project was initially developed and is currently maintained by [Jose-Luis Landabaso](https://github.com/landabaso). Contributions and help from other developers are welcome.\n\nHere are some resources to help you get started with contributing:\n\n### Building from source\n\nTo download the source code and build the project, follow these steps:\n\n1. Clone the repository:\n\n```\ngit clone https://github.com/bitcoinerlab/miniscript.git\n```\n\n2. Install the dependencies:\n\n```\nnpm install\n```\n\n3. Make sure you have the [`em++` compiler](https://emscripten.org/) in your PATH.\n\n4. Run the Makefile:\n\n```\nmake\n```\n\nThis will download and build Wuille's sources and generate the necessary Javascript files for the compilers.\n\n5. Build the project:\n\n```\nnpm run build\n```\n\nThis will build the project and generate the necessary files in the `dist` directory.\n\n### Documentation\n\nTo generate the programmers's documentation, which describes the library's programming interface, use the following command:\n\n```\nnpm run docs\n```\n\nThis will generate the documentation in the `docs` directory.\n\n### Testing\n\nBefore committing any code, make sure it passes all tests by running:\n\n```\nnpm run tests\n```\n\n## License\n\nThis project is licensed under the MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitcoinerlab%2Fminiscript","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbitcoinerlab%2Fminiscript","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitcoinerlab%2Fminiscript/lists"}