diff --git a/docs/about.md b/docs/about.md new file mode 100644 index 0000000000..5a4a19908b --- /dev/null +++ b/docs/about.md @@ -0,0 +1,3 @@ + + +{{ git_site_authors }} \ No newline at end of file diff --git a/docs/architecture.md b/docs/architecture.md index 36f281f65b..1b45365466 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -1,21 +1,21 @@ -# Architectural Notes +# Architectural notes -specter-desktop and specter-cloud are flask-applications and follow typical Model-View-Control-principles. The model-part is covered by a number of business-objects and managers who are responsible for maintaining/managing those. Currently we have these managers: +Specter Desktop and Specter Cloud are flask applications and follow typical model-view-controller principles. The model part is covered by a number of business objects and managers who are responsible for maintaining/managing those. Currently we have these managers: ## Managers -* GenericDataManager is abstracting persistence-aspects and most managers which are persisting json-data are derived from this one. -* ConfigManager where the api-docs tells us: "The ConfigManager manages the configuration persisted in config.json. It's not supposed to have any side-effects. Setting and getting only with a lot of validation and computing while setting/getting." -* DeviceManager where the api-docs tells us: "A DeviceManager mainly manages the persistence of a device-json-structures compliant to helper.load_jsons.py". +* GenericDataManager is abstracting persistence aspects and most managers which are persisting json data are derived from this one. +* The ConfigManager manages the configuration persisted in config.json. It's not supposed to have any side-effects. Setting and getting only with a lot of validation and computing while setting/getting. +* A DeviceManager mainly manages the persistence of a device-json structure compliant to helper.load_jsons.py. * NodeManager manages internal and external nodes. * UserManager manages all stuff regarding Users. -* Similarly the WalletManager +* Similarly, the WalletManager manages all wallet stuff. -## Views / Blueprints -The controller is covered by "server_endpoints". Those are split up in “blueprints”. This is a way to split the urls in sub-urls. These sub-urls are loosely related to the business-objects: `/welcome`, `/auth`, `/devices`, `/nodes`, `/price`, `/services` (should be renamed "`/plugins`"), `/settings`, `/setup`, `/wallets`. +## Views and blueprints +The controller part is covered by "server_endpoints". Those are split up in “blueprints”. This is a way to split the urls in sub-urls. These sub-urls are loosely related to the business-objects: `/welcome`, `/auth`, `/devices`, `/nodes`, `/price`, `/services` (should be renamed "`/plugins`"), `/settings`, `/setup`, `/wallets`. ## Views -The views are effectively jinja2 templates which can extend from higher order ones and have placeholders which templates can then override. The `base.jinja` lays out the basic layout having a block for the `sidebar` and a `main` block (plus `head` and `scripts` ). Some blueprints (`/settings`,`/wallets`) span up a top-level-navigation. In that case, the template extend from its specific blueprint-base-template which in turn provides a block called `content` and the template decides which menu-point is active: +The views are effectively jinja2 templates which can extend from higher order ones and have placeholders which templates can then override. The `base.jinja` lays out the basic layout having a block for the `sidebar` and a `main` block (plus `head` and `scripts` ). Some blueprints (`/settings`,`/wallets`) span up a top-level navigation. In that case, the template extends from its specific blueprint-base template which in turn provides a block called `content` and the template decides which menu point is active: ``` {% extends "wallet/components/wallet_tab.jinja" %} {% set tab = 'receive' %} @@ -26,6 +26,6 @@ This is also a pattern used for plugins. # Plugins -The more specific a functionality became, the more awkward it felt to be integrated in the above core-Architecture. When we started to make exchange specific functionality, we wanted to protect the core-Architecture from deluting. Therefore we created a plugin-concept which allows to have the above concepts replicated in it there own self-contained standalone units. +The more specific a functionality became, the more awkward it felt to integrate it in the core architecture. When we started to make exchange specific functionality, we wanted to protect the core architecture. Therefore, we created a plugin concept which allows to have the above concepts replicated in their own self-contained standalone units. -We try now to implement bigger chunks of functionality in plugins. Maybe even core-functionality might be placed with "core-plugins" in the future. Those are placed in `src/specterext`. But plugins can also live in there own repos, have their own release-lifecycle and be used by Specter like any other dependency as well. For more information about plugins see [Third Party Service Integrations](./services/services.md). \ No newline at end of file +We now try to implement bigger chunks of functionality in plugins. Maybe, even core functionality might be implemented in "core plugins" in the future. Internal plugins are placed in `src/specterext`. But, plugins can also live in there own repos, have their own release lifecycle and be used by Specter like any other dependency. For more information about plugins see [Third Party Service Integrations](./extensions.md) where we also discuss the nuances between plugins and extensions. \ No newline at end of file diff --git a/docs/continuous-integration.md b/docs/continuous-integration.md index 6b367de8fd..bc10ef1b8c 100644 --- a/docs/continuous-integration.md +++ b/docs/continuous-integration.md @@ -11,7 +11,7 @@ Cirrus-CI: * supports the PR-model * quite easy to setup even though it's using docker -# Gitlab +## Gitlab Gitlab is a great CI/CD-platform and in the meantime it's quite easy to use it for GitHub-repositories. https://docs.gitlab.com/ee/ci/ci_cd_for_external_repos/github_integration.html @@ -32,17 +32,17 @@ start_bitcoind-function: * adding -rpcallowip= (from a docker network) to bitcoind * not use localhost but the docker-network-ip-address when talking to the bitcoind -# Travis-CI +## Travis-CI We're no longer using travis-ci due to the abuse-detection-system going wild on us. -# Cirrus-CI +## Cirrus-CI [Cirrus-CI](https://cirrus-ci.org) is used by Bitcoin-Core and HWI and is a quite good replacement for travis. We're using it only for PRs so far. The [../.cirrus.yml] file defines the build. We have two task, one for pytest and one for the [cypress-tests](./cypress-testing.md). -# Releasing +## Releasing -## What gets released +### What gets released We're mostly releasing automatically. Currently the following artifacts are released: * specterd (daemon) is a binary for kicking off the specter-desktop service on the command-line. We have binaries for windows, Linux and macOS @@ -50,13 +50,13 @@ We're mostly releasing automatically. Currently the following artifacts are rele * We release a pip-package * Usually some time after the release, the lncm is releasing [docker-images](https://hub.docker.com/r/lncm/specter-desktop). Very much appreciated, even though we can't guarantee for them, obviously. -# How we release +### How we release As we have a strict build-only-on-private-hardware build-policy, we're using GitLab private runners in order to build our releases. In order to test and develop the releasing automation, people can setup GitLab-projects which are syncing from their GitHub-forks. With such a setup it's possible to create test-releases and therefore test the whole procedure end-to-end. The automation of that kicks in if someone creates a tag which is named like "vX.Y.Z". This is specified in the gitlab-ci.yml. The release-job will only be triggered in cases of tags. One step will also check that the tag follows the convention above. The package upload will need a token. How to obtain the token is described in the packaging-tutorial. It's injected via GitLab-variables. ToDo: put the token on a trusted build-node. -## pyinstaller system-dependent binaries +### pyinstaller system-dependent binaries The [pyinstaller directory](../pyinstaller) contains scripts to create the platform-specific binaries (plus electron) to use specter-desktop as a desktop-software. Some of them are created and uploaded to [GitHub-releases](https://github.com/cryptoadvance/specter-desktop/releases) via more or less special build-agents. The [windows-build-agent](https://docs.gitlab.com/runner/install/windows.html) needs manual installation of git, python and docker. Docker is used to build the innosetup-file. @@ -65,7 +65,7 @@ log into the windows-machine to get docker started. Clearly there is an opportunity to move all of the creation of the windows-binary to wine on docker, similiar to the way the innosetup is running within docker. -# CI/CD-dev-env setup +## CI/CD-dev-env setup Here is a brief description on how to create a setup where the release-procedures can be tested: * We assume you have a fork of cryptoadvance/specter-desktop. We also assume that your GitLab-user-handle is the exact same as on GitHub. @@ -77,11 +77,11 @@ Here is a brief description on how to create a setup where the release-procedure * create a tag on your GitHub-fork * watch the test-release unfolding, ready to hack -# GitLab-runner setup (Windows) +### GitLab-runner setup (Windows) For Windows-releasing, we're using a windows GitLab-runner. Here is a short description on how to set one up. -## Prerequisites +#### Prerequisites You need at least Windows Home 10 which is up-to-date. The most complex dependency is setting up docker. Docker-Desktop needs a WSL2 which is a good idea to install on windows anyway. [Here](https://www.omgubuntu.co.uk/how-to-install-wsl2-on-windows-10) is a description on how to do that. @@ -96,7 +96,7 @@ Now open and check the "Environment-variables" and check that the following line ![](./images/continuous-integration_runner_windows_envvars.png) -## Runner +#### Runner The runner itself is easy to [setup](https://docs.gitlab.com/runner/install/windows.html). Follow the link or this very brief description: * `mkdir \Gitlab-Runner` diff --git a/docs/daemon.md b/docs/daemon.md index 1f1df0b15c..f80f08f1e4 100644 --- a/docs/daemon.md +++ b/docs/daemon.md @@ -68,7 +68,7 @@ WantedBy=multi-user.target You can check the status of specter.service by running `systemctl status specter.service` or for debugging, you can get more information by running `sudo journalctl -fu specter.service` -The commented section of the service file above refers to an optional reverse proxy setup which is covered in the [reverse_proxy.md](reverse_proxy.md) document. +The commented section of the service file above refers to an optional reverse proxy setup which is covered in the [reverse_proxy.md](reverse-proxy.md) document. ## bitcoind as a Service diff --git a/docs/elements.md b/docs/elements.md index 526e60d494..4485614ea7 100644 --- a/docs/elements.md +++ b/docs/elements.md @@ -5,10 +5,10 @@ This document is a description on how to get started with elements/liquid. We'll After that, we'll explain how to connect your Specter Desktop to that node, create wallets and receive some coins (via sideshift.ai). Signing transactions is nowhere different than in any other Hotwallet. -# Elements Installation +## Elements Installation The Elements's instalaation is highly dependent to your system. Choose a fitting [artifact](https://github.com/ElementsProject/elements/releases) and install them. -# Liquid Node +## Liquid Node In order to validate Peg-Ins, you'll need RPC-access to your Bitcoin-Core node. I did this with a fullnode, it might also work with a pruned node (not tested, though). First, we need to create the `elements.conf` file which is located in the `datadir`. If you don't specify the datadir at startup, the standard-directory is `/.elements/elements.conf`. Here is an example: @@ -40,7 +40,7 @@ A successfull startup will result in validating the blocks. Currently the blockh It took about 12 hours for a full-sync in my case on a Intel Quadcore Gen 6 3.50GHz. -# Liquid Configuration in Specter +## Liquid Configuration in Specter You're probably familiar with this part. On the upper-left, click on the `two arrows -> connect a new node -> Connect existing node`. Here is a screenshots with the values fitting to the configuration above: @@ -54,7 +54,7 @@ As you can your wallets disappeared but your devices did not. The shown wallets ![](./images/elements/nodechoose.png) -# Hotwallet-Creation +## Hotwallet-Creation The process of creating a Liquid Hotwallet is very similiar to creating a Bitcoin-Core Hotwallet. First you need to create a Hotwallet-Device `Add new device -> Elements Core (hot wallet) -> Continue -> Enter Name -> Continue` (Don't forget to note the seed). After that, you can directly create a single key wallet: `Create single key wallet -> Enter Name -> Create Wallet`. You can download the usual Backup Pdf. @@ -63,7 +63,7 @@ So if you now get a receive-address, you have to choose between a Confidential a ![](./images/elements/receive.png) -# Fund the wallet +## Fund the wallet There are many ways you can fund your wallet. Let's assume you have Bitcoin and want to receive LiquidBtc (LBTC). At [https://sideswap.io/peg-in-out/](https://sideswap.io/peg-in-out/) you can Peg-In some Btc as a service. At [https://sideshift.ai/](https://sideshift.ai/) you can [https://sideshift.ai/btc/liquid](swap) BTC agains LBTC (and [vice versa](https://sideshift.ai/liquid/btc)). @@ -73,9 +73,9 @@ As an example, let'S choose sideshift.ai to swap some BTC to LBTC. ![](./images/elements/txs.png) -## Advanced stuff: Elements Compilation +### Advanced stuff: Elements Compilation -# Elements Compilation +## Elements Compilation Since `v1.7.0`, It's no longer needed to compile Elements yourself as Specter is now working with Elements [0.21.0](https://github.com/ElementsProject/elements/releases/tag/elements-0.21.0). However, maybe you want to compile it for some reason, so here is a quick guide on how to do that. diff --git a/docs/endless-pacman.md b/docs/endless-pacman.md index 38e6ce5bbd..8c2a0a5e9c 100644 --- a/docs/endless-pacman.md +++ b/docs/endless-pacman.md @@ -1,21 +1,23 @@ +# Introduction + Sometimes people have issues where they get an endless Pacman animation and the application is not coming up. If you suffer from this, here are some hints on how to deal with that. -# Check The Logs +## Check The Logs The logs are usually in the `.specter` subfolder of your homediretory. There, you might find a file called `specter.log` and/or specterApp.log. If you're running Specter as a binary application (in contrast to a pip installation) which most people do that `specterApp.log` is the relevant file for you. This file might contain content which gives a hint on what's wrong. If you can't find anything suspicious, feel free to create a [pastebin](https://pastebin.com/) and ask in the chat for help (with a link to the created pastebin). -# USB-issues +## USB-issues Sometimes some devices attached via USB are blocking the startup. We had that in the past with a Game-Controller. In one case, the USB drivers where so screwed up, that only a windows in protected mode could start Specter. -# Check Port 25441 +## Check Port 25441 Maybe there is another instance (still) running. Check that via opening your brower here: [http://localhost:25441](http://localhost:25441) If that's the case, the most easy solution is to reboot your computer. -# Check security software +## Check security software Sometimes, security software is distorting the startup. E.g. Acronis is a protective system which is known to prevent starting up of Specter on windows. Other security-software might be behaving similary. For troubleshooting purposes, switch off your protective software and try again. If that helps, you need to allow specter to be running on port 25441. Check the manual on how to achieve that manually. -# Check Whether the Binary is Existing +## Check Whether the Binary is Existing The first thing Specter is doing if you start up the app is downloading the correct specterd from the GitHub-release page and storing that executable in the `Homefolder/.specter/specterd-binaries` subfolder. You should find a file called `specterd`. If the file is there but you still get the endless Pacman, try one of the following things: * delete the file so it'll get redownloaded diff --git a/docs/services/services.md b/docs/extensions.md similarity index 51% rename from docs/services/services.md rename to docs/extensions.md index fd8316daff..e4eeb3250b 100644 --- a/docs/services/services.md +++ b/docs/extensions.md @@ -1,25 +1,109 @@ -# Third-Party Service Integrations +# Extensions A developer's guide for the Specter Desktop `Extension` framework. We currently rework the naming of extensions/plugins/services. If not otherwise stated, you can see those three terms as the same, for now. +## TL;DR + +You can create an extension with an up to date Specter Desktop instance as simple as this: +``` +$ pip3 install cryptoadvance.specter --upgrade +$ mkdir /tmp/rubberduck && cd /tmp/rubberduck +$ python3 -m cryptoadvance.specter ext gen + + We need an id and a prefix for your extension. + The id should be a short string. + The prefix is usually your GitHub username + or GitHub organisation name. + Both will be used to to create a directory structure like this: + ./src/mycorpname/specterext/myextension + They will also be used when publishing this extension to pypi. + +Enter the id of your extension (lowercase only): rubberduck +Enter the prefix: mynym + + Note: Isolated client mode means that the extensions won't share the session cookie with + Specter Desktop and the integration only happens on the server side. + +Should the extension work in isolated client mode (y/n)?: n + --> Created requirements.txt + --> Created .gitignore + --> Created src/mynym/specterext/rubberduck/service.py + --> Created src/mynym/specterext/rubberduck/controller.py + --> Created src/mynym/specterext/rubberduck/config.py + --> Created src/mynym/specterext/rubberduck/__init__.py + --> Created src/mynym/specterext/rubberduck/__main__.py + --> Created src/mynym/specterext/rubberduck/templates/rubberduck/index.jinja + --> Created src/mynym/specterext/rubberduck/static/rubberduck/css/styles.css + --> Created src/mynym/specterext/rubberduck/static/rubberduck/img/ghost.png (via Github) + --> Created src/mynym/specterext/rubberduck/static/rubberduck/img/logo.jpeg (via Github) + --> Created src/mynym/specterext/rubberduck/templates/rubberduck/base.jinja + --> Created src/mynym/specterext/rubberduck/templates/rubberduck/transactions.jinja + --> Created src/mynym/specterext/rubberduck/templates/rubberduck/settings.jinja + --> Created src/mynym/specterext/rubberduck/templates/rubberduck/components/rubberduck_menu.jinja + --> Created src/mynym/specterext/rubberduck/templates/rubberduck/components/rubberduck_tab.jinja + --> Created pytest.ini + --> Created tests/conftest.py + --> Created tests/fix_ghost_machine.py + --> Created tests/fix_devices_and_wallets.py + --> Created tests/fix_testnet.py + --> Created tests/fix_keys_and_seeds.py + --> Created pyproject.toml + --> Created setup.py + --> Created setup.cfg + --> Created MANIFEST.in + + Congratulations, you've created a new extension! + + Here is how to get it to run in your development environment: + pip3 install -e . + python3 -m cryptoadvance.specter server --config DevelopmentConfig --debug + # Point your browser to http://localhost:25441 + # Click "Choose plugins" --> rubberduck + + If you want to package it, you can build it like this: + python3 -m pip install --upgrade build + python3 -m build + # Install it like this: + pip3 install dist/mynym_rubberduck-0.0.1-py3-none-any.whl + + If you want to bring your extension to production, please refer to + the readme in the dummy-extension repo: + https://github.com/cryptoadvance/specterext-dummy#how-to-get-this-to-production + + To publish your package + + python3 -m pip install --upgrade twine + python3 -m twine upload --repository testpypi dist/* + + You can get all this information again via: + python3 -m cryptoadvance.specter ext gen --help +$ +``` +The created file structure looks like this and you will feel right at home if you have some knowledge about how Flask works: + + +![](./images/extensions_file_layout.png) + + + ## Concept -As much as possible, each `Service` implementation should be entirely self-contained with little or no custom code altering existing/core Specter functionality. There is a name for that: Extension-/Pluginframework. -The term `extension` will be used for all sorts extensions whereas `plugin` will be used as a component which can be de-/activated by a user. +As much as possible, each `extension` should be entirely self-contained with little or no custom code altering core Specter functionality. There is a name for that: Extension framework. +The term `extension` will be used for all sorts of extensions whereas `plugin` will be used as a component which can be de-/activated by a user. -All extensions are completely sperated in a specific folder-structure. There are internal extensions which `SHOULD` be located in `cryptoadvance.specterext.id_of_extension` but at least 2 extensions are still at the deprecated location of `cryptoadvance.specter.services`. However that does not mean that an extension needs to be located in the same repository than specter itself. There can and will be extensions which are located in their own repositories. +All extensions are completely seperated in a specific folder structure. There are internal extensions which SHOULD be located in `cryptoadvance.specterext.id_of_extension` but at least 2 extensions are still at the deprecated location of `cryptoadvance.specter.services`. However, that does not mean that an extension needs to be located in the same repository as Specter itself. Extensions can be located in their own repository even if they are incorporated into the official Specter release. -Independent whether an extension is shipped with the official specter-release-binaries and whether it's an internal (which is shipped) or external extension (which might be shipped), the creation of extensions is already heavily supported and encouraged. -Whether an extension is shipped with the official binary is entirely the choice of the Specter Team. However, you can simply develop extensions and use them on production (only for technical personel) as described in `specterext-dummy` (see below). +Independent of whether an extension is shipped with the official Specter-release binaries and whether it's an internal (which is shipped) or external extension (which might be shipped), the creation of extensions is already heavily supported and encouraged. +Whether an extension is shipped with the official binary is ultimately a choice of the Specter team. However, you can simply develop extensions and use them on production (only for technical personel) as described in `specterext-dummy` (see below). -A description of how to create your own extension can be found at the [dummy-extension](https://github.com/cryptoadvance/specterext-dummy/). You will need to choose an organisation or username if you create one. This is used for package-structure. +A description of how to create your own extension can be found above. -All the attributes of an extension are currently (json-support is planned sooner or later) defined as attributes of a class which is derived from the class `Service` (should be renamed). That class has attributes which are essential. So let's discuss them briefly. +All the attributes of an extension are currently (json support is planned) defined as attributes of a class which is derived from the class `Service` (should be renamed). That class has attributes which are essential. So let's discuss them briefly. -## Extension Attributes -Here is an Example. This class definition MUST be stored in a file called "service.py" within a package with the name `org-id.specterext.extions-id`. +## Extension attributes +Here is an example. This class definition MUST be stored in a file called "service.py" within a package with the name `org-id.specterext.extions-id`. ``` class DiceService(Service): id = "dice" @@ -32,19 +116,18 @@ class DiceService(Service): isolated_client = False devstatus = devstatus_alpha ``` -So this defines the base `Service` class (to be renamed to "Extension") that all extensions must inherit from. This is wired to enable `Extension` auto-discovery. Any feature that is common to most or all `Service` integrations should be implemented here. +This defines the base `Service` class (to be renamed to "Extension") that all extensions must inherit from. This also enables `extension` auto-discovery. Any feature that is common to most or all `Service` integrations should be implemented here. With inheriting from `Service` you get some usefull methods explained later. - -The `id` needs to be unique within a specific specter-instance where this extension is part of. The `name` is the displayname as shown to the user in the plugin-area (currently there is not yet a technical difference between extensions and plugins). The `icon` will be used where labels are used to be diplayed if this extension is reserving addresses. The `logo` and the `desc` (ription) is also used in the plugin-area ("choose plugins"). -If the extension has a UI (currently all of them have one), `has_blueprint` is True. `The blueprint_module` is referencing the controller-module where endpoints are defined. It's recommended to follow the format `org.specterext.extions-id.controller`. -`isolated_client` Should not be used yet. It is determining where in the url-path-tree the blueprint will be mounted. This might have an impact on whether the extension's frontend-client has access to the cookie used in specter. Check `config.py` for details. -`devstatus` is one of `devstatus_alpha`, `devstatus_beta` or `devstatus_prod` defined in `cryptoadvance.specter.services.service`. Each specter-instance will have a config-variable called `SERVICES_DEVSTATUS_THRESHOLD` (prod in Production and alpha in Development) and depending on that, the plugin will be available to the user. +The `id` needs to be unique within a specific specter-instance where this extension is part of. The `name` is the displayname as shown to the user in the plugin-area (currently there is not yet a technical difference between extensions and plugins). The `icon` will be used where labels are used to be diplayed if this extension is reserving addresses. The `logo` and the `desc`ription is also used in the plugin-area ("choose plugins"). +If the extension has a UI (currently all of them have one), `has_blueprint` is True. `The blueprint_module` is referencing the controller module where endpoints are defined. It's recommended to follow the format `org.specterext.extions-id.controller`. +`isolated_client` should not be used yet. It is determining where in the url-path tree the blueprint will be mounted. This might have an impact on whether the extension's frontend client has access to the cookie used in Specter. Check `config.py` for details. +`devstatus` is one of `devstatus_alpha`, `devstatus_beta` or `devstatus_prod` defined in `cryptoadvance.specter.services.service`. Each Specter instance will have a config variable called `SERVICES_DEVSTATUS_THRESHOLD` (prod in Production and alpha in Development) and depending on that, the plugin will be available to the user. ## Frontend aspects As stated, you can have your own frontend with a blueprint. If you only have one, it needs to have a `/` route in order to be linkable from the `choose your plugin` page. -If you create your extension with a blueprint, it'll create also a controller for you which, simplified, look like this: +If you create your extension with a blueprint, it'll also create a controller for you which, simplified, looks like this: ``` rubberduck_endpoint = ScratchpadService.blueprint @@ -66,53 +149,44 @@ def index(): ) [...] ``` - But you can also have more than one blueprint. Define them like this in your service-class: + But you can also have more than one blueprint. Define them like this in your service class: ``` blueprint_modules = { "default" : "mynym.specterext.rubberduck.controller", "ui" : "mynym.specterext.rubberduck.controller_ui" } ``` -You have to have a default-blueprint which has the above mentioned index-page. +You have to have a default blueprint which has the above mentioned index page. In your controller, the endpoint needs to be specified like this: ``` ui = RubberduckService.blueprints["ui"] ``` -## Data-Storage -Effort has been taken to provide `Service` data storage that is separate from existing data stores in order to keep those areas clean and simple. Where touchpoints are unavoidable, they are kept to the absolute bare minimum (e.g. `User.services` list, `Address.service_id` field). - - ## `Address`-Level Integration An `Address` can be associated with a `Service` (e.g. addr X received a smash buy from `Service` Foo) via the `Address.service_id` field. -A `Service` can also "reserve" and `Address` for future use by setting `Address.service_id`. The normal "Receive" UI will automatically skip any reserved `Address`es when generating a new receive addr. The reserved addresses are interleaved with ready-to-use addresses so that we don't create any potentially confusing wallet gaps (e.g. addrs 4, 6, and 8 are reserved but addrs 3, 5, and 7 are available). +A `Service` can also "reserve" an `Address` for future use by setting `Address.service_id`. The normal "Receive" UI will automatically skip any reserved `Address` when generating a new receive address. The reserved addresses are interleaved with ready-to-use addresses so that we don't create any potentially confusing wallet gaps (e.g. addrs 4, 6, and 8 are reserved but addrs 3, 5, and 7 are available). Users can also manually associate an existing `Address` with a `Service` (this is useful when the user has info that the particular `Service` api can't provide for whatever reason). _Note: TODO: manually un-reserve an `Address` from a `Service`._ +## Data storage +Effort has been taken to provide `Service` data storage that is separate from existing data stores in order to keep those areas clean and simple. Where touchpoints are unavoidable, they are kept to the absolute bare minimum (e.g. `User.services` list in `users.json`, `Address.service_id` field). +As an extension developer, you have the choice to completely manage your own persistence or rely/use one of the two options: You either have data which need encryption (via the passwords of the users) or you don't have that requirement. + -### Service Configuration -In order to separate the service-configuration from the main-configuration, you can specify your config in a file called `config.py`. It's structure is similiar to the specter-wide `config.py`, e.g.: -``` -class BaseConfig(): - SWAN_API_URL="https://dev-api.swanbitcoin.com" -class ProductionConfig(BaseConfig): - SWAN_API_URL="https://api.swanbitcoin.com" -``` -In your code, you can access the correct value as in any other flask-code, like `api_url = app.config.get("SWAN_API_URL")`. If the instance is running a config (e.g. `DevelopmentConfig`) which is not available in your service-specific config (as above), the inheritance-hirarchy from the mainconfig will get traversed and the first hit will get get configured. In this example, it would be `BaseConfig`. ### ServiceEncryptedStorage -Most `Service`s will require user secrets (e.g. API key and secret). Each Specter `User` will have their own on-disk encrypted `ServiceEncryptedStorage` with filename `_services.json`. Note that the user's secrets for all `Service`s will be stored in this one file. +Some `Services` will require user secrets (e.g. API key and secret). Each Specter `User` will have their own on-disk encrypted `ServiceEncryptedStorage` with filename `_services.json`. Note that the user's secrets for all `Services` will be stored in this one file. This is built upon the `GenericDataManager` class which supports optional encrypted fields. In this case all fields are encrypted. The `GenericDataManager` encryption can only be unlocked by each `User`'s individual `user_secret` that itself is stored encrypted on-disk; it is decrypted to memory when the `User` logs in. -For this reason `Service`s cannot be activated unless the user is signing in with a password-protected account (the default no-password `admin` account will not work). +For this reason `Services` cannot be activated unless the user is signing in with a password-protected account (the default no-password `admin` account will not work). -_Note: during development if the Flask server is restarted or auto-reloads, the user's decrypted `user_secret` will no longer be in memory. The Flask context will still consider the user logged in after restart, but code that relies on having access to the `ServiceEncryptedStorage` will throw an error and/or prompt the user to log in again._ +_Note: During development if the Flask server is restarted or auto-reloads, the user's decrypted `user_secret` will no longer be in memory. The Flask context will still consider the user logged in after restart, but code that relies on having access to the `ServiceEncryptedStorage` will throw an error and/or prompt the user to log in again._ It is up to each `Service` implementation to decide what data is stored; the `ServiceEncryptedStorage` simply takes arbitrary json in and delivers it back out. @@ -143,7 +217,7 @@ A disadvantage of the `ServiceEncryptedStorage` is, that the user needs to be fr In parallel with the `ServiceEncryptedStorageManager` there is also a `ServiceUnencryptedStorageManager` which is used exactly the same way. ### `ServiceAnnotationsStorage` -Annotations are any address-specific or transaction-specific data from a `Service` that we might want to present to the user (not yet implemented). Example: a `Service` that integrates with a onchain storefront would have product/order data associated with a utxo. That additional data could be imported by the `Service` and stored as an annotation. This annotation data could then be displayed to the user when viewing the details for that particular address or tx. +Annotations are any address specific or transaction specific data from a `Service` that we might want to present to the user (not yet implemented). Example: a `Service` that integrates with a onchain store would have product/order data associated with a utxo. That additional data could be imported by the `Service` and stored as an annotation. This annotation data could then be displayed to the user when viewing the details for that particular address or tx. Annotations are stored on a per-wallet and per-`Service` basis as _unencrypted_ on-disk data (filename: `_.json`). @@ -155,48 +229,22 @@ Unfortunately, the two unencrypted classes are derived from the encrypted one ra [![](https://mermaid.ink/img/pako:eNqVVMFuwjAM_ZUqJzaVw66IIU0D7bRd0G6VItO4LFvqoCRlqhj_PpeWASLduhyiqH7v-dlOsxO5VSgmIjfg_VzD2kGZUcKr3Z-Q0Ol8DgGegWCNLpl-jcfJEt1W57ig3NWbgGoZrONoS-oJXjBfCaPcPxI-ENkAQVvyF7RHS4VeVw5WBpea1gaDpZbZZ6eT_9VyzMK18_8oZeIuE8l4fMsn4tOQRvZm7FPra24XZgLjK4--38BFTe1-uCORAe3acLOk1KSDlCOPpkgTxSBZWKPQpUlniUcnP7C-f7GENycmQYnSFvLdc7zQBk-hn1r4OxrlTxFjQY3ORKSHbUfcn3vuqTFm_MIyt4h3pX1zraTCA_0sX0b9ya5varxPB7DUKk0-wfC1HSh_PeJdFB7_Mc6sTKf--Hk2G96769lHhJrlW7xc1bJp538qGpQjJnVqhUhFia4ErfiROwhlIrxhiZmY8FFhAZUJmciogVYbHj8ulOb8YlKA8ZgKqIJd1pSLSXAVHkHdW9mh9t9YNMxZ)](https://mermaid-js.github.io/mermaid-live-editor/edit#pako:eNqVVMFuwjAM_ZUqJzaVw66IIU0D7bRd0G6VItO4LFvqoCRlqhj_PpeWASLduhyiqH7v-dlOsxO5VSgmIjfg_VzD2kGZUcKr3Z-Q0Ol8DgGegWCNLpl-jcfJEt1W57ig3NWbgGoZrONoS-oJXjBfCaPcPxI-ENkAQVvyF7RHS4VeVw5WBpea1gaDpZbZZ6eT_9VyzMK18_8oZeIuE8l4fMsn4tOQRvZm7FPra24XZgLjK4--38BFTe1-uCORAe3acLOk1KSDlCOPpkgTxSBZWKPQpUlniUcnP7C-f7GENycmQYnSFvLdc7zQBk-hn1r4OxrlTxFjQY3ORKSHbUfcn3vuqTFm_MIyt4h3pX1zraTCA_0sX0b9ya5varxPB7DUKk0-wfC1HSh_PeJdFB7_Mc6sTKf--Hk2G96769lHhJrlW7xc1bJp538qGpQjJnVqhUhFia4ErfiROwhlIrxhiZmY8FFhAZUJmciogVYbHj8ulOb8YlKA8ZgKqIJd1pSLSXAVHkHdW9mh9t9YNMxZ) -### callback methods -Your service-class will inherit a callback-method which will get called for various reasons with the "reason" being a string as the first parameter. Checkout the `cryptoadvance.specter.services.callbacks` file for the specific callbacks. - -Some important one is the `after_serverpy_init_app` which passes a `Scheduler` class which can be used to setup regular tasks. - -### `controller.py` -The minimal url routes for `Service` selection and management. - - -## Implementation Class Structure -Child implementation classes (e.g. `SwanService`) should be self-contained within their own subdirectory in `services`. e.g.: -``` -cryptoadvance.specter.services.swan +### Service configuration +In order to separate the service-configuration from the main-configuration, you can specify your config in a file called `config.py`. It's structure is similiar to the specter-wide `config.py`, e.g.: ``` +class BaseConfig(): + SWAN_API_URL="https://dev-api.swanbitcoin.com" -Each implementation must have the following required components: -``` -/static/ -/templates/ -controller.py -service.py +class ProductionConfig(BaseConfig): + SWAN_API_URL="https://api.swanbitcoin.com" ``` +In your code, you can access the correct value as in any other flask-code, like `api_url = app.config.get("SWAN_API_URL")`. If the instance is running a config (e.g. `DevelopmentConfig`) which is not available in your service-specific config (as above), the inheritance-hirarchy from the mainconfig will get traversed and the first hit will get get configured. In this example, it would be `BaseConfig`. +### Callback methods +Your service class will inherit a callback-method which will get called for various reasons with the "reason" being a string as the first parameter. Checkout the `cryptoadvance.specter.services.callbacks` file for the specific callbacks. -This makes each implementation its own Flask `Blueprint`. - -### `/static` -Because of Flask `Blueprint` imports, you can just add static files here and reference them (e.g. "static//img/blah.png") as if they were in the main `/static` files root dir. - -### `/templates/` -Again, Flask `Blueprint`s import the `/templates` directory as-is, but to avoid namespace collisions on the template files (e.g. `/templates/index.html`) they should be contained within a subdirectory named with the `Service.id` (e.g. `/templates/swan/index.html`) - -### `Service` Implementation Class -Must inherit from `Service` and provide any additional functionality needed. The `Service` implementation class is meant to be the main hub for all things related to that particular `Service`. In general, external code would ideally only interact with the `Service` implementation class (e.g. ) +Some important one is the `after_serverpy_init_app` which passes a `Scheduler` class which can be used to setup regular tasks. A list of currently implemented callback-methods along with their descriptions are available in [`/src/cryptoadvance/specter/services/callbacks.py`](https://github.com/cryptoadvance/specter-desktop/blob/master/src/cryptoadvance/specter/services/callbacks.py). ### `controller.py` -Flask `Blueprint` for any endpoints required by this `Service`. - -The coding philosophy should be to keep this code as simple as possible and keep most or all of the actual logic in the `Service` implementation class. - -### Additional Files -The `SwanService` also includes an `api.py` to separate its back-end API calls from the user-facing `controller.py` endpoints. In general this is recommended to provide a clear separation. - -An individual `Service` implementation may add whatever additional files or classes it needs. +The minimal url routes for `Service` selection and management. As usualy in Flask, `templates` and `static` resources are in their respective subfolders. Please note that there is an additional directory with the id of the extension which looks redundant at first. This is due to the way blueprints are loading templates and ensures that there are no naming collisions. Maybe at a later stage, this can be used to let plugins override other plugin's templates. diff --git a/docs/faq.md b/docs/faq.md index 04923552da..9b1eaee04a 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -12,7 +12,7 @@ - [*What's the difference between Specter-desktop and Specter-DIY?*](#whats-the-difference-between-specter-desktop-and-specter-diy) - [*Is a full node necessary for using Specter-desktop?*](#is-a-full-node-necessary-for-using-specter-desktop) - [*Can I use pruned mode?*](#can-i-use-pruned-mode) - - [*I get this message: "This is a development server. Do not use it in a production deployment." Should I worry?*](#i-get-this-message-this-is-a-development-server-do-not-use-it-in-a-production-deployment-should-i-worry) + - [*I get this message: "This is a development server. Do not use it in a production deployment.". Should i worry?](#i-get-this-message-this-is-a-development-server-do-not-use-it-in-a-production-deployment-should-i-worry) - [*I'm not sure I want the Bitcoin-Core wallet functionality to be used, is that mandatory? If so, is it considered secure?*](#im-not-sure-i-want-the-bitcoin-core-wallet-functionality-to-be-used-is-that-mandatory-if-so-is-it-considered-secure) - [How many addresses does an HD wallet have, and are they all the same?](#how-many-addresses-does-an-hd-wallet-have-and-are-they-all-the-same) - [*I make unsigned transactions from my cold storage using a watching-only Electrum wallet. I use public servers instead of my own node because doing it "right" is too complicated for me. Specter may be an ideal alternative if it will connect to my **headless bitcoind node**. Will this be possible?*](#i-make-unsigned-transactions-from-my-cold-storage-using-a-watching-only-electrum-wallet-i-use-public-servers-instead-of-my-own-node-because-doing-it-right-is-too-complicated-for-me-specter-may-be-an-ideal-alternative-if-it-will-connect-to-my-headless-bitcoind-node-will-this-be-possible) @@ -53,9 +53,9 @@ - [The AppImage is not starting on Debian 10](#the-appimage-is-not-starting-on-debian-10) - [I have issues connecting my Hardware-Wallet via USB?!](#i-have-issues-connecting-my-hardware-wallet-via-usb) - [*How to upgrade Specter-desktop?*](#how-to-upgrade-specter-desktop) - - [Laptop/Desktop](#laptopdesktop) - - [Raspiblitz](#raspiblitz) - - [umbrel](#umbrel) + - [Laptop/Desktop](#laptopdesktop) + - [Raspiblitz](#raspiblitz) + - [umbrel](#umbrel) - [*How can I access the web interface if it's hosted on a headless computer?*](#how-can-i-access-the-web-interface-if-its-hosted-on-a-headless-computer) - [*How can I access the Specter Desktop web interface with my phone?*](#how-can-i-access-the-specter-desktop-web-interface-with-my-phone) - [*Keep getting: No matching distribution found for cryptoadvance.specter*](#keep-getting-no-matching-distribution-found-for-cryptoadvancespecter) @@ -84,7 +84,7 @@ -# ABOUT THE PROJECT +## ABOUT THE PROJECT The goal of this project is to make a convenient and user-friendly GUI around Bitcoin Core with a focus on multisignature setup with air-gapped (offline) hardware wallets. @@ -100,7 +100,7 @@ We first wanted to make a new hardware wallet (HWW), but after we understood tha We can actually incentivize the Bitcoin community to run their own node with this user-friendly multisig & node setup! -## *Why the name Specter?* +### *Why the name Specter?* "A specter is haunting the modern world, the specter of crypto anarchy." The Crypto Anarchist Manifesto - Timothy C. May - Sun, 22 Nov 92 12:11:24 PST @@ -110,57 +110,57 @@ We are aware of the vulnerability (Spectre) and know there is an infinite game a https://en.wikipedia.org/wiki/Spectre_(security_vulnerability) In Bitcoin Cold storage we can use multisig setups and different hardware wallets to mitigate these risks, while protecting our privacy by verifying transactions on our own node. -# GENERAL QUESTIONS +## GENERAL QUESTIONS -## *How safe is the app to use? Is it still considered alpha/beta or safe enough to use it with real sats in a HWW or Specter-DIY multisig setup?* +### *How safe is the app to use? Is it still considered alpha/beta or safe enough to use it with real sats in a HWW or Specter-DIY multisig setup?* It is watch-only (private keys are protected by HWW) and compatible with multisig in Electrum, so even if something breaks you always have a fallback option while we fix the bug. So go for it :) We try to use default descriptors and derivation paths exactly for this reason - to be compatible with other wallets. Would be nice to keep it this way, but at a certain point we will need to diverge - for example when we add miniscript support. -## *What does WIP mean?* +### *What does WIP mean?* WIP means that we don't try to be very backward-compatible at the moment. At some point we may change wallet storage format for example, and you would need to migrate using some script or create wallets from scratch. In this case, we would provide migration scripts. -## *What's the difference between Specter-desktop and Specter-DIY?* +### *What's the difference between Specter-desktop and Specter-DIY?* Specter-desktop is a watch-only GUI software wallet running on Bitcoin Core using its wallet and full node functionality. Bitcoin Core tracks addresses, UTXO (unspent transaction outputs) and composes PSBT (partially-signed bitcoin transactions). Whereas, [Specter-DIY](https://github.com/cryptoadvance/specter-diy) is a do-it-yourself hardware wallet from off the shelf components, that signs and broadcasts transactions using QR codes that forgets your private keys when powered off. -## *Is a full node necessary for using Specter-desktop?* +### *Is a full node necessary for using Specter-desktop?* Yes, a Bitcoin node is needed to provide all relevant data without relying on 3rd parties, and also for its watch-only wallet capabilities. However, Specter allows you to easily setup a (pruned-) node easily within Specter. If you can, a full-node is recommended but will take a lot longer to synchronize. -## *Can I use pruned mode?* +### *Can I use pruned mode?* Yes, but if you have many older addresses you will need to re-download the blockchain in order to see your balance and transaction history, which will take some time. Since v0.8.0 there is a workaround as you can download history from an external blockexplorer which has privacy implications. Make sure to read the tooltip-hints when using that feature and also consider this question in the [troubleshooting-section](#i-created-an-existing-wallets-but-even-after-rescanning-specter-couldnt-find-any-funds).. -## *I get this message: "This is a development server. Do not use it in a production deployment." Should I worry?* +### *I get this message: "This is a development server. Do not use it in a production deployment.". Should i worry? No you don't have to worry unless you plan to run specter as a public service on the internet with a growing number of people using it. That was traditionally the use-case for web-apps: Run in the open public internet getting accessed by MANY people. However, that's not how specter is meant to be used. If people get performance issues, it's most likely not because the user-base is growing on their specter but because their Raspberry Pi is too weak for that one user who is doing all sorts of other stuff on that Pi on top. -## *I'm not sure I want the Bitcoin-Core wallet functionality to be used, is that mandatory? If so, is it considered secure?* +### *I'm not sure I want the Bitcoin-Core wallet functionality to be used, is that mandatory? If so, is it considered secure?* You don't need private keys in Bitcoin Core, but you need wallets to be enabled `disablewallet=0` in your `bitcoin.conf` file. And if you don't want that, make also sure you're not using the Hotwallet-Feature. -## How many addresses does an HD wallet have, and are they all the same? +### How many addresses does an HD wallet have, and are they all the same? By default the gap limit is 20, but you can go to the wallet settings and import as many addresses as you want. If you know the wallet is old you may want to try importing many addresses (~1000), and then rescanning. The order is the same, and the addresses are also the same as the address derivation process is deterministic for a wallet. Address index is a derivation index of the wallet, so the index and the address itself are connected. -## *I make unsigned transactions from my cold storage using a watching-only Electrum wallet. I use public servers instead of my own node because doing it "right" is too complicated for me. Specter may be an ideal alternative if it will connect to my **headless bitcoind node**. Will this be possible?* +### *I make unsigned transactions from my cold storage using a watching-only Electrum wallet. I use public servers instead of my own node because doing it "right" is too complicated for me. Specter may be an ideal alternative if it will connect to my **headless bitcoind node**. Will this be possible?* Yes, this is the plan - to use a HWW like ColdCard/Trezor with Specter DIY, with a user-friendly multisig Specter desktop app, which is connected to your own node for better privacy. -## *What is the practical difference of using PSBT (partially signed bitcoin transaction) with multisig vs. just signing the raw multisig transaction normally?* +### *What is the practical difference of using PSBT (partially signed bitcoin transaction) with multisig vs. just signing the raw multisig transaction normally?* It gives you the ability to store the transaction temporarily before it is signed. -## *If the Bitcoin Core instance we are connecting to already has a wallet, is it possible to load it via the UI if we know the name, and could we import a .dat file?* +### *If the Bitcoin Core instance we are connecting to already has a wallet, is it possible to load it via the UI if we know the name, and could we import a .dat file?* Currently, you can create a hot wallet from within the specter-desktop UI, but at the moment it's not possible to extract XPUBs from the existing Core wallet, and without XPUBs change verification will break in all hardware wallets. Change address verification in multisig on a hardware wallet requires ability to check that change and inputs were derived from the same XPUBs. Without XPUBs all hardware wallets will show two outputs so you never know if the change output is actually change or not. @@ -168,32 +168,32 @@ With that being said, wallets created by Bitcoin Core always use hardened deriva The seed is generated by specter-desktop and then it's imported in a Bitcoin Core wallet, but instead of watch-only it's an XPRV imported using descriptors. More info on descriptors can be found [here](https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md). -## *How are Bitcoin Core mnemonic seeds created? With Core there's only the option to backup the wallet.dat file, so how does specter-desktop transform the wallet.dat file into a mnemonic seed?* +### *How are Bitcoin Core mnemonic seeds created? With Core there's only the option to backup the wallet.dat file, so how does specter-desktop transform the wallet.dat file into a mnemonic seed?* Specter-desktop generates a random mnemonic using Trezor's mnemonic package, then converts it to XPRVs and imports these keys to Bitcoin Core. This feature is very experimental at the moment and shouldn't be used for large amounts. -## *Why when I export a multisig wallet from specter-desktop (settings > export > copy wallet data) created from devices with only segwit ZPUBs, do I get a data structure with expected segwit derivation paths but XPUBs instead?* +### *Why when I export a multisig wallet from specter-desktop (settings > export > copy wallet data) created from devices with only segwit ZPUBs, do I get a data structure with expected segwit derivation paths but XPUBs instead?* XPUB is a canonical representation that is supported by Bitcoin Core, whereas ZPUB is an invention of SatoshiLabs that got adopted by the industry, but not by Bitcoin Core. In wallet export file we export Bitcoin Core's descriptor, so it contains master keys in the format that Bitcoin Core understands. More info on descriptors can be found [here](https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md). -## *Does Specter have coin control?* +### *Does Specter have coin control?* Yes, Specter supports coin control. Go to "Send". Open the "Advanced" features - and down at the right you have "Select coins manually" bottom. -# USAGE +## USAGE -## *How do I run the app?* +### *How do I run the app?* After following [these steps](https://github.com/cryptoadvance/specter-desktop#how-to-run) You should be able to view it in a browser at: 127.0.0.1:25441/ If not, see [Troubleshoot](https://github.com/cryptoadvance/specter-desktop/new/master/docs#troubleshoot) -## *How do i verify the signatures of the binaries?* +### *How do i verify the signatures of the binaries?* There is a great tutorial [here](https://bitcoiner.guide/verifysoftware/) explaining it for specter-desktop. A more generic video from kryptokids is [here](https://www.youtube.com/watch?v=S257nUqs13A). -## *Where do i find the logs?* +### *Where do i find the logs?* If you use a binary-installation (a platform specific download-package) there is a log-file called `specterApp.log` in the SPECTER_DATA_FOLDER in your user-directory. So for different platforms, default places are: * Windows: `C:\Users\YourUser\.specter\specterApp.log` @@ -201,7 +201,7 @@ If you use a binary-installation (a platform specific download-package) there is For pip installations, you need to look into the file `specter.log` in the same directory. If you still have trouble finding that file on your harddrive, have a look at the tooltip in the settings/general/Loglevel item. -## *What types of ways can I run specter-desktop?* +### *What types of ways can I run specter-desktop?* There are many ways how to run Specter: - Specter on local computer, node on remote @@ -214,44 +214,44 @@ Specter-desktop makes many requests to Bitcoin Core RPC, so it works better from If you use hardware wallets and they are usb-connected to specter-desktop then you need to use the hwibridge in the remote cases. However if your HWW is air-gapped (ColdCard, specter-diy, cobo) - then you can use remote web interface. -## Devices? Wallets? What is the difference? +### Devices? Wallets? What is the difference? The logic is that devices store keys, and you can combine these keys in different wallets like multisig or singlesig. So the same device can be used for a nested segwit wallet, native segwit, and many multisig wallets. The only requirement is that all cosigners in multisig wallets should be different devices. For some devices it makes sense to import keys, for example for another passphrase. However it's also possible (and recommended) to create a new device if you want to use a different passphrase for the same device. -## *What do I need to do in order to create a multisig wallet?* +### *What do I need to do in order to create a multisig wallet?* XPUBs are needed (from HWW's, laptop with Electrum desktop wallet, Specter-DIY, etc.) in order to create a multisig setup, but don't worry it's in watch-only mode and it's your own full node! First you need to “add devices” that store keys for the wallet. After creating the devices, you have to create the type of wallet you want (2-of-2, 3-of-5, etc.) and select the corresponding devices/keys - you need at least two devices setup in order to create a multisig wallet. -## *Is my understanding correct that specter-desktop does not hold any keys and you need to create a multisig wallet in order to sign transactions and send funds?* +### *Is my understanding correct that specter-desktop does not hold any keys and you need to create a multisig wallet in order to sign transactions and send funds?* As of late, you can also use a hot wallet as a signer with specter-desktop, but this is not recommended as a default setup. You can however use devices like Electrum wallet or FullyNoded for example (Electrum or Bitcoin Core can be air-gapped). This [video](https://youtu.be/4YXklLh2srA) is quite useful for using Electrum, and this [guide](https://github.com/Fonta1n3/FullyNoded/blob/master/Docs/Connect-node.md#importing-a-wallet-from-specter) is useful for connecting with FullyNoded. -## *How would one sign with Electrum? Do I need to create multisig wallet in Electrum first or can I create it with specter-desktop?* +### *How would one sign with Electrum? Do I need to create multisig wallet in Electrum first or can I create it with specter-desktop?* You need to create it in both wallets. When you start creating multisig wallet in Electrum it will give you the bech32 extended public key (ZPUB) where you can then add it to specter-desktop as well as other ZPUBS from other devices, and then add them to Electrum. After that you can start using Electrum as a signer. Electrum support got much better lately. We now have a dedicated electrum device with a specific explanation. If you're running into trouble, this [video](https://www.youtube.com/watch?v=4YXklLh2srA) might still help a lot and gives more details. -## *Can I use Ledger and ColdCard multisig while CC remains air-gapped?* +### *Can I use Ledger and ColdCard multisig while CC remains air-gapped?* Yes you can use the ColdCard with its SD card without connecting it to the computer via USB. You just need to import the ColdCard public keys with SD card. Just after creating the multisig wallet, you should go to the wallet page, click on the Settings tab, then scroll down to the Export and click on the export to ColdCard option. It will download a file you can import with the SD card to ColdCard and show you a notification with the instructions on how to do this. This will allow the ColdCard to be “aware” of the multisig and sign transactions for it. -## *Can I use Bluewallet with Specter DIY?* +### *Can I use Bluewallet with Specter DIY?* Yes you can use BlueWallet in watch-only mode and sign with Specter DIY. See it in action [here](https://twitter.com/StepanSnigirev/status/1209426608949465088) -## *Which hardware wallets are supported?* +### *Which hardware wallets are supported?* All major once! Checkout the list when you add a new device. -## *Can this also work with external nodes like Casa, MyNode, and Raspilitz?* +### *Can this also work with external nodes like Casa, MyNode, and Raspilitz?* Absolutely, as well as any other DIY bitcoin full, or pruned, node! Currently Raspiblitz (https://github.com/rootzoll/raspiblitz), has explicit support and you can automatically install it as bonus-software. Also [umbrel](https://getumbrel.com/) has it in the app-store. Mynode has it on Mynode [premium](https://mynodebtc.com/products/premium). Start9 is currently preparing support. There are differences mainly on update-policy and update-freuency. -## *Can I use Tor?* +### *Can I use Tor?* Yes there is a way to access specter-desktop over Tor from outside, here is the [doc](https://github.com/cryptoadvance/specter-desktop/blob/master/docs/tor.md). @@ -265,7 +265,7 @@ With that being said, beware that it's not practical yet to sign transactions vi Progress on Tor Support for QR-code scanning is tracked in this [issue](https://github.com/cryptoadvance/specter-desktop/issues/536) -## I forgot my password, how can I reset it? +### I forgot my password, how can I reset it? Check the .specter-folder in your home folder (or on your mynode/raspiblitz/...). There is a file called `config.json` in there which has a line like this: ``` @@ -279,9 +279,9 @@ Depending on "what's written in `somethingInHere`: * If it's `usernamepassword`, you won't be able to recover the password but you can deactivate it by setting it to `none` * If it's `none` (or you just set it to `none`) you can login without any password. So hurry up with setting it again within specter. -# BACKING UP FUNDS +## BACKING UP FUNDS -## *If something happens to the `~/.specter` folder, is it still possible to **restore** access to multisigs created there (assuming there is no backup of the `~/.specter` folder)?* +### *If something happens to the `~/.specter` folder, is it still possible to **restore** access to multisigs created there (assuming there is no backup of the `~/.specter` folder)?* Yes, it's a standard multisig. So you can recreate it as soon as you have **master public keys of ALL the devices** - either with Specter, or Electrum. @@ -290,13 +290,13 @@ If your `~/.specter` folder is gone and only one of your devices is lost When using Specter and importing an old wallet you would need to re-scan the blockchain in the wallet settings page. -## *To recover a multisig that was built on specter (eg: 2 of 3 with ColdCard), is having the seeds of all 3 signing wallets sufficient or do we need to backup more info?* +### *To recover a multisig that was built on specter (eg: 2 of 3 with ColdCard), is having the seeds of all 3 signing wallets sufficient or do we need to backup more info?* Having seeds is enough, but in case you lose one of the seeds it is also **highly recommended** that you also backup your XPUBs. You can go to the wallet settings and export it as json file, this file has all the information needed to find your funds. "Export to wallet" software should give you one json file with all information needed for the recovery of your watch only wallet later on. -# SPECTER-DIY +## SPECTER-DIY -## *What does the Specter-DIY consist of?* +### *What does the Specter-DIY consist of?* It consists of: @@ -310,40 +310,40 @@ It consists of: [Shopping list link](https://github.com/cryptoadvance/specter-diy/blob/master/docs/shopping.md) + [assembly link](https://github.com/cryptoadvance/specter-diy/blob/master/docs/assembly.md) Waveshare QR scanner is recommended as it has a good quality/price ratio. -## *Is specter-DIY safe to use?* +### *Is specter-DIY safe to use?* Do not use it on mainnet yet unless it's only being used as one of the signers in multisig setup! But feel free to experiment with it on testnet, regtest or signet. -## *I'm wondering what if someone takes the device? How does Specter-DIY approach this scenario?* +### *I'm wondering what if someone takes the device? How does Specter-DIY approach this scenario?* It supports passphrases as an additional security layer, but currently it has two modes of operation - agnostic when your secrets are not stored on the device and you need to enter recovery phrase every time you use the device, and reckless when it is stored on flash and can be extracted. We are working on smart card support so you could store your keys on removable secure element in a credit card form factor, as well as an option to encrypt secrets with a key stored on the SD card. See this recently opened [issue](https://github.com/cryptoadvance/specter-diy/issues/64) thanks to @Thomas1378 in the Telegram chat! -## *Currently there is a `specter_hwi.py` file, which implements the HWIClient for Specter-DIY. Is there any reason you didn't add that directly to HWI?* +### *Currently there is a `specter_hwi.py` file, which implements the HWIClient for Specter-DIY. Is there any reason you didn't add that directly to HWI?* Putting it into HWI means: "this is a hardware wallet people should consider using for real". Currently, we would strongly advice NOT to use USB with Specter-DIY, but to use QR codes instead. We will make a pull request to HWI when we think it's safe enough. In particular when we will have a secure bootloader that verifies signatures of the firmware, and USB communication is more reliable. -## *Do you have a physical security design?* +### *Do you have a physical security design?* No security at the moment, but it also doesn't store the private key. Working on integration of secure element similar to the ColdCard's (mikroe secure chip). At the moment it's more like a toy. -## *Is there a simulator I can try the Specter-DIY with?* +### *Is there a simulator I can try the Specter-DIY with?* Yes. Specter-DIY in simulator-mode simulates QR code scanner over TCP, see [here](https://diybitcoinhardware.com/f469-disco/simulator/?script=https://raw.githubusercontent.com/diybitcoinhardware/f469-disco/master/docs/tutorial/4_miniwallet/main.py) -## *Is there a goal to get Specter-DIY loading firmware updates from the SD card?* +### *Is there a goal to get Specter-DIY loading firmware updates from the SD card?* At the moment we don't have a proper bootloader and secure element integration yet, but we're moving in that direction! I think SD card is a good choice, also QR codes might be possible, but we need to experiment with them a bit. -## *Can Specter-DIY register cosigner xpubs like ColdCard? I know you wipe private keys on shutdown, but do you save stuff like that?* +### *Can Specter-DIY register cosigner xpubs like ColdCard? I know you wipe private keys on shutdown, but do you save stuff like that?* Yes, we keep wallet descriptors and other public info. -## *Once you add the javacard (secure element) you'll save the private keys, too?* +### *Once you add the javacard (secure element) you'll save the private keys, too?* With the secure element you will have three options: @@ -353,12 +353,12 @@ With the secure element you will have three options: Last seems to be the most secure, but then you trust proprietary crypto implementation. Second option saves private key on the secure element under pin protection, but also encrypted, so secure element never knows the private key. -# TROUBLESHOOT +## TROUBLESHOOT -## The AppImage is not starting on Debian 10 +### The AppImage is not starting on Debian 10 This is a known issue. See [here](https://github.com/cryptoadvance/specter-desktop/issues/769). A questionable workaround might be to start with `--no-sandbox`. The security-implications are beyond this FAQ. Please check the issues for more information. -## I have issues connecting my Hardware-Wallet via USB?! +### I have issues connecting my Hardware-Wallet via USB?! * Make sure to not use the Safari-Browser. Chrome is the best option, Firefox should work as well. * Make sure that your USB-cable is working. Often enough they are not working anymore. @@ -368,7 +368,7 @@ This is a known issue. See [here](https://github.com/cryptoadvance/specter-deskt * Also unplug other maybe exotic USB hardware like game-controllers, printers and basically everything, just for testing purposes. * If you're using the hwi-bridge, skip it for testing purposes and use specter locally to let it connect to your local -## *How to upgrade Specter-desktop?* +### *How to upgrade Specter-desktop?* This depends very much on how you've installed it in the first place. You might have it running on a node-implementation like nodl, RaspiBlitz or MyNode or you have it running on your desktop or laptop. MyNode doesn't support manual upgrade, but let's start with the laptop: @@ -392,7 +392,7 @@ service cryptoadvance-specter restart ### umbrel -## *How can I access the web interface if it's hosted on a headless computer?* +### *How can I access the web interface if it's hosted on a headless computer?* You can either set --host 0.0.0.0 `python -m cryptoadvance.specter server --host 0.0.0.0` or configure nginx to forward connections from specific port to specter. @@ -400,25 +400,25 @@ Alternatively, you can also define --port 80 if you want to have it on default h One drawback though is that with http and **external access** you will not get camera scanning functionality. It is an issue if you are using specter-DIY as it's necessary to scan QR codes with signed transactions. To fix that you will need a self-signed certificate, we have a document on that [here](https://github.com/cryptoadvance/specter-desktop/blob/master/docs/self-signed-certificates.md) -## *How can I access the Specter Desktop web interface with my phone?* +### *How can I access the Specter Desktop web interface with my phone?* Similar as above, add `--host 0.0.0.0` when starting the Specter server (to bind the Specter server to the local IP of the machine that you are running Specter on), thus `python -m cryptoadvance.specter server --host 0.0.0.0`. You can then access the Specter server with your phone by typing `http://LOCAL_IP_OF_MACHINE_RUNNING_SPECTER:25441/` in the phone's browser. **Note**: Your phone and the machine running Specter have to be connected to the same LAN for this simple approach to work. You might also need to adjust your firewall settings on the machine running Specter. For remote access of your Specter server check the [Tor docs](https://docs.specter.solutions/desktop/tor/). -## *Keep getting: No matching distribution found for cryptoadvance.specter* +### *Keep getting: No matching distribution found for cryptoadvance.specter* Try `pip3 install cryptoadvance.specter` Specter only works with python3, so use pip3 to install it `brew install python3` -## *Even after upgrading to python3 it's still looking at 2.7 version. I uninstalled 2.7, so not sure where to go next?* +### *Even after upgrading to python3 it's still looking at 2.7 version. I uninstalled 2.7, so not sure where to go next?* Run it with the command `python3 -m cryptoadvance.specter server` - then it will use python3 -## *I created an existing wallets but even after rescanning, specter couldn't find any (or not enough) funds?* +### *I created an existing wallets but even after rescanning, specter couldn't find any (or not enough) funds?* Make sure you're using the right type of wallet. Specter is only supporting "Nested Segwit" and "Native SegWit". If you have an older wallet, where addresses are starting with "1" or "3", those funds won't be able to show up in specter. So, make sure you know which type of wallet you want to choose. Also, it's relevant whether you're watching enough addresses. By default only 20 addresses are watched. Maybe your wallet needs more so increase them in the settings-menu of the wallet. @@ -437,60 +437,60 @@ Now that the other account's keys have been imported, create a new wallet using Apart from that, your old wallet might have used non-standard derivation pathes or extended them in a non-standard-way. [https://walletsrecovery.org/](https://walletsrecovery.org/) is a good source for collecting such information about your old wallet. -## *How to delete a wallet using a remote full node?* +### *How to delete a wallet using a remote full node?* You can't delete the wallet if you are using remote Bitcoin Core node - there is no RPC call to do it remotely. So, deleting wallet works only on the same computer. You can also just delete the wallet manually. It's a folder in `~/.bitcoin` directory and in `~/.specter` as well. -## *Trying to connect specter-desktop to my remote node on my LAN few times but no success. `bitcoin.conf` has the `server=1` option, should there be something else since I get this error `Process finished with code -1Error message: Failed to connect` message?* +### *Trying to connect specter-desktop to my remote node on my LAN few times but no success. `bitcoin.conf` has the `server=1` option, should there be something else since I get this error `Process finished with code -1Error message: Failed to connect` message?* `rpcallowip` and `rpcbind` parameters need to be set in `bitcoin.conf` -## Backup files not showing when trying to load backups +### Backup files not showing when trying to load backups When trying to load backups you are required to select the backup folders for either devices or wallets, you are NOT trying to select the JSON files. You can also select the specter-backup folder itself which will allow both devices and wallets to be loaded together. If you have issues doing this on the Specter app then try in browser instead. -# DIY TROUBLESHOOT +## DIY TROUBLESHOOT -## *Does anyone have any tips on mounting the power bank and QR code scanner to the STM32 board in a somewhat ergonomic manner?* +### *Does anyone have any tips on mounting the power bank and QR code scanner to the STM32 board in a somewhat ergonomic manner?* Use the smallest powerbank possible. -# HWW TROUBLESHOOT +## HWW TROUBLESHOOT Got stuck for a second because I wasn't safely removing my SD card reader, so the files were 0 bytes. -## *With achow's HWI tool, input and output PSBT are the same. And with Electrum 4, I get a rawtransaction, not a base64 PSBT.* +### *With achow's HWI tool, input and output PSBT are the same. And with Electrum 4, I get a rawtransaction, not a base64 PSBT.* I solved my issue, it turns out my PSBT needed bip32 hints (whatever that means) included. I can now open lightning channels straight from hardware wallet! -# TECHNICAL QUESTIONS (not dev related) +## TECHNICAL QUESTIONS (not dev related) -## *Does specter-desktop require `txindex=1` to be set in your `bitcoin.conf`?* +### *Does specter-desktop require `txindex=1` to be set in your `bitcoin.conf`?* No, but you need to enable wallets! `disablewallet=0` -## *Does specter-desktop specify an RPC wallet in the `bitcoin.conf` or append wallet name to node url?* +### *Does specter-desktop specify an RPC wallet in the `bitcoin.conf` or append wallet name to node url?* It specifes `-rpcwallet` with every call to `bitcoin-cli` -# FUTURE FEATURES +## FUTURE FEATURES -## *How are you guys planning to do air-gapped firmware updates via QR codes?* +### *How are you guys planning to do air-gapped firmware updates via QR codes?* We haven't tested it yet. We will work on the bootloader soon and try different update mechanisms. QR codes is one of them. Also considering SD card - might be easier as firmware is 1Mb, so it would require 1000 QR codes. -## *Will this device be Shamir Secret Shares compatible?* +### *Will this device be Shamir Secret Shares compatible?* Yes it will be, and especially effective in "forget after turn off" mode. Then one could use it to split a secret for wallets that don't support it. -## *Will there be CoinJoin support in the future?* +### *Will there be CoinJoin support in the future?* When CoinJoin servers and hardware wallets support proof of ownership: https://github.com/satoshilabs/slips/blob/slips-19-20-coinjoin-proofs/slip-0019.md -# VIDEOS +## VIDEOS -## **1** [Getting started with Specter-DIY and Specter-Desktop](https://twitter.com/CryptoAdvance/status/1235151027348926464) +### **1** [Getting started with Specter-DIY and Specter-Desktop](https://twitter.com/CryptoAdvance/status/1235151027348926464) ![video](https://www.youtube.com/embed/eF4cgK_L6T4) How to flash and set up an air-gapped hardware wallet that uses QR codes to communicate with the host. @@ -504,7 +504,7 @@ In the video: - Creating a multisignature wallet and importing it to the device - Signing multisig transactions -## **2** [Assembling Specter-DIY](https://www.youtube.com/watch?v=1H7FqG_FmCw) +### **2** [Assembling Specter-DIY](https://www.youtube.com/watch?v=1H7FqG_FmCw) ![video](https://www.youtube.com/embed/1H7FqG_FmCw) Specter-DIY hardware wallet: @@ -514,12 +514,12 @@ Specter-DIY hardware wallet: - no soldering - forgets your private key when powered off -## **3** [Specter-DIY air-gapped open source bitcoin hardware wallet overview](https://twitter.com/KeithMukai/status/1189565099259944961) +### **3** [Specter-DIY air-gapped open source bitcoin hardware wallet overview](https://twitter.com/KeithMukai/status/1189565099259944961) -## **4** [Build your own bitcoin hardware-wallet YT series](https://www.youtube.com/playlist?list=PLn2qRQUAAg0z_-R0swVuSsNS9bzRu6oP5&app=desktop) +### **4** [Build your own bitcoin hardware-wallet YT series](https://www.youtube.com/playlist?list=PLn2qRQUAAg0z_-R0swVuSsNS9bzRu6oP5&app=desktop) ![video](https://www.youtube.com/embed/AgOqTGeDrac) [playlist](https://www.youtube.com/playlist?list=PLn2qRQUAAg0z_-R0swVuSsNS9bzRu6oP5&app=desktop) -## *What is the difference between that project (DIYbitcoinhardware) & Specter? Is DIYbitcoinhardware sort of a prerequisite for Specter?* +### *What is the difference between that project (DIYbitcoinhardware) & Specter? Is DIYbitcoinhardware sort of a prerequisite for Specter?* Specter is built on top of that micropython build. DIYbitcoinhardware is focusing more on the toolbox without actual application logic, Specter implements logic and GUI on top of it. diff --git a/docs/hwibridge.md b/docs/hwibridge.md index 98ca9fea6d..5167a2d868 100644 --- a/docs/hwibridge.md +++ b/docs/hwibridge.md @@ -12,7 +12,7 @@ This will allow Specter to detect the device and continue normally. However, if you don't have physical access to the machine Specter is running on, you will need to set up a `Specter HWIBridge`. This procedure is also explained in this [video](https://www.youtube.com/watch?v=rUOxjyOGOGw). The following steps will help you set up a local `Specter HWIBridge`, which you could connect to the remote server and will allow it to detect devices connected to your local machine: -1. On the local machine you are accessing Specter from, [install Specter](../README.md#how-to-run) and run it with the `--hwibridge` flag. +1. On the local machine you are accessing Specter from, [install Specter](/#how-to-run) and run it with the `--hwibridge` flag.
You could do that by downloading the binary from the [Specter's GitHub releases page](https://github.com/cryptoadvance/specter-desktop/releases), and double clicking it. 2. Then open `http://127.0.0.1:25441/hwi/settings` in your browser. 3. In the `Whitelisted domains` form field, enter the domain of your remote Specter server you are connecting to and click update. diff --git a/docs/images/sign-message/continuous-integration_runner_windows_envvars.png b/docs/images/continuous-integration_runner_windows_envvars.png similarity index 100% rename from docs/images/sign-message/continuous-integration_runner_windows_envvars.png rename to docs/images/continuous-integration_runner_windows_envvars.png diff --git a/docs/images/extensions_file_layout.png b/docs/images/extensions_file_layout.png new file mode 100644 index 0000000000..5df4d50019 Binary files /dev/null and b/docs/images/extensions_file_layout.png differ diff --git a/docs/performance.md b/docs/performance.md index ed0291a05b..faeccd09dd 100644 --- a/docs/performance.md +++ b/docs/performance.md @@ -9,8 +9,8 @@ So here is a small checklist which you can use to improve your performance on Sp ## Mempool.Space Currently (`v1.7.0`) , Mempool.Space is the default fee-estimation implementation and it's used via Tor. Changing it to Bitcoin Core in the general settings should speed up performance. -# Bitcoin Core via Tor +## Bitcoin Core via Tor It's possible to connect to your Bitcoin Node via Tor. However, if you want to have access to your Specter instance from the street, perhaps rather expose Specter over Tor. If you want or have to run Bitcoin Core on a different machine than Specter, it is more advisable do that on the same network at home and not via Tor. -# Tor only-mode +## Tor only-mode Yes, we have a Tor only-mode but it's also coming with a huge performance impact. Think twice before you activate it and keep it in mind while waiting. diff --git a/docs/services/swan.md b/docs/swan.md similarity index 100% rename from docs/services/swan.md rename to docs/swan.md diff --git a/docs/test-new-releases.md b/docs/test-new-releases.md index 803d1e3276..782643fc6a 100644 --- a/docs/test-new-releases.md +++ b/docs/test-new-releases.md @@ -6,7 +6,7 @@ However, sometimes you want to test a new feature from a PR, a release candidate We'll discuss here some hints on separating environments and maybe even running installations in parallel. At the end, we will show how to make a copy of the production system and let it run completely in parallel with the existing system. But, first, let's look at the building blocks. -# On specterd, branches and PRs +## On specterd, branches and PRs We'll assume here, that you're a little familiar with the command line. If a change has been made but not yet released, there are several ways how the change could already be available. Here are the possibilities: @@ -24,7 +24,7 @@ git pull https://github.com/k9ert/specter-desktop.git service_swan Adjust the branch/user accordingly. After that, continue to setup your environment as described in the link above. If you need a more comprehensive guide, you can check out (what a pun!) [this blog post](https://snyk.io/blog/git-checkout-remote-branch/). -# specterd binary or source cli +## specterd binary or source cli No matter whether you've downloaded a specterd binary or you've cloned/checked out a specific environment, you're ready to start Specter via the cli. A specterd would be started as follows ``` @@ -95,7 +95,7 @@ Initializing HWI... ``` As you can see from the output, Specter is now running on your local machine and you can go visit it by following the link shown: [http://127.0.0.1:25441/](http://127.0.0.1:25441/). You can stop Specter again, by pressing `CTRL+C` in the terminal. -# The specter-data folder and port +## The specter-data folder and port As almost all programs on a computer Specter needs a place to store its data. Specter uses no databases only files on disk. These files are all located in a single directory, usually in your homefolder called `.specter`. The dot in the name makes that directory hidden, so you might need to switch to `show-hidden-files` in your filebrowser or use the a-switch in ls (`ls -a`). @@ -117,7 +117,7 @@ $ ./specterd server --specter-data-folder ~/.specter_manual_test --port 26441 ``` You will then find this instance running at [http://127.0.0.1:26441/](http://127.0.0.1:26441/). The nice thing is, that you can run Specter instances in parallel if they run on different ports. -# Configurations +## Configurations Running a development environment has different requirements than a production env, e.g.: * You want debugging messages @@ -130,7 +130,7 @@ That set of configurations can be passed over by referencing the `DevelopmentCon $ ./specterd server --config DevelopmentConfig --debug ``` -# Walkthrough +## Walkthrough So let's assume you want to run a test system almost completely separate from your production system. The only thing which is shared is the external Bitcoin Core node. So here are the steps: diff --git a/docs/tor.md b/docs/tor.md index de92e85795..b071d7028b 100644 --- a/docs/tor.md +++ b/docs/tor.md @@ -2,13 +2,13 @@ When using Specter Desktop, there might be certain cases where you would want to make calls over the Tor network. The simplest way to setup Tor integration with Specter Desktop is to click on the "Get Started" button of the welcome page and follow the setup wizard, which will install and configure Tor for you. You can also access it by going to `Settings -> Tor` tab, and clicking on "Setup Tor". -Screen Shot 2021-04-24 at 10 42 08 +get-started-setup.png -Screen Shot 2021-04-24 at 10 43 42 +tor-config-setup.png These will take you through the one click setup process, just click "Setup Tor" and Specter will take care of installing, configuring and running the Tor daemon. -Screen Shot 2021-04-24 at 10 42 17 +Screen Shot 2021-04-24 at 10 42 17 ## Running Specter Desktop over a Tor hidden service @@ -22,7 +22,7 @@ Make sure authentication is enabled to avoid access to your Specter by random st After setting up authentication, running the hidden service to remotely access specter is as easy as going to the `Settings -> Tor` tab, scrolling to the bottom and clicking the "Start" button under the "Tor Hidden Service" section. -Screen Shot 2021-04-24 at 10 58 30 +Screen Shot 2021-04-24 at 10 58 30 ## Manual Tor configurations diff --git a/mkdocs.yml b/mkdocs.yml index 383959031b..34d96f9e26 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -27,7 +27,7 @@ nav: - build-instructions.md - 'Continuous Integration': continuous-integration.md - cypress-testing.md - - services/services.md + - 'Extensions': extensions.md - 'Architectural Notes': architecture.md - 'Some Random Dev Thoughts': archblog.md - API: @@ -41,8 +41,9 @@ nav: theme: name: readthedocs markdown_extensions: - - mdx_truly_sane_lists + - mdx_truly_sane_lists # pip3 install mdx_truly_sane_lists mkdocs-video plugins: + - search - mkdocs-video: mark: "small_video" css_style: @@ -55,3 +56,4 @@ plugins: css_style: width: "100%" height: "22.172vw" + diff --git a/src/cryptoadvance/specter/cli/cli_ext.py b/src/cryptoadvance/specter/cli/cli_ext.py index 1bf2995244..e89355fe54 100644 --- a/src/cryptoadvance/specter/cli/cli_ext.py +++ b/src/cryptoadvance/specter/cli/cli_ext.py @@ -36,7 +36,7 @@ def ext(): @ext.command() @click.option("--org", "org", default=None, help="Use a specific organsiation") -@click.option("--ext-id", "ext_id", default=None, help="Use a specific Extension ID") +@click.option("--ext-id", "ext_id", default=None, help="Use a specific extension id") @click.option( "--isolated-client/--no-isolated-client", default=None, @@ -59,24 +59,24 @@ def gen(org, ext_id, isolated_client, tmpl_fs_source, dryrun): It'll ask you for the missing information if you don't pass the necessary details (see below). - After creation, you can get the extension to run like this in your Development Environment: + After creation, you can get the extension to run like this in your development environment: \b pip3 install -e . python3 -m cryptoadvance.specter server --config DevelopmentConfig --debug - # point your browser to http://localhost:25441 - # "choose Services" --> YourService + # Point your browser to http://localhost:25441 + # Click "Choose plugins" --> YourExtension If you want to package it, you can build it like this: \b python3 -m pip install --upgrade build python3 -m build - # install it like this: - pip3 install dist/{org}_{ext_id}-0.0.1-py3-none-any.whl + # Install it like this: + pip3 install dist/YourOrg_YourId-0.0.1-py3-none-any.whl - In order to use your extension in production, please refer to the Readme.md in the - https://github.com/cryptoadvance/{ext_mark}-dummy#how-to-get-this-to-production + If you want to bring your extension to production, please refer to the readme in the dummy-extension repo: + https://github.com/cryptoadvance/specterext-dummy#how-to-get-this-to-production To publish your package: @@ -89,32 +89,28 @@ def gen(org, ext_id, isolated_client, tmpl_fs_source, dryrun): if ext_id == None: print( """ - We need an ID and a prefix for your extension. It'll - reflect in the package-layout. The id should be a - short string. - The prefix is usually something like your github-username - or github organisation-name. Both will be used to to - create the directory structure - ( like ./src/mycorpname/specterext/myextension ) - and it will be used to prepare the files in order to - publish this extension to pypi. - + We need an id and a prefix for your extension. + The id should be a short string. + The prefix is usually your GitHub username + or GitHub organisation name. + Both will be used to to create a directory structure like this: + ./src/mycorpname/specterext/myextension + They will also be used when publishing this extension to pypi. """ ) ext_id = click.prompt( - "What should be the ID of your extension (lowercase only)", type=str + "Enter the id of your extension (lowercase only):", type=str ) if org == None: org = click.prompt( - "what should be the prefix?", + "Enter the prefix:", type=str, ) if isolated_client == None: print( """ - Should the extension be working in isolated_client-mode? - In that case it's won't share the session-cookie with - specter and the integration can only happen on server-side? + Isolated client mode means that the extensions won't share the session cookie with + Specter Desktop and the integration only happens on the server side. """ ) isolated_client = click.prompt( @@ -125,12 +121,12 @@ def gen(org, ext_id, isolated_client, tmpl_fs_source, dryrun): if result["code"] == 0: author = result["out"].decode("ascii").strip() else: - author = click.prompt("Please type in your Name: ", type=str) + author = click.prompt("Please type in your name: ", type=str) result = run_shell(["git", "config", "--get", "user.email"]) if result["code"] == 0: email = result["out"].decode("ascii").strip() else: - email = click.prompt("Please type in your E-Mail: ", type=str) + email = click.prompt("Please type in your email: ", type=str) extgen = ExtGen( ".", @@ -150,13 +146,13 @@ def gen(org, ext_id, isolated_client, tmpl_fs_source, dryrun): print( f""" - Congratulations, you've created a new extension + Congratulations, you've created a new extension! - Here is how to get it tor run on your Development Environment: + Here is how to get it to run in your development environment: pip3 install -e . python3 -m cryptoadvance.specter server --config DevelopmentConfig --debug - # point your browser to http://localhost:25441 - # "choose Services" --> {ext_id} + # Point your browser to http://localhost:25441 + # Click "Choose plugins" --> {ext_id} If you want to package it, you can build it like this: python3 -m pip install --upgrade build @@ -164,9 +160,8 @@ def gen(org, ext_id, isolated_client, tmpl_fs_source, dryrun): # install it like this: pip3 install dist/{org}_{ext_id}-0.0.1-py3-none-any.whl - In order to use your extension in production, please refer to - the Readme.md in the dummy-extension-repo. - https://github.com/cryptoadvance/{ext_mark}-dummy#how-to-get-this-to-production + If you want to bring your extension to production, please refer to the readme in the dummy-extension repo: + https://github.com/cryptoadvance/specterext-dummy#how-to-get-this-to-production To publish your package diff --git a/src/cryptoadvance/specterext/devhelp/controller.py b/src/cryptoadvance/specterext/devhelp/controller.py index d4c72acc77..022326aa25 100644 --- a/src/cryptoadvance/specterext/devhelp/controller.py +++ b/src/cryptoadvance/specterext/devhelp/controller.py @@ -24,14 +24,13 @@ def index(): @devhelp_endpoint.route("/html/") @login_required -@user_secret_decrypted_required def html_component(html_component): associated_wallet: Wallet = DevhelpService.get_associated_wallet() return render_template( f"devhelp/html/{html_component}", wallet=associated_wallet, services=app.specter.service_manager.services, - address=associated_wallet.get_address(3), + address=associated_wallet.get_address(3) if associated_wallet else None, ) diff --git a/utils/mkdocs-wrapper.sh b/utils/mkdocs-wrapper.sh index 319ec7b4c4..6bd836c314 100755 --- a/utils/mkdocs-wrapper.sh +++ b/utils/mkdocs-wrapper.sh @@ -26,8 +26,8 @@ pip3 install mkdocs mkdocs-video mdx_truly_sane_lists if [ "$1" = "build" ]; then cp README.md docs sed -i 's/docs\///g' docs/README.md + sed -i 's/Checkout our Documentation at.*//' docs/README.md sed -i 's/\.\.\/README.md/README.m/g' docs/*.md - fi diff --git a/utils/release.sh b/utils/release.sh index b32d1607ef..84ba375d60 100755 --- a/utils/release.sh +++ b/utils/release.sh @@ -53,7 +53,7 @@ function main() { if ! [ "$(git remote -v | grep upstream | grep 'git@github.com:cryptoadvance/specter-desktop.git' | wc -l)" = "2" ]; then echo " --> You don't have the correct upstream-remote. You need this to release. Please do this:" - echo "git remote add upstream git@gitlab.com:cryptoadvance/specter-cloud.git " + echo "git remote add upstream git@github.com:cryptoadvance/specter-desktop.git " exit 2 fi @@ -118,13 +118,17 @@ function main() { echo "Here are the release-notes:" echo "--------------------------------------------------" - echo "## ${new_version} $(date +'%B %d, %Y')" > docs/new_release_notes.md - docker run registry.gitlab.com/cryptoadvance/specter-desktop/github-changelog:latest --github-token $GH_TOKEN --branch master cryptoadvance specter-desktop $latest_version | sort >> docs/new_release_notes.md + echo "# Release Notes" > docs/new_release_notes.md echo "" >> docs/new_release_notes.md + echo "## ${new_version} $(date +'%B %d, %Y')" >> docs/new_release_notes.md + docker run registry.gitlab.com/cryptoadvance/specter-desktop/github-changelog:latest --github-token $GH_TOKEN --branch master cryptoadvance specter-desktop $latest_version | sort >> docs/new_release_notes.md + + cat docs/new_release_notes.md echo "--------------------------------------------------" cp docs/release-notes.md docs/release-notes.md.orig + sed -i '1,2d/' docs/release-notes.md.orig # Assuming the release-Notes start with # Release Notes\n cat docs/new_release_notes.md docs/release-notes.md.orig > docs/release-notes.md rm docs/release-notes.md.orig docs/new_release_notes.md