update for beem: support for Ledger Nano (S/X) has been added

in HiveDevs2 months ago (edited)

Repository

https://github.com/holgern/beem


beem-logo

beem is a python library and command line tool for HIVE. The current version is 0.23.7.

There is also a discord channel for beem: https://discord.gg/4HM592V

The newest beem version can be installed by:

pip install -U beem

If you want to use Ledger Nano, then you need also:

pip install -U ledgerblue

Check that you are using hive nodes. The following command

beempy updatenodes --hive

updates the nodelist and uses only hive nodes. After setting hive as default_chain, beempy updatenodes can be used.

The list of nodes can be checked with

beempy config

and

beempy currentnode

shows the currently connected node.

Changelog for versions 0.23.7

  • Fix update_account_jsonmetadata and add posting_json_metadata property to Account
  • Add Ledger Nano S support
  • beempy -u activates ledger signing
  • beempy -u listkeys shows pubkey from ledger
  • beempy -u listaccounts searches for accounts that have pubkey derived from attached ledger
  • beempy -u keygen creates pubkey lists that can be used for newaccount and changekeys
  • new option use_ledger and path for Hive
  • Allow role selection in keygen

Changelog for versions 0.23.6

  • beempy --key key_list.json command can be used to set keys in beempy without using the wallet.

Using the Ledger Nano for signing

beem/beepy is the first library/application that supports signing of operation with the ledger Nano S/X hardware wallet. It uses the Hive wallet application for ledger Nano S/X from @netuoso.

Uploading the app to a Nano X is not yet possible.

You need to install the Hive app to your ledger Nano. You can download it from ledger-hive-app by @netuoso.
Please read the readme on how to install the app to your ledger.

When you sucessfully could install the Hive app to your ledger, you need to select it and enter Open application.

You need also install ledgerblue

pip install -U ledgerblue

You can test if everything works with

beempy -u listkeys

The -u or --use-ledger parameter activates ledger support for all beempy commands.
If you see

ledgerblue.commException.CommException: Exception : Invalid status 6d00 (Unexpected state of device: verify that the right application is opened?)

your setup is not correct. If you see

+-------------------------------------------------------+
| Available Key for 48'/13'/0'/0'/0'                    |
+-------------------------------------------------------+
| STM...                                                | 
+-------------------------------------------------------+

everything is set up.

Changing your keys

You need to change your keys to the public keys that your ledger provides before using the ledger for signing. It is also possible to change only the owner key.

As private keys will not leave your hardware wallet, you cannot put them into keychain or peakd as before. You can only sign operations on apps that support the ledger.

When you lose your ledger and your recovery phrase, you lose the ability to sign with that role. E.g. when you changed your owner key, and you lost your ledger and the recovery phrase, you cannot change your account keys anymore.

In the current state (lack of ledger support by other apps), i recommend to change only the owner key.

Setting the path

The pubkeys that are provided by the ledger are derived from the given path.
A path for hive consists of

48'/13'/role number'/account index'/key sequence'

The role number is 0 for owner, 1 for active, 4 for posting and 3 for memo.

You need to assign an account index number to your account. You are starting with 0 and when you plan to use a second account, you need to increase this index. The key index starts with 0 for each role and account index. Whenever you change your keys, you need to increase the key sequence index.

Changing your owner, active and posting key

It is not recommended to change the memo key (no encryption support for ledger yet on beem yet), this is the maximum setup. Changing your owner, active and posting key means at this moment (when more app add support for ledger, this will change):

  • all operation can only be broadcasted by beem/beempy
  • Voting, transferring on a mobile device is not possible
  • keychain usage is not possible
  • peakd, hive.blog cannot be used for voting or any other operation
  • hive-engine or any dapp cannot be longer used

At first, three new pubkeys needs to be obtained from the ledger:

beempy -u keygen --account 3 --role owner,active,posting

This beempy command creates three pubkeys for the account index 3 derived from the following paths:

  • 48'/13'/0'/3'/0'
  • 48'/13'/1'/3'/0'
  • 48'/13'/4'/3'/0'

You can save the pubkeys to a json for easier key changing by:

beempy -u keygen --account 3 --role owner,active,posting --export-pub beembot.json

In both cases you will be asked to approve the shown pubkeys on your ledger Nano.

We can now change the keys with

beempy changekeys --import-pub beembot.json beembot

Changing your owner and active key

This involves changing your owner and active key.

  • all operation that need an active key can only be broadcasted by beem/beempy.
  • transferring Hive/HBD on a mobile device is not possible
  • keychain usage is not possible for operation needing an active key
  • hive-engine or any dapps that are using custom_json signed with an active key cannot be longer used.
beempy -u keygen  --role owner,active --export-pub account_pubkeys.json

You can set the account index with --account.
Changing the keys can be done with beempy changekeys as shown above.

Changing your owner key

This changes only the owner key. Active and posting keys are still managed with private keys as before. Until ledger is not supported by keychain or on mobile, this is the most likely use-case now.

  • Changing your keys needs to be done with beem/beempy
beempy -u keygen --role owner --export-pub account_pubkeys.json

You can set the account index with --account.
Changing the keys can be done with beempy changekeys as shown above.

You may need to change the default path. When you used --account 2, you need to set

beempy set default_path "48'/13'/0'/2'/0'"

Whenever you use beempy -u, this path is used for signing.

Checking if changing keys was successfully

The following command checks if a derived pubkey from the ledger is set somewhere in Hive using getAccountFromPublicKey from the wallet class.

beempy -u listaccounts

returns then

+---------+---------+-------------------------------------------------------+------------------+
| Name    | Type    | Available Key                                         | Path             |
+---------+---------+-------------------------------------------------------+------------------+
| beembot | owner   | STM7UYXcqJsZqoroPKoziDmB3XHSVfnLbLJ9TWSVsD4zC7YHsdgo5 | 48'/13'/0'/3'/0' |
| beembot | active  | STM7a1bcn9Anx7F2dKZGEkbVRFbCHT9exx42SSKd4JicJW82VQtAc | 48'/13'/1'/3'/0' |
| beembot | posting | STM7cvheXK2FTEAkWe1U7SD2W6H6H3a6uJ28ors37rxcE5evP5fji | 48'/13'/4'/3'/0' |
+---------+---------+-------------------------------------------------------+------------------+

Set the path

As we have used an account index > 0, we must change the default path. At the moment, only one path can be stored in default_path.

beempy set default_path "48'/13'/0'/3'/0'"

We will now sign all transactions with the owner key, until the path is changed or set for a transaction with --path.

You can check which pubkey is returned for the actually set default_path with

beempy -u listkeys

The shown pubkey can checked with

beempy info STM...

Using the ledger to sign transactions

We can now sign all transactions by the ledger, when -u or --use-ledger is set.

beempy -u transfer -a beembot holger80 0.001 HIVE "test with ledger"

This is now signed with the owner key, as default_path is "48'/13'/0'/3'/0'".
We can sign the same trx with the active by setting the path to "48'/13'/1'/3'/0'":

beempy -u --path "48'/13'/1'/3'/0'" transfer -a beembot holger80 0.001 HIVE "test with ledger"

Building and signing a transaction in python

from beem import Hive
from beem.transactionbuilder import TransactionBuilder
from beembase import operations
hive = Hive(use_ledger=True, path="48'/13'/1'/3'/0'")

tx = TransactionBuilder(blockchain_instance=hive)

transfer_dict = {"from": 'beembot', "to": 'holger80',
                 "amount": '0.001 HIVE', "memo": 'test with ledger'}
op = operations.Transfer(**transfer_dict)
tx.appendOps(op)
tx.sign()
tx.broadcast()

It is also possible to use the predefined broadcast function

from beem import Hive
from beem.account import Account
hive = Hive(use_ledger=True, path="48'/13'/1'/3'/0'")
account = Account("beembot", blockchain_instance=hive)
account.transfer("holger80", 0.001, "HIVE", "test with ledger")

Sending all four transfers had worked:

I was asked everytime to check the transfer op and had to validate every field.

Advantages for changing the owner key

Letting the ledger signing with the owner key has some advantages:

  • beempy can be used without entering any keys, as I can sign all operations with the owner key
  • Each operation must be reviewed on the ledger before broadcasting
  • The owner key cannot be accidentally pasted
  • When I lose the keys to my hive account, I can easily create new keys, as the owner key is stored in the ledger.
  • My owner key is protected against pishing and hacking.

I just need to take good care of the ledger device and the recovery words.

Roadmap

For the next release, I will work on multisigning with ledger as one signer (at the moment, only one signer is possible when using ledger). Also, a better path handling is needed. At the moment, only one default_path can be set. Something like storing the path for all used keys, depending on roles and accounts in a database would be useful. Parallel storage of keys and paths would also nice.


If you like what I do, consider casting a vote for me as witness on Hivesigner or on PeakD

Sort:  

THIS IS ABSOLUTELY FUCKING AMAZING!

I have tested it and found a minor issue. Submitted a PR on the repo for you to review. Otherwise, it works and it works damn well! Your implementation is such beauty and you did it in like 2 days. I am impressed!

It is quite rewarding to see this thing live and working so well! Hive has the best fucking community around.

Thanks,
I published 0.23.8 which includes your PR.

@netuoso is "F" excited. It's all over the texts. Great work @holger80

Amazing work @holger80 - I am going to give this a try today. Thanks a million for building this out!

Hi @holger80, you have received a small bonus upvote from MAXUV.
This is to inform you that you now have new MPATH tokens in your Hive-Engine wallet.
Please read this post for more information.
Thanks for being a member of both MAXUV and MPATH!

You never cease to amaze us with your awesome works. We really appreciate your contribution to the growth of Hive. This nice publication will be featured in our Gitplait-elite publication today.

THIS IS AWESOME !

You managed this in such a short amount of time I'm impressed. I can't wait to receive my ledger to test it !

Thank you for amazing work! I know it is not related to current topic, but could you, please make a post or explain how to claim pending rewards using hiveengine or beem? It is quite clear how to stake tokens but in order to do it one should claim them first. I wreck my brain in order to solve it but so far with no result.

I have picked your post for my daily hive voting initiative, Keep it up and Hive On!!