DocumentationDevice interactionLedgerJS: Soon deprecatedIntegration walkthroughsWeb ApplicationWeb USB/HID

Web USB/HID

Introduction

In this section, we will guide you through the creation of a web application.
The instructions for Web USB and Web HID are very similar, with only a few lines to comment out, so this is a combined walkthrough.
This application will connect to your Nano to display the address of a Bitcoin account. You can easily modify the code, if you want it for Ethereum.

Reference note: the packages referenced here are
Web USB: @ledgerhq/hw-transport-webusb
Web HID: @ledgerhq/hw-transport-webhid.

One-time setup

Make sure you go through the Development Prerequisites.

App Coding (Desktop)

App setup

For this tutorial, the folder will be named example-web-hid-usb, so that it can be used for either Web USB or Web HID.

From your Github folder or favourite examples folder, run:

mkdir example-web-hid-usb
cd example-web-hid-usb

Initialize the project by running:

npm init

Answer the questions displayed or by default press enter. There is no incidence on the execution.

Run:

mkdir src
touch src/index.html
touch src/main.js

The folder will contain these files:

Folder USB and HID Fig. 1: File structure

Files

Open the folder example-web-hid-usb in an code editor.

index.html

In index.html copy-paste the following code :

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>My First Embedded App</title>
    <script type="module" src="main.js"></script>
  </head>
  <body id="main">
 
  </body>
</html>

main.js

In main.js copy-paste the following code:

⚠️

Comment out or remove the import package you don’t need
(@ledgerhq/hw-transport-webusb or @ledgerhq/hw-transport-webhid)
and the const transport you don’t use.

import 'core-js/actual';
import { listen } from "@ledgerhq/logs";
import AppBtc from "@ledgerhq/hw-app-btc";
 
// Keep this import if you want to use a Ledger Nano S/X/S Plus with the USB protocol and delete the @ledgerhq/hw-transport-webhid import
import TransportWebUSB from "@ledgerhq/hw-transport-webusb";
// Keep this import if you want to use a Ledger Nano S/X/S Plus with the HID protocol and delete the @ledgerhq/hw-transport-webusb import
import TransportWebHID from "@ledgerhq/hw-transport-webhid";
 
//Display the header in the div which has the ID "main"
const initial = "<h1>Connect your Nano and open the Bitcoin app. Click anywhere to start...</h1>";
const $main = document.getElementById("main");
$main.innerHTML = initial;
 
document.body.addEventListener("click", async () => {
  $main.innerHTML = initial;
  try {
 
    // Keep if you chose the USB protocol
    const transport = await TransportWebUSB.create();
 
    // Keep if you chose the HID protocol
    const transport = await TransportWebHID.create();
 
    //listen to the events which are sent by the Ledger packages in order to debug the app
    listen(log => console.log(log))
 
    //When the Ledger device connected it is trying to display the bitcoin address
    const appBtc = new AppBtc({ transport, currency: "bitcoin" });
    const { bitcoinAddress } = await appBtc.getWalletPublicKey(
      "44'/0'/0'/0/0",
      { verify: false, format: "legacy"}
    );
 
    //Display your bitcoin address on the screen
    const h2 = document.createElement("h2");
    h2.textContent = bitcoinAddress;
    $main.innerHTML = "<h1>Your first Bitcoin address:</h1>";
    $main.appendChild(h2);
 
    //Display the address on the Ledger device and ask to verify the address
    await appBtc.getWalletPublicKey("44'/0'/0'/0/0", {format:"legacy", verify: true});
  } catch (e) {
 
    //Catch any error thrown and displays it on the screen
    const $err = document.createElement("code");
    $err.style.color = "#f66";
    $err.textContent = String(e.message || e);
    $main.appendChild($err);
  }
});

Dependencies

Installation

Run:

npm install --save core-js
npm install --save @ledgerhq/logs
npm install --save-dev parcel
npm install --save @ledgerhq/hw-app-btc
PackageWhat does it do?
core-jsModular standard library for JavaScript.
@ledgerhq/logsIt provides you the log of all the errors from your connection with your Nano that may appear when developing.
parcelIt is a build tool that will help you package your application to run it in the browser.
@ledgerhq/hw-app-btcIt will help you ask your Nano to access the Bitcoin address.

Install the Transport HID or USB package

Then depending on your choice install one of the corresponding packages:

  • Install the Ledger package @ledgerhq/hw-transport-webhid which provide you with all the methods to interact with your Nano with an HID connection:
    npm install --save @ledgerhq/hw-transport-webhid
  • Install the Ledger package @ledgerhq/hw-transport-webusb which provide you with all the methods to interact with your Nano with a USB connection:
    npm install --save @ledgerhq/hw-transport-webusb

Package.json

Modify "main": "index.js" to "source": "src/index.html".

And ensure you have this line in your package.json:

  "scripts": {
    "build": "parcel build", 
    "start": "parcel"
  },

Add this at the end of the script:

  "alias": {
    "@ledgerhq/devices": "@ledgerhq/devices/lib-es"
  }

Your “package.json” should look like this:

⚠️

In the dependencies section of package.json, comment out or remove the line you don’t need
(@ledgerhq/hw-transport-webusb or @ledgerhq/hw-transport-webhid)
Do not copy-paste as is, without removing the other line.

{
  "name": "update-doc-web-hid-usb",
  "version": "1.0.0",
  "description": "",
  "source": "src/index.html",
  "dependencies": {
    "@ledgerhq/hw-app-btc": "^10.1.0",
    "@ledgerhq/hw-transport-webhid": "^6.28.0",
    "@ledgerhq/hw-transport-webusb": "^6.28.4",
    "@ledgerhq/logs": "^6.12.0",
    "core-js": "^3.33.3"
  },
  "scripts": {
    "build": "parcel build",
    "start": "parcel"
  },
  "devDependencies": {
    "buffer": "^6.0.3",
    "parcel": "^2.10.3",
    "process": "^0.11.10",
    "stream-browserify": "^3.0.0"
  },
  "alias": {
    "@ledgerhq/devices": "@ledgerhq/devices/lib-es"
  }
}

App Launch

1. Start the Server

Now that the Setup is finished, the app has to be built to be displayed. Start the development server:

npm run start

2. Launch the App

Now the application is up and running. Open the browser and go to localhost:1234, it will display :

Application running on browser Fig. 3: Application Running on Browser

Before clicking on the text connect your Nano to the USB port, unlock it and run the bitcoin application. The steps are described below.

3. Plug your Nano

Nano Enter Code Pin
Fig. 4: Enter Pin

Select Bictoin
Fig. 5: Select Bictoin

Embedded Run Application
Fig. 6: Embedded Run Application

4. Connect the Application

Now you can click on the text and a popup will be prompt. Choose your Nano and click connect:

Connect your Nano Fig. 7: Connect your Nano

5. Check displayed address

The App gets the Bitcoin address and displays it.
Check that the address displayed on the App is the same as the one displayed on the Ledger device.

Address Account Displayed Fig. 8: Address Account Displayed

Congratulations, you have successfully built your first application connected to a Nano!

ℹ️

Note that if your finalize the operation on your Nano by accepting or rejecting, the corresponding message appears on your web application.

App Coding (Android Chrome)

Android chrome supports HID and USB.
For smartphones, only Android supports web applications.
For Android, only Chrome supports web application.

package.json

To test your application on android, a little change has to be made.
Add the --https flag in your "start" script

⚠️

In the dependencies section of package.json, comment out or remove the line you don’t need
(@ledgerhq/hw-transport-webusb or @ledgerhq/hw-transport-webhid)
Do not copy-paste as is, without removing the other line.

{
  "name": "example-web-hid-usb",
  "version": "1.0.0",
  "description": "",
  "source": "src/index.html",
  "dependencies": {
    "@ledgerhq/hw-app-btc": "^6.12.1",
    "@ledgerhq/hw-transport-webhid": "^6.11.2", 
    "@ledgerhq/hw-transport-webusb": "^6.11.2",
    "@ledgerhq/logs": "^6.10.0",
    "core-js": "^3.20.2"
  },
  "devDependencies": {
    "parcel": "^2.0.0"
  },
  "scripts": {
    "build": "parcel build",
    "start": "parcel --https" 
  },
  "author": "",
  "license": "ISC"
}

The browser will warn that the website is malicious, to continue, click on “advanced settings” and then on “continue to the localhost site”. Now you can test to connect your Nano on your Android.

Ledger
Copyright © Ledger SAS. All rights reserved. Ledger, Ledger Nano S, Ledger Vault, Ledger OS are registered trademarks of Ledger SAS