Creating a 2of2 multisig wallet p2wsh
During the following step we are going to create a multisig wallet 2of2 in testnet and we are going to sign and broadcast a transaction. It is required a synced bitcoin node.
In the first steps we are going to create two master keys.
Create first Master Key
This step creates the first master key. (It is possible to create the key with dice, see firma-offline dice --help)
firma-offline random --key-name a1
Create second Master Key
This one is created providing dice launches:
firma-offline dice --key-name a2 --faces 20 -l 12 -l 11 -l 1 -l 1 -l 16 -l 8 -l 1 -l 12 -l 7 -l 4 -l 12 -l 8 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 1 -l 18 -l 19 -l 12 -l 1 -l 16 -l 1 -l 18 -l 1 -l 13 -l 1 -l 1 -l 16 -l 4 -l 3 -l 1 -l 1 -l 1 -l 1 -l 1 -l 20 -l 19 -l 18 -l 17 -l 12 -l 2
Create the 2of2 multisig wallet
For the example we are using the two master_key created in the previous step. From the offline machines
copy $HOME/.firma/testnet/keys/a1/public.json and $HOME/.firma/testnet/keys/a2/public.json to the
online machine.
COOKIE_FILE must point to the bitcoin node cookie file
firma-online --wallet-name firma-wallet create-wallet --url http://127.0.0.1:18332 --cookie-file $COOKIE_FILE -r 2 --xpub-file $HOME/.firma/testnet/keys/a1/public.json --xpub-file $HOME/.firma/testnet/keys/a2/public.json```
```json
{
"qr_files": [
"$HOME/.firma/testnet/wallets/firma-wallet/qr/qr-0.png",
"$HOME/.firma/testnet/wallets/firma-wallet/qr/qr-1.png"
],
"wallet": {
"created_at_height": 1746374,
"daemon_opts": {
"cookie_file": "/Volumes/Transcend/bitcoin-testnet/testnet3/.cookie",
"url": "http://127.0.0.1:18332"
},
"descriptor_change": "wsh(multi(2,tpubD6NzVbkrYhZ4WUShmaCWa9ZQwAVe2kKxyfY1sENpyNfaQhjLHuS82RLjz19gaFTRknZhmSVAbzbeE79RjTb5coEjsjA4yg9seCLK8EFm5Q6/1/*,tpubD6NzVbkrYhZ4WjQJ11opoGvw5D81FfKeu6DarBzVYK9UZJSFf4BJ6Dp3y8WeYWvgA5LXAjx4T2pjYVNTxBGAjwEHrcc7Q2Smkcy8VRQX62Y/1/*))#wa245p6k",
"descriptor_main": "wsh(multi(2,tpubD6NzVbkrYhZ4WUShmaCWa9ZQwAVe2kKxyfY1sENpyNfaQhjLHuS82RLjz19gaFTRknZhmSVAbzbeE79RjTb5coEjsjA4yg9seCLK8EFm5Q6/0/*,tpubD6NzVbkrYhZ4WjQJ11opoGvw5D81FfKeu6DarBzVYK9UZJSFf4BJ6Dp3y8WeYWvgA5LXAjx4T2pjYVNTxBGAjwEHrcc7Q2Smkcy8VRQX62Y/0/*))#da6q39w9",
"fingerprints": [
"7938c502",
"cabe32d7"
],
"name": "firma-wallet",
"required_sig": 2
},
"wallet_file": "$HOME/.firma/testnet/wallets/firma-wallet/descriptor.json"
}
Create a receiving address
Create a new address from the just generated wallet. Bitcoin node parameters are not needed anymore since have been saved in $HOME/.firma/testnet/firma-wallet/descriptor.json
firma-online --wallet-name firma-wallet get-address
State of indexes is saved in .firma/testnet/wallets/firma-wallet/indexes.json and by calling the command again we have:
Send some funds to tb1qz2h8n70cnp0w6290scdl5ycvm0z7sqkrlgy5kgkds0n0fp7wwk6qyn8ywd
Check balance and coins
firma-online --wallet-name firma-wallet balance
firma-online --wallet-name firma-wallet list-coins
{
"coins": [
{
"amount": 2000,
"outpoint": "1c9bbb8df5a03433f9cc3e77c102e06eda016ba7ae846166fa005c3db8b97ea1:0",
"unconfirmed": true
}
]
}
Create the PSBT
After funds receive a confirmation we can create the PSBT specifiying the recipient and the amount, you can specify more than one recipient and you can explicitly spend specific utxo with --coin. See firma-online create-tx --help
firma-online --wallet-name firma-wallet create-tx --recipient tb1qnxv2x36fk6qhg3623jmsvy0x8d97jsvf0n5vyy:1400 --psbt-name test
{
"address_reused": [],
"funded_psbt": {
"name": "test",
"psbt": "cHNidP8BAH0CAAAAAaF+ubg9XAD6ZmGErqdrAdpu4ALBdz7M+TM0oPWNu5scAAAAAAD+////AqMBAAAAAAAAIgAgaMI+YcHlEUY9mvkIVax3/a4d42jXZgcjrbWqpKNFp7l4BQAAAAAAABYAFJmYo0dJtoF0R0qMtwYR5jtL6UGJAAAAAAX8bmFtZQZ0ZXN0LWEAAQEr0AcAAAAAAAAiACASrnn5+Jhe7Sivhhv6EwzbxegCw/oJSyLNg+b0h851tAEFR1IhAuOPRdJj6043K51DVaw+MIyMHEBOuEGrv89me8fOaQLpIQLgQluouXrqa42FwP/Ki9mwFxHFQy/50SN4Zcn73HSwZFKuIgYC4EJbqLl66muNhcD/yovZsBcRxUMv+dEjeGXJ+9x0sGQMeTjFAgAAAAAAAAAAIgYC449F0mPrTjcrnUNVrD4wjIwcQE64Qau/z2Z7x85pAukMyr4y1wAAAAAAAAAAAAEBR1IhAkiG9PSdcBAS08R6LIRS6iGFbQ5ZbjY2an2EMxXcmGbPIQM2XzQNCYGxaFTBlw1c4XU4hQxj7p7ntZZDaVLjrJg39VKuIgICSIb09J1wEBLTxHoshFLqIYVtDlluNjZqfYQzFdyYZs8Myr4y1wEAAAABAAAAIgIDNl80DQmBsWhUwZcNXOF1OIUMY+6e57WWQ2lS46yYN/UMeTjFAgEAAAABAAAAAAA="
},
"psbt_file": "$HOME/.firma/testnet/psbts/test/psbt.json",
"qr_files": [
"$HOME/.firma/testnet/psbts/test/qr/qr-0.png",
"$HOME/.firma/testnet/psbts/test/qr/qr-1.png"
]
}
Sign from node A
firma-offline sign ~/.firma/testnet/psbts/test/psbt.json --key $HOME/.firma/testnet/keys/a1/PRIVATE.json --wallet-descriptor-file ~/.firma/testnet/wallets/firma-wallet/descriptor.json
The psbt.json at ~/.firma/testnet/psbts/test/psbt.json now has 1 signature.
Sign from node B
firma-offline sign ~/.firma/testnet/psbts/test/psbt.json --key $HOME/.firma/testnet/keys/r1/PRIVATE.json --wallet-descriptor-file ~/.firma/testnet/wallets/firma-wallet/descriptor.json
Combine, finalize and send TX
firma-online --wallet-name firma-wallet send-tx --psbt-file ~/.firma/testnet/psbts/test/psbt.json --broadcast
{
"broadcasted": true,
"hex": "02000000000101a17eb9b83d5c00fa666184aea76b01da6ee002c1773eccf93334a0f58dbb9b1c0000000000feffffff02a30100000000000022002068c23e61c1e511463d9af90855ac77fdae1de368d7660723adb5aaa4a345a7b978050000000000001600149998a34749b68174474a8cb70611e63b4be941890400473044022035d77e5540f64b785430469965bcb015472a69461eaf29b628b3852c4d16217c022072bd4d1790ce201761f316a7ce87976fe2f470031141d0b26d61777e3b5ed9e101483045022100b735d13b126178fd929b69fe0601fa3b08111618083ed884f95d8e1eabe3561c02203a8fff2ef514a4bdb46b9d37474c9bb39f343f6e19b35e04b47faffdd294bd8f0147522102e38f45d263eb4e372b9d4355ac3e308c8c1c404eb841abbfcf667bc7ce6902e92102e0425ba8b97aea6b8d85c0ffca8bd9b01711c5432ff9d1237865c9fbdc74b06452ae00000000",
"txid": "54233ffea203f5dd2810ed12cd811bab53b441d51a75c26cbf6fef862fe984ec"
}
View tx 54233ffea203f5dd2810ed12cd811bab53b441d51a75c26cbf6fef862fe984ec