Skip to main content

Move to WebUSB

Use this transitional path when the project must keep the @ukeyfe/hardware-web-sdk package for now, but the underlying connection should move from Bridge to WebUSB. The SDK entry stays the same; the initialization environment and authorization flow are the parts that change.


Requirements

  • Use a desktop browser built on Chromium, such as Chrome or Edge.
  • Node.js 18 or later is recommended, with LTS preferred.

Key Changes

  • The initialization environment is changed from Bridge's env: 'web' to WebUSB's env: 'webusb'.
  • hardware-web-sdk still requires connectSrc, please stay with the currently available iframe host version, such as https://jssdk.demo.example/1.1.16/.
  • USB device authorization changed to navigator.usb.requestDevice() and uses official UKey Wallet filter.
  • Device selector must be triggered by user gesture; do not auto-discover devices before authorizing.
  • Bridge check logic (such as checkBridgeStatus()) no longer works with WebUSB.
  • The way the chain API is called usually does not need to be changed.

Init Setup (hardware-web-sdk + WebUSB)

import HardwareWebSdk from "@ukeyfe/hardware-web-sdk";

// Continue using the default export from hardware-web-sdk.
const ukeySdk = HardwareWebSdk.HardwareWebSdk;

await ukeySdk.init({
env: "webusb",
// hardware-web-sdk still needs iframe host configuration.
connectSrc: "https://jssdk.demo.example/1.1.16/",
debug: true,
fetchConfig: true,
});

Request USB Permission

import { UKEY_WEBUSB_FILTER } from "@ukeyfe/hardware-shared";

// Trigger this from a visible user action, then continue scanning after permission is granted.
// Before that grant, the browser will not expose USB devices to the page.
await navigator.usb.requestDevice({ filters: UKEY_WEBUSB_FILTER });

Scan and Call

// 1) Scan for devices
const deviceList = await ukeySdk.searchDevices();
if (!deviceList.success) throw new Error(deviceList.payload.error);
const { connectId, deviceId } = deviceList.payload[0] ?? {};

// 2) Optionally fetch featureInfo and derive the device_id from them
const featureInfo = await ukeySdk.getFeatures(connectId);
if (!featureInfo.success) throw new Error(featureInfo.payload.error);
const resolvedDeviceId = featureInfo.payload.device_id ?? deviceId;

// 3) Sample: retrieve a BTC address
const addressResult = await ukeySdk.btcGetAddress(connectId, resolvedDeviceId, {
path: "m/84'/0'/2'/0/0",
coin: "btc",
showOnUKey: false,
});

if (addressResult.success) {
console.log("Resolved BTC address:", addressResult.payload.address);
} else {
console.error("Request failed:", addressResult.payload.error, addressResult.payload.code);
}

Wrap Up

  • Remove Bridge-specific checks and hints, such as checkBridgeStatus().
  • connectSrc still needs to be kept and pointed to the latest iframe host.
  • Detect navigator.usb in the page, and give a browser compatibility prompt if it is not supported.
  • Upper-layer processes such as chain API, PIN, Passphrase, etc. maintain the original processing methods.