listdescriptors true always show the master private key.
Therefore it means the key is at m/ level, so I should write everything after m.
Is this the logic?
listdesciptors true will show the private descriptors which has an xprv key
but it's not indicated if it's the master private key or just an extended private key.We should be able to tell based from the derivation path in the descriptor.
In my example, I'm using it as an extended private/public key.
I retried the process ten times with the full derivation path and each times the receiving addresses for each cosigners were the same.
I have retried the process ten times without the full derivation path but only /0/* and each times the receiving addresses for each cosigners were different.
But viewing your answer, it seems it should not be.
So why that happen?
That's because of this (
highlighted some parts):
22. switch to wallet1of2
23. importdescriptors "[{"desc":"wsh(sortedmulti(2,xprv1/84'/0'/0'/0/,xpub2/0/))#checksum1.0","timestamp":"now","active":true,"watching-only":false,"internal":false,"range":[0,999]}]"
24. importdescriptors "[{"desc":"wsh(sortedmulti(2,xprv1/84'/0'/0'/1/,xpub2/1/))#checksum1.1","timestamp":"now","active":true,"watching-only":false,"internal":true,"range":[0,999]}]"
25. switch to wallet2of2
26. importdescriptors "[{"desc":"wsh(sortedmulti(2,xprv2/84'/0'/0'/0/,xpub1/0/))#checksum2.0","timestamp":"now","active":true,"watching-only":false,"internal":false,"range":[0,999]}]"
nn. importdescriptors "[{"desc":"wsh(sortedmulti(2,xprv2/84'/0'/0'/1/,xpub1/1/))#checksum2.1","timestamp":"now","active":true,"watching-only":false,"internal":true,"range":[0,999]}]"
In wallet cosigner1, xprv1/xpub1 has a derivation path of
m/84'/0'/0'/0/* while
In wallet cosigner2, xprv1/xpub1 has a derivation path of
m/0/* which will produce different child keys.
The 'segwit sortedmulti' descriptors for those xprv/xpub key
pairs should be,
For cosigner1 (
receiving):
wsh(sortedmulti(2,"xprv1"/0/*,"xpub2"/0/*)))For cosigner1 (
change):
wsh(sortedmulti(2,"xprv1"/1/*,"xpub2"/1/*)))For cosigner2 (
receiving):
wsh(sortedmulti(2,"xprv2"/0/*,"xpub1"/0/*)))For cosigner2 (
change):
wsh(sortedmulti(2,"xprv2"/1/*,"xpub1"/1/*)))
But if you want to use the xprv as the master private key to use the full derivation path and the "
cut-off" path for the xpub (
extended public key),
you'll have to derive the master private key's "
extended public key" at the correct level first before you can use the paths you've used in your descriptor.
I used iancoleman's BIP39 tool to get the extended keys in the example below.
(
the master private key should pasted in "BIP32 Root Key" text box, then type custom derivation path, the extended keys will show below it)
For example (
RegTest - BIP48):
Cosigner1:
Master Private key:
tprv8ZgxMBicQKsPeVVYWjJqFVveMsJYUHC2Z2MxQ4sbd3FnfaQeCB3ACHFUbhkDojKF5LanxLtEbSA eBppqYR9DSYMmiX8ckuc6V84p79ZiBm3Derive the extended public key at
m/48'/0'/0'/2' (
script level for native segwit)
Extended public key:
tpubDF6UPFNY19vsBRAJ1XJ3GkatKf3NL8tQtJFfTqp8JXJe4v95A3pB2ppnxVproRB25uGzoJqSmkx ZCYEgLA1BEhRaTuvPFGQDrXbJYXZ5kv6Cosigner2:
Master Private key:
tprv8ZgxMBicQKsPej5sbayjwxAYerQAdBw6zeexWj3juLP2buD5YuEExRDVUNBkzdDQJU7hizofNBm k7Fxe7zUDF3kYAoqTfp6wNa9mFceD5mDDerive the extended public key at
m/48'/0'/0'/2' (
script level for native segwit)
Extended public key:
tpubDEwuZxw5ri4w8CErxS1Sk2nJmn7WBcZCz6yCK6M3tTWCYTK6G3sZpbMMSdhxpK8Pykfsv5W3xEQ GK2bqGEEqzCuMcYhvWMwoSJHB9kcQZLbWith that, you can now use your descriptor set-up:
Import to cosigner1:
importdescriptors "[{\"desc\": \"wsh(sortedmulti(2,tprv8ZgxMBicQKsPeVVYWjJqFVveMsJYUHC2Z2MxQ4sbd3FnfaQeCB3ACHFUbhkDojKF5LanxLtEbSAeBppqYR9DSYMmiX8ckuc6V84p79ZiBm3/48'/0'/0'/2'/0/*,tpubDEwuZxw5ri4w8CErxS1Sk2nJmn7WBcZCz6yCK6M3tTWCYTK6G3sZpbMMSdhxpK8Pykfsv5W3xEQGK2bqGEEqzCuMcYhvWMwoSJHB9kcQZLb/0/*))#e9sdw8sm\",\"timestamp\": \"now\",\"active\": true,\"watching-only\": false,\"internal\": false,\"range\": [0,999]}]"
Import to cosigner2:
importdescriptors "[{\"desc\": \"wsh(sortedmulti(2,tprv8ZgxMBicQKsPej5sbayjwxAYerQAdBw6zeexWj3juLP2buD5YuEExRDVUNBkzdDQJU7hizofNBmk7Fxe7zUDF3kYAoqTfp6wNa9mFceD5mD/48'/0'/0'/2'/0/*,tpubDF6UPFNY19vsBRAJ1XJ3GkatKf3NL8tQtJFfTqp8JXJe4v95A3pB2ppnxVproRB25uGzoJqSmkxZCYEgLA1BEhRaTuvPFGQDrXbJYXZ5kv6/0/*))#2gew492h\",\"timestamp\": \"now\",\"active\": true,\"watching-only\": false,\"internal\": false,\"range\": [0,999]}]"
(
the path for the master prv key should be up to the "address_index" level: master_prv_key/48'/0'/0'/2'/0/*)
(
the extended pub key is already at "script_type" level [the 2' above] so the path to "address_index" should only be: extended_pub_key/0/*)
Both wallets should generate the same address at first index:
bcrt1qkhl5vjge39jv7c74frtq4pzxpa5jmguwz26vqatrm03uuhtjhtnq3dmftq