GithubHelp home page GithubHelp logo

unchained-capital / hermit Goto Github PK

View Code? Open in Web Editor NEW
70.0 20.0 29.0 797 KB

Command-line, (SLIP39) sharded wallet designed for air-gapped deployments

Home Page: https://unchained.com

License: Apache License 2.0

Makefile 0.89% Python 98.06% Shell 1.05%

hermit's Introduction

Hermit

PyPI Travis Codecov

Hermit is a sharded, HD command-line wallet designed for cryptocurrency owners who demand the highest possible form of security.

Hermit implements the SLIP-0039 standard for hierarchical Shamir sharding.

Hermit is designed to operate in tandem with an online wallet which can talk to a blockchain. All communication between the user, Hermit, and the online wallet is done via QR codes, cameras, screen, and keyboard.

This means that a Hermit installation does not require WiFi, Bluetooth, or any other form of wired or wireless communication. Hermit can operate in a completely air-gapped environment.

Read on or watch these videos to learn more about Hermit:

Quickstart

$ pip install hermit                          # may need 'sudo' for this command
...
$ hermit                                      # launch hermit
...
wallet> help                                  # see wallet commands
...
wallet> shards                                # enter shard mode
...
shards> help                                  # see shard commands
...
shards> list-shards                           # see current shards
...
shards> build-family-from-random              # create new shard family from random data
...
shards> list-shards                           # see newly created shards
...
shards> write                                 # save newly created shards to disk
shards> quit                                  # back to wallet mode
wallet> export-xpub m/45'/0'/0'               # export an extended public key
...
wallet> sign-bitcoin                          # sign a bitcoin transaction
                                              # see examples/signature_requests/bitcoin_testnet.png

...

See more details in the "Usage" section below.

Design

Hermit follows the following design principles:

  • Unidirectional information transfer -- information should only move in one direction
  • Always-on sharding & encryption -- keys should always be sharded and each shard encrypted
  • Open-source everything -- complete control over your software and hardware gives you the best security
  • Flexibility for human security -- you can customize the sharding configuration to suit your organization

Audience

Hermit is a difficult to use but highly-secure wallet.

Hermit is not recommended for non-technical individuals with a small amount of cryptocurrency.

Hermit is designed for computer-savvy people and organizations to self-custody significant amounts of cryptocurrency.

Sharding

Hermit is different than other wallets you may have used because it always shards your key.

Sharding is done using SLIP-39 which means there are two levels of structure:

  • Groups -- some quorum of P of Q groups is required to unlock a key

  • Shards -- some quorum of n of m shards is required to unlock each group, with n and m possibly different for each group

This structure creates a lot of flexibility for different scenarios.

Hermit extends the current SLIP-39 proposal by encrypting each shard with a password.

Shards in Hermit are generally encrypted by a password. Each shard has its own password, allowing for teams to operate a key together, each team member operating a given shard (in some group). However, if the user explicitly supplies an empty string as the password when either creating a shard, or changing the password on the shard, the resulting shard will be unencrypted. While this makes the transport of the shard less safe, it does make it possible to export the shards to technologies that support only unencrypted SLIP-39 implementations.

Compatibility with other wallets

If you are using a non-sharded wallet such as a hardware wallet (Trezor, Ledger, &c.) or Electrum, you can import your key from your BIP39 "seed phrase" and Hermit will shard it for you.

You may also input a new key using whatever source of randomness you like.

Hermit will not export keys as BIP39 phrases; only as encrypted SLIP39 phrases. This means it is challenging to extract a key from a Hermit installation for use in, for example, a hardware wallet or Electrum. This constraint is present by design.

Input & Output

Hermit is designed to be deployed in air-gapped environments.

  • The only way data should be able to enter the device Hermit is running on is via keyboard and camera.

  • The only way data can leave Hermit is via the screen of the device it is running on.

Hermit has no idea what is happening on the blockchain and relies on an external, online wallet application to draft transaction requests. These transaction requests are passed to Hermit via QR codes. Signatures produced by Hermit are similarly displayed on screen as QR codes.

The usage of QR codes for transaction requests and signatures creates a limit to how complex of a transaction Hermit can sign. This limitation will be addressed by a QR code packeting algorithm one day.

Storage

Hermit uses 3 storage locations:

 _________               _____________                  ____________
|         |             |             |                |            |
| memory  | -- write -> | filesystem  | -- persist --> | data store |
|_________|             |_____________|                |____________|

When Hermit first boots, shards from the data store or filesystem (in that order) are loaded into memory. Changes made to shards are always made in memory and will not survive Hermit restarts.

To save data across Hermit restarts, ensure you write it to the filesystem.

If your Hermit lives on a read-only filesystem, to save data across Hermit machine restarts, ensure you persist it to the data store.

Modes

Hermit is a modal application with two modes:

  • wallet mode is where you will spend most of your time, signing transactions and exporting public keys
  • shards mode is accessed when you need to import keys or shards, export shards, or otherwise change something about how your key is unlocked

Bitcoin Only

As a sharded, HD wallet, Hermit is a tool that can be used with any cryptocurrency that operates with the BIP32 standard.

But Hermit also ships with a sign-bitcoin command that will sign Bitcoin (BTC) transactions.

You can extend Hermit for other cryptocurrencies if you need; see the "Plugins" section below.

Usage

Installation

Installing Hermit can be done via pip:

$ pip install hermit

If you want to develop against Hermit, see the "Developers" section below for a different way of installing Hermit.

Starting Hermit

To start Hermit, just run the hermit command.

$ hermit

You can also pass a configuration file

$ HERMIT_CONFIG=/path/to/hermit.yml hermit

See the "Configuration" section below for more information on how to configure Hermit.

Creating a Key

Before you can do much with Hermit you'll need to create or import at least one key. To do so, first enter shards mode:

$ hermit
...
wallet> shards

Two shard mode commands will let you import a key:

  • build-family-from-phrase -- enter a BIP39 phrase. This is useful if you are importing a key from a hardware wallet such as Trezor or Ledger or from another software wallet such as Electrum.
  • build-family-from-random -- enter random characters. This is useful if you want to generate your own entropy (from, say, rolling dice)

Whichever you choose, you will be prompted to enter a shard configuration.

Creating a secure shard set from a key requires additional randomness beyond the seed of the key. So even if you choose to build-family-from-phrase, you will still be asked to input random characters. Ensure you are prepared to do so using a good source of randomness (such as rolling dice).

Exporting Public Keys

Hermit can export public keys (or extended public keys) from the key it protects. These are useful for other applications which want to refer to Hermit's key but, obviously, can't be allowed to see its private contents.

Two wallet mode commands are useful for this:

  • export-xpub -- exports an extended public key
  • export-pub -- exports a public key

Each of these commands expects a BIP32 path as an argument and each will display its data as a QR code.

Signing Transactions

The whole point of Hermit is to ultimately sign transactions. Transaction signature requests must be created by an external application. You can also use a test signature request available at examples/signature_requests/bitcoin.png.

Once you have a signature request, and you're in wallet mode, you can run sign-bitcoin to start signing a Bitcoin transaction.

Configuration

Hermit looks for a configuration file at /etc/hermit.yml by default. You can change this path by passing theHERMIT_CONFIG environment variable when you start the hermit program:

$ HERMIT_CONFIG=/path/to/hermit.yml hermit

The configuration file is a YAML file. See the documentation for the HermitConfig class for details on allowed configuration settings.

Developers

Developers will want to clone a copy of the Hermit source code:

$ git clone --recursive https://github.com/unchained-capital/hermit
$ cd hermit
$ make

NOTE: To develop using the Hermit code in this directory, run source environment.sh. This applies to all the commands below in this section.

Testing

Hermit ships with a full pytest suite. Run it as follows:

$ source environment.sh
$ make test
$ make lint

Hermit has been tested on the following platforms:

  • OS X High Sierra 10.13.6
  • Linux Ubuntu 18.04
  • Linux Slax 9.6.4

There is also a full-flow example script provided at (tests/test_script.md)[tests/test_script.md] that you can follow to see and test all functionality.

Developers

Integrating

Hermit needs an external, online wallet application in order to work. This application has a few ways it may need to integrate with Hermit:

In all cases, Hermit uses the same scheme to encode/decode data into QR codes. The pipelines look like this:

  • To create a QR code from a string: utf-8 encode -> gzip-compress -> Base32 encode
  • To parse a QR code string: Base32 decode -> gzip-decompress -> utf-8 decode

The string data may sometimes itself be JSON.

Plugins

Hermit allows you to write plugins to extend its functionality. This is chiefly so that you can write Signer classes for cryptocurrencies beyond Bitcoin (BTC).

The default directory for plugin code is /var/lib/hermit. Any *.py files in this directory will be loaded by Hermit when it boots (though you can customize this directory; see the "Configuration" section above).

An example signer class is below

#
# Example signer class for a putative "MyCoin" currency.
#
# Put in /var/lib/hermit/mycoin_signer.py
#

from hermit.errors import InvalidSignatureRequest
from hermit.signer.base import Signer
from hermit.ui.wallet import wallet_command
import hermit.ui.state as state

# Some library for MyCoin
from mycoin_lib import sign_mycoin_transaction

class MyCoinSigner(Signer):
    """Signs MyCoin transactions"""

    def validate_request(self) -> None:
        """Validates a MyCoin signature request"""
	# This is built into the Signer class
	self.validate_bip32_path(request.get('bip32_path'))

	# this isn't great validation code, but you get the point...
	if 'input' not in self.request:
	    raise InvalidSignatureRequest("The param 'input' is required.")
	if 'output' not in self.request:
	    raise InvalidSignatureRequest("The param 'output' is required.")
	if 'amount' not in self.request:
	    raise InvalidSignatureRequest("The param 'amount' is required.")

	self.bip32_path = self.request['bip32_path']
	self.input = self.request[input]
	self.output = self.request['output']
	self.amount = self.request['amount']

    def display_request(self) -> None:
        """Displays the transaction to be signed"""
        print("""
        INPUT:  {}
	OUTPUT: {}
	AMOUNT: {}
        SIGNING AS: {}
	""".format(self.input,
                 self.output,
                 self.amount,
	           self.bip32_path))

    def create_signature(self) -> None:
        """Signs a transaction"""
	keys = self.generate_child_keys(self.bip32_path)
	# Here is the magic of MyCoin...
        self.signature = sign_mycoin_transaction(self.input, self.output, self.amount, keys)

@wallet_command('sign-mycoin')
def sign_mycoin():
    """usage:  sign-mycoin

  Create a signature for a MyCoin transaction.

  Hermit will open a QR code reader window and wait for you to scan an
  Ethereum transaction signature request.

  Once scanned, the details of the signature request will be displayed
  on screen and you will be prompted whether or not you want to sign
  the transaction.

  If you agree, Hermit will open a window displaying the signature as
  a QR code.

  Creating a signature requires unlocking the wallet.

    """
    MyCoinSigner(state.Wallet, state.Session).sign()

Contributing to Hermit

Unchained Capital welcomes bug reports, new features, and better documentation for Hermit. To contribute, create a pull request (PR) on GitHub against the Unchained Capital fork of Hermit.

Before you submit your PR, make sure to lint your code and run the test suite!

$ source environment.sh
$ make test
$ make lint

(Linting is done with flake8 and mypy.)

Key rotation

Each individual share should be managed by a team. Each team has multiple copies of the passphrase to decrypt the share. The share only exists on the Hermit device, and it's encrypted. Rotating out a member is achieved by using one of the other team members to decrypt the share and then re-encrypting the share with a new passphrase, thus excluding the previous user.

TODO

  • Validate wallet public keys/signatures against the provided redeem script in the bitcoin signer.
  • Re-do QR-code protocol details once a standard emerges

hermit's People

Contributors

bitstein avatar dependabot[bot] avatar destrys avatar dhruvbansal avatar howech avatar kajalkris avatar kanzure avatar robertshuford avatar waldenraines avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hermit's Issues

Fresh build on OSX doesn't work

Describe the bug

mflaxman@Michaels-MacBook-Pro:~/workspace$ git clone https://github.com/unchained-capital/hermit
Cloning into 'hermit'...
remote: Enumerating objects: 388, done.
remote: Counting objects: 100% (388/388), done.
remote: Compressing objects: 100% (291/291), done.
remote: Total 388 (delta 155), reused 315 (delta 90), pack-reused 0
Receiving objects: 100% (388/388), 386.73 KiB | 2.97 MiB/s, done.
Resolving deltas: 100% (155/155), done.

mflaxman@Michaels-MacBook-Pro:~/workspace$ cd hermit

mflaxman@Michaels-MacBook-Pro:~/workspace/hermit$ make
brew ls --versions zbar || brew install zbar
zbar 0.10_9
/usr/local/bin/python3 -m venv --prompt='hermit' .virtualenv
.virtualenv/bin/pip install wheel
Collecting wheel
  Using cached https://files.pythonhosted.org/packages/00/83/b4a77d044e78ad1a45610eb88f745be2fd2c6d658f9798a15e384b7d57c9/wheel-0.33.6-py2.py3-none-any.whl
Installing collected packages: wheel
Successfully installed wheel-0.33.6
You are using pip version 19.0.3, however version 19.2.2 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
.virtualenv/bin/pip install -r requirements.frozen.txt
Collecting alabaster==0.7.12 (from -r requirements.frozen.txt (line 1))
  Using cached https://files.pythonhosted.org/packages/10/ad/00b090d23a222943eb0eda509720a404f531a439e803f6538f35136cae9e/alabaster-0.7.12-py2.py3-none-any.whl
Collecting asn1crypto==0.24.0 (from -r requirements.frozen.txt (line 2))
  Using cached https://files.pythonhosted.org/packages/ea/cd/35485615f45f30a510576f1a56d1e0a7ad7bd8ab5ed7cdc600ef7cd06222/asn1crypto-0.24.0-py2.py3-none-any.whl
Collecting atomicwrites==1.3.0 (from -r requirements.frozen.txt (line 3))
  Using cached https://files.pythonhosted.org/packages/52/90/6155aa926f43f2b2a22b01be7241be3bfd1ceaf7d0b3267213e8127d41f4/atomicwrites-1.3.0-py2.py3-none-any.whl
Collecting attrs==19.1.0 (from -r requirements.frozen.txt (line 4))
  Using cached https://files.pythonhosted.org/packages/23/96/d828354fa2dbdf216eaa7b7de0db692f12c234f7ef888cc14980ef40d1d2/attrs-19.1.0-py2.py3-none-any.whl
Collecting Babel==2.7.0 (from -r requirements.frozen.txt (line 5))
  Using cached https://files.pythonhosted.org/packages/2c/60/f2af68eb046c5de5b1fe6dd4743bf42c074f7141fe7b2737d3061533b093/Babel-2.7.0-py2.py3-none-any.whl
Collecting bleach==3.1.0 (from -r requirements.frozen.txt (line 6))
  Using cached https://files.pythonhosted.org/packages/ab/05/27e1466475e816d3001efb6e0a85a819be17411420494a1e602c36f8299d/bleach-3.1.0-py2.py3-none-any.whl
Collecting bson==0.5.8 (from -r requirements.frozen.txt (line 7))
Collecting certifi==2019.6.16 (from -r requirements.frozen.txt (line 8))
  Using cached https://files.pythonhosted.org/packages/69/1b/b853c7a9d4f6a6d00749e94eb6f3a041e342a885b87340b79c1ef73e3a78/certifi-2019.6.16-py2.py3-none-any.whl
Collecting cffi==1.12.3 (from -r requirements.frozen.txt (line 9))
  Using cached https://files.pythonhosted.org/packages/f0/48/5aa4ea664eba26dd5142558d04762f5065c02220b4665b3f7eecb9bb614e/cffi-1.12.3-cp37-cp37m-macosx_10_9_x86_64.whl
Collecting chardet==3.0.4 (from -r requirements.frozen.txt (line 10))
  Using cached https://files.pythonhosted.org/packages/bc/a9/01ffebfb562e4274b6487b4bb1ddec7ca55ec7510b22e4c51f14098443b8/chardet-3.0.4-py2.py3-none-any.whl
Collecting Click==7.0 (from -r requirements.frozen.txt (line 11))
  Using cached https://files.pythonhosted.org/packages/fa/37/45185cb5abbc30d7257104c434fe0b07e5a195a6847506c074527aa599ec/Click-7.0-py2.py3-none-any.whl
Collecting colorama==0.4.1 (from -r requirements.frozen.txt (line 12))
  Using cached https://files.pythonhosted.org/packages/4f/a6/728666f39bfff1719fc94c481890b2106837da9318031f71a8424b662e12/colorama-0.4.1-py2.py3-none-any.whl
Collecting coverage==4.5.4 (from -r requirements.frozen.txt (line 13))
  Using cached https://files.pythonhosted.org/packages/93/07/8302163cdbe2008441aa69f2119750110fde15ffd8a56a687311b143365a/coverage-4.5.4-cp37-cp37m-macosx_10_13_x86_64.whl
Collecting cryptography==2.7 (from -r requirements.frozen.txt (line 14))
  Using cached https://files.pythonhosted.org/packages/63/4e/57b7a6bd98906872fcd2531e74b532de2abe17d675a5cf171931fcb4a9e8/cryptography-2.7-cp34-abi3-macosx_10_6_intel.whl
Collecting docutils==0.15.2 (from -r requirements.frozen.txt (line 15))
  Using cached https://files.pythonhosted.org/packages/22/cd/a6aa959dca619918ccb55023b4cb151949c64d4d5d55b3f4ffd7eee0c6e8/docutils-0.15.2-py3-none-any.whl
Collecting ecdsa==0.13 (from -r requirements.frozen.txt (line 16))
  Using cached https://files.pythonhosted.org/packages/63/f4/73669d51825516ce8c43b816c0a6b64cd6eb71d08b99820c00792cb42222/ecdsa-0.13-py2.py3-none-any.whl
Collecting entrypoints==0.3 (from -r requirements.frozen.txt (line 17))
  Using cached https://files.pythonhosted.org/packages/ac/c6/44694103f8c221443ee6b0041f69e2740d89a25641e62fb4f2ee568f2f9c/entrypoints-0.3-py2.py3-none-any.whl
Collecting flake8==3.7.7 (from -r requirements.frozen.txt (line 18))
  Using cached https://files.pythonhosted.org/packages/e9/76/b915bd28976068a9843bf836b789794aa4a8eb13338b23581005cd9177c0/flake8-3.7.7-py2.py3-none-any.whl
Collecting idna==2.8 (from -r requirements.frozen.txt (line 19))
  Using cached https://files.pythonhosted.org/packages/14/2c/cd551d81dbe15200be1cf41cd03869a46fe7226e7450af7a6545bfc474c9/idna-2.8-py2.py3-none-any.whl
Collecting imagesize==1.1.0 (from -r requirements.frozen.txt (line 20))
  Using cached https://files.pythonhosted.org/packages/fc/b6/aef66b4c52a6ad6ac18cf6ebc5731ed06d8c9ae4d3b2d9951f261150be67/imagesize-1.1.0-py2.py3-none-any.whl
Collecting importlib-metadata==0.19 (from -r requirements.frozen.txt (line 21))
  Using cached https://files.pythonhosted.org/packages/ad/aa/25fcbded2ab4ed4ff3071d1e000cd4f8f9c65653d2d7157dd105a8e81d42/importlib_metadata-0.19-py2.py3-none-any.whl
Collecting imutils==0.5.1 (from -r requirements.frozen.txt (line 22))
Collecting Jinja2==2.10.1 (from -r requirements.frozen.txt (line 23))
  Using cached https://files.pythonhosted.org/packages/1d/e7/fd8b501e7a6dfe492a433deb7b9d833d39ca74916fa8bc63dd1a4947a671/Jinja2-2.10.1-py2.py3-none-any.whl
Collecting MarkupSafe==1.1.1 (from -r requirements.frozen.txt (line 24))
  Using cached https://files.pythonhosted.org/packages/ce/c6/f000f1af136ef74e4a95e33785921c73595c5390403f102e9b231b065b7a/MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl
Collecting mccabe==0.6.1 (from -r requirements.frozen.txt (line 25))
  Using cached https://files.pythonhosted.org/packages/87/89/479dc97e18549e21354893e4ee4ef36db1d237534982482c3681ee6e7b57/mccabe-0.6.1-py2.py3-none-any.whl
Collecting mnemonic==0.18 (from -r requirements.frozen.txt (line 26))
Collecting more-itertools==7.2.0 (from -r requirements.frozen.txt (line 27))
  Using cached https://files.pythonhosted.org/packages/45/dc/3241eef99eb45f1def35cf93af35d1cf9ef4c0991792583b8f33ea41b092/more_itertools-7.2.0-py3-none-any.whl
Collecting mypy==0.701 (from -r requirements.frozen.txt (line 28))
  Using cached https://files.pythonhosted.org/packages/aa/f3/74577ff2b4f29c4b8112b7dc22746ce41c88c36a3e1829641a1b1ec09e3b/mypy-0.701-cp37-cp37m-macosx_10_6_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl
Collecting mypy-extensions==0.4.1 (from -r requirements.frozen.txt (line 29))
  Using cached https://files.pythonhosted.org/packages/4d/72/8d54e2b296631b9b14961d583e56e90d9d7fba8a240d5ce7f1113cc5e887/mypy_extensions-0.4.1-py2.py3-none-any.whl
Collecting numpy==1.17.0 (from -r requirements.frozen.txt (line 30))
  Using cached https://files.pythonhosted.org/packages/c1/4b/78119133136c20e5ad2e01bf72b0633241defd619939908223cd394a9c32/numpy-1.17.0-cp37-cp37m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl
Collecting opencv-python==3.4.3.18 (from -r requirements.frozen.txt (line 31))
  Using cached https://files.pythonhosted.org/packages/e2/96/e7a196456fa75c75a7759c98fa6ba5bdacebdd66fbf4fd31e10b80f9d32e/opencv_python-3.4.3.18-cp37-cp37m-macosx_10_6_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl
Collecting packaging==19.1 (from -r requirements.frozen.txt (line 32))
  Using cached https://files.pythonhosted.org/packages/ec/22/630ac83e8f8a9566c4f88038447ed9e16e6f10582767a01f31c769d9a71e/packaging-19.1-py2.py3-none-any.whl
Collecting pbkdf2==1.3 (from -r requirements.frozen.txt (line 33))
Collecting Pillow==6.1.0 (from -r requirements.frozen.txt (line 34))
  Using cached https://files.pythonhosted.org/packages/8f/f3/c6d351d7e582e4f2ef4343c9be1f0472cb249fb69695e68631e337f4b6e9/Pillow-6.1.0-cp37-cp37m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl
Collecting pkginfo==1.5.0.1 (from -r requirements.frozen.txt (line 35))
  Using cached https://files.pythonhosted.org/packages/e6/d5/451b913307b478c49eb29084916639dc53a88489b993530fed0a66bab8b9/pkginfo-1.5.0.1-py2.py3-none-any.whl
Collecting pluggy==0.12.0 (from -r requirements.frozen.txt (line 36))
  Using cached https://files.pythonhosted.org/packages/06/ee/de89e0582276e3551df3110088bf20844de2b0e7df2748406876cc78e021/pluggy-0.12.0-py2.py3-none-any.whl
Collecting prompt-toolkit==2.0.7 (from -r requirements.frozen.txt (line 37))
  Using cached https://files.pythonhosted.org/packages/d1/e6/adb3be5576f5d27c6faa33f1e9fea8fe5dbd9351db12148de948507e352c/prompt_toolkit-2.0.7-py3-none-any.whl
Collecting py==1.8.0 (from -r requirements.frozen.txt (line 38))
  Using cached https://files.pythonhosted.org/packages/76/bc/394ad449851729244a97857ee14d7cba61ddb268dce3db538ba2f2ba1f0f/py-1.8.0-py2.py3-none-any.whl
Collecting pyAesCrypt==0.4.2 (from -r requirements.frozen.txt (line 39))
  Using cached https://files.pythonhosted.org/packages/65/f4/eacfcc319fda64428cd985d6ccb2a7f130feeca3c2fcc1dd8822b3b7b414/pyAesCrypt-0.4.2-py3-none-any.whl
Collecting pycodestyle==2.5.0 (from -r requirements.frozen.txt (line 40))
  Using cached https://files.pythonhosted.org/packages/0e/0c/04a353e104d2f324f8ee5f4b32012618c1c86dd79e52a433b64fceed511b/pycodestyle-2.5.0-py2.py3-none-any.whl
Collecting pycparser==2.19 (from -r requirements.frozen.txt (line 41))
Collecting pyflakes==2.1.1 (from -r requirements.frozen.txt (line 42))
  Using cached https://files.pythonhosted.org/packages/84/f2/ed0ffb887f8138a8fe5a621b8c0bb9598bfb3989e029f6c6a85ee66628ee/pyflakes-2.1.1-py2.py3-none-any.whl
Collecting Pygments==2.4.2 (from -r requirements.frozen.txt (line 43))
  Using cached https://files.pythonhosted.org/packages/5c/73/1dfa428150e3ccb0fa3e68db406e5be48698f2a979ccbcec795f28f44048/Pygments-2.4.2-py2.py3-none-any.whl
Collecting pyparsing==2.4.2 (from -r requirements.frozen.txt (line 44))
  Using cached https://files.pythonhosted.org/packages/11/fa/0160cd525c62d7abd076a070ff02b2b94de589f1a9789774f17d7c54058e/pyparsing-2.4.2-py2.py3-none-any.whl
Collecting pysha3==1.0.2 (from -r requirements.frozen.txt (line 45))
Collecting pytest==4.4.0 (from -r requirements.frozen.txt (line 46))
  Using cached https://files.pythonhosted.org/packages/7e/16/83b2a35c427b838df9836c9e7e4ae6dfbcbdea643db44652f693b1c57d70/pytest-4.4.0-py2.py3-none-any.whl
Collecting pytest-cov==2.6.1 (from -r requirements.frozen.txt (line 47))
  Using cached https://files.pythonhosted.org/packages/7d/b5/92f32674ab954f80499ac73347bfeb815545ea295439c12b0ef3ac8f0975/pytest_cov-2.6.1-py2.py3-none-any.whl
Collecting python-bitcoinlib==0.10.1 (from -r requirements.frozen.txt (line 48))
  Using cached https://files.pythonhosted.org/packages/30/03/fb7df95fe89baede202cf3fe65e65bea4bf863061b5e8f59b12dab538240/python_bitcoinlib-0.10.1-py2.py3-none-any.whl
Collecting python-dateutil==2.8.0 (from -r requirements.frozen.txt (line 49))
  Using cached https://files.pythonhosted.org/packages/41/17/c62faccbfbd163c7f57f3844689e3a78bae1f403648a6afb1d0866d87fbb/python_dateutil-2.8.0-py2.py3-none-any.whl
Collecting pytz==2019.2 (from -r requirements.frozen.txt (line 50))
  Using cached https://files.pythonhosted.org/packages/87/76/46d697698a143e05f77bec5a526bf4e56a0be61d63425b68f4ba553b51f2/pytz-2019.2-py2.py3-none-any.whl
Collecting PyYAML==5.1.1 (from -r requirements.frozen.txt (line 51))
Collecting pyzbar==0.1.7 (from -r requirements.frozen.txt (line 52))
  Using cached https://files.pythonhosted.org/packages/bd/e7/dc9aa3ee5ddc71df6ea1698f7e9d12dcc874346ad3051524155e121006a6/pyzbar-0.1.7-py2.py3-none-any.whl
Collecting qrcode==6.0 (from -r requirements.frozen.txt (line 53))
  Using cached https://files.pythonhosted.org/packages/79/be/11999004f7e6e5db0fa410c2feacd67c07f472f4500fde0026101f31d0df/qrcode-6.0-py2.py3-none-any.whl
Collecting readme-renderer==24.0 (from -r requirements.frozen.txt (line 54))
  Using cached https://files.pythonhosted.org/packages/c3/7e/d1aae793900f36b097cbfcc5e70eef82b5b56423a6c52a36dce51fedd8f0/readme_renderer-24.0-py2.py3-none-any.whl
Collecting requests==2.22.0 (from -r requirements.frozen.txt (line 55))
  Using cached https://files.pythonhosted.org/packages/51/bd/23c926cd341ea6b7dd0b2a00aba99ae0f828be89d72b2190f27c11d4b7fb/requests-2.22.0-py2.py3-none-any.whl
Collecting requests-toolbelt==0.9.1 (from -r requirements.frozen.txt (line 56))
  Using cached https://files.pythonhosted.org/packages/60/ef/7681134338fc097acef8d9b2f8abe0458e4d87559c689a8c306d0957ece5/requests_toolbelt-0.9.1-py2.py3-none-any.whl
Collecting shamir-mnemonic==0.1.0 (from -r requirements.frozen.txt (line 57))
  Using cached https://files.pythonhosted.org/packages/da/7b/be61fae6dc3685197e3de75d78bcab7b40caac3235a235b2f8170cfc1cd2/shamir_mnemonic-0.1.0-py3-none-any.whl
Collecting six==1.12.0 (from -r requirements.frozen.txt (line 58))
  Using cached https://files.pythonhosted.org/packages/73/fb/00a976f728d0d1fecfe898238ce23f502a721c0ac0ecfedb80e0d88c64e9/six-1.12.0-py2.py3-none-any.whl
Collecting snowballstemmer==1.9.0 (from -r requirements.frozen.txt (line 59))
Collecting Sphinx==1.8.5 (from -r requirements.frozen.txt (line 60))
  Using cached https://files.pythonhosted.org/packages/7d/66/a4af242b4348b729b9d46ce5db23943ce9bca7da9bbe2ece60dc27f26420/Sphinx-1.8.5-py2.py3-none-any.whl
Collecting sphinxcontrib-websupport==1.1.2 (from -r requirements.frozen.txt (line 61))
  Using cached https://files.pythonhosted.org/packages/2a/59/d64bda9b7480a84a3569be4dde267c0f6675b255ba63b4c8e84469940457/sphinxcontrib_websupport-1.1.2-py2.py3-none-any.whl
Collecting tqdm==4.32.2 (from -r requirements.frozen.txt (line 62))
  Using cached https://files.pythonhosted.org/packages/9f/3d/7a6b68b631d2ab54975f3a4863f3c4e9b26445353264ef01f465dc9b0208/tqdm-4.32.2-py2.py3-none-any.whl
Collecting twine==1.13.0 (from -r requirements.frozen.txt (line 63))
  Using cached https://files.pythonhosted.org/packages/28/90/59eec88c0b2ac9e47fe135959007acb93a3cc9f7146366e11fecf718dd15/twine-1.13.0-py2.py3-none-any.whl
Collecting typed-ast==1.3.5 (from -r requirements.frozen.txt (line 64))
  Using cached https://files.pythonhosted.org/packages/a4/7b/3d18d46c64c7052c5ad9b4301562cc46383c20dcbe69409b75cfd7096451/typed_ast-1.3.5-cp37-cp37m-macosx_10_9_x86_64.whl
Collecting urllib3==1.25.3 (from -r requirements.frozen.txt (line 65))
  Using cached https://files.pythonhosted.org/packages/e6/60/247f23a7121ae632d62811ba7f273d0e58972d75e58a94d329d51550a47d/urllib3-1.25.3-py2.py3-none-any.whl
Collecting wcwidth==0.1.7 (from -r requirements.frozen.txt (line 66))
  Using cached https://files.pythonhosted.org/packages/7e/9f/526a6947247599b084ee5232e4f9190a38f398d7300d866af3ab571a5bfe/wcwidth-0.1.7-py2.py3-none-any.whl
Collecting webencodings==0.5.1 (from -r requirements.frozen.txt (line 67))
  Using cached https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl
Collecting zipp==0.5.2 (from -r requirements.frozen.txt (line 68))
  Using cached https://files.pythonhosted.org/packages/da/bd/1a5fdf15aa44231fd09f63ecf175b60f057ae37ec65b343bb009364923f3/zipp-0.5.2-py2.py3-none-any.whl
Requirement already satisfied: setuptools in ./.virtualenv/lib/python3.7/site-packages (from pytest==4.4.0->-r requirements.frozen.txt (line 46)) (40.8.0)
Installing collected packages: alabaster, asn1crypto, atomicwrites, attrs, pytz, Babel, six, webencodings, bleach, python-dateutil, bson, certifi, pycparser, cffi, chardet, Click, colorama, coverage, cryptography, docutils, ecdsa, entrypoints, pyflakes, pycodestyle, mccabe, flake8, idna, imagesize, zipp, importlib-metadata, imutils, MarkupSafe, Jinja2, pbkdf2, mnemonic, more-itertools, mypy-extensions, typed-ast, mypy, numpy, opencv-python, pyparsing, packaging, Pillow, pkginfo, pluggy, wcwidth, prompt-toolkit, py, pyAesCrypt, Pygments, pysha3, pytest, pytest-cov, python-bitcoinlib, PyYAML, pyzbar, qrcode, readme-renderer, urllib3, requests, requests-toolbelt, shamir-mnemonic, snowballstemmer, sphinxcontrib-websupport, Sphinx, tqdm, twine
Successfully installed Babel-2.7.0 Click-7.0 Jinja2-2.10.1 MarkupSafe-1.1.1 Pillow-6.1.0 PyYAML-5.1.1 Pygments-2.4.2 Sphinx-1.8.5 alabaster-0.7.12 asn1crypto-0.24.0 atomicwrites-1.3.0 attrs-19.1.0 bleach-3.1.0 bson-0.5.8 certifi-2019.6.16 cffi-1.12.3 chardet-3.0.4 colorama-0.4.1 coverage-4.5.4 cryptography-2.7 docutils-0.15.2 ecdsa-0.13 entrypoints-0.3 flake8-3.7.7 idna-2.8 imagesize-1.1.0 importlib-metadata-0.19 imutils-0.5.1 mccabe-0.6.1 mnemonic-0.18 more-itertools-7.2.0 mypy-0.701 mypy-extensions-0.4.1 numpy-1.17.0 opencv-python-3.4.3.18 packaging-19.1 pbkdf2-1.3 pkginfo-1.5.0.1 pluggy-0.12.0 prompt-toolkit-2.0.7 py-1.8.0 pyAesCrypt-0.4.2 pycodestyle-2.5.0 pycparser-2.19 pyflakes-2.1.1 pyparsing-2.4.2 pysha3-1.0.2 pytest-4.4.0 pytest-cov-2.6.1 python-bitcoinlib-0.10.1 python-dateutil-2.8.0 pytz-2019.2 pyzbar-0.1.7 qrcode-6.0 readme-renderer-24.0 requests-2.22.0 requests-toolbelt-0.9.1 shamir-mnemonic-0.1.0 six-1.12.0 snowballstemmer-1.9.0 sphinxcontrib-websupport-1.1.2 tqdm-4.32.2 twine-1.13.0 typed-ast-1.3.5 urllib3-1.25.3 wcwidth-0.1.7 webencodings-0.5.1 zipp-0.5.2
You are using pip version 19.0.3, however version 19.2.2 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.

mflaxman@Michaels-MacBook-Pro:~/workspace/hermit$ source environment.sh 
basename: illegal option -- b
usage: basename string [suffix]
       basename [-a] [-s suffix] string [...]
[virtualenv] Entering Python virtualenv at /Users/mflaxman/workspace/hermit/.virtualenv
[pythonpath] /Users/mflaxman/workspace/hermit already on PYTHONPATH (:/Users/mflaxman/workspace/hermit)
[path]       Adding /Users/mflaxman/workspace/hermit/bin to PATH (/Users/mflaxman/workspace/hermit/.virtualenv/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Users/mflaxman/gocode/bin)

(hermit) mflaxman@Michaels-MacBook-Pro:~/workspace/hermit$ hermit
Traceback (most recent call last):
  File "/Users/mflaxman/workspace/hermit/bin/hermit", line 4, in <module>
    from hermit.ui import main
  File "/Users/mflaxman/workspace/hermit/hermit/__init__.py", line 3, in <module>
    from .wallet       import *
  File "/Users/mflaxman/workspace/hermit/hermit/wallet.py", line 5, in <module>
    from pybitcointools import (bip32_ckd,
ModuleNotFoundError: No module named 'pybitcointools'

What is your environment?

  • Operation system & version: [Mac OS 10.14.5]
  • Python & pip versions: [Python 3.7.4, pip 19.0.3]
  • Terminal emulator: [Terminal.app]

environment.sh script throws warning/error

Describe the bug

mflaxman@Michaels-MacBook-Pro:~/workspace/hermit$ source environment.sh
basename: illegal option -- b
usage: basename string [suffix]
       basename [-a] [-s suffix] string [...]
[virtualenv] Entering Python virtualenv at /Users/mflaxman/workspace/hermit/.virtualenv
[pythonpath] Adding /Users/mflaxman/workspace/hermit to PYTHONPATH ()
[path]       Adding /Users/mflaxman/workspace/hermit/bin to PATH (/Users/mflaxman/workspace/hermit/.virtualenv/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Users/mflaxman/gocode/bin)
[git]        Submodules present

See #6 for my setup

Error in shards on Mac: unpack requires a buffer of 4 bytes

I compiled the code but I get errors every time I interact with shards:

 shards> list-shards
unpack requires a buffer of 4 bytes
Hmm. Something went wrong.

I include test results and the errors i get with

# make lint

What is your environment?

  • Operation system & version: [Mac OS 10.14.6]
  • Python & pip versions: [Python3 3.8.3, pip3 19.2.3]
  • Terminal emulator: [iTerm]

Screenshots

Tests: 

===================================== test session starts ======================================
platform darwin -- Python 3.7.0, pytest-4.4.0, py-1.8.0, pluggy-0.12.0
rootdir: /Users/roberto/hermit
plugins: cov-2.6.1
collected 109 items

tests/test_config.py ....                                                                [  3%]
tests/test_errors.py ..                                                                  [  5%]
tests/test_functional_bitcoin_tests.py ..                                                [  7%]
tests/test_rng.py ...                                                                    [ 10%]
tests/test_wallet.py ..........                                                          [ 19%]
tests/qrcode/test_displayer.py ....                                                      [ 22%]
tests/qrcode/test_format.py .........                                                    [ 31%]
tests/qrcode/test_limits.py .........                                                    [ 39%]
tests/qrcode/test_reader.py ..                                                           [ 41%]
tests/shards/test_shard.py ........                                                      [ 48%]
tests/shards/test_shard_set.py .ss.......                                                [ 57%]
tests/signer/test_base.py .........                                                      [ 66%]
tests/signer/test_bitcoin_signer.py ...................................                  [ 98%]
tests/signer/test_echo_signer.py ..                                                      [100%]

======================================= warnings summary =======================================
tests/qrcode/test_displayer.py::TestDisplayQRCode::test_valid_qr_code[fixture_opensource_bitcoin_vector_0]
tests/qrcode/test_displayer.py::TestDisplayQRCode::test_valid_qr_code[fixture_opensource_bitcoin_vector_1]
  /Users/roberto/hermit/.virtualenv/lib/python3.7/site-packages/_pytest/python.py:178: RuntimeWarning: coroutine 'TestDisplayQRCode.test_valid_qr_code' was never awaited
    testfunction(**testargs)

-- Docs: https://docs.pytest.org/en/latest/warnings.html

---------- coverage: platform darwin, python 3.7.0-final-0 -----------
Name                              Stmts   Miss Branch BrPart  Cover   Missing
-----------------------------------------------------------------------------
hermit/config.py                     29      0     14      0   100%
hermit/errors.py                      5      0      0      0   100%
hermit/plugin.py                     11      5      6      1    41%   10-15, 9->10
hermit/qrcode/displayer.py           22      8      2      0    58%   13-14, 18-26
hermit/qrcode/format.py              40      7      8      1    83%   11, 41-46, 10->11
hermit/qrcode/reader.py              43      3     10      4    87%   47-48, 62, 27->65, 31->55, 51->31, 59->62
hermit/qrcode/utils.py                3      1      0      0    67%   5
hermit/rng.py                        58     29     12      0    50%   48-76, 93-96, 99-105, 108-109
hermit/shamir_share.py               43      2      6      0    92%   30-31
hermit/shards/interface.py          128    103     42      0    16%   24-25, 28-36, 39-49, 56-68, 75-83, 88-109, 112, 116, 120-121, 124-142, 145-163, 166-216
hermit/shards/shard.py               67      6     12      5    86%   29, 45, 55, 65, 93, 128, 28->29, 44->45, 54->55, 64->65, 92->93
hermit/shards/shard_set.py          205     78     62      7    60%   58-83, 86, 94-96, 99-100, 198-199, 205-207, 210, 226-232, 235-246, 249, 252-254, 257-269, 275-277, 285-298, 301, 304-305, 308-310, 313-318, 322, 325, 328, 331-333, 57->58, 85->86, 89->exit, 132->134, 197->198, 209->210, 274->275
hermit/signer/base.py                73      0     18      0   100%
hermit/signer/bitcoin_signer.py     183      0     80      0   100%
hermit/signer/echo_signer.py         11      0      0      0   100%
hermit/ui/base.py                    27     27      6      0     0%   1-40
hermit/ui/common.py                  27     27      2      0     0%   1-74
hermit/ui/main.py                    16     16      2      0     0%   1-29
hermit/ui/relocker.py                15     15      6      0     0%   1-21
hermit/ui/repl.py                    62     62     26      0     0%   1-91
hermit/ui/shards.py                  49     49      2      0     0%   1-341
hermit/ui/state.py                    8      8      0      0     0%   1-15
hermit/ui/toolbar.py                 17     17      6      0     0%   1-25
hermit/ui/wallet.py                  41     41      2      0     0%   1-203
hermit/wallet.py                     55      0     12      0   100%
-----------------------------------------------------------------------------
TOTAL                              1238    504    336     18    59%

====================== 107 passed, 2 skipped, 2 warnings in 16.15 seconds ======================

make lint
.virtualenv/bin/flake8 hermit --exclude=__init__.py
hermit/config.py:16:80: E501 line too long (131 > 79 characters)
hermit/config.py:82:80: E501 line too long (90 > 79 characters)
hermit/rng.py:7:1: E302 expected 2 blank lines, found 1
hermit/shamir_share.py:2:80: E501 line too long (85 > 79 characters)
hermit/shamir_share.py:3:80: E501 line too long (84 > 79 characters)
hermit/shamir_share.py:7:47: W291 trailing whitespace
hermit/shamir_share.py:11:1: F401 'hashlib' imported but unused
hermit/shamir_share.py:12:1: F401 'hmac' imported but unused
hermit/shamir_share.py:13:1: F401 'os' imported but unused
hermit/shamir_share.py:16:1: F403 'from shamir_mnemonic import *' used; unable to detect undefined names
hermit/shamir_share.py:17:80: E501 line too long (82 > 79 characters)
hermit/shamir_share.py:20:80: E501 line too long (80 > 79 characters)
hermit/shamir_share.py:25:1: E302 expected 2 blank lines, found 0
hermit/shamir_share.py:29:1: E302 expected 2 blank lines, found 1
hermit/shamir_share.py:30:8: F405 'length' may be undefined, or defined from star imports: shamir_mnemonic
hermit/shamir_share.py:30:24: E225 missing whitespace around operator
hermit/shamir_share.py:33:1: E302 expected 2 blank lines, found 1
hermit/shamir_share.py:37:12: F405 'mnemonic_from_indices' may be undefined, or defined from star imports: shamir_mnemonic
hermit/shamir_share.py:37:75: E231 missing whitespace after ','
hermit/shamir_share.py:37:80: E501 line too long (130 > 79 characters)
hermit/shamir_share.py:37:107: F405 'RADIX_BITS' may be undefined, or defined from star imports: shamir_mnemonic
hermit/shamir_share.py:37:119: F405 'RADIX_BITS' may be undefined, or defined from star imports: shamir_mnemonic
hermit/shamir_share.py:45:30: F405 'mnemonic_to_indices' may be undefined, or defined from star imports: shamir_mnemonic
hermit/shamir_share.py:45:70: F405 'bits_to_bytes' may be undefined, or defined from star imports: shamir_mnemonic
hermit/shamir_share.py:45:80: E501 line too long (113 > 79 characters)
hermit/shamir_share.py:45:84: F405 'RADIX_BITS' may be undefined, or defined from star imports: shamir_mnemonic
hermit/shamir_share.py:45:106: E203 whitespace before ','
hermit/shamir_share.py:45:107: E231 missing whitespace after ','
hermit/shamir_share.py:47:1: E302 expected 2 blank lines, found 1
hermit/shamir_share.py:48:80: E501 line too long (133 > 79 characters)
hermit/shamir_share.py:52:80: E501 line too long (85 > 79 characters)
hermit/shamir_share.py:53:80: E501 line too long (130 > 79 characters)
hermit/shamir_share.py:55:1: E302 expected 2 blank lines, found 1
hermit/shamir_share.py:56:80: E501 line too long (141 > 79 characters)
hermit/shamir_share.py:60:80: E501 line too long (95 > 79 characters)
hermit/shamir_share.py:61:80: E501 line too long (130 > 79 characters)
hermit/shamir_share.py:63:1: E302 expected 2 blank lines, found 1
hermit/shamir_share.py:64:15: F405 'decode_mnemonic' may be undefined, or defined from star imports: shamir_mnemonic
hermit/shamir_share.py:66:12: F405 'encode_mnemonic' may be undefined, or defined from star imports: shamir_mnemonic
hermit/shamir_share.py:68:1: E302 expected 2 blank lines, found 1
hermit/shamir_share.py:69:15: F405 'decode_mnemonic' may be undefined, or defined from star imports: shamir_mnemonic
hermit/shamir_share.py:72:12: F405 'encode_mnemonic' may be undefined, or defined from star imports: shamir_mnemonic
hermit/shamir_share.py:74:1: E302 expected 2 blank lines, found 1
hermit/shamir_share.py:75:15: F405 'decode_mnemonic' may be undefined, or defined from star imports: shamir_mnemonic
hermit/shamir_share.py:77:12: F405 'encode_mnemonic' may be undefined, or defined from star imports: shamir_mnemonic
hermit/shamir_share.py:78:1: W391 blank line at end of file
hermit/plugin.py:8:10: E222 multiple spaces after operator
hermit/ui/repl.py:1:1: F401 'asyncio' imported but unused
hermit/ui/repl.py:11:1: F403 'from .base import *' used; unable to detect undefined names
hermit/ui/repl.py:12:1: F403 'from .toolbar import *' used; unable to detect undefined names
hermit/ui/repl.py:17:1: E302 expected 2 blank lines, found 1
hermit/ui/repl.py:17:18: E231 missing whitespace after ':'
hermit/ui/repl.py:17:19: F405 'Dict' may be undefined, or defined from star imports: .base, .toolbar
hermit/ui/repl.py:20:22: E261 at least two spaces before inline comment
hermit/ui/repl.py:25:29: E128 continuation line under-indented for visual indent
hermit/ui/repl.py:25:44: F405 'bottom_toolbar' may be undefined, or defined from star imports: .base, .toolbar
hermit/ui/repl.py:26:29: E128 continuation line under-indented for visual indent
hermit/ui/repl.py:27:64: F405 'bottom_toolbar' may be undefined, or defined from star imports: .base, .toolbar
hermit/ui/repl.py:35:80: E501 line too long (97 > 79 characters)
hermit/ui/repl.py:36:47: E128 continuation line under-indented for visual indent
hermit/ui/repl.py:37:47: E124 closing bracket does not match visual indentation
hermit/ui/repl.py:52:27: F405 'HermitError' may be undefined, or defined from star imports: .base, .toolbar
hermit/ui/repl.py:56:20: F405 'HermitError' may be undefined, or defined from star imports: .base, .toolbar
hermit/ui/repl.py:75:25: F405 'DeadTime' may be undefined, or defined from star imports: .base, .toolbar
hermit/ui/toolbar.py:1:1: F401 'asyncio' imported but unused
hermit/ui/toolbar.py:3:1: F403 'from .base import *' used; unable to detect undefined names
hermit/ui/toolbar.py:6:12: F405 'DeadTime' may be undefined, or defined from star imports: .base
hermit/ui/toolbar.py:6:27: F405 'DeadTime' may be undefined, or defined from star imports: .base
hermit/ui/toolbar.py:8:1: E302 expected 2 blank lines, found 1
hermit/ui/toolbar.py:19:9: F405 'DeadTime' may be undefined, or defined from star imports: .base
hermit/ui/toolbar.py:21:55: F405 'DeadTime' may be undefined, or defined from star imports: .base
hermit/ui/common.py:1:1: F403 'from .base import *' used; unable to detect undefined names
hermit/ui/common.py:5:1: F401 'traceback' imported but unused
hermit/ui/common.py:6:1: F401 'sys' imported but unused
hermit/ui/common.py:7:31: E703 statement ends with a semicolon
hermit/ui/common.py:9:1: E302 expected 2 blank lines, found 1
hermit/ui/common.py:20:7: E111 indentation is not a multiple of four
hermit/ui/common.py:21:12: F405 'HermitError' may be undefined, or defined from star imports: .base
hermit/ui/common.py:22:7: E111 indentation is not a multiple of four
hermit/ui/common.py:22:7: F405 'print_formatted_text' may be undefined, or defined from star imports: .base
hermit/ui/common.py:23:7: E114 indentation is not a multiple of four (comment)
hermit/ui/common.py:23:7: E265 block comment should start with '# '
hermit/ui/common.py:25:25: F405 'DeadTime' may be undefined, or defined from star imports: .base
hermit/ui/common.py:41:1: E302 expected 2 blank lines, found 1
hermit/ui/common.py:48:5: F405 'clear_screen' may be undefined, or defined from star imports: .base
hermit/ui/common.py:50:1: E302 expected 2 blank lines, found 1
hermit/ui/common.py:65:1: E302 expected 2 blank lines, found 1
hermit/ui/common.py:65:1: F811 redefinition of unused 'unlock' from line 9
hermit/ui/common.py:71:1: W293 blank line contains whitespace
hermit/ui/common.py:72:1: W293 blank line contains whitespace
hermit/ui/common.py:74:5: F405 'print_formatted_text' may be undefined, or defined from star imports: .base
hermit/ui/main.py:5:1: F403 'from .wallet import *' used; unable to detect undefined names
hermit/ui/main.py:6:1: F403 'from .common import *' used; unable to detect undefined names
hermit/ui/main.py:7:1: F403 'from .relocker import *' used; unable to detect undefined names
hermit/ui/main.py:21:1: E302 expected 2 blank lines, found 1
hermit/ui/main.py:22:5: F405 'clear_screen' may be undefined, or defined from star imports: .common, .relocker, .wallet
hermit/ui/main.py:27:12: F405 'asyncio' may be undefined, or defined from star imports: .common, .relocker, .wallet
hermit/ui/main.py:28:5: F841 local variable 'deadman_task' is assigned to but never used
hermit/ui/main.py:28:37: F405 'relock_wallet_if_timed_out' may be undefined, or defined from star imports: .common, .relocker, .wallet
hermit/ui/main.py:29:29: F405 'wallet_repl' may be undefined, or defined from star imports: .common, .relocker, .wallet
hermit/ui/relocker.py:3:1: F403 'from .base import *' used; unable to detect undefined names
hermit/ui/relocker.py:3:1: F401 '.base.*' imported but unused
hermit/ui/relocker.py:6:1: E302 expected 2 blank lines, found 1
hermit/ui/relocker.py:11:1: E302 expected 2 blank lines, found 1
hermit/ui/shards.py:3:1: F403 'from .base import *' used; unable to detect undefined names
hermit/ui/shards.py:6:16: F405 'Dict' may be undefined, or defined from star imports: .base
hermit/ui/shards.py:8:1: E302 expected 2 blank lines, found 1
hermit/ui/shards.py:9:12: F405 'command' may be undefined, or defined from star imports: .base
hermit/ui/shards.py:79:2: W291 trailing whitespace
hermit/ui/shards.py:145:15: F405 'reader' may be undefined, or defined from star imports: .base
hermit/ui/shards.py:159:1: E302 expected 2 blank lines, found 1
hermit/ui/shards.py:167:5: F405 'displayer' may be undefined, or defined from star imports: .base
hermit/ui/shards.py:284:1: E303 too many blank lines (3)
hermit/ui/shards.py:298:1: E303 too many blank lines (3)
hermit/ui/shards.py:313:1: E302 expected 2 blank lines, found 3
hermit/ui/shards.py:318:5: F405 'clear_screen' may be undefined, or defined from star imports: .base
hermit/ui/shards.py:341:9: F405 'print_formatted_text' may be undefined, or defined from star imports: .base
hermit/ui/shards.py:341:30: F405 'HTML' may be undefined, or defined from star imports: .base
hermit/ui/base.py:4:1: F401 'prompt_toolkit.HTML' imported but unused
hermit/ui/base.py:4:1: F401 'prompt_toolkit.print_formatted_text' imported but unused
hermit/ui/base.py:7:1: F401 'hermit.qrcode.displayer' imported but unused
hermit/ui/base.py:7:1: F401 'hermit.qrcode.reader' imported but unused
hermit/ui/base.py:11:1: E302 expected 2 blank lines, found 1
hermit/ui/base.py:15:1: E302 expected 2 blank lines, found 1
hermit/ui/base.py:18:1: E302 expected 2 blank lines, found 1
hermit/ui/base.py:18:27: E231 missing whitespace after ':'
hermit/ui/wallet.py:7:1: F403 'from .base import *' used; unable to detect undefined names
hermit/ui/wallet.py:12:17: F405 'Dict' may be undefined, or defined from star imports: .base
hermit/ui/wallet.py:14:1: E302 expected 2 blank lines, found 1
hermit/ui/wallet.py:15:12: F405 'command' may be undefined, or defined from star imports: .base
hermit/ui/wallet.py:83:5: F405 'displayer' may be undefined, or defined from star imports: .base
hermit/ui/wallet.py:83:80: E501 line too long (81 > 79 characters)
hermit/ui/wallet.py:106:5: F405 'displayer' may be undefined, or defined from star imports: .base
hermit/ui/wallet.py:106:80: E501 line too long (85 > 79 characters)
hermit/ui/wallet.py:116:5: F405 'clear_screen' may be undefined, or defined from star imports: .base
hermit/ui/wallet.py:128:5: F405 'clear_screen' may be undefined, or defined from star imports: .base
hermit/ui/wallet.py:166:30: F405 'HTML' may be undefined, or defined from star imports: .base
hermit/ui/wallet.py:202:1: E302 expected 2 blank lines, found 1
hermit/signer/bitcoin_signer.py:79:1: W293 blank line contains whitespace
hermit/signer/bitcoin_signer.py:108:80: E501 line too long (81 > 79 characters)
hermit/signer/bitcoin_signer.py:115:80: E501 line too long (119 > 79 characters)
hermit/signer/bitcoin_signer.py:183:80: E501 line too long (85 > 79 characters)
hermit/signer/bitcoin_signer.py:233:20: E221 multiple spaces before operator
hermit/signer/bitcoin_signer.py:238:55: E261 at least two spaces before inline comment
hermit/signer/bitcoin_signer.py:239:1: W293 blank line contains whitespace
hermit/signer/bitcoin_signer.py:280:80: E501 line too long (111 > 79 characters)
hermit/signer/bitcoin_signer.py:317:10: W291 trailing whitespace
hermit/signer/bitcoin_signer.py:320:10: W291 trailing whitespace
hermit/signer/echo_signer.py:1:1: F401 'hermit.qrcode.displayer' imported but unused
hermit/signer/echo_signer.py:17:1: W293 blank line contains whitespace
hermit/signer/base.py:7:1: F401 'hermit' imported but unused
hermit/signer/base.py:78:45: E231 missing whitespace after ':'
hermit/signer/base.py:123:45: E231 missing whitespace after ':'
hermit/signer/base.py:143:5: E303 too many blank lines (2)
hermit/signer/base.py:162:80: E501 line too long (80 > 79 characters)
hermit/signer/base.py:169:5: E303 too many blank lines (2)
hermit/signer/base.py:176:5: E303 too many blank lines (2)
hermit/shards/interface.py:28:80: E501 line too long (80 > 79 characters)
hermit/shards/interface.py:35:1: W293 blank line contains whitespace
hermit/shards/interface.py:37:1: W293 blank line contains whitespace
hermit/shards/interface.py:41:18: E222 multiple spaces after operator
hermit/shards/interface.py:41:80: E501 line too long (85 > 79 characters)
hermit/shards/interface.py:61:44: W291 trailing whitespace
hermit/shards/interface.py:76:80: E501 line too long (116 > 79 characters)
hermit/shards/interface.py:83:80: E501 line too long (96 > 79 characters)
hermit/shards/interface.py:97:80: E501 line too long (80 > 79 characters)
hermit/shards/interface.py:124:80: E501 line too long (92 > 79 characters)
hermit/shards/interface.py:165:67: E231 missing whitespace after ','
hermit/shards/interface.py:168:80: E501 line too long (81 > 79 characters)
hermit/shards/interface.py:172:80: E501 line too long (141 > 79 characters)
hermit/shards/interface.py:173:15: E203 whitespace before ':'
hermit/shards/interface.py:173:32: E231 missing whitespace after ','
hermit/shards/interface.py:176:80: E501 line too long (88 > 79 characters)
hermit/shards/interface.py:188:80: E501 line too long (148 > 79 characters)
hermit/shards/interface.py:192:80: E501 line too long (158 > 79 characters)
hermit/shards/interface.py:212:80: E501 line too long (130 > 79 characters)
hermit/shards/shard_set.py:18:1: E302 expected 2 blank lines, found 1
hermit/shards/shard_set.py:35:12: E713 test for membership should be 'not in'
hermit/shards/shard_set.py:86:80: E501 line too long (89 > 79 characters)
hermit/shards/shard_set.py:108:80: E501 line too long (80 > 79 characters)
hermit/shards/shard_set.py:152:80: E501 line too long (86 > 79 characters)
hermit/shards/shard_set.py:155:80: E501 line too long (86 > 79 characters)
hermit/shards/shard_set.py:158:80: E501 line too long (117 > 79 characters)
hermit/shards/shard_set.py:177:17: E203 whitespace before ':'
hermit/shards/shard_set.py:177:36: E225 missing whitespace around operator
hermit/shards/shard_set.py:178:26: E203 whitespace before ':'
hermit/shards/shard_set.py:178:42: E225 missing whitespace around operator
hermit/shards/shard_set.py:179:27: E203 whitespace before ':'
hermit/shards/shard_set.py:180:24: E203 whitespace before ':'
hermit/shards/shard_set.py:190:80: E501 line too long (92 > 79 characters)
hermit/shards/shard_set.py:196:31: E231 missing whitespace after ','
hermit/shards/shard_set.py:196:80: E501 line too long (94 > 79 characters)
hermit/shards/shard_set.py:199:80: E501 line too long (101 > 79 characters)
hermit/shards/shard_set.py:205:13: E722 do not use bare 'except'
hermit/shards/shard_set.py:210:80: E501 line too long (81 > 79 characters)
hermit/shards/shard_set.py:220:80: E501 line too long (85 > 79 characters)
hermit/shards/shard_set.py:230:80: E501 line too long (81 > 79 characters)
hermit/shards/shard_set.py:265:80: E501 line too long (85 > 79 characters)
hermit/shards/shard_set.py:291:80: E501 line too long (92 > 79 characters)
hermit/shards/shard.py:6:1: E302 expected 2 blank lines, found 1
hermit/shards/shard.py:77:80: E501 line too long (89 > 79 characters)
hermit/shards/shard.py:105:80: E501 line too long (91 > 79 characters)
hermit/shards/shard.py:131:80: E501 line too long (110 > 79 characters)
hermit/shards/shard.py:135:80: E501 line too long (95 > 79 characters)
hermit/shards/shard.py:138:80: E501 line too long (124 > 79 characters)
make: [lint] Error 1 (ignored)
.virtualenv/bin/mypy hermit/
hermit/shards/interface.py:34: error: Incompatible return value type (got "None", expected "bytes")
hermit/shards/interface.py:46: error: Incompatible return value type (got "None", expected "bytes")
hermit/shards/interface.py:63: error: Incompatible types in assignment (expression has type "None", variable has type "bytes")
hermit/shards/interface.py:66: error: Incompatible types in assignment (expression has type "None", variable has type "bytes")
hermit/shards/shard_set.py:183: error: Need type annotation for 'filled_groups'
hermit/signer/bitcoin_signer.py:109: error: Need type annotation for 'inputs'
hermit/signer/bitcoin_signer.py:157: error: "bytes" has no attribute "encode"; maybe "decode"?
hermit/signer/bitcoin_signer.py:277: error: Need type annotation for 'parsed_redeem_scripts'
hermit/signer/bitcoin_signer.py:290: error: "CBitcoinAddress" has no attribute "to_scriptPubKey"; maybe "from_scriptPubKey"?
hermit/signer/bitcoin_signer.py:299: error: Need type annotation for 'keys'
hermit/ui/repl.py:24: error: Incompatible types in assignment (expression has type "PromptSession", variable has type "None")
hermit/ui/repl.py:35: error: "None" has no attribute "prompt"
hermit/ui/common.py:65: error: Name 'unlock' already defined on line 9
make: [lint] Error 1 (ignored)
´´´

AttributeError: module 'hermit' has no attribute 'ui'

Hermit won't start

Traceback (most recent call last):
  File "/home/kirill/.local/bin/hermit", line 4, in <module>
    from hermit.ui import main
  File "/home/kirill/.local/lib/python3.6/site-packages/hermit/ui/__init__.py", line 1, in <module>
    from .main import main
  File "/home/kirill/.local/lib/python3.6/site-packages/hermit/ui/main.py", line 5, in <module>
    from .wallet import *
  File "/home/kirill/.local/lib/python3.6/site-packages/hermit/ui/wallet.py", line 8, in <module>
    from .repl import repl
  File "/home/kirill/.local/lib/python3.6/site-packages/hermit/ui/repl.py", line 12, in <module>
    from .toolbar import *
  File "/home/kirill/.local/lib/python3.6/site-packages/hermit/ui/toolbar.py", line 4, in <module>
    import hermit.ui.state as state
AttributeError: module 'hermit' has no attribute 'ui'
  • Operation system & version: [Windows 1903, WSL]
  • Python & pip versions: [pip 9.0.1 from /usr/lib/python3/dist-packages (python 3.6)]
  • Terminal emulator: [bash.exe]

Unable to install dependencies

Can you please help me with this problem? Installing dependencies fails with:

ERROR: Ignored the following versions that require a different python version: 1.21.2 Requires-Python >=3.7,<3.11; 1.21.3 Requires-Python >=3.7,<3.11; 1.21.4 Requires-Python >=3.7,<3.11; 1.21.5 Requires-Python >=3.7,<3.11; 1.21.6 Requires-Python >=3.7,<3.11
ERROR: Could not find a version that satisfies the requirement opencv-python==3.4.3.18 (from versions: 3.4.0.14, 3.4.10.37, 3.4.11.39, 3.4.11.41, 3.4.11.43, 3.4.11.45, 3.4.13.47, 3.4.15.55, 3.4.16.57, 3.4.16.59, 3.4.17.61, 3.4.17.63, 3.4.18.65, 4.3.0.38, 4.4.0.40, 4.4.0.42, 4.4.0.44, 4.4.0.46, 4.5.1.48, 4.5.3.56, 4.5.4.58, 4.5.4.60, 4.5.5.62, 4.5.5.64, 4.6.0.66, 4.7.0.68, 4.7.0.72, 4.8.0.74, 4.8.0.76, 4.8.1.78, 4.9.0.80)
ERROR: No matching distribution found for opencv-python==3.4.3.18

Step to reproduce using docker:

  • Create this dockerfile:
# Dockerfile
FROM debian:bookworm
RUN apt-get update -y
RUN apt-get install -y python3
RUN apt-get install -y libzbar0
RUN apt-get install -y make
RUN apt-get install -y sudo
RUN apt-get install -y python3-venv
RUN apt-get install -y python3-pip
RUN apt-get install -y git
  • Build it:
$ docker build . -t hermit
  • Run the image:
$ docker run -ti hermit
  • See the versions:
$ python3 --version
Python 3.11.2
$ pip --version
pip 23.0.1 from /usr/lib/python3/dist-packages/pip (python 3.11)
  • Follow the developer guide in readme:
$ git clone --recursive https://github.com/unchained-capital/hermit
$ cd hermit
$ make
See the full output:
sudo apt install libzbar0
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
libzbar0 is already the newest version (0.23.92-7+deb12u1).
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
/usr/bin/python3 -m venv --prompt='hermit' .virtualenv
.virtualenv/bin/pip install wheel
Collecting wheel
  Downloading wheel-0.43.0-py3-none-any.whl (65 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 65.8/65.8 kB 2.7 MB/s eta 0:00:00
Installing collected packages: wheel
Successfully installed wheel-0.43.0
.virtualenv/bin/pip install -r requirements.frozen.txt
Collecting alabaster==0.7.12
  Downloading alabaster-0.7.12-py2.py3-none-any.whl (14 kB)
Collecting asn1crypto==0.24.0
  Downloading asn1crypto-0.24.0-py2.py3-none-any.whl (101 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 101.6/101.6 kB 4.0 MB/s eta 0:00:00
Collecting atomicwrites==1.3.0
  Downloading atomicwrites-1.3.0-py2.py3-none-any.whl (5.9 kB)
Collecting attrs==19.1.0
  Downloading attrs-19.1.0-py2.py3-none-any.whl (35 kB)
Collecting Babel==2.7.0
  Downloading Babel-2.7.0-py2.py3-none-any.whl (8.4 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.4/8.4 MB 6.3 MB/s eta 0:00:00
Collecting bleach==3.1.2
  Downloading bleach-3.1.2-py2.py3-none-any.whl (151 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 151.0/151.0 kB 7.0 MB/s eta 0:00:00
Collecting bson==0.5.8
  Downloading bson-0.5.8.tar.gz (10 kB)
  Preparing metadata (setup.py) ... done
Collecting certifi==2019.6.16
  Downloading certifi-2019.6.16-py2.py3-none-any.whl (157 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 157.1/157.1 kB 7.1 MB/s eta 0:00:00
Collecting cffi==1.12.3
  Downloading cffi-1.12.3.tar.gz (456 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 456.3/456.3 kB 7.0 MB/s eta 0:00:00
  Preparing metadata (setup.py) ... done
Collecting chardet==3.0.4
  Downloading chardet-3.0.4-py2.py3-none-any.whl (133 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 133.4/133.4 kB 5.9 MB/s eta 0:00:00
Collecting Click==7.0
  Downloading Click-7.0-py2.py3-none-any.whl (81 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 81.3/81.3 kB 5.6 MB/s eta 0:00:00
Collecting colorama==0.4.1
  Downloading colorama-0.4.1-py2.py3-none-any.whl (15 kB)
Collecting coverage==4.5.4
  Downloading coverage-4.5.4.tar.gz (385 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 385.2/385.2 kB 7.2 MB/s eta 0:00:00
  Preparing metadata (setup.py) ... done
Collecting cryptography==2.7
  Downloading cryptography-2.7-cp34-abi3-manylinux1_x86_64.whl (2.3 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.3/2.3 MB 7.6 MB/s eta 0:00:00
Collecting docutils==0.15.2
  Downloading docutils-0.15.2-py3-none-any.whl (547 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 547.6/547.6 kB 7.5 MB/s eta 0:00:00
Collecting ecdsa==0.13.3
  Downloading ecdsa-0.13.3-py2.py3-none-any.whl (52 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 52.1/52.1 kB 3.7 MB/s eta 0:00:00
Collecting entrypoints==0.3
  Downloading entrypoints-0.3-py2.py3-none-any.whl (11 kB)
Collecting flake8==3.7.7
  Downloading flake8-3.7.7-py2.py3-none-any.whl (68 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 68.8/68.8 kB 4.7 MB/s eta 0:00:00
Collecting idna==2.8
  Downloading idna-2.8-py2.py3-none-any.whl (58 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 58.6/58.6 kB 4.1 MB/s eta 0:00:00
Collecting imagesize==1.1.0
  Downloading imagesize-1.1.0-py2.py3-none-any.whl (4.4 kB)
Collecting importlib-metadata==0.19
  Downloading importlib_metadata-0.19-py2.py3-none-any.whl (26 kB)
Collecting imutils==0.5.1
  Downloading imutils-0.5.1.tar.gz (15 kB)
  Preparing metadata (setup.py) ... done
Collecting Jinja2==2.10.1
  Downloading Jinja2-2.10.1-py2.py3-none-any.whl (124 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 124.9/124.9 kB 5.7 MB/s eta 0:00:00
Collecting MarkupSafe==1.1.1
  Downloading MarkupSafe-1.1.1.tar.gz (19 kB)
  Preparing metadata (setup.py) ... done
Collecting mccabe==0.6.1
  Downloading mccabe-0.6.1-py2.py3-none-any.whl (8.6 kB)
Collecting mnemonic==0.18
  Downloading mnemonic-0.18.tar.gz (21 kB)
  Preparing metadata (setup.py) ... done
Collecting more-itertools==7.2.0
  Downloading more_itertools-7.2.0-py3-none-any.whl (57 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 57.3/57.3 kB 4.5 MB/s eta 0:00:00
Collecting mypy==0.701
  Downloading mypy-0.701-py3-none-any.whl (1.5 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.5/1.5 MB 8.8 MB/s eta 0:00:00
Collecting mypy-extensions==0.4.1
  Downloading mypy_extensions-0.4.1-py2.py3-none-any.whl (3.6 kB)
Collecting numpy==1.17.0
  Downloading numpy-1.17.0.zip (6.5 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 6.5/6.5 MB 6.4 MB/s eta 0:00:00
  Preparing metadata (setup.py) ... done
ERROR: Ignored the following versions that require a different python version: 1.21.2 Requires-Python >=3.7,<3.11; 1.21.3 Requires-Python >=3.7,<3.11; 1.21.4 Requires-Python >=3.7,<3.11; 1.21.5 Requires-Python >=3.7,<3.11; 1.21.6 Requires-Python >=3.7,<3.11
ERROR: Could not find a version that satisfies the requirement opencv-python==3.4.3.18 (from versions: 3.4.0.14, 3.4.10.37, 3.4.11.39, 3.4.11.41, 3.4.11.43, 3.4.11.45, 3.4.13.47, 3.4.15.55, 3.4.16.57, 3.4.16.59, 3.4.17.61, 3.4.17.63, 3.4.18.65, 4.3.0.38, 4.4.0.40, 4.4.0.42, 4.4.0.44, 4.4.0.46, 4.5.1.48, 4.5.3.56, 4.5.4.58, 4.5.4.60, 4.5.5.62, 4.5.5.64, 4.6.0.66, 4.7.0.68, 4.7.0.72, 4.8.0.74, 4.8.0.76, 4.8.1.78, 4.9.0.80)
ERROR: No matching distribution found for opencv-python==3.4.3.18
make: *** [Makefile:53: python-dependencies] Error 1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.