[LOCKED] Support Ledger Wallet

Thanks for providing your extensive design considerations!

Are they still conducting tests? Does Ledger provide any timelines on how long it takes to to go from code submission to firmware release?


Not sure, will ask the guy that talked to Trezor/Ledger after weekend.
In general I think we’re too insignificant for them, and it’s a lot of code actually. It’s not just another “standard” crypto, where the wallet code just add a standard signature.
They just won’t budge.

But IMHO you can release a custom firmware to your users.


It’s a great alternative!
I think Ledger will be more likely to accept the introduction of GRIN.

Hi @vlad, thank you for your input ! Do you have a link for the Beam Ledger firmware code?

Can’t find the Ledger firmware code right now. I’ll ask the person that worked with us on it.

Here’s the link to the “cryptographic” code that we used in that firmware: beam/hw_crypto at master · BeamMW/beam · GitHub

To encapsulate the HW wallet logic we defined the “KeyKeeper” interface, and all the wallet logic (transaction negotiation and etc.) uses it instead of directly accessing the blinding factors. For wallets without HW wallet and with master secret in memory we have a “software KeyKeeper” implementation.

The “hw_crypto” library that I provided is written in plain C, in the embedded-friendly way, whereas it mimics the exact behavior of our standard C++ implementation of “KeyKeeper” which is used if there’s no HW wallet.
We deliberately included this library into our main codebase, this way we have unit tests that verify that it works exactly as our default C++ implementation.

The person that worked on the Trezor/Ledger firmware took that code as-is, and took care of things like communication with the device, messages for the user and confirmations, and etc.

Not sure the code as-is would be useful for grin, because it contains a lot of our proprietary code, our rangeproof implementation, the logic how our blinding factors and challenges are derived, and etc.

But I think I can outline the main idea behind our implementation.

  • “OwnerKey” that allows UTXO recognition but not spending - can be extracted without limitations once the device is activated (user entered the pin code)
  • Obviously no blinding factor can ever leave the device!
    • But its image (from which UTXO commitment is constructed) can be extracted without limitations
  • UTXO blinding factor is derived from “coin number” ** AND ** its value in an opaque way
  • Rangeproof (bulletproof) can be created for arbitrary UTXO without limitations
  • No need to compute the full rangeproof, it can be done in an MPC mode with the host (like a multi-signed UTXO for payment channels, whereas host contributes zero blinding factor).
    • However the host should NOT be able to construct a valid rangeproof that won’t be detected by the “OwnerKey”
  • User permission may be necessary only when the transactions should be signed. Other allowed operations are “silent”
  • For each transaction type (send, receive, split, etc.) the HW wallet gets the list of all input/output UTXOs (coin number + value). Based on this, it deduces the transaction type automatically.
  • If the user spends money - obviously its permission is required
  • To sign the transaction the HW wallet accounts for all the blinding factors of user inputs/outputs, and deduces the kernel blidning factor + offset to balance it.
  • Typical Send transaction is more complex, it assumes the HW wallet is called twice (1st time to present the kernel commitments, 2nd time to complete the signature). This is where “nonce slots” are required (explained in our wiki). It’s essential to re-generate the nonce immediately after it was used.
  • For receive transaction, in addition to signing the kernel, it also signs the “payment proof” (I think in grin it’s called “receipt”), this assures that this device is the final receiver of the money.
  • For send transaction, before completing the final signature, the HW wallet verifies that the “payment proof” was indeed signed by the asserted receiver. Its public key is also displayed to the user for verification.

Ledger mentions the following here

Currently, your best shot is to build your own companion app with its own backend. It is less convenient for users than a full integration to Ledger Live, but on the other hand, it gives you more freedom on the design of the interface you want users to see, and the way it will be implemented (Web app? Native app? It’s up to you!).

Should the Grin interface be a web app or a native app (given we use JavaScript)?

In the first place, connecting the ledger app to grin-wallet would probably be an excellent start.


I agree. Supporting it in grin-wallet should be a priority. Ledger Live is an electron-based monstrosity with unclear data privacy that I don’t really want to have on my computer. Unfortunately, it seems to be the only way to load the apps onto the device.

Here is my application:


My professional background is some years as an embedded software developer, working with C. More specifically PIC Microcontrollers, Atmel AVR and Atmel ARM. I also have written GUI software to control embedded devices. My educational background is a master’s degree in computer engineering, with a focus on software development. There, I used JavaScript extensively in my thesis.

Since late 2019, I have been interested in the Grin project. I previously participated in the 2020 winter challenge.

Recently, I have taken an interest in cryptographic primitives that are common to privacy projects, like range proofs, bulletproofs etc.

This bounty would be my first contribution codewise. I have looked at the Grin core codebase before and also at the Owner and Foreign RPC API calls. I have some knowledge of Rust, but I haven’t developed in it yet.

Technical Approach

I can make myself available, at least during evenings and during the weekend. In a more advanced stage of this project, having more time for this project could be an option. I have some spare Ledger Nano S devices ordered, they should come in tomorrow.

  • First, I would try to get used to the tools I will use during the development. I will go through building a minimal BOLOS App. I will look in detail through the resources that Vlad and quentinlesceller already provided, or will provide. Access to the BEAM Ledger code would make subsequent steps more clear. Ledger also recommends studying this example of a full-fledged app: GitHub - LedgerHQ/app-sia: The official Sia app for the Ledger Nano S. I would also get used to the application debugging tools, as described here: Application Debug — Ledger Documentation Hub 3 documentation.

  • Then I would build a skeleton version of the BOLOS application.

  • As quentinlesceller suggested, connecting the Ledger app to our existing grin-wallet is a good start. In the end-to-end architecture diagram of Ledger (Publishing an Application — Ledger Documentation Hub 3 documentation), grin-wallet fills more or less the role of the desktop app and the remote backend. The connection would be done using USB (to start, as this is the most straightforward). I think I would need the BOLOS Python loader here, the communicate between the device and the host computer. The sia example app provides comment about the ADPU packet communication between device and host PC. This link would be helpful here: Application Structure and I/O — Ledger Documentation Hub 3 documentation.

  • First try to connect from a Rust program to a Ledger app, using this library: GitHub - Zondax/ledger-rs: Rust crate to connect to Ledger devices

  • Then research how grin-wallet can be adapted to support the Ledger app.

  • I would take a detailled look at the approach followed by the BEAM team.

  • Define the messages that the user sees and the confirmations.

From then on, I am not sure how to progress further at the moment. I expect this will become more clear as I start working on this. Some more well-defined parts are the different transaction types. Maybe that’s a way I can partition the project into smaller tasks:

  • Implement Receive transaction. I would start with this transaction type.

    • Sign kernel and payment proof.
  • Implement Send transaction. As this transaction type is more complex, I would implement this in a later phase.

    • Verify payment proof was signed by receiver.
  • Implement Restore Wallet

  • 2 mandatory icons, as stipulated by Ledger

  • Documentation. I would do this during the development.

  • Tests. The Monero BOLOS app source code already provides how tests could be implemented.

Execution Risks

As this is my first contribution, I would have to spend a lot of time in the beginning to get up to speed. The interactive part seems the hardest to implement.

One other risk is wasted efforts. One suggestion about how I could avoid wasted efforts is that I would try to write the documentation before I write the code as much as possible, and share this with the community. This way I would make sure it is clear what will be implemented. For example, I would write (parts of) the user tutorial before I implement the feature. This way, people can judge if the approach is correct.

There is still some uncertainty about how the Ledger code audit time schedule looks like. However, one can expect that due to the code complexity, code review will like a considerable long time. Maybe the waiting time could be used to work on the Grin Interface module?

As security is important, it would be very helpful if some others persons could code review. These persons should look at the code with a C security attacker perspective.

If I am unable to execute subsequent activities, I would hand over the code/documents to someone who could complete the project further.


Technical debt can occur, for example, when Ledger updates their software, or when Grin will update its software. Some training is needed to use the Ledger app. For example, videos could be made that demonstrate usage.

Evaluation Plan

The end criteria are quite clear:

  • The BOLOS app project is succesful when it passes the security audit by the Ledger Wallet security team.
  • The Grin interface project is succesful when Tor transactions and slatepack copying are supported.

However, these are criteria in a more distant future, I should think about how I could make the feedback loop shorter.

Some other evaluation criteria:

  • Sending a small amount of Grin to the Ledger device. Then check if it was received.

  • Then, try to execute a transaction from the Ledger device. Also check that this was executed correctly.

The code should be checked during development for errors as described here: Developing Secure Ledger Apps — Ledger Documentation Hub 3 documentation.

Again, code review would be immensely helpful.


It has hard to give actual timeframes are dates, due to current lack of technical knowledge and some needed practical steps I should first take for my personal work situation.

The following milestone should be reached:

  • Connection between grin-wallet and Ledger device app using USB.

  • Connection between Grin JavaScript Interface and Ledger device app, using Tor (Tor seems the only way, according to the Slatepack RFC).

  • Copy pasting Slatepacks

    • This involves researching how this could be done. One could take a look at how GUI projects like Niffler already implement this.

The following deliverables should be sent to Ledger for the audit process (this is from the Ledger website):

  • Bolos app Release Candidate source code in a git repository

  • Companion app, (binaries or package) for Windows/MacOS/Linux

  • Adobe Illustrator templates filled with icons (perhaps someone who knows Adobe Illustrator can do this?)

  • Contact information to Ledger (Name, Surname, Legal Entity, URL, email address, phone number). I would provide my own contact information to Ledger.

  • Link to tutorial hosted on third party website

  • Video of the BOLOS application running on the Ledger device

    • Verify public address on the Ledger device
    • Display transaction information before allowing signature
    • Reject a transaction on the Ledger device
    • Sign a transaction on the Ledger device

Apart from the audit process, the following would be needed to educate the user.

  • Video of Grin Interface:
    • Demonstrate Tor usage
    • Demonstrate Slatepack copypasting

Note that Grin uses different signature schemes for signing kernels (secp256k) and signing payment proofs (ed22519). I hope that the Ledge Nano S can support the use of both under a single coin type.

Although it hasn’t been finalized yet, I hope you can make provisions to support the more general payment proofs in this RFC: grin-rfcs/0000-early-payment-proofs.md at early-payment-proofs · tromp/grin-rfcs · GitHub
It might make sense to allow the memo to be as long as the maximum that can be shown on the Ledger device.

What is a Split transaction?

1 Like

My mistake, split transaction is a transaction type from the BEAM project. I was looking at Vlad’s post, but I forgot that Grin doesn’t has this transaction type.

Thank you @markhollis for your application :rocket: ! It looks promising. In terms of next steps:

  • We will discuss your application at the next governance meeting next Tuesday (16/03).
  • If we agree, I will assign the bounty to you so that you can start working on it.

All add more details on this post later.


It’s when you send to yourself. We defined it as a separate tx type, since there’s no negotiation with peer, no need in payment proofs and etc.

Mining pools and exchanges use it to “split” large UTXO into small ones, that later can be used to pay different miners.

1 Like

@markhollis thanks for this thorough application!

The meeting Quentin refers to above is Agenda: Governance Mar 16 2021 · Issue #403 · mimblewimble/grin-pm · GitHub, if you can make it, it would be great to have you present answering any questions. :v:


I’ll try to make it. Regarding the full time, I’ve thought about it more. I think it’s best to start during weekends and evenings.

I have to admit that the more I read about this project, the more scared I become, and the more I feel the weight of responsibility that comes with this sort of project. Add that together with having relatively little experience with Grin developent and becomes it becomes a very challenging task. But at the same time it’s a very interesting project and a fantastic learning opportunity.

I’m at the moment trying to make a connection between a simple Rust program and a boilerplate Ledger app, using this library: GitHub - Zondax/ledger-rs: Rust crate to connect to Ledger devices


Don’t let yourself become intimidated! Break it off into smaller chunks (as you’ve done), tackle one by one, and see how far you can get. We can try to be creative in terms of how to best fund you without setting expectations neither too high or too low.

Happy to discuss further.


There’s also Grin++, which would likely be much easier to integrate. Whether you go with grin++, or just stick with grinmw, don’t be afraid to reach out to me for any technical guidance.


Unfortunately I can’t make it to the meeting; it is during my working hours. If there are questions, I’m glad to answer them.

Roger that. We’ll keep you posted.

1 Like

Congratulations @markhollis :champagne:, as per Tuesday March 17 governance meeting decision, the bounty is now assigned to you. I’m changing the status of the request to LOCKED.
We will check every 2 weeks the progress. If there is no sign of life after a month this bounty will be set to available again.
Good luck and feel free to ask any questions that you have on Keybase!