Skip to content

Commit

Permalink
Merge branch 'master' into fixes/multiconf
Browse files Browse the repository at this point in the history
  • Loading branch information
k9ert authored Jan 11, 2023
2 parents 05911ca + cb85062 commit 8908482
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 106 deletions.
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

- [Specter Desktop](#specter-desktop)
- [DISCLAIMER](#disclaimer)
- [Video Walkthrough](#video-walkthrough)
- [Documentation and Video Walkthrough](#documentation-and-video-walkthrough)
- [Why?](#why)
- [Help wanted: Do you like Specter?](#help-wanted-do-you-like-specter)
- [How to run](#how-to-run)
Expand All @@ -27,16 +27,17 @@
The Crypto Anarchist Manifesto - Timothy C. May - Sun, 22 Nov 92 12:11:24 PST

[![Build Status](https://api.cirrus-ci.com/github/cryptoadvance/specter-desktop.svg)](https://cirrus-ci.com/github/cryptoadvance/specter-desktop)
[![Support the project](https://img.shields.io/badge/btcpay-support%20project-orange.svg)](https://donate.specter.solutions/apps/3k77BAT6zshCGNd3i7gw9WKwXQy1/pos)

## DISCLAIMER

This software might be ready to be used but at your own risk.

If something doesn't work open an issue here or ask a question in our [Telegram group](https://t.me/spectersupport).

## Video Walkthrough
![video](https://www.youtube.com/embed/v3SEp0SkOWs) [Watch here](https://www.youtube.com/watch?v=v3SEp0SkOWs)
## Documentation and Video Walkthrough

* ![video](https://www.youtube.com/embed/v3SEp0SkOWs) [Watch here](https://www.youtube.com/watch?v=v3SEp0SkOWs)
* [documentation](https://docs.specter.solutions/desktop/)

## Why?

Expand Down
6 changes: 3 additions & 3 deletions docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ sudo yum -y install libusb libudev-devel libffi libffi-devel openssl-devel && su
```

#### Windows
* Install python 3.8.x by downloading from [python.org](https://www.python.org/downloads/windows/)
* Install python 3.10.x by downloading from [python.org](https://www.python.org/downloads/windows/)

_Do NOT install python from the Microsoft Store! It runs in a different execution environment that creates enormous headaches!_

Expand All @@ -85,8 +85,7 @@ sudo yum -y install libusb libudev-devel libffi libffi-devel openssl-devel && su


### Set up virtualenv
Specter is using `hwi-2.1.0` which by now supports higher Python versions than Specter itself. Specter currently supports Python 3.7-3.9.
If you have Python 3.10 as your global version then be sure to also install an old Python version and pass it to `virtualenv` (e.g. `virtualenv --python=python3.8 .env`) or use pyenv.
Specter is using `hwi-2.1.0` which by now supports higher Python versions than Specter itself. Specter currently supports Python 3.9 and 3.10.

```sh
git clone https://github.com/cryptoadvance/specter-desktop.git
Expand All @@ -113,6 +112,7 @@ Run the server:
cd specter-desktop
python3 -m cryptoadvance.specter server --config DevelopmentConfig --debug
```
After that, Specter will be available at http://127.0.0.1:25441/.

#### If `pip install` fails on `cryptography==3.4.x`

Expand Down
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 19 additions & 25 deletions pyinstaller/electron/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

107 changes: 46 additions & 61 deletions src/cryptoadvance/specter/server_endpoints/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import cryptography
import pgpy
import requests
from cryptoadvance.specter.util.wallet_importer import WalletImporter
from flask import Blueprint, Flask
from flask import current_app as app
from flask import jsonify, redirect, render_template, request, send_file, url_for
Expand All @@ -29,7 +30,7 @@
from ..persistence import write_devices, write_wallet
from ..server_endpoints import flash
from ..services.service import callbacks
from ..specter_error import handle_exception
from ..specter_error import SpecterError, handle_exception
from ..user import UserSecretException
from ..util.sha256sum import sha256sum
from ..util.shell import get_last_lines_from_file
Expand Down Expand Up @@ -149,74 +150,58 @@ def general():
app.specter.device_manager.update()

rescanning = False
logger.info(f"Importing {len(restore_wallets)} wallets ...")
counter = {
"success": 0,
"specific_error": 0,
"unspecific_error": 0,
"rescan_error": 0,
}
for wallet in restore_wallets:
try:
app.specter.wallet_manager.rpc.createwallet(
os.path.join(
app.specter.wallet_manager.rpc_path, wallet["alias"]
),
True,
)
except Exception as e:
# if wallet already exists in Bitcoin Core
# continue with the existing one
if "already exists" not in str(e):
flash(
_("Failed to import wallet {}, error: {}").format(
wallet["name"], e
),
"error",
)
handle_exception(e)
continue
logger.debug(
f"Wallet {wallet['alias']} already exists, skipping creation"
)
write_wallet(wallet)
app.specter.wallet_manager.update(use_threading=False)

try:
wallet_obj = app.specter.wallet_manager.get_by_alias(
wallet["alias"]
logger.info(f"Importing wallet {wallet['name']}")
wallet_importer = WalletImporter(json.dumps(wallet), app.specter)
wallet_importer.create_wallet(app.specter.wallet_manager)
wallet_importer.rescan_as_needed(app.specter)
counter["success"] += 1
except SpecterError as se:
error_type = (
"rescan_error" if "rescan" in str(se) else "specific_error"
)
wallet_obj.keypoolrefill(0, wallet_obj.IMPORT_KEYPOOL, change=False)
wallet_obj.keypoolrefill(0, wallet_obj.IMPORT_KEYPOOL, change=True)
wallet_obj.import_labels(wallet.get("labels", {}))
try:
wallet_obj.rpc.rescanblockchain(
wallet["blockheight"]
if "blockheight" in wallet
else get_startblock_by_chain(app.specter),
no_wait=True,
)
app.logger.info("Rescanning Blockchain ...")
rescanning = True
except Exception as e:
app.logger.exception(
"Exception while rescanning blockchain for wallet {}: {}".format(
wallet["alias"], e
),
e,
)
flash(
_("Failed to perform rescan for wallet: {}").format(e),
"error",
)
wallet_obj.getdata()
flash(f"Wallet '{wallet.get('name')}': {se} (skipped)", "error")
counter[error_type] += 1
except Exception as e:
flash(
_("Failed to import wallet {}").format(wallet["name"]), "error"
f"Error while importing wallet {wallet['name']}, check logs for details! (skipped)",
"error",
)
handle_exception(e)
flash(_("Specter data was successfully loaded from backup"), "info")
logger.exception(
f"Error while importing wallet {wallet['name']}: {e}"
)
counter["unspecific_error"] += 1

counter["errors_sum"] = (
counter["rescan_error"]
+ counter["specific_error"]
+ counter["unspecific_error"]
)
if counter["success"] > 0:
message = f"{counter['success']} wallets successfully restored. "

else:
message = f"Sorry, this doesn't went that well. "
if counter["errors_sum"] > 0:
message += "however, we had " if counter["success"] > 0 else "We had "
message += f"""<br>
Successful imports: {counter["success"]}<br>
Specific errors: {counter["specific_error"]}<br>
Unspecific errors: {counter["unspecific_error"]} (create an issue about it on github)<br>
Rescan issues: {counter["rescan_error"]}<br>
"""
if rescanning:
flash(
_(
"Wallets are rescanning for transactions history.\n\
This may take a few hours to complete."
),
"info",
)
message += "Wallets are rescanning for transactions history. This may take a few hours to complete."
flash(message, "info")

return render_template(
"settings/general_settings.jinja",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,13 +183,21 @@
reader.onload = function(e) {
if (files[i].webkitRelativePath.indexOf('devices/') != -1) {
console.log(files[i].name);
devices.push(JSON.parse(reader.result));
try {
devices.push(JSON.parse(reader.result));
} catch {
showError(`Could not load Device ${files[i].name}: not valid json! This Device will be skipped for import which might affect corresponding Wallets.`)
}
document.getElementById('restoredevices').value = JSON.stringify(devices);
document.getElementById('filesloaded').innerHTML = `<br>Found ${devices.length} devices and ${wallets.length} wallets:`;
document.getElementById('restore').style.display = 'block';
} else if (files[i].webkitRelativePath.indexOf('wallets/') != -1) {
console.log(files[i].name);
wallets.push(JSON.parse(reader.result));
try {
wallets.push(JSON.parse(reader.result));
} catch {
showError(`Could not load Wallet ${files[i].name}: not valid json! This wallet will be skipped for import.`)
}
document.getElementById('restorewallets').value = JSON.stringify(wallets);
document.getElementById('filesloaded').innerHTML = `<br>Found ${devices.length} devices and ${wallets.length} wallets:`;
document.getElementById('restore').style.display = 'block';
Expand Down
17 changes: 12 additions & 5 deletions src/cryptoadvance/specter/util/wallet_importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ def __init__(self, wallet_json, specter, device_manager=None):
try:
self.descriptor = DescriptorCls.from_string(recv_descriptor)
self.check_descriptor()
except Exception as e:
raise SpecterError(f"Invalid wallet descriptor: {e}")
except ValueError as e:
raise SpecterError(f"{e}: {recv_descriptor}")
if self.wallet_name in specter.wallet_manager.wallets_names:
raise SpecterError(f"Wallet with the same name already exists")
(
Expand Down Expand Up @@ -242,7 +242,7 @@ def create_wallet(self, wallet_manager):
)
except Exception as e:
logger.exception(e)
raise SpecterError(f"Failed to create wallet: {e}")
raise SpecterError(f"Failed to create wallet: {e} (check logs for details)")
logger.info(f"Created Wallet {self.wallet}")
self.wallet.keypoolrefill(0, self.wallet.IMPORT_KEYPOOL, change=False)
self.wallet.keypoolrefill(0, self.wallet.IMPORT_KEYPOOL, change=True)
Expand Down Expand Up @@ -333,7 +333,7 @@ def parse_wallet_data_import(cls, wallet_data):
wallet_data["x1/"]["xpub"]
)
else:
raise Exception('"xpub" not found in "x1/" in Electrum backup json')
raise SpecterError('"xpub" not found in "x1/" in Electrum backup json')

required_sigs = int(wallet_data.get("wallet_type").split("of")[0])
recv_descriptor = "{}(sortedmulti({},{}))".format(
Expand Down Expand Up @@ -482,7 +482,7 @@ def parse_wallet_data_import(cls, wallet_data):
wallet_data["keystore"]["xpub"], is_multisig=False
)
else:
raise Exception(
raise SpecterError(
'"xpub" not found in "keystore" in Electrum backup json'
)
recv_descriptor = "{}({})".format(
Expand Down Expand Up @@ -517,6 +517,13 @@ def parse_wallet_data_import(cls, wallet_data):
wallet_name = wallet_data.get("label", "Imported Wallet")
recv_descriptor = wallet_data.get("descriptor", None)

if wallet_name is None:
raise SpecterError(
f"Couldn't find 'name' in wallet json (alias: {wallet_data.get('alias','also not existing')})."
)
if recv_descriptor is None:
raise SpecterError("Couldn't find 'recv_descriptor' in wallet json.")

return (wallet_name, recv_descriptor, cosigners_types)

@classmethod
Expand Down
1 change: 1 addition & 0 deletions src/cryptoadvance/specter/wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -1454,6 +1454,7 @@ def update_balance(self):
else self.rpc.getbalances()["watchonly"]
)
except Exception as e:
handle_exception(e)
raise SpecterError(f"was not able to get wallet_balance because {e}")
self.balance = balance
return self.balance
Expand Down

0 comments on commit 8908482

Please sign in to comment.