{"id":19178039,"url":"https://github.com/cmdruid/musig2","last_synced_at":"2025-05-07T20:43:37.224Z","repository":{"id":180491020,"uuid":"655405200","full_name":"cmdruid/musig2","owner":"cmdruid","description":"A simple and easy-to-use musig2 library, written in typescript.","archived":false,"fork":false,"pushed_at":"2024-08-15T18:22:32.000Z","size":832,"stargazers_count":16,"open_issues_count":2,"forks_count":6,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-07T20:43:31.774Z","etag":null,"topics":["bitcoin","multisig","musig","schnorr","taproot"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@cmdcode/musig2","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"cc0-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cmdruid.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2023-06-18T19:42:59.000Z","updated_at":"2025-04-09T10:25:41.000Z","dependencies_parsed_at":"2023-10-16T08:24:07.163Z","dependency_job_id":"976021cf-a7a5-4623-8685-75880a64e6f0","html_url":"https://github.com/cmdruid/musig2","commit_stats":null,"previous_names":["cmdruid/musig2"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cmdruid%2Fmusig2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cmdruid%2Fmusig2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cmdruid%2Fmusig2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cmdruid%2Fmusig2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cmdruid","download_url":"https://codeload.github.com/cmdruid/musig2/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252954140,"owners_count":21830894,"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":["bitcoin","multisig","musig","schnorr","taproot"],"created_at":"2024-11-09T10:36:18.629Z","updated_at":"2025-05-07T20:43:37.199Z","avatar_url":"https://github.com/cmdruid.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# musig2\n\nA simple and easy-to-use musig2 library, written in typescript.\n\n- Simplified version of the latest musig2 protocol [BIP0327](https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki).\n- Uses four simple methods for a signing session: `get_ctx`, `musign`, `combine_psigs` and `verify`.\n- Supports key tweaking for taproot script paths.\n- Includes `keys` util for generating proper keys and nonce values.\n\n\u003e NOTE: This library is still under development. Expect dragons!  \n\nMore documentation coming soon!\n\n## Import\n\nThis package is available on NPM for easy import into your nodejs or browser-based project:\n\n```bash\n# Node via NPM:\nnpm install @cmdcode/musig2\n# Node via Yarn:\nyarn add @cmdcode/musig2\n```\nExample import as an ES module:\n```ts\nimport * as musig from '@cmdcode/musig2'\n```\nExample import into a browser-based project:\n```html\n\u003cscript src=\"https://unpkg.com/@cmdcode/musig2\"\u003e\u003c/script\u003e\n\u003cscript\u003e const musig = window.musig2 \u003c/script\u003e\n```\n\n## Basic Usage\n\nHere is a basic example of using Musig2 for signing. The steps are as follows:\n\n * Each signer must collect the public keys and nonces from other signers.\n * Each signer then creates a partial signature and shares it around.\n * Once all partial signatures are collected, any signer can combine them into the full signature.\n\nCheck out [`test/src/demo.test.ts`](test/src/demo.test.ts) for a full reference implementation.\n\n```ts\n// Import the package.\nimport * as musig from '@cmdcode/musig2'\n\n// Encode an example string as bytes.\n  const encoder = new TextEncoder()\n  const message = encoder.encode('Hello world!')\n\n  // Let's create an example list of signers.\n  const signers = [ 'alice', 'bob', 'carol' ]\n  // We'll store each member's wallet in an array.\n  const wallets : any[] = []\n  // Let's also add some additional key tweaks.\n  const tweak1  = musig.util.random(32)\n  const tweak2  = musig.util.random(32)\n  const options = { key_tweaks : [ tweak1, tweak2 ] }\n\n  // Setup a dummy wallet for each signer.\n  for (const name of signers) {\n    // Generate some random secrets using WebCrypto.\n    const secret = musig.util.random(32)\n    const nonce  = musig.util.random(64)\n    // Create a pair of signing keys.\n    const [ sec_key, pub_key     ] = musig.keys.get_keypair(secret)\n    // Create a pair of nonces (numbers only used once).\n    const [ sec_nonce, pub_nonce ] = musig.keys.get_nonce_pair(nonce)\n    // Add the member's wallet to the array.\n    wallets.push({\n      name, sec_key, pub_key, sec_nonce, pub_nonce\n    })\n  }\n\n  // Collect public keys and nonces from all signers.\n  const group_keys   = wallets.map(e =\u003e e.pub_key)\n  const group_nonces = wallets.map(e =\u003e e.pub_nonce)\n\n  // Combine all your collected keys into a signing session.\n  const ctx = musig.ctx.get_ctx(group_keys, group_nonces, message, options)\n\n  // Each member creates their own partial signature,\n  // using their own computed signing session.\n  const group_sigs = wallets.map(wallet =\u003e {\n    return musig.sign.with_ctx(\n      ctx,\n      wallet.sec_key,\n      wallet.sec_nonce\n    )\n  })\n\n  // Combine all the partial signatures into our final signature.\n  const signature = musig.combine.psigs(ctx, group_sigs)\n\n  // Check if the signature is valid.\n  const isValid1 = musig.verify.with_ctx(ctx, signature)\n```\n\nYou can also verify the signature using an independent cryptography library, such as the excellent [@noble/curves](https://github.com/paulmillr/noble-curves) library by Paul Miller.\n\n```ts\n// BONUS: Check if the signature is valid using an independent library.\nimport { schnorr } from '@noble/curves/secp256k1'\n\nconst isValid2 = schnorr.verify(signature, message, ctx.group_pubkey)\n```\n\n## Development / Testing\n\nThis library uses `yarn` for package management.\n\n```bash\n## Clean up any old builds.\nyarn clean\n## Run all tests in the suite.\nyarn test\n## Build a new release.\nyarn release\n```\n\n## Bugs / Issues\n\nIf you run into any bugs or have any questions, please submit an issue ticket.\n\n## Contribution\n\nFeel free to fork and make contributions. Suggestions are welcome!\n\n## License\n\nUse this library however you want!\n\n## Contact\n\nYou can find me on nostr at: `npub1gg5uy8cpqx4u8wj9yvlpwm5ht757vudmrzn8y27lwunt5f2ytlusklulq3`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcmdruid%2Fmusig2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcmdruid%2Fmusig2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcmdruid%2Fmusig2/lists"}