Move to Common
Use this migration path when a project is leaving the old Bridge channel and moving its SDK entry to @ukeyfe/hardware-common-connect-sdk. After the switch, the browser talks to UKey Wallet directly over WebUSB instead of going through the iframe Bridge.
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 SDK entry is switched from
@ukeyfe/hardware-web-sdkto@ukeyfe/hardware-common-connect-sdk. - The initialization environment is changed to
env: 'webusb', andconnectSrcis no longer configured. - USB authorization must be triggered by a user gesture and opening the browser device selector via
UKEY_WEBUSB_FILTER. - Interactions such as PIN, Passphrase, device plugging and unplugging are uniformly handled through the
UI_EVENT / DEVICEevent of@ukeyfe/hardware-core. - Removed Bridge-specific checks such as
checkBridgeStatus(), Bridge installation prompt, and restart prompt. - Most of the business API names remain the same, such as
searchDevices,getFeatures,btcGetAddress.
Setup
npm i @ukeyfe/hardware-common-connect-sdk @ukeyfe/hardware-core @ukeyfe/hardware-shared
Init Common
import ukeySdk from "@ukeyfe/hardware-common-connect-sdk";
await ukeySdk.init({
env: "webusb",
debug: process.env.NODE_ENV !== "production",
fetchConfig: true,
});
hardware-common-connect-sdkuses WebUSB directly and does not rely on iframe, soconnectSrcis not needed.- Keep
fetchConfig: trueand let the SDK pull the device capabilities and prompt configuration.
Bind Events
import { UI_EVENT, UI_REQUEST, UI_RESPONSE, DEVICE } from "@ukeyfe/hardware-core";
function bindDeviceEventHandlers() {
ukeySdk.on(UI_EVENT, async (message: any) => {
switch (message.type) {
case UI_REQUEST.REQUEST_PIN: {
// For production, swap this out for your own PIN UI
await ukeySdk.uiResponse({
type: UI_RESPONSE.RECEIVE_PIN,
// Keep PIN entry on the hardware first (safer)
payload: "@@UKEY_INPUT_PIN_IN_DEVICE",
});
break;
}
case UI_REQUEST.REQUEST_PASSPHRASE: {
// For production, replace this with your Passphrase UI (device or software entry)
await ukeySdk.uiResponse({
type: UI_RESPONSE.RECEIVE_PASSPHRASE,
payload: { passphraseOnDevice: true, value: "" },
});
break;
}
default:
break;
}
});
ukeySdk.on(DEVICE.CONNECT, (payload: any) => {
console.log("Connected device event:", payload);
});
ukeySdk.on(DEVICE.DISCONNECT, (payload: any) => {
console.log("Disconnected device event:", payload);
});
}
bindDeviceEventHandlers();
- Subscribe to
UI_EVENTas early as possible, otherwise the request will be stuck waiting for no one to respond to the PIN, Passphrase or confirmation event. - For details, see: Configure events
Request USB Permission
import { UKEY_WEBUSB_FILTER } from "@ukeyfe/hardware-shared";
// Call this from a click handler or another explicit user gesture; browsers block silent USB prompts.
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 read featureInfo again to resolve the final device_id
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
- Swap out
@ukeyfe/hardware-web-sdkfor@ukeyfe/hardware-common-connect-sdk, and drop the old Bridge entry path. - Move the browser init straight to
env: 'webusb'; the oldconnectSrcwiring is no longer needed. - Anything Bridge-only, such as
checkBridgeStatus(), install guidance, or restart reminders, can be removed with the migration. - Make sure
UI_EVENT / DEVICElisteners are in place so PIN, Passphrase, and plug/unplug events are all covered. - Keep
requestDevice()behind a user action instead of auto-enumerating before authorization. - If
navigator.usbis missing, steer users to a desktop browser with WebUSB support.
Q&A
- HTTP page has no permission prompt? Please change to HTTPS or local security context.
- UI request stuck? First confirm whether
UI_EVENTis subscribed in advance, and calluiResponseafter receiving the event. - Still configure
connectSrc? The description code is still stuck in the iframe scheme and needs to be switched to the WebUSB initialization ofhardware-common-connect-sdk. requestDevicenot responding? Check whether the call is triggered by a user gesture such as a button click.
More Reading
- Events and Interactions: Configure events
- API reference and inputs: Hardware SDK Core API Guide, shared request options, error code