/** Execute the example */
  public void executeExample() {

    // Use factory to statically bind the specific hardware wallet
    TrezorV1HidHardwareWallet wallet =
        HardwareWallets.newUsbInstance(
            TrezorV1HidHardwareWallet.class,
            Optional.<Integer>absent(),
            Optional.<Integer>absent(),
            Optional.<String>absent());

    // Wrap the hardware wallet in a suitable client to simplify message API
    HardwareWalletClient client = new TrezorHardwareWalletClient(wallet);

    // Wrap the client in a service for high level API suitable for downstream applications
    hardwareWalletService = new HardwareWalletService(client);

    // Register for the high level hardware wallet events
    HardwareWalletEvents.subscribe(this);

    hardwareWalletService.start();
  }
  /**
   * Downstream consumer applications should respond to hardware wallet events
   *
   * @param event The hardware wallet event indicating a state change
   */
  @Subscribe
  public void onHardwareWalletEvent(HardwareWalletEvent event) {

    log.debug("Received hardware event: '{}'.{}", event.getEventType().name(), event.getMessage());

    switch (event.getEventType()) {
      case SHOW_DEVICE_FAILED:
        // Treat as end of example
        System.exit(0);
        break;
      case SHOW_DEVICE_DETACHED:
        // Can simply wait for another device to be connected again
        break;
      case SHOW_DEVICE_READY:
        if (hardwareWalletService.isWalletPresent()) {

          // Create an identity
          URI uri =
              URI.create(
                  "ssh://[email protected]/trezor-connect"); // avoid using underscore in hostname
                                                             // (Java URI restriction)

          // Request an identity public key from the device (no screen support at present)
          hardwareWalletService.requestPublicKeyForIdentity(uri, 0, "nist256p1", false);

        } else {
          log.info("You need to have created a wallet before running this example");
        }

        break;

      case SHOW_PIN_ENTRY:
        // Device requires the current PIN to proceed
        PinMatrixRequest request = (PinMatrixRequest) event.getMessage().get();
        Scanner keyboard = new Scanner(System.in);
        String pin;
        switch (request.getPinMatrixRequestType()) {
          case CURRENT:
            System.err.println(
                "Recall your PIN (e.g. '1').\n"
                    + "Look at the device screen and type in the numerical position of each of the digits\n"
                    + "with 1 being in the bottom left and 9 being in the top right (numeric keypad style) then press ENTER.");
            pin = keyboard.next();
            hardwareWalletService.providePIN(pin);
            break;
        }
        break;
      case SHOW_PASSPHRASE_ENTRY:
        // Device requires the current passphrase to proceed
        Scanner passKeyboard = new Scanner(System.in);
        String passphrase;

        System.err.println("Please enter your current passphrase: \n");
        passphrase = passKeyboard.next();
        hardwareWalletService.providePassphrase(passphrase);

        break;
      case PUBLIC_KEY_FOR_IDENTITY:
        // Successful identity public key
        PublicKey pubKey = (PublicKey) event.getMessage().get();

        try {
          log.info("Raw Public Key:\n{}", (pubKey.getHdNodeType().get().getPublicKey().get()));

          // Retrieve public key from node (not xpub)
          ECPublicKey publicKey =
              IdentityUtils.getPublicKeyFromBytes(
                  pubKey.getHdNodeType().get().getPublicKey().get());

          // Decompress key
          String decompressedSSHKey = IdentityUtils.decompressSSHKeyFromNistp256(publicKey);

          // Convert key to openSSH format
          log.info(
              "SSH Public Key:\n{}",
              IdentityUtils.printOpenSSHkeyNistp256(decompressedSSHKey, "User1"));

          System.exit(0);

        } catch (Exception e) {
          log.error("deviceTx FAILED.", e);
        }

        // Must have failed to be here
        // Treat as end of example
        System.exit(-1);
        break;

      case SHOW_OPERATION_FAILED:
        // Treat as end of example
        System.exit(-1);
        break;
      default:
        // Ignore
    }
  }