From 3b648e71e6cae29009c5b83c69d45add8caa505b Mon Sep 17 00:00:00 2001 From: Tyera Eulberg Date: Wed, 26 Feb 2020 11:04:28 -0700 Subject: [PATCH] Ledger hardware wallet docs (#8472) * Update protocol documentation * Correct app-version command const * Rough initial Ledger docs * Add more docs * Cleanup * Add remote-wallet to docs TOC Co-authored-by: Greg Fitzgerald --- docs/src/SUMMARY.md | 2 + docs/src/remote-wallet/README.md | 12 +++ docs/src/remote-wallet/ledger.md | 132 +++++++++++++++++++++++++++++++ remote-wallet/src/ledger.rs | 9 +-- 4 files changed, 148 insertions(+), 7 deletions(-) create mode 100644 docs/src/remote-wallet/README.md create mode 100644 docs/src/remote-wallet/ledger.md diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 8d4dda51e..14a466945 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -3,6 +3,8 @@ * [Introduction](introduction.md) * [Using Solana from the Command-line](cli/README.md) * [Command-line Usage](cli/usage.md) + * [Remote Wallet](remote-wallet/README.md) + * [Ledger Hardware Wallet](remote-wallet/ledger.md) * [Paper Wallet](paper-wallet/README.md) * [Installation](paper-wallet/installation.md) * [Paper Wallet Usage](paper-wallet/usage.md) diff --git a/docs/src/remote-wallet/README.md b/docs/src/remote-wallet/README.md new file mode 100644 index 000000000..25babad4d --- /dev/null +++ b/docs/src/remote-wallet/README.md @@ -0,0 +1,12 @@ +# Remote Wallet + +This document describes how to use a remote wallet with the Solana CLI +tools. Currently, Solana supports: +- Ledger hardware wallet (Nano S) + +## Overview + +Solana's remote-wallet integration provides Solana CLI methods to query a +device's BIP32 public keys and send messages to the device for secure signing. + +{% page-ref page="ledger.md" %} diff --git a/docs/src/remote-wallet/ledger.md b/docs/src/remote-wallet/ledger.md new file mode 100644 index 000000000..aaf897cce --- /dev/null +++ b/docs/src/remote-wallet/ledger.md @@ -0,0 +1,132 @@ +# Ledger Hardware Wallet + +The Ledger Nano S hardware wallet offers secure storage of your Solana private +keys. The Solana Ledger app enables derivation of essentially infinite keys, and +secure transaction signing. + +## Before You Begin + +- [Initialize your Ledger Nano S](https://support.ledger.com/hc/en-us/articles/360000613793) +- [Install the latest device firmware](https://support.ledgerwallet.com/hc/en-us/articles/360002731113-Update-Ledger-Nano-S-firmware) +- [Install Ledger Live](https://support.ledger.com/hc/en-us/articles/360006395553/) software on your computer + +## Install the Solana App on Ledger Nano S + +1. Open the Manager in Ledger Live +2. Connect and unlock your Ledger Nano S +3. If asked, allow the manager on your device by pressing the right button +4. Find Solana in the app catalog and click Install +5. An installation window appears and your device will display Processing… +6. The app installation is confirmed + +## Use Ledger Device with Solana CLI + +1. Plug your Ledger device into your computer's USB port +2. Enter your pin and start the Solana app on the Ledger device +3. On your computer, run: + +```text +solana address --keypair usb://ledger +``` + +This confirms your Ledger device is connected properly and in the correct state +to interact with the Solana CLI. The command returns your Ledger's unique +*wallet key*. When you have multiple Nano S devices connected to the same +computer, you can use your wallet key to specify which Ledger hardware wallet +you want to use. Run the same command again, but this time, with its fully +qualified URL: + +```text +solana address --keypair usb://ledger/nano-s/ +``` + +Confirm it prints the same key as when you entered just `usb://ledger`. + +### Ledger Device URLs + +Solana defines a format for the URL protocol "usb://" to uniquely locate any Solana key on +any remote wallet connected to your computer. + +The URL has the form, where square brackets denote optional fields: + +```text +usb://ledger[/[/]][?key=] +``` + +`LEDGER_TYPE` is optional and defaults to the value "nano-s". If the value is provided, +it must be "nano-s" without quotes, the only supported Ledger device at this time. + +`WALLET_KEY` is used to disambiguate multiple Nano S devices. Every Ledger has +a unique master key and from that key derives a separate unique key per app. + +`DERVIATION_PATH` is used to navigate to Solana keys within your Ledger hardware +wallet. The path has the form `[/]`, where each `ACCOUNT` and +`CHANGE` are postive integers. + +All derivation paths implicitly include the prefix `44'/501'`, which indicates +the path follows the [BIP44 specifications](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) +and that any dervied keys are Solana keys (Coin type 501). The single quote +indicates a "hardened" derivation. Because Solana uses Ed25519 keypairs, all +derivations are hardened and therefore adding the quote is optional and +unnecessary. + +For example, a complete Ledger device path might be: + +```text +usb://ledger/nano-s/BsNsvfXqQTtJnagwFWdBS7FBXgnsK8VZ5CmuznN85swK?key=0/0 +``` + +### Set CLI Configuration + +If you want to set a Ledger key as the default signer for CLI commands, use the +[CLI configuration settings](../cli/usage.md#solana-config): + +```text +solana config set --keypair +``` + +For example: + +```text +solana config set --keypair usb://ledger?key=0 +``` + +### Check Account Balance + +```text +solana balance --keypair usb://ledger?key=12345 +``` + +Or with the default signer: + +```text +solana balance +``` + +### Send SOL via Ledger Device + +```text +solana transfer --from +``` + +Or with the default signer: + +```text +solana transfer +``` + +### Delegate Stake with Ledger Device + +```text +solana delegate-stake --keypair +``` + +Or with the default signer: + +```text +solana delegate-stake +``` + +## Support + +Email maintainers@solana.com diff --git a/remote-wallet/src/ledger.rs b/remote-wallet/src/ledger.rs index 3e008f82d..fffc4201f 100644 --- a/remote-wallet/src/ledger.rs +++ b/remote-wallet/src/ledger.rs @@ -43,7 +43,7 @@ const HID_PREFIX_ZERO: usize = 0; mod commands { #[allow(dead_code)] - pub const GET_APP_CONFIGURATION: u8 = 0x06; + pub const GET_APP_CONFIGURATION: u8 = 0x01; pub const GET_PUBKEY: u8 = 0x02; pub const SIGN_MESSAGE: u8 = 0x03; } @@ -76,7 +76,7 @@ impl LedgerWallet { // * APDU_INS (1 byte) // * APDU_P1 (1 byte) // * APDU_P2 (1 byte) - // * APDU_LENGTH (1 byte) + // * APDU_LENGTH (2 bytes) // * APDU_Payload (Variable) // fn write(&self, command: u8, p1: u8, p2: u8, data: &[u8]) -> Result<(), RemoteWalletError> { @@ -141,11 +141,6 @@ impl LedgerWallet { // * Payload (Optional) // // Payload - // * APDU Total Length (2 bytes big endian) - // * APDU_CLA (1 byte) - // * APDU_INS (1 byte) - // * APDU_P1 (1 byte) - // * APDU_P2 (1 byte) // * APDU_LENGTH (1 byte) // * APDU_Payload (Variable) //