|
6 | 6 | import re |
7 | 7 |
|
8 | 8 | from electrum import constants |
| 9 | +from electrum.bip32 import BIP32Node |
9 | 10 | from electrum.plugin import BasePlugin, hook |
10 | 11 | from electrum.i18n import _ |
11 | 12 | from electrum.util import UserFacingException |
@@ -74,8 +75,12 @@ def start(self): |
74 | 75 | args.extend([ '--unix-listener-path', self.socket_path ]) |
75 | 76 |
|
76 | 77 | for wallet in self.wallets: |
77 | | - for xpub in wallet.get_master_public_keys(): |
| 78 | + if wallet.m is None: |
| 79 | + xpub = wallet.get_master_public_key() |
78 | 80 | args.extend([ '--xpub', xpub ]) |
| 81 | + else: # Multisig wallet |
| 82 | + for desc in get_multisig_descriptors(wallet): |
| 83 | + args.extend([ '--descriptor', desc ]) |
79 | 84 |
|
80 | 85 | for i in range(self.verbose): |
81 | 86 | args.append('-v') |
@@ -198,6 +203,31 @@ def proc_logger(proc, log_handler): |
198 | 203 | else: |
199 | 204 | log_handler('INFO', 'bwt', line) |
200 | 205 |
|
| 206 | +DESCRIPTOR_MAP_SH = { |
| 207 | + 'p2sh': 'sh(%s)', |
| 208 | + 'p2wsh': 'wsh(%s)', |
| 209 | + 'p2wsh-p2sh': 'sh(wsh(%s))', |
| 210 | +} |
| 211 | + |
| 212 | +def get_multisig_descriptors(wallet): |
| 213 | + descriptor_fmt = DESCRIPTOR_MAP_SH[wallet.txin_type] |
| 214 | + if not descriptor_fmt: |
| 215 | + _logger.warn('missing descriptor type for %s' % wallet.txin_type) |
| 216 | + return () |
| 217 | + |
| 218 | + xpubs = [convert_to_std_xpub(xpub) for xpub in wallet.get_master_public_keys()] |
| 219 | + def get_descriptor(child_index): |
| 220 | + desc_keys = ['%s/%d/*' % (xpub, child_index) for xpub in xpubs] |
| 221 | + return descriptor_fmt % 'sortedmulti(%d,%s)' % (wallet.m, ','.join(desc_keys)) |
| 222 | + |
| 223 | + # one for receive, one for change |
| 224 | + return (get_descriptor(0), get_descriptor(1)) |
| 225 | + |
| 226 | +# Convert SLIP32 ypubs/zpubs into standard BIP32 xpubs |
| 227 | +def convert_to_std_xpub(xpub): |
| 228 | + return BIP32Node.from_xkey(xpub) \ |
| 229 | + ._replace(xtype='standard') \ |
| 230 | + .to_xpub() |
201 | 231 |
|
202 | 232 | def get_network_name(): |
203 | 233 | if constants.net == constants.BitcoinMainnet: |
|
0 commit comments