Blog

/

Zcash integration Guide

Zcash integration Guide

December 12, 2024

10 min read

Security


The new Zcash Shielded App is now available, but Ledger support is limited to a ZecWallet fork by Zondax.This guide details steps to integrate Ledger into wallets like Ledger Live, Zingo, YWallet, Zashi etc.

For devs, how to integrate Zcash Shielded app into your wallet

Intro


  • The new Zcash Shielded Application has become officially available to the public recently.

  • While numerous wallets support Zcash, currently, there is no support for Ledger devices for this new app besides the development ZecWallet fork from zondax

  • This article provides a comprehensive overview of the essential steps required to integrate support for the Ledger Zcash Shielded App into your wallet.

  • This initiative is expected to benefit a wide range of wallets including Ledger Live, Zingo, YWallet, Zashi, Flexa, Nighthawk, Unstoppable etc.

First thing first


In order to integrate the Ledger Zcash Shielded application into your wallet there aren’t magical recipes but we’ll make an exhaustive list of all the available resources and some general guidelines to achieve this.

You’ll need to establish communication with the device. To achieve this, Zondax provides 2 communication packages:

Those packages provide the abstraction for establishing communication with your device, using a protocol called APDU (the same protocol as SIM cards). This implies that the zcash application running on the ledger device cannot initiate communication but just respond to commands.

To get the updated list of commands that the app will understand, you can check it on the APDU spec documentation

You have one extra thing to have in consideration when working with Ledger devices: private keys / highly sensitive information won’t be shared with any external party. This means that the different keys that are part of either Transparent/Sapling protocols will be computed and used on the device. You won’t have direct access to them. This means that any signing process or revealing information regarding shielded transactions must be done in the device itself.

Integrating Zcash Shielded app


Key management integration guidelines


In order to integrate our Ledger application, first you need to design a common interface that handles key management, which would provide access to view/public keys and also useful methods for signing transactions or any other operation that requires access to private keys. A common interface like this would be called a Keystore component that would integrate your current key management system in your wallet that generates keys probably in-memory, and the Ledger application.

The first step is to abstract both elements into one type that generalizes over methods for handling and using keys. In the case of Rust, it is suggested to use a sum type like Enum that holds both variants. You can check how this was implemented by Zondax in ZecWallet, where we added an enum type that abstracts the in-memory Keystore and the LedgerKeystore component while providing a common set of methods that the rest of your wallet would use for dealing with keys, either requesting view/public keys or signing transactions.

Keep in mind that the common interface must align with the security of the Ledger application, which will not allow any spending/private key to be sent out of the device. That means you cannot keep any sensitive information in-memory in your wallet implementation. If your current design relies on this, you must change it to align with this requirement.

At the moment, Zondax is collaborating with Zingolabs and Zashi to add support for the app. Even though the integration is not completed, you can check how the approach was there for Keystore abstraction and LedgerKeystore component.

Signing Integration guideline


This functionality must be centralized as well by the Keystore component. The reason is that as mentioned in the previous sections, private keys must not be kept in memory as the ledger application won't let them be moved out of the device. Because of this strong requirement, both keystore implementations must align in this regard. This implies that the common interface would provide a method for revealing/signing data using the private keys. For example in our ZecWallet integration, the Keystore integration provides methods for creating node commitments, signing transactions, and many more that require the usage of private keys.

You can see how we check for the current Keystore variant being used, and call the corresponding handler. It is important to mention that in the zecwallet integration, only one instance could be used at the time.

It is relevant to note that the ledger keystore component internally uses the ZcashApp abstraction provided by our ledger-zcash-rs library. The ZcashApp component provides a defined set of methods that at the moment we consider sufficient for transparent and sapling operations within zcash protocol. This means that the Orchard and unified addresses protocols are not supported yet. In the following section, we will describe some of the supported operations this component provides and how to use it for establishing communication with the device. A further list of available methods can be found in the source code here.

Basic commands


Before you can start sending commands to the app, you need to open the communication channel. This can be done using Ledger transport. This is just a generic interface for communicating with a Ledger hardware device. There are different kinds of transports based on the technology (channels like U2F, HID, Bluetooth, Webusb) and environment (Node, Web,...)

So.. let’s start with simple commands like or since they don’t need any additional parameters.

You can check some tests that will be really helpful examples:

Here you can see the rest of the examples for both Rust and Javascript.

Transparent Address


To get the transparent address from your device, you’ll need the command . It will need a derivation path. Keep in mind that this is an asynchronous operation and it might fail. This command and any other that doesn’t share sensitive information can be retrieved without explicit user confirmation.
Showing the address on the device is a really important confirmation step that the user needs to do before sharing an address. It would be good to add a button or some UI element to allow the user to verify that the wallet and the device show the same address.

Sapling keys


Within the Sapling upgrade in Zcash, there are several types of keys, each serving different purposes. These keys can be categorized into private and public keys:

Spending key: this would be like your private key and therefore will never be moved out of the device. Any operation that uses this key will be carried out within the device.

Viewing keys: even though these can be considered public keys, since they can be used to disclose sensitive information, they will need an explicit approval from the user to be shared with the wallet or any other party.

Nullifiers: in order to prevent double-spending, Zcash relies on nullifiers that are revealed and recorded in the blockchain when the tokens are spent. These will be needed by the wallets to keep the right balance from your account. Once again, an explicit approval from the user is necessary here.

Payment addresses: these addresses are are inherently public since the user creates them to shared with someone in order to get a payment. Having one of these addresses doesn't reveal the movements from any other payment address or any of the keys.

The Ledger application provides functionalities for retrieving Sapling public keys and addresses. Bellow a short example of the provided API in rust to get the incomming viewing key (IVK):

And the next code block demostrates how to use the ZcashApp interface for getting a shielded address from the device:

The device, as mentioned previously, features a limited UI that enables the review of transaction fields and relevant data. The user is required to confirm the accuracy of this data and approve the operation. This verification and approval process will be conducted by the user each time sensitive information needs to leave the device.

Transaction signing


This is one of the most important command that our communication interface provides. The overall idea is that the transaction data is sent serialized to the devices, users would them have to review the transaction and upon user confirmation, it would be signed. The returned data to the wallet would contain the signature. This is the general idea but to integrate the Zcash transaction signing feature of our Ledger application into your wallet, it's crucial to understand that the signing process is not straightforward, but rather interactive and step-by-step due to the cryptographic complexities involved, and the limited resources in terms of storage, memory and computing power from Ledger devices. Below you can see an overview of the process:

  1. Initialization: The process begins with gathering transaction input data, including transparent and shielded inputs and outputs. This would depend of the kind of transaction:

    • transparent->shielded

    • transparent->transparent

    • shielded->transparent

    • shielded->shielded transactions

  1. Building the Transaction:

    • Transparent Inputs: Add transparent inputs to the transaction builder without needing fresh information from the Ledger. This step requires the public key and outpoint from the blockchain.

    • Shielded Spends: For each shielded spend, the Ledger device provides the proof generation key, value commitment randomness (), and randomness for the random verification key (). This data is added to the transaction builder.

    • Shielded Outputs: Similar to shielded spends, adding shielded outputs requires randomness for the value commitment (), note commitment (), and random encryption key (), provided by the Ledger. This step is repeated for each shielded output.

  2. Finalizing the Transaction: Once all inputs and outputs are added, the transaction builder compiles the transaction, including Zero-Knowledge (ZK) proofs. This compiled transaction data () is then sent back to the Ledger for validation and signing.

  3. Extracting Signatures: The final step involves extracting signatures for both shielded spends and any transparent inputs from the Ledger. These signatures are then added to the transaction builder.

  4. Completion: With all signatures in place, the transaction builder finalizes the transaction, making it ready for broadcast to the Zcash network.

This interactive process ensures the security and integrity of the transaction by leveraging the Ledger's cryptographic capabilities. It's essential for wallet developers to implement this step-by-step approach to integrate Zcash transaction signing functionality successfully. For further details, you can look at our transaction builder component written in Rust, and some tests on how it is used to build a transactions. If you are integrating this Ledger application in , you can take a look at our tests that provides a good insight on how perform this interactive process.

Considerations



Generic communication package


The communication package is completely decoupled from any type used on ZecWallet or Zcash ecosystem. Therefore, it should fit well on any wallet or integration that wants to use it. This includes both Rust and Javascript/Typescript packages.

Documentation


The best place to find documentation about the app is located alongside with the app source code. You can find a mermaid diagram where the whole integration flow is explained clearly here. Besides, the APDU specification describes what each instruction is meant for, as well as expected input and output.

Useful test cases


The app counts with a wide set of test cases. Each of them is meant to verify a certain feature or instruction works as expected. They are extremely useful as a reference for full integration. You can find them here. Moreover, if you want to see how the review process in the ledger device would look like, you can check this folder. There are snapshots for each test case that is executed on CI using an emulator, called speculous.

Limitations


At the moment, there are some features that are not supported by the application and have to be considered when you plan to integrate this app in your wallet.

UTXO limitation


Due to the very limited resources from the device, the application can handle up to 5 transparent and 5 shielded inputs/outputs. If your transaction involves too many inputs/outputs, the device might not be able to handle it and it will be rejected every time.
At the moment, these values are fixed. So a transaction with 6 transparent inputs cannot be processed but a transaction with 5 transparent inputs, 5 shielded inputs, 5 transparent outputs and 5 shielded output would work just fine.

Unified address


After the activation from Network Upgrade 5 (NU5), the default address type is the Unified Address (UA). At the moment, the app is not able to generate these types of addresses, so you'll need to consider this while making the integration.

Orchard


Orchard protocol is not supported yet by the application. Consider that the application can only process Sapling transactions and you might need to adapt the wallet for it

Zondax zcash tools package


The zcash tools package is highly coupled with types that were used by ZecWallet. They are outdated, according to the latest version for zcash crates. As it is today, they are useful for implementation references for any wallet to incorporate support to the ledger app.


Read More


Brussels Takes Center Stage: Key Highlights from EthCC, Polkadot Decoded, and More

Brussels hosted key Web3 events, highlighting progress in UX, AI integration, and blockchain innovations from Polkadot Decoded and Fil Brussels, aiming for a user-friendly Web3 future.


Cosmos Rosetta Dockerization: Simplifying Deployment and Enhancing Accessibility

The Rosetta project, amidst blockchain's complexity, emphasizes simplicity and accessibility. Docker integration underscores this commitment, empowering users and developers alike. Rosetta, now a plug-and-play solution, paves the way for seamless blockchain innovation.


Looking ahead: Integrating Rosetta with Cosmos SDK v0.50

"At Zondax, we're dedicated to innovation in the ever-evolving blockchain space. Our latest move is with Cosmos SDK v0.50.0-beta.0, offering Rosetta users an enhanced, seamless experience."

Other Articles


6697e65e0dfd3b00aaef4e0f

July 18, 2024

Brussels Takes Center Stage: Key Highlights from EthCC, Polkadot Decoded, and More

Brussels hosted key Web3 events, highlighting progress in UX, AI integration, and blockchain innovations from Polkadot Decoded and Fil Brussels, aiming for a user-friendly Web3 future.

65e774c1de14c600a846ed6a

News

March 6, 2024

All in one: The new Polkadot app

The new Polkadot Ledger app is designed to easily manage different parts of the Polkadot network, like parachains and relay chain, even when there are updates. It was made as a result of community requests, and it brings together control of the network into one easy-to-use app. It's made to add new features without losing security. We found out that to make something really secure, we had to make changes on the node. Several alternatives were analyzed and each has advantages and disadvantages.

66156d53bb73d300a8615839

Protocol

April 9, 2024

The Evolution of Transaction Signing in Cosmos: Introducing Sign Mode Textual

Sign Mode Textual introduces a secure, user-friendly method for transaction signing with hardware devices, advancing efficiency and security in the Cosmos SDK.

News

All in one: The new Polkadot app

The new Polkadot Ledger app is designed to easily manage different parts of the Polkadot network, like parachains and relay chain, even when there are updates. It was made as a result of community requests, and it brings together control of the network into one easy-to-use app. It's made to add new features without losing security. We found out that to make something really secure, we had to make changes on the node. Several alternatives were analyzed and each has advantages and disadvantages.

65e774c1de14c600a846ed6a

Protocol

The Evolution of Transaction Signing in Cosmos: Introducing Sign Mode Textual

Sign Mode Textual introduces a secure, user-friendly method for transaction signing with hardware devices, advancing efficiency and security in the Cosmos SDK.

66156d53bb73d300a8615839