{"id":13525570,"url":"https://github.com/sardariuss/ic_btc_multisig","last_synced_at":"2025-04-01T05:31:49.336Z","repository":{"id":208327582,"uuid":"717098058","full_name":"sardariuss/ic_btc_multisig","owner":"sardariuss","description":null,"archived":false,"fork":false,"pushed_at":"2023-12-04T15:21:01.000Z","size":181,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-11-02T10:32:20.743Z","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":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sardariuss.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-11-10T14:53:42.000Z","updated_at":"2024-08-02T20:37:19.000Z","dependencies_parsed_at":"2024-11-02T10:30:46.520Z","dependency_job_id":null,"html_url":"https://github.com/sardariuss/ic_btc_multisig","commit_stats":null,"previous_names":["sardariuss/ic_btc_multisig"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sardariuss%2Fic_btc_multisig","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sardariuss%2Fic_btc_multisig/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sardariuss%2Fic_btc_multisig/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sardariuss%2Fic_btc_multisig/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sardariuss","download_url":"https://codeload.github.com/sardariuss/ic_btc_multisig/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246591316,"owners_count":20801982,"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-08-01T06:01:20.030Z","updated_at":"2025-04-01T05:31:48.899Z","avatar_url":"https://github.com/sardariuss.png","language":"TypeScript","funding_links":[],"categories":["Chain Fusion"],"sub_categories":["Bitcoin"],"readme":"# Multi-subnet wallet on the Internet Computer\n\n## ⚠️ Disclaimer\n\n**USE AT YOUR OWN RISK!**\n\nThe following code is provided as-is and has not undergone deep testing or auditing. It is strongly advised not to use this code for transferring real bitcoin funds on the mainnet. The authors and contributors disclaim any responsibility for potential issues or losses resulting from the use of this code.\n\n## 🚀 Deploy the smart contract on the [Internet Computer](https://internetcomputer.org/)\n\nThe contracts are already deployed on the IC for the Bitcoin testnet [here](https://o3zgr-waaaa-aaaap-abr2q-cai.raw.icp0.io/).  \nTo deploy it yourself on the IC, you can inspire yourself from the script _install-ic.sh_. However note that to install the fiduciary canister on the fiduciary subnet, the only present way to do so is to create the canister with the dfx ledger command:  \n```dfx ledger create-canister --subnet-type=fiduciary --e8s=50000000 --ic \u003cCONTROLLER\u003e```\n\n## 🔎 How does it work?\n\nThe Internet Computer can be used to create Bitcoin wallets, where the private key never exists physically, but signatures are generated by a secure multi-party computation among the nodes of a subnet. To make such wallet even more secure, we can create P2WSH multi-sig addresses that request signatures generated from different subnets, so that the node providers of these subnets would need to collude to steal the assets.\n\n### Architecture\n\nThe multi-subnet wallet is composed of two backend canisters: the custody wallet canister and the fiduciary canister.  \nThe custody wallet is the main canister. It interfaces with the bitcoin API to get the balance, query the UTXOs and construct the transaction to send when withdrawing funds.  \nThe fiduciary canister is the second canister which jobs are to create to generate the second public key for the multi-sig address and insert the second signature then send the multi-sig transaction created by the custody wallet canister.\nBoth canisters use the code from src/multisig_common.\n\n### Signatures\n\nThe canisters generate 2x2 multisig bitcoin P2WSH addresses based on two public keys:  \n - the first pk is generated by the custody wallet itself, directly calling the ecdsa_public_key method with the key name \"test_key_1\"\n - the second pk is generated by the fiduciary canister, which also calls the ecdsa_public_key method but with a different key name (hard-coded to \"key_1\")\nThe principal's caller is used for derivation path so that a unique bitcoin address and signature is derived for each user.\n\n### Address creation flow\n\n```mermaid\nsequenceDiagram\nFrontend-\u003e\u003eCustody Wallet: get_bitcoin_address\nCustody Wallet-\u003e\u003eECDSA API: ecdsa_public_key(\"test_key_1\", principal)\nCustody Wallet-\u003e\u003eFiduciary: public_key(principal)\nFiduciary-\u003e\u003eECDSA API: ecdsa_public_key(\"key_1\", principal)\nNote right of Custody Wallet: generate 2x2 P2WSH multisig address\nCustody Wallet-\u003e\u003eFrontend: address\n```\n\nWhen a new address is generated for a user, the custody wallet canister keeps in memory the witness script that has been used to generate the address for that user. When the user sends funds from that address, the associated script is used to generate sighashes which are signed by both canisters and added to the witness to form a valid transaction.  \n\nThe withdrawal process unfolds in two distinct stages. First the custody wallet canister creates the transaction and add the first signature by signing the sighash itself. Then the transaction is passed to the fiduciary canister which generates and adds the second signature and finally sends the transaction to the bitcoin network.\n\n### Withdrawal flow\n\n```mermaid\nsequenceDiagram\nFrontend-\u003e\u003eCustody Wallet: init_send_request\nCustody Wallet-\u003e\u003eBitcoin API: get_utxos(btc_address)\nBitcoin API--\u003e\u003eCustody Wallet: utxos\nCustody Wallet-\u003e\u003eCustody Wallet: build transaction\nCustody Wallet-\u003e\u003eECDSA API: sign_with_ecdsa(\"test_key_1\", principal, sighash)\nECDSA API--\u003e\u003eCustody Wallet: signature 1\nCustody Wallet-\u003e\u003eCustody Wallet: insert signature 1\nCustody Wallet--\u003e\u003eFrontend: transaction\nFrontend-\u003e\u003eFiduciary: finalize_send_request(transaction)\nFiduciary-\u003e\u003eECDSA API: sign_with_ecdsa(\"key_1\", principal, sighash)\nECDSA API--\u003e\u003eFiduciary: signature 2\nFiduciary-\u003e\u003eFiduciary: insert signature 2\nFiduciary-\u003e\u003eBitcoin API: send_transaction(transaction)\nFiduciary--\u003e\u003eFrontend: transaction identifier\n```\n\n## 📃 Notes\n\n - The fee to sign_with_ecdsa is set to 25 billions (contrary to the 10 billions found in the dfinity btc example) otherwise the ecdsa signature sometimes failed with the error \"insufficient cycles\".\n\n## 🚧 Pending improvements\n\n - [ ] During pre-upgrade, save the CustodyData in stable memory to restore it after the upgrade\n - [ ] Add an estimation of the fee to send bitcoins in the UI\n - [ ] Allow the user to change the bitcoin network live\n - [ ] Allow each user to have multiple accounts (e.g. incremental suffix added to principal for the derivation path)\n - [ ] Ideally, the principal of the fiduciary canister shall be hard-coded in the custody wallet (instead of injected during the install)\n - [ ] Test on Bitcoin mainnet\n - [ ] Audit, black-hole, create verifiable wasm hash\n\n## 🙏 Credits\n\n - The rust code is based on Dfinity's [bitcoin example](https://github.com/rust-bitcoin/rust-bitcoin/tree/master)\n - The welcome logo effects are from the [Vite-React-Motoko template](https://github.com/rvanasa/vite-react-motoko/tree/main)\n - The CSS title [glitch effect](https://codepen.io/aldrie/pen/PojGYLo)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsardariuss%2Fic_btc_multisig","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsardariuss%2Fic_btc_multisig","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsardariuss%2Fic_btc_multisig/lists"}