本页目录
Passphrase(核心指南)
处理 OneKey 设备 Passphrase(隐藏钱包)的基本规则与最佳实践。
关键要点
- 标准钱包 = 助记词 + 空 Passphrase;隐藏钱包 = 助记词 + 非空 Passphrase(区分大小写)。
- 每个不同的 Passphrase 都会生成完全不同的钱包——即使只差一个字符。
- Passphrase 遗忘后无法恢复,请妥善备份。
- 设置
useEmptyPassphrase: true可强制使用标准钱包。
设备支持
不要仅凭机型名称假定设备端或宿主端输入可用。先读取 getDeviceState 确认设备、固件和当前状态,再按实际 UI 请求提供输入方式;功能可用性取决于设备、固件、SDK 和运行环境。
| 当前请求 | 应用行为 |
|---|---|
REQUEST_PASSPHRASE | 按当前输入流程提供选择,并转发请求的响应关联字段。 |
请求带 deviceOnly | 必须选择设备端输入,不显示宿主输入入口。 |
REQUEST_PASSPHRASE_ON_DEVICE | 只显示“在设备上输入”的提示,不调用 uiResponse。 |
若目标输入方式不可用,应向用户报告,不自动切换输入方式。只保存成功返回的 deviceId + passphraseState 绑定,不保存密码短语或固件 session_id。
交互流程
Hardware SDK 1.2.x:searchDevices → getDeviceState → openWalletSession → 地址 / 签名带 deviceId + passphraseState(或 useEmptyPassphrase: true)。开钱包前先订阅 UI_EVENT。见 钱包会话。
标准钱包
const state = await HardwareSDK.getDeviceState(connectId);
if (!state.success) throw new Error(state.payload.error);
const deviceId = state.payload.identity.deviceId;
if (!deviceId) throw new Error("Device has no wallet identity");
const standard = await HardwareSDK.openWalletSession(connectId, { mode: 'standard' });
if (!standard.success) throw new Error(standard.payload.error);
await HardwareSDK.evmGetAddress(connectId, deviceId, {
path: "m/44'/60'/0'/0/0",
useEmptyPassphrase: true,
});隐藏钱包(开一次,复用指纹)
import { UI_EVENT, UI_REQUEST, UI_RESPONSE } from '@onekeyfe/hd-core';
HardwareSDK.on(UI_EVENT, async (message) => {
if (message.type === UI_REQUEST.REQUEST_PASSPHRASE) {
await HardwareSDK.uiResponse({
type: UI_RESPONSE.RECEIVE_PASSPHRASE,
...message.payload.responseCorrelation,
payload: { passphraseOnDevice: true, value: '', save: false },
});
}
});
const opened = await HardwareSDK.openWalletSession(connectId, {
mode: 'select-hidden',
});
if (!opened.success) throw new Error(opened.payload.error);
if (opened.payload.walletType !== 'hidden') {
throw new Error('A hidden wallet was not opened');
}
const deviceId = opened.payload.deviceId;
const passphraseState = opened.payload.passphraseState;
await HardwareSDK.evmGetAddress(connectId, deviceId, {
path: "m/44'/60'/0'/0/0",
passphraseState,
});
await HardwareSDK.btcGetAddress(connectId, deviceId, {
path: "m/84'/0'/0'/0/0",
coin: 'btc',
passphraseState,
});设备端与软件输入示例:默认不缓存秘密值。只有用户明确选择受支持的会话缓存流程时,才启用 save。
// 设备端
payload: { passphraseOnDevice: true, value: '' }
// 软件
payload: { value: userInput, passphraseOnDevice: false, save: false }之后的进程 / 重连
只持久化 deviceId + passphraseState。不要存固件 session_id。读出绑定,带到下一笔地址 / 签名即可。Core 会在那笔方法里恢复。openWalletSession 没有 resume mode。
import { OpenWalletSessionMode } from '@onekeyfe/hd-core';
// 进程 1 — 用户选完隐藏钱包
const opened = await HardwareSDK.openWalletSession(connectId, {
mode: OpenWalletSessionMode.SelectHidden,
});
if (!opened.success) throw new Error(opened.payload.error);
if (opened.payload.walletType !== 'hidden') {
throw new Error('A hidden wallet was not opened');
}
saveBinding({
deviceId: opened.payload.deviceId,
passphraseState: opened.payload.passphraseState,
});
// 进程 2 — 之后另一次进程
const { deviceId, passphraseState } = loadBinding();
await HardwareSDK.evmGetAddress(connectId, deviceId, {
path: "m/44'/60'/0'/0/0",
passphraseState,
});preloadSessionCache 只给旧 App/CLI Keychain 记录做兼容。新接入不要调用它,也不要存 session_id。
两次进程之间如果设备锁屏了,PIN 会在第一笔受保护调用里再走一遍。见 钱包会话。
先解锁模式(CLI)
const state = await HardwareSDK.getDeviceState(connectId);
if (!state.success) throw new Error(state.payload.error);
if (!state.payload.status.unlocked) {
await HardwareSDK.deviceUnlock(connectId, {});
}
await HardwareSDK.evmGetAddress(connectId, savedDeviceId, {
path: "m/44'/60'/0'/0/0",
passphraseState: savedPassphraseState,
});注意事项
- 不要记录或持久化 Passphrase 明文。
- 使用
useEmptyPassphrase: true防止意外创建隐藏钱包。 - Pro/Touch 设备:PIN 必须在设备上输入;Passphrase 可在设备或软件端输入。
常见问题
忘记 Passphrase 会怎样?
隐藏钱包中的资金将永久无法访问。没有任何方式可以恢复遗忘的 Passphrase。请务必保留安全备份。
Passphrase 和 PIN 是同一个东西吗?
不是。PIN 保护设备的物理访问。Passphrase 从同一个助记词创建完全不同的钱包。它们有不同的安全用途:
| PIN | Passphrase | |
|---|---|---|
| 用途 | 设备访问保护 | 隐藏钱包创建 |
| 恢复 | 可通过擦除设备 + 恢复助记词重置 | 无法恢复 |
| 存储 | 存储在设备上 | 不要持久化明文;SDK 缓存取决于输入流程与 save |
| 区分大小写 | 不适用(纯数字) | 是 |
可以有多个隐藏钱包吗?
可以。每个不同的 Passphrase 创建一个独立的隐藏钱包。你可以拥有任意数量的隐藏钱包——每个 Passphrase 对应一个。
设备会验证我的 Passphrase 吗?
首次输入不同的 Passphrase 可以派生不同钱包。后续调用如果传入预期的 passphraseState,SDK 会校验绑定并在不匹配时失败;不要将输错后派生的钱包当作目标钱包。
passphraseOnDevice 和软件输入有什么区别?
- 设备端输入:Passphrase 直接在硬件设备的屏幕/键盘上输入,永远不会离开设备。
- 软件输入:Passphrase 在你的应用中输入后通过 SDK 发送到设备。
Protocol V1 在关闭 passphrase 保护时,select-hidden 可能返回标准钱包。保存或使用 passphraseState 前先检查 walletType。