@onekeyfe/hardware-cli 1.2.0-alpha.67 → 1.2.0-alpha.69

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.d.ts CHANGED
@@ -53,7 +53,7 @@ export declare function runFirmwareUpdateV4WithRetry({ sdk, globalOpts, params,
53
53
  }): Promise<unknown>;
54
54
  declare function buildFirmwareUpdateV4Params(opts: {
55
55
  chunkSize?: string;
56
- resourceBundle?: string[];
56
+ resourceFile?: string[];
57
57
  romloader?: string;
58
58
  bootloader?: string;
59
59
  applicationP1?: string;
@@ -69,7 +69,7 @@ declare function buildFirmwareUpdateV4Params(opts: {
69
69
  connectProtocol: "V2";
70
70
  chunkSize: number | undefined;
71
71
  forcedUpdateRes: boolean | undefined;
72
- resourceBundleFiles: {
72
+ resourceFiles: {
73
73
  binary: ArrayBuffer;
74
74
  devicePath: string;
75
75
  }[] | undefined;
package/dist/cli.js CHANGED
@@ -485,7 +485,7 @@ program
485
485
  .command('firmware-update-v4')
486
486
  .description('Run Protocol V2 firmware update through sdk.firmwareUpdateV4')
487
487
  .option('--chunk-size <bytes>', 'Transfer chunk size in bytes')
488
- .option('--resource-bundle <spec...>', 'RESC bundle direct-write spec: <localPath>:<devicePath>, e.g. wallpaper.okpkg:vol0:/bundles/images/wallpaper.okpkg')
488
+ .option('--resource-file <spec...>', 'Resource direct-write spec: <localPath>:<devicePath>, e.g. wallpaper.okpkg:vol0:/bundles/images/wallpaper.okpkg')
489
489
  .option('--romloader <path>', 'FW_MGMT_TARGET_ROMLOADER binary path')
490
490
  .option('--bootloader <path>', 'FW_MGMT_TARGET_BOOTLOADER binary path')
491
491
  .option('--application-p1 <path>', 'FW_MGMT_TARGET_APPLICATION_P1 binary path')
@@ -957,15 +957,15 @@ async function resolveLegacyFirmwareConnectId(sdk, explicitConnectId, deviceName
957
957
  throw new Error(`BLE device has no connect ID: ${name}`);
958
958
  return connectId;
959
959
  }
960
- function parseResourceBundleParam(spec) {
960
+ function parseResourceFileParam(spec) {
961
961
  const sep = spec.indexOf(':');
962
962
  if (sep <= 0 || sep === spec.length - 1) {
963
- throw new Error(`Invalid --resource-bundle value: "${spec}". Expected <localPath>:<devicePath>`);
963
+ throw new Error(`Invalid --resource-file value: "${spec}". Expected <localPath>:<devicePath>`);
964
964
  }
965
965
  const localPath = spec.slice(0, sep);
966
966
  const devicePath = spec.slice(sep + 1);
967
967
  if (!devicePath.startsWith('vol')) {
968
- throw new Error(`Invalid --resource-bundle device path: "${devicePath}". Expected a vol*:/... path`);
968
+ throw new Error(`Invalid --resource-file device path: "${devicePath}". Expected a vol*:/... path`);
969
969
  }
970
970
  return {
971
971
  binary: readBinaryParam(localPath),
@@ -974,7 +974,7 @@ function parseResourceBundleParam(spec) {
974
974
  }
975
975
  function getFirmwareUpdateV4TotalBytes(params) {
976
976
  return [
977
- ...(params.resourceBundleFiles?.map(item => item.binary) ?? []),
977
+ ...(params.resourceFiles?.map(item => item.binary) ?? []),
978
978
  params.bootloaderBinary,
979
979
  params.applicationP1Binary,
980
980
  params.applicationP2Binary,
@@ -1209,7 +1209,7 @@ function buildFirmwareUpdateV4Params(opts) {
1209
1209
  connectProtocol: 'V2',
1210
1210
  chunkSize: opts.chunkSize ? safeParseInt(opts.chunkSize, '--chunk-size') : undefined,
1211
1211
  forcedUpdateRes: opts.forcedUpdateRes,
1212
- resourceBundleFiles: opts.resourceBundle?.map(parseResourceBundleParam),
1212
+ resourceFiles: opts.resourceFile?.map(parseResourceFileParam),
1213
1213
  romloaderBinary: opts.romloader ? readBinaryParam(opts.romloader) : undefined,
1214
1214
  bootloaderBinary: opts.bootloader ? readBinaryParam(opts.bootloader) : undefined,
1215
1215
  applicationP1Binary: opts.applicationP1 ? readBinaryParam(opts.applicationP1) : undefined,
@@ -1221,7 +1221,7 @@ function buildFirmwareUpdateV4Params(opts) {
1221
1221
  se04Binary: opts.se04 ? readBinaryParam(opts.se04) : undefined,
1222
1222
  };
1223
1223
  const hasPayload = [
1224
- params.resourceBundleFiles,
1224
+ params.resourceFiles,
1225
1225
  params.romloaderBinary,
1226
1226
  params.bootloaderBinary,
1227
1227
  params.applicationP1Binary,
@@ -20,5 +20,6 @@ export declare function findPinentry(): string | null;
20
20
  export interface PinentryResult {
21
21
  value: string;
22
22
  passphraseOnDevice: boolean;
23
+ attachPinOnDevice?: boolean;
23
24
  }
24
25
  export declare function promptPassphraseViaPinentry(): Promise<PinentryResult>;
package/dist/sdk.d.ts CHANGED
@@ -9,6 +9,7 @@
9
9
  * but public SDK responses never expose new device session ids
10
10
  */
11
11
  import HardwareSDK from '@onekeyfe/hd-common-connect-sdk';
12
+ import type { PinentryResult } from './pinentry';
12
13
  export interface SDKOptions {
13
14
  connectId?: string;
14
15
  passphraseState?: string;
@@ -16,6 +17,13 @@ export interface SDKOptions {
16
17
  debug?: boolean;
17
18
  transport?: 'usb' | 'ble';
18
19
  }
20
+ /**
21
+ * Prompt user to select wallet type (aligns with app-monorepo flow):
22
+ * 1. Standard wallet (no passphrase)
23
+ * 2. Hidden wallet — enter passphrase via pinentry (secure OS dialog)
24
+ * 3. Hidden wallet — enter passphrase on device screen
25
+ */
26
+ export declare function resolvePassphraseByChoice(choice: '1' | '2' | '3' | '4'): Promise<PinentryResult>;
19
27
  export declare function createSDK(opts: SDKOptions): Promise<typeof HardwareSDK>;
20
28
  /**
21
29
  * Release the SDK and clear the singleton. Must be called before the CLI
package/dist/sdk.js CHANGED
@@ -36,7 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.disposeSDK = exports.createSDK = void 0;
39
+ exports.disposeSDK = exports.createSDK = exports.resolvePassphraseByChoice = void 0;
40
40
  const readline = __importStar(require("node:readline"));
41
41
  const hd_common_connect_sdk_1 = __importDefault(require("@onekeyfe/hd-common-connect-sdk"));
42
42
  const hd_core_1 = require("@onekeyfe/hd-core");
@@ -76,8 +76,15 @@ function resolvePassphraseByChoice(choice) {
76
76
  return Promise.resolve({ value: '', passphraseOnDevice: false });
77
77
  if (choice === '2')
78
78
  return (0, pinentry_1.promptPassphraseViaPinentry)();
79
+ if (choice === '4')
80
+ return Promise.resolve({
81
+ value: '',
82
+ passphraseOnDevice: false,
83
+ attachPinOnDevice: true,
84
+ });
79
85
  return Promise.resolve({ value: '', passphraseOnDevice: true });
80
86
  }
87
+ exports.resolvePassphraseByChoice = resolvePassphraseByChoice;
81
88
  function promptPassphraseMode() {
82
89
  if (!process.stdin.isTTY) {
83
90
  return Promise.resolve({ value: '', passphraseOnDevice: true });
@@ -94,16 +101,17 @@ function promptPassphraseMode() {
94
101
  ' 1. Standard wallet (no passphrase)',
95
102
  ' 2. Hidden wallet — enter passphrase on this computer (pinentry)',
96
103
  ' 3. Hidden wallet — enter passphrase on device screen',
104
+ ' 4. Attach PIN wallet — enter Attach PIN on device screen',
97
105
  '',
98
106
  ].join('\n'));
99
107
  rl.question('Enter selection [1/2/3]: ', answer => {
100
108
  const n = answer.trim();
101
- if (n === '1' || n === '2' || n === '3') {
109
+ if (n === '1' || n === '2' || n === '3' || n === '4') {
102
110
  rl.close();
103
111
  resolvePassphraseByChoice(n).then(resolve);
104
112
  return;
105
113
  }
106
- process.stderr.write('Invalid selection. Enter 1, 2, or 3.\n');
114
+ process.stderr.write('Invalid selection. Enter 1, 2, 3, or 4.\n');
107
115
  prompt();
108
116
  });
109
117
  };
@@ -147,6 +155,7 @@ function registerEventHandlers(sdk) {
147
155
  payload: {
148
156
  value: result.value,
149
157
  passphraseOnDevice: result.passphraseOnDevice,
158
+ attachPinOnDevice: result.attachPinOnDevice,
150
159
  save: false,
151
160
  },
152
161
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/hardware-cli",
3
- "version": "1.2.0-alpha.67",
3
+ "version": "1.2.0-alpha.69",
4
4
  "description": "OneKey hardware wallet CLI for testing device communication",
5
5
  "author": "OneKey",
6
6
  "license": "Apache-2.0",
@@ -31,12 +31,12 @@
31
31
  "test": "jest"
32
32
  },
33
33
  "dependencies": {
34
- "@onekeyfe/hd-common-connect-sdk": "1.2.0-alpha.67",
35
- "@onekeyfe/hd-core": "1.2.0-alpha.67",
36
- "@onekeyfe/hd-shared": "1.2.0-alpha.67",
37
- "@onekeyfe/hd-transport-usb": "1.2.0-alpha.67",
34
+ "@onekeyfe/hd-common-connect-sdk": "1.2.0-alpha.69",
35
+ "@onekeyfe/hd-core": "1.2.0-alpha.69",
36
+ "@onekeyfe/hd-shared": "1.2.0-alpha.69",
37
+ "@onekeyfe/hd-transport-usb": "1.2.0-alpha.69",
38
38
  "@stoprocent/noble": "2.3.16",
39
39
  "commander": "^12.0.0"
40
40
  },
41
- "gitHead": "5fea66e8c65a1fab2ccc099b2811c8749b2487e0"
41
+ "gitHead": "c6baed25917e3c3f027f83dfc23cde85400de558"
42
42
  }
@@ -1,4 +1,5 @@
1
1
  import { prepareSession } from '../cli';
2
+ import { resolvePassphraseByChoice } from '../sdk';
2
3
  import { preloadSessionFromKeychain } from '../session';
3
4
 
4
5
  jest.mock('../session', () => ({
@@ -7,6 +8,14 @@ jest.mock('../session', () => ({
7
8
  }));
8
9
 
9
10
  describe('CLI wallet session', () => {
11
+ test('maps the Attach PIN choice to an on-device Attach PIN response', async () => {
12
+ await expect(resolvePassphraseByChoice('4')).resolves.toEqual({
13
+ value: '',
14
+ passphraseOnDevice: false,
15
+ attachPinOnDevice: true,
16
+ });
17
+ });
18
+
10
19
  test('uses the public wallet identity without persisting an internal session id', async () => {
11
20
  const sdk = {
12
21
  searchDevices: jest.fn().mockResolvedValue({
package/src/cli.ts CHANGED
@@ -629,8 +629,8 @@ program
629
629
  .description('Run Protocol V2 firmware update through sdk.firmwareUpdateV4')
630
630
  .option('--chunk-size <bytes>', 'Transfer chunk size in bytes')
631
631
  .option(
632
- '--resource-bundle <spec...>',
633
- 'RESC bundle direct-write spec: <localPath>:<devicePath>, e.g. wallpaper.okpkg:vol0:/bundles/images/wallpaper.okpkg'
632
+ '--resource-file <spec...>',
633
+ 'Resource direct-write spec: <localPath>:<devicePath>, e.g. wallpaper.okpkg:vol0:/bundles/images/wallpaper.okpkg'
634
634
  )
635
635
  .option('--romloader <path>', 'FW_MGMT_TARGET_ROMLOADER binary path')
636
636
  .option('--bootloader <path>', 'FW_MGMT_TARGET_BOOTLOADER binary path')
@@ -1253,18 +1253,16 @@ async function resolveLegacyFirmwareConnectId(
1253
1253
  return connectId;
1254
1254
  }
1255
1255
 
1256
- function parseResourceBundleParam(spec: string): { binary: ArrayBuffer; devicePath: string } {
1256
+ function parseResourceFileParam(spec: string): { binary: ArrayBuffer; devicePath: string } {
1257
1257
  const sep = spec.indexOf(':');
1258
1258
  if (sep <= 0 || sep === spec.length - 1) {
1259
- throw new Error(
1260
- `Invalid --resource-bundle value: "${spec}". Expected <localPath>:<devicePath>`
1261
- );
1259
+ throw new Error(`Invalid --resource-file value: "${spec}". Expected <localPath>:<devicePath>`);
1262
1260
  }
1263
1261
  const localPath = spec.slice(0, sep);
1264
1262
  const devicePath = spec.slice(sep + 1);
1265
1263
  if (!devicePath.startsWith('vol')) {
1266
1264
  throw new Error(
1267
- `Invalid --resource-bundle device path: "${devicePath}". Expected a vol*:/... path`
1265
+ `Invalid --resource-file device path: "${devicePath}". Expected a vol*:/... path`
1268
1266
  );
1269
1267
  }
1270
1268
  return {
@@ -1275,7 +1273,7 @@ function parseResourceBundleParam(spec: string): { binary: ArrayBuffer; devicePa
1275
1273
 
1276
1274
  function getFirmwareUpdateV4TotalBytes(params: ReturnType<typeof buildFirmwareUpdateV4Params>) {
1277
1275
  return [
1278
- ...(params.resourceBundleFiles?.map(item => item.binary) ?? []),
1276
+ ...(params.resourceFiles?.map(item => item.binary) ?? []),
1279
1277
  params.bootloaderBinary,
1280
1278
  params.applicationP1Binary,
1281
1279
  params.applicationP2Binary,
@@ -1600,7 +1598,7 @@ export async function runFirmwareUpdateV4WithRetry({
1600
1598
 
1601
1599
  function buildFirmwareUpdateV4Params(opts: {
1602
1600
  chunkSize?: string;
1603
- resourceBundle?: string[];
1601
+ resourceFile?: string[];
1604
1602
  romloader?: string;
1605
1603
  bootloader?: string;
1606
1604
  applicationP1?: string;
@@ -1617,7 +1615,7 @@ function buildFirmwareUpdateV4Params(opts: {
1617
1615
  connectProtocol: 'V2' as const,
1618
1616
  chunkSize: opts.chunkSize ? safeParseInt(opts.chunkSize, '--chunk-size') : undefined,
1619
1617
  forcedUpdateRes: opts.forcedUpdateRes,
1620
- resourceBundleFiles: opts.resourceBundle?.map(parseResourceBundleParam),
1618
+ resourceFiles: opts.resourceFile?.map(parseResourceFileParam),
1621
1619
  romloaderBinary: opts.romloader ? readBinaryParam(opts.romloader) : undefined,
1622
1620
  bootloaderBinary: opts.bootloader ? readBinaryParam(opts.bootloader) : undefined,
1623
1621
  applicationP1Binary: opts.applicationP1 ? readBinaryParam(opts.applicationP1) : undefined,
@@ -1630,7 +1628,7 @@ function buildFirmwareUpdateV4Params(opts: {
1630
1628
  };
1631
1629
 
1632
1630
  const hasPayload = [
1633
- params.resourceBundleFiles,
1631
+ params.resourceFiles,
1634
1632
  params.romloaderBinary,
1635
1633
  params.bootloaderBinary,
1636
1634
  params.applicationP1Binary,
package/src/pinentry.ts CHANGED
@@ -73,6 +73,7 @@ export function findPinentry(): string | null {
73
73
  export interface PinentryResult {
74
74
  value: string;
75
75
  passphraseOnDevice: boolean;
76
+ attachPinOnDevice?: boolean;
76
77
  }
77
78
 
78
79
  // CLI-variant policy differs from app-monorepo: we fall back to on-device
package/src/sdk.ts CHANGED
@@ -59,9 +59,15 @@ let sdkReadyPromise: Promise<typeof HardwareSDK> | null = null;
59
59
  * 2. Hidden wallet — enter passphrase via pinentry (secure OS dialog)
60
60
  * 3. Hidden wallet — enter passphrase on device screen
61
61
  */
62
- function resolvePassphraseByChoice(choice: '1' | '2' | '3'): Promise<PinentryResult> {
62
+ export function resolvePassphraseByChoice(choice: '1' | '2' | '3' | '4'): Promise<PinentryResult> {
63
63
  if (choice === '1') return Promise.resolve({ value: '', passphraseOnDevice: false });
64
64
  if (choice === '2') return promptPassphraseViaPinentry();
65
+ if (choice === '4')
66
+ return Promise.resolve({
67
+ value: '',
68
+ passphraseOnDevice: false,
69
+ attachPinOnDevice: true,
70
+ });
65
71
  return Promise.resolve({ value: '', passphraseOnDevice: true });
66
72
  }
67
73
 
@@ -84,18 +90,19 @@ function promptPassphraseMode(): Promise<PinentryResult> {
84
90
  ' 1. Standard wallet (no passphrase)',
85
91
  ' 2. Hidden wallet — enter passphrase on this computer (pinentry)',
86
92
  ' 3. Hidden wallet — enter passphrase on device screen',
93
+ ' 4. Attach PIN wallet — enter Attach PIN on device screen',
87
94
  '',
88
95
  ].join('\n')
89
96
  );
90
97
 
91
98
  rl.question('Enter selection [1/2/3]: ', answer => {
92
- const n = answer.trim() as '1' | '2' | '3';
93
- if (n === '1' || n === '2' || n === '3') {
99
+ const n = answer.trim() as '1' | '2' | '3' | '4';
100
+ if (n === '1' || n === '2' || n === '3' || n === '4') {
94
101
  rl.close();
95
102
  resolvePassphraseByChoice(n).then(resolve);
96
103
  return;
97
104
  }
98
- process.stderr.write('Invalid selection. Enter 1, 2, or 3.\n');
105
+ process.stderr.write('Invalid selection. Enter 1, 2, 3, or 4.\n');
99
106
  prompt();
100
107
  });
101
108
  };
@@ -143,6 +150,7 @@ function registerEventHandlers(sdk: typeof HardwareSDK): void {
143
150
  payload: {
144
151
  value: result.value,
145
152
  passphraseOnDevice: result.passphraseOnDevice,
153
+ attachPinOnDevice: result.attachPinOnDevice,
146
154
  save: false,
147
155
  },
148
156
  });