Package: hermit
HermitHermit is a sharded,HDcommand-line
wallet designed for cryptocurrency owners who demand the highest
possible form of security.Hermit implements theSLIP-0039standard 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:Creating a shard familyExporting/importing shardsExport a public keySign a bitcoin transactionQuickstart$ 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.DesignHermit follows the following design principles:Unidirectional information transfer -- information should only move in one directionAlways-on sharding & encryption -- keys should always be sharded and each shard encryptedOpen-source everything -- complete control over your software and hardware gives you the best securityFlexibility for human security -- you can customize the sharding configuration to suit your organizationAudienceHermit is a difficult to use but highly-secure wallet.Hermit isnot recommendedfor 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.ShardingHermit is different than other wallets you may have used because it
always shards your key.Sharding is done usingSLIP-39which means there are two levels of structure:Groups -- some quorum ofPofQgroups is required to unlock a keyShards -- some quorum ofnofmshards is required to unlock
each group, withnandmpossibly different for each groupThis 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 walletsIf 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 willnotexport 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 & OutputHermit 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.StorageHermit 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 madein memoryand will not survive Hermit restarts.To save data across Hermit restarts, ensure youwriteit to the
filesystem.If your Hermit lives on a read-only filesystem, to save data
across Hermit machine restarts, ensure youpersistit to the
data store.ModesHermit is a modal application with two modes:walletmode is where you will spend most of your time, signing transactions and exporting public keysshardsmode is accessed when you need to import keys or shards, export shards, or otherwise change something about how your key is unlockedBitcoin OnlyAs 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 asign-bitcoincommand that will sign
Bitcoin (BTC) transactions.You can extend Hermit for other cryptocurrencies if you need; see the
"Plugins" section below.UsageInstallationInstalling Hermit can be done viapip:$ pip install hermitIf you want to develop against Hermit, see the "Developers" section
below for a different way of installing Hermit.Starting HermitTo start Hermit, just run thehermitcommand.$ hermitYou can also pass a configuration file$ HERMIT_CONFIG=/path/to/hermit.yml hermitSee the "Configuration" section below for more information on how to
configure Hermit.Creating a KeyBefore 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> shardsTwoshardmode 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 tobuild-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 KeysHermit 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.Twowalletmode commands are useful for this:export-xpub-- exports an extended public keyexport-pub-- exports a  public keyEach of these commands expects a BIP32 path as an argument and each
will display its data as a QR code.Signing TransactionsThe 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 atexamples/signature_requests/bitcoin.png.Once you have a signature request, and you're inwalletmode, you
can runsign-bitcointo start signing a Bitcoin transaction.ConfigurationHermit looks for a configuration file at/etc/hermit.ymlby default.
You can change this path by passing theHERMIT_CONFIGenvironment
variable when you start thehermitprogram:$ HERMIT_CONFIG=/path/to/hermit.yml hermitThe configuration file is a YAML file.  See the documentation for theHermitConfigclass for details on allowed configuration settings.DevelopersDevelopers will want to clone a copy of the Hermit source code:$ git clone --recursive https://github.com/unchained-capital/hermit
$ cd hermit
$ makeNOTE:To develop using the Hermit code in this directory, runsource environment.sh.  This applies to all the commands below in
this section.TestingHermit ships with a fullpytestsuite.  Run it as follows:$ source environment.sh
$ make test
$ make lintHermit has been tested on the following platforms:OS X High Sierra 10.13.6Linux Ubuntu 18.04Linux Slax 9.6.4There 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.DevelopersIntegratingHermit needs an external, online wallet application in order to work.
This application has a few ways it may need to integrate with
Hermit:Read a public key displayed by HermitGenerate a signature request for Hermit (seeexamples/signature_requests/bitcoin_testnet.json)Read a signature displayed by Hermit (seeexamples/signatures/bitcoin.json)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 astring: utf-8 encode -> gzip-compress -> Base32 encodeTo parse a QR codestring: Base32 decode -> gzip-decompress -> utf-8 decodeThestringdata may sometimes itself be JSON.PluginsHermit allows you to write plugins to extend its functionality.  This
is chiefly so that you can writeSignerclasses for cryptocurrencies
beyond Bitcoin (BTC).The default directory for plugin code is/var/lib/hermit.  Any*.pyfiles 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#fromhermit.errorsimportInvalidSignatureRequestfromhermit.signer.baseimportSignerfromhermit.ui.walletimportwallet_commandimporthermit.ui.stateasstate# Some library for MyCoinfrommycoin_libimportsign_mycoin_transactionclassMyCoinSigner(Signer):"""Signs MyCoin transactions"""defvalidate_request(self)->None:"""Validates a MyCoin signature request"""# This is built into the Signer classself.validate_bip32_path(request.get('bip32_path'))# this isn't great validation code, but you get the point...if'input'notinself.request:raiseInvalidSignatureRequest("The param 'input' is required.")if'output'notinself.request:raiseInvalidSignatureRequest("The param 'output' is required.")if'amount'notinself.request:raiseInvalidSignatureRequest("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']defdisplay_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))defcreate_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')defsign_mycoin():"""usage:  sign-mycoinCreate a signature for a MyCoin transaction.Hermit will open a QR code reader window and wait for you to scan anEthereum transaction signature request.Once scanned, the details of the signature request will be displayedon screen and you will be prompted whether or not you want to signthe transaction.If you agree, Hermit will open a window displaying the signature asa QR code.Creating a signature requires unlocking the wallet."""MyCoinSigner(state.Wallet,state.Session).sign()Contributing to HermitUnchained Capital welcomes bug reports, new features, and better
documentation for Hermit.  To contribute, create a pull request (PR)
on GitHub against theUnchained 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 withflake8andmypy.)Key rotationEach 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.TODOValidate wallet public keys/signatures against the provided redeem script in the bitcoin signer.Re-do QR-code protocol details once astandard emerges