Identifiers
Hardware SDK flows use several identifiers at the same time. They look similar, but they answer different questions: which transport channel should receive the request, which wallet state is active, and whether the current operation belongs to a hidden-wallet session.
Quick Map
| Identifier | Origin | Lifetime | Primary use |
|---|---|---|---|
connectId | searchDevices() | Stable for the current physical connection path | Route SDK calls to a specific device |
uuid | searchDevices() | Stable device-side identifier exposed for display or deduplication | Recognize the physical device in UI lists |
deviceId | getFeatures(connectId).payload.device_id | Changes after reset, wipe, restore, or seed replacement | Verify the current wallet before signing or deriving addresses |
device_id | getFeatures().payload | Same value as deviceId, using firmware-style naming | Read the wallet identifier from feature data |
session_id | getFeatures().payload | Expires when the device locks or the live session ends | Reuse an unlocked session only while it is still valid |
passphraseState | getPassphraseState(connectId) | Reusable for the same hidden wallet until the app discards it | Continue calls against the selected hidden wallet |
ukey_serial | getFeatures().payload | Physical-device serial, not wallet state | Audit or display the physical device identity |
Typical Flow
Most integrations first locate a device, then read features, then call a chain method with both the connection handle and the current wallet identifier.
const availableDevices = await ukeySdk.searchDevices();
const [{ connectId }] = availableDevices.payload;
const featureInfo = await ukeySdk.getFeatures(connectId);
const deviceId = featureInfo.payload.device_id;
await ukeySdk.evmGetAddress(connectId, deviceId, {
path: "m/44'/60'/6'/0/2",
useEmptyPassphrase: true,
});
For hidden wallets, read passphraseState once and pass it in later calls that should keep using that hidden wallet.
const passphraseInfo = await ukeySdk.getPassphraseState(connectId);
const passphraseState = passphraseInfo.payload;
await ukeySdk.evmSignTransaction(connectId, deviceId, {
path: "m/44'/60'/6'/0/2",
transaction,
passphraseState,
});
Which Identifiers Do Calls Need?
| Call scenario | Identifier set | Typical actions |
|---|---|---|
| Device status and management | connectId | getFeatures, getPassphraseState, cancel, deviceSettings, deviceReset |
| Chain address, signing, encryption, and decryption | connectId + deviceId | evmGetAddress, evmSignTransaction, btcSignTransaction, solanaSignMessage, allNetworkGetAddress |
| Hidden-wallet chain calls | connectId + deviceId + passphraseState | The same chain actions, with a non-empty passphraseState in params |
device_id, session_id, and ukey_serial are returned by feature reads. Do not pass them into a method unless the method signature or params explicitly asks for the corresponding camelCase value.
connectId Formats
Different transports expose different connection handles. Treat the value as an opaque string and pass it back to the SDK unchanged.
| Transport mode | Typical shape | Sample |
|---|---|---|
| WebUSB / bridge | Device serial-like string | 1f6dad0b8782aab31d2f7ae2b11e5b6c |
| Desktop BLE on Windows | 12-character lowercase MAC without colons | e4e65539cf33 |
| Desktop BLE on Linux | MAC address | AA:BB:CC:DD:EE:FF |
| iOS BLE | CoreBluetooth UUID | 8F4E2C6A-1D2B-4B7F-9C2E-... |
Common Confusions
connectId vs uuid
Use connectId for SDK routing. It is the handle the transport layer needs in order to send a request to the correct device.
Use uuid when you need a stable value for display, deduplication, or remembering the physical device in your own UI. On WebUSB, connectId and uuid are often the same serial-like value. On BLE, connectId may be an OS-level handle, such as an Android MAC address or an iOS CoreBluetooth UUID, while uuid is the stable ID surfaced by the SDK.
deviceId vs uuid / ukey_serial
deviceId describes the current wallet state. If the user wipes the device, restores another seed, or replaces the seed, this value can change. Chain signing and address APIs use it to avoid accidentally sending a request to the wrong wallet.
uuid and ukey_serial describe the physical device. They are useful for display and device matching, but they should not be treated as proof that the same wallet is still loaded.
session_id vs passphraseState
session_id is about the currently unlocked device session. It can become invalid after the device locks, disconnects, or restarts. If that happens, discard the cached session_id and unlock again.
passphraseState is about which hidden wallet the user selected. When the app needs several calls against the same hidden wallet, pass the same passphraseState in request params instead of asking the user to re-enter the passphrase each time.
device_id vs deviceId
They refer to the same wallet identifier in different naming contexts. device_id appears in firmware-style payloads returned by getFeatures(). deviceId is the camelCase name commonly used in SDK method signatures and examples.
Practical Rules
- Cache
connectIdanddeviceIdtogether after device selection. - Refresh
deviceIdby callinggetFeatures(connectId)after reset, restore, seed replacement, device switch, orDeviceCheckDeviceIdError. - Route requests with
connectId, notuuid. - Use
deviceIdfor chain operations that derive addresses, sign transactions, sign messages, or encrypt and decrypt data. - Do not use
session_idas long-term storage. It is only a live-session optimization. - Keep
passphraseStateonly as long as your product flow needs to reuse the same hidden wallet.
See also: Search Devices, Get Features, Get Passphrase State, Passphrase.