Skip to content

Commit

Permalink
make electrum watch-only export (#530)
Browse files Browse the repository at this point in the history
  • Loading branch information
mflaxman committed Oct 20, 2020
1 parent d845c22 commit 2643538
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,22 @@
{{ wallet.account_map }}
</pre>
<button onclick="copyText(document.getElementById('account_map').innerText, 'Copied wallet data')" type="button" class="btn centered padded">Copy wallet data</button>
<br />
<hr />
<h4>Create Electrum Watch-Only Wallet</h4>
<a
id="electrum_watchonly_export"
download="{{ wallet.alias | ascii20 }}_electrum_watchonly.backup"
onclick="showNotification('Import wallet file to your Electrum: File -> Open -> Choose... -> {{ wallet.alias | ascii20 }}_electrum_watchonly.backup', 0)"
class="btn centered padded">
Download Electrum Watch-Only File
</a>
</div>
<script>
document.addEventListener("DOMContentLoaded", function(){
document.getElementById('export_wallet_file').href = 'data:text/json,' + encodeURIComponent('{{ wallet.account_map }}');
});
document.addEventListener("DOMContentLoaded", function(){
document.getElementById('electrum_watchonly_export').href = 'data:text/plain,' + encodeURIComponent('{{ wallet.get_electrum_watchonly()|tojson }}');
});
</script>
47 changes: 47 additions & 0 deletions src/cryptoadvance/specter/wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from .util.merkleblock import is_valid_merkle_proof
from .helpers import der_to_bytes, sort_descriptor, fslock, parse_utxo
from .util.base58 import decode_base58
from .util.descriptor import Descriptor
from .util.xpub import get_xpub_fingerprint
from .persistence import write_json_file
from hwilib.serializations import PSBT, CTransaction
Expand Down Expand Up @@ -663,6 +664,52 @@ def get_descriptor(self, index=None, change=False, address=None):
pass
return result

def get_electrum_watchonly(self):
if len(self.keys) == 1:
# Single-sig case:
key = self.keys[0]
return {
"keystore": {
"derivation": key.derivation.replace("h", "'"),
"root_fingerprint": key.fingerprint,
"type": "bip32",
"xprv": None,
"xpub": key.original,
},
"wallet_type": "standard",
}

# Multisig case

# Build lookup table to convert from xpub to slip132 encoded xpub (while maintaining sort order)
LOOKUP_TABLE = {}
for key in self.keys:
LOOKUP_TABLE[key.xpub] = key

desc = Descriptor.parse(
desc=self.recv_descriptor,
# assume testnet status is the same across all keys
testnet=key.is_testnet,
)
slip132_keys = []
for desc_key in desc.base_key:
# Find corresponding wallet key
slip132_keys.append(LOOKUP_TABLE[desc_key])

to_return = {
"wallet_type": "{}of{}".format(self.sigs_required, len(self.keys)),
}
for cnt, slip132_key in enumerate(slip132_keys):
to_return["x{}/".format(cnt + 1)] = {
"derivation": slip132_key.derivation.replace("h", "'"),
"root_fingerprint": slip132_key.fingerprint,
"type": "bip32",
"xprv": None,
"xpub": slip132_key.original,
}

return to_return

def get_balance(self):
try:
self.balance = self.rpc.getbalances()["watchonly"]
Expand Down

0 comments on commit 2643538

Please sign in to comment.