@onekeyfe/hardware-cli 1.2.0-alpha.66 → 1.2.0-alpha.67
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 +2 -2
- package/dist/cli.js +7 -7
- package/dist/pinentry.d.ts +0 -1
- package/dist/sdk.d.ts +0 -8
- package/dist/sdk.js +3 -12
- package/package.json +6 -6
- package/src/__tests__/wallet-session.test.ts +0 -9
- package/src/cli.ts +11 -9
- package/src/pinentry.ts +0 -1
- package/src/sdk.ts +4 -12
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
|
-
|
|
56
|
+
resourceBundle?: 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
|
-
|
|
72
|
+
resourceBundleFiles: {
|
|
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-
|
|
488
|
+
.option('--resource-bundle <spec...>', 'RESC bundle 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
|
|
960
|
+
function parseResourceBundleParam(spec) {
|
|
961
961
|
const sep = spec.indexOf(':');
|
|
962
962
|
if (sep <= 0 || sep === spec.length - 1) {
|
|
963
|
-
throw new Error(`Invalid --resource-
|
|
963
|
+
throw new Error(`Invalid --resource-bundle 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-
|
|
968
|
+
throw new Error(`Invalid --resource-bundle device path: "${devicePath}". Expected a vol*:/... path`);
|
|
969
969
|
}
|
|
970
970
|
return {
|
|
971
971
|
binary: readBinaryParam(localPath),
|
|
@@ -974,7 +974,7 @@ function parseResourceFileParam(spec) {
|
|
|
974
974
|
}
|
|
975
975
|
function getFirmwareUpdateV4TotalBytes(params) {
|
|
976
976
|
return [
|
|
977
|
-
...(params.
|
|
977
|
+
...(params.resourceBundleFiles?.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
|
-
|
|
1212
|
+
resourceBundleFiles: opts.resourceBundle?.map(parseResourceBundleParam),
|
|
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.
|
|
1224
|
+
params.resourceBundleFiles,
|
|
1225
1225
|
params.romloaderBinary,
|
|
1226
1226
|
params.bootloaderBinary,
|
|
1227
1227
|
params.applicationP1Binary,
|
package/dist/pinentry.d.ts
CHANGED
package/dist/sdk.d.ts
CHANGED
|
@@ -9,7 +9,6 @@
|
|
|
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';
|
|
13
12
|
export interface SDKOptions {
|
|
14
13
|
connectId?: string;
|
|
15
14
|
passphraseState?: string;
|
|
@@ -17,13 +16,6 @@ export interface SDKOptions {
|
|
|
17
16
|
debug?: boolean;
|
|
18
17
|
transport?: 'usb' | 'ble';
|
|
19
18
|
}
|
|
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>;
|
|
27
19
|
export declare function createSDK(opts: SDKOptions): Promise<typeof HardwareSDK>;
|
|
28
20
|
/**
|
|
29
21
|
* 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 =
|
|
39
|
+
exports.disposeSDK = exports.createSDK = 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,15 +76,8 @@ 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
|
-
});
|
|
85
79
|
return Promise.resolve({ value: '', passphraseOnDevice: true });
|
|
86
80
|
}
|
|
87
|
-
exports.resolvePassphraseByChoice = resolvePassphraseByChoice;
|
|
88
81
|
function promptPassphraseMode() {
|
|
89
82
|
if (!process.stdin.isTTY) {
|
|
90
83
|
return Promise.resolve({ value: '', passphraseOnDevice: true });
|
|
@@ -101,17 +94,16 @@ function promptPassphraseMode() {
|
|
|
101
94
|
' 1. Standard wallet (no passphrase)',
|
|
102
95
|
' 2. Hidden wallet — enter passphrase on this computer (pinentry)',
|
|
103
96
|
' 3. Hidden wallet — enter passphrase on device screen',
|
|
104
|
-
' 4. Attach PIN wallet — enter Attach PIN on device screen',
|
|
105
97
|
'',
|
|
106
98
|
].join('\n'));
|
|
107
99
|
rl.question('Enter selection [1/2/3]: ', answer => {
|
|
108
100
|
const n = answer.trim();
|
|
109
|
-
if (n === '1' || n === '2' || n === '3'
|
|
101
|
+
if (n === '1' || n === '2' || n === '3') {
|
|
110
102
|
rl.close();
|
|
111
103
|
resolvePassphraseByChoice(n).then(resolve);
|
|
112
104
|
return;
|
|
113
105
|
}
|
|
114
|
-
process.stderr.write('Invalid selection. Enter 1, 2,
|
|
106
|
+
process.stderr.write('Invalid selection. Enter 1, 2, or 3.\n');
|
|
115
107
|
prompt();
|
|
116
108
|
});
|
|
117
109
|
};
|
|
@@ -155,7 +147,6 @@ function registerEventHandlers(sdk) {
|
|
|
155
147
|
payload: {
|
|
156
148
|
value: result.value,
|
|
157
149
|
passphraseOnDevice: result.passphraseOnDevice,
|
|
158
|
-
attachPinOnDevice: result.attachPinOnDevice,
|
|
159
150
|
save: false,
|
|
160
151
|
},
|
|
161
152
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hardware-cli",
|
|
3
|
-
"version": "1.2.0-alpha.
|
|
3
|
+
"version": "1.2.0-alpha.67",
|
|
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.
|
|
35
|
-
"@onekeyfe/hd-core": "1.2.0-alpha.
|
|
36
|
-
"@onekeyfe/hd-shared": "1.2.0-alpha.
|
|
37
|
-
"@onekeyfe/hd-transport-usb": "1.2.0-alpha.
|
|
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",
|
|
38
38
|
"@stoprocent/noble": "2.3.16",
|
|
39
39
|
"commander": "^12.0.0"
|
|
40
40
|
},
|
|
41
|
-
"gitHead": "
|
|
41
|
+
"gitHead": "5fea66e8c65a1fab2ccc099b2811c8749b2487e0"
|
|
42
42
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { prepareSession } from '../cli';
|
|
2
|
-
import { resolvePassphraseByChoice } from '../sdk';
|
|
3
2
|
import { preloadSessionFromKeychain } from '../session';
|
|
4
3
|
|
|
5
4
|
jest.mock('../session', () => ({
|
|
@@ -8,14 +7,6 @@ jest.mock('../session', () => ({
|
|
|
8
7
|
}));
|
|
9
8
|
|
|
10
9
|
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
|
-
|
|
19
10
|
test('uses the public wallet identity without persisting an internal session id', async () => {
|
|
20
11
|
const sdk = {
|
|
21
12
|
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-
|
|
633
|
-
'
|
|
632
|
+
'--resource-bundle <spec...>',
|
|
633
|
+
'RESC bundle 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,16 +1253,18 @@ async function resolveLegacyFirmwareConnectId(
|
|
|
1253
1253
|
return connectId;
|
|
1254
1254
|
}
|
|
1255
1255
|
|
|
1256
|
-
function
|
|
1256
|
+
function parseResourceBundleParam(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(
|
|
1259
|
+
throw new Error(
|
|
1260
|
+
`Invalid --resource-bundle value: "${spec}". Expected <localPath>:<devicePath>`
|
|
1261
|
+
);
|
|
1260
1262
|
}
|
|
1261
1263
|
const localPath = spec.slice(0, sep);
|
|
1262
1264
|
const devicePath = spec.slice(sep + 1);
|
|
1263
1265
|
if (!devicePath.startsWith('vol')) {
|
|
1264
1266
|
throw new Error(
|
|
1265
|
-
`Invalid --resource-
|
|
1267
|
+
`Invalid --resource-bundle device path: "${devicePath}". Expected a vol*:/... path`
|
|
1266
1268
|
);
|
|
1267
1269
|
}
|
|
1268
1270
|
return {
|
|
@@ -1273,7 +1275,7 @@ function parseResourceFileParam(spec: string): { binary: ArrayBuffer; devicePath
|
|
|
1273
1275
|
|
|
1274
1276
|
function getFirmwareUpdateV4TotalBytes(params: ReturnType<typeof buildFirmwareUpdateV4Params>) {
|
|
1275
1277
|
return [
|
|
1276
|
-
...(params.
|
|
1278
|
+
...(params.resourceBundleFiles?.map(item => item.binary) ?? []),
|
|
1277
1279
|
params.bootloaderBinary,
|
|
1278
1280
|
params.applicationP1Binary,
|
|
1279
1281
|
params.applicationP2Binary,
|
|
@@ -1598,7 +1600,7 @@ export async function runFirmwareUpdateV4WithRetry({
|
|
|
1598
1600
|
|
|
1599
1601
|
function buildFirmwareUpdateV4Params(opts: {
|
|
1600
1602
|
chunkSize?: string;
|
|
1601
|
-
|
|
1603
|
+
resourceBundle?: string[];
|
|
1602
1604
|
romloader?: string;
|
|
1603
1605
|
bootloader?: string;
|
|
1604
1606
|
applicationP1?: string;
|
|
@@ -1615,7 +1617,7 @@ function buildFirmwareUpdateV4Params(opts: {
|
|
|
1615
1617
|
connectProtocol: 'V2' as const,
|
|
1616
1618
|
chunkSize: opts.chunkSize ? safeParseInt(opts.chunkSize, '--chunk-size') : undefined,
|
|
1617
1619
|
forcedUpdateRes: opts.forcedUpdateRes,
|
|
1618
|
-
|
|
1620
|
+
resourceBundleFiles: opts.resourceBundle?.map(parseResourceBundleParam),
|
|
1619
1621
|
romloaderBinary: opts.romloader ? readBinaryParam(opts.romloader) : undefined,
|
|
1620
1622
|
bootloaderBinary: opts.bootloader ? readBinaryParam(opts.bootloader) : undefined,
|
|
1621
1623
|
applicationP1Binary: opts.applicationP1 ? readBinaryParam(opts.applicationP1) : undefined,
|
|
@@ -1628,7 +1630,7 @@ function buildFirmwareUpdateV4Params(opts: {
|
|
|
1628
1630
|
};
|
|
1629
1631
|
|
|
1630
1632
|
const hasPayload = [
|
|
1631
|
-
params.
|
|
1633
|
+
params.resourceBundleFiles,
|
|
1632
1634
|
params.romloaderBinary,
|
|
1633
1635
|
params.bootloaderBinary,
|
|
1634
1636
|
params.applicationP1Binary,
|
package/src/pinentry.ts
CHANGED
package/src/sdk.ts
CHANGED
|
@@ -59,15 +59,9 @@ 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
|
-
|
|
62
|
+
function resolvePassphraseByChoice(choice: '1' | '2' | '3'): 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
|
-
});
|
|
71
65
|
return Promise.resolve({ value: '', passphraseOnDevice: true });
|
|
72
66
|
}
|
|
73
67
|
|
|
@@ -90,19 +84,18 @@ function promptPassphraseMode(): Promise<PinentryResult> {
|
|
|
90
84
|
' 1. Standard wallet (no passphrase)',
|
|
91
85
|
' 2. Hidden wallet — enter passphrase on this computer (pinentry)',
|
|
92
86
|
' 3. Hidden wallet — enter passphrase on device screen',
|
|
93
|
-
' 4. Attach PIN wallet — enter Attach PIN on device screen',
|
|
94
87
|
'',
|
|
95
88
|
].join('\n')
|
|
96
89
|
);
|
|
97
90
|
|
|
98
91
|
rl.question('Enter selection [1/2/3]: ', answer => {
|
|
99
|
-
const n = answer.trim() as '1' | '2' | '3'
|
|
100
|
-
if (n === '1' || n === '2' || n === '3'
|
|
92
|
+
const n = answer.trim() as '1' | '2' | '3';
|
|
93
|
+
if (n === '1' || n === '2' || n === '3') {
|
|
101
94
|
rl.close();
|
|
102
95
|
resolvePassphraseByChoice(n).then(resolve);
|
|
103
96
|
return;
|
|
104
97
|
}
|
|
105
|
-
process.stderr.write('Invalid selection. Enter 1, 2,
|
|
98
|
+
process.stderr.write('Invalid selection. Enter 1, 2, or 3.\n');
|
|
106
99
|
prompt();
|
|
107
100
|
});
|
|
108
101
|
};
|
|
@@ -150,7 +143,6 @@ function registerEventHandlers(sdk: typeof HardwareSDK): void {
|
|
|
150
143
|
payload: {
|
|
151
144
|
value: result.value,
|
|
152
145
|
passphraseOnDevice: result.passphraseOnDevice,
|
|
153
|
-
attachPinOnDevice: result.attachPinOnDevice,
|
|
154
146
|
save: false,
|
|
155
147
|
},
|
|
156
148
|
});
|