@onekeyfe/hardware-cli 1.1.26-alpha.106 → 1.1.26-alpha.4

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.
Files changed (41) hide show
  1. package/.eslintignore +4 -0
  2. package/dist/chains.d.ts +6 -0
  3. package/dist/chains.js +191 -87
  4. package/dist/cli.js +615 -496
  5. package/dist/index.d.ts +16 -89
  6. package/dist/index.js +1 -2
  7. package/dist/sdk.d.ts +15 -5
  8. package/dist/sdk.js +237 -131
  9. package/dist/session.d.ts +22 -0
  10. package/dist/session.js +83 -0
  11. package/dist/storage/index.d.ts +2 -0
  12. package/dist/storage/index.js +5 -0
  13. package/dist/storage/process-utils.d.ts +2 -0
  14. package/dist/storage/process-utils.js +44 -0
  15. package/dist/storage/secure-storage.linux.d.ts +11 -0
  16. package/dist/storage/secure-storage.linux.js +59 -0
  17. package/dist/storage/secure-storage.macos.d.ts +11 -0
  18. package/dist/storage/secure-storage.macos.js +65 -0
  19. package/dist/storage/storage-factory.d.ts +3 -0
  20. package/dist/storage/storage-factory.js +14 -0
  21. package/dist/storage/types.d.ts +18 -0
  22. package/dist/storage/types.js +2 -0
  23. package/package.json +15 -13
  24. package/src/chains.ts +229 -85
  25. package/src/cli.ts +620 -297
  26. package/src/sdk.ts +244 -125
  27. package/src/session.ts +89 -0
  28. package/src/storage/index.ts +2 -0
  29. package/src/storage/process-utils.ts +50 -0
  30. package/src/storage/secure-storage.linux.ts +68 -0
  31. package/src/storage/secure-storage.macos.ts +68 -0
  32. package/src/storage/storage-factory.ts +13 -0
  33. package/src/storage/types.ts +17 -0
  34. package/tsconfig.json +5 -7
  35. package/.claude-plugin/plugin.json +0 -14
  36. package/AGENTS.md +0 -40
  37. package/CLAUDE.md +0 -40
  38. package/README.md +0 -112
  39. package/evals/cases.json +0 -373
  40. package/evals/run-evals.sh +0 -136
  41. package/rollup.config.js +0 -28
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ /**
3
+ * Passphrase session management for hd-cli.
4
+ *
5
+ * Aligns with app-monorepo's CLI pattern:
6
+ * Login: getPassphraseState → passphraseState + sessionId → keychain
7
+ * Command: keychain → preloadSessionCache → SDK call (no passphrase prompt)
8
+ * Stale: error 112 → clear keychain → re-prompt → retry
9
+ * Logout: keychain delete
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.clearSessionFromKeychain = exports.saveSessionToKeychain = exports.preloadSessionFromKeychain = void 0;
13
+ const hd_core_1 = require("@onekeyfe/hd-core");
14
+ const storage_1 = require("./storage");
15
+ // Keychain key format: scoped by deviceId for multi-device support
16
+ function psKey(deviceId) {
17
+ return `onekey-hw:${deviceId}/passphrase-state`;
18
+ }
19
+ function sidKey(deviceId) {
20
+ return `onekey-hw:${deviceId}/session-id`;
21
+ }
22
+ let storageInstance = null;
23
+ function getStorage() {
24
+ if (!storageInstance) {
25
+ storageInstance = (0, storage_1.createSecureStorage)();
26
+ }
27
+ return storageInstance;
28
+ }
29
+ /**
30
+ * Load passphraseState + sessionId from keychain and call preloadSessionCache.
31
+ * Non-fatal: returns the loaded passphraseState or undefined.
32
+ */
33
+ async function preloadSessionFromKeychain(deviceId) {
34
+ try {
35
+ const storage = getStorage();
36
+ const [psBuf, sidBuf] = await Promise.all([
37
+ storage.get(psKey(deviceId)),
38
+ storage.get(sidKey(deviceId)),
39
+ ]);
40
+ if (psBuf && sidBuf) {
41
+ const passphraseState = psBuf.toString('utf-8');
42
+ const sessionId = sidBuf.toString('utf-8');
43
+ (0, hd_core_1.preloadSessionCache)(deviceId, passphraseState, sessionId);
44
+ return passphraseState;
45
+ }
46
+ }
47
+ catch {
48
+ // Non-fatal — fall through to passphrase prompt
49
+ }
50
+ return undefined;
51
+ }
52
+ exports.preloadSessionFromKeychain = preloadSessionFromKeychain;
53
+ /**
54
+ * Save passphraseState + sessionId to keychain for next CLI invocation.
55
+ */
56
+ async function saveSessionToKeychain(deviceId, passphraseState, sessionId) {
57
+ try {
58
+ const storage = getStorage();
59
+ await Promise.all([
60
+ storage.set(psKey(deviceId), Buffer.from(passphraseState, 'utf-8')),
61
+ storage.set(sidKey(deviceId), Buffer.from(sessionId, 'utf-8')),
62
+ ]);
63
+ }
64
+ catch {
65
+ // Non-fatal — session still works in-memory for this invocation
66
+ }
67
+ }
68
+ exports.saveSessionToKeychain = saveSessionToKeychain;
69
+ /**
70
+ * Clear cached session from keychain.
71
+ */
72
+ async function clearSessionFromKeychain(deviceId) {
73
+ try {
74
+ const storage = getStorage();
75
+ if (deviceId) {
76
+ await Promise.allSettled([storage.delete(psKey(deviceId)), storage.delete(sidKey(deviceId))]);
77
+ }
78
+ }
79
+ catch {
80
+ // Non-fatal
81
+ }
82
+ }
83
+ exports.clearSessionFromKeychain = clearSessionFromKeychain;
@@ -0,0 +1,2 @@
1
+ export { createSecureStorage } from './storage-factory';
2
+ export type { ISecureStorage, SecureStorageBackend } from './types';
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createSecureStorage = void 0;
4
+ var storage_factory_1 = require("./storage-factory");
5
+ Object.defineProperty(exports, "createSecureStorage", { enumerable: true, get: function () { return storage_factory_1.createSecureStorage; } });
@@ -0,0 +1,2 @@
1
+ import type { IProcessRunner } from './types';
2
+ export declare const defaultProcessRunner: IProcessRunner;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defaultProcessRunner = void 0;
4
+ const node_child_process_1 = require("node:child_process");
5
+ exports.defaultProcessRunner = {
6
+ execFileAsync(cmd, args) {
7
+ return new Promise((resolve, reject) => {
8
+ (0, node_child_process_1.execFile)(cmd, args, (error, stdout, stderr) => {
9
+ if (error) {
10
+ error.stderr = stderr;
11
+ reject(error);
12
+ return;
13
+ }
14
+ resolve({ stdout, stderr });
15
+ });
16
+ });
17
+ },
18
+ spawnWithStdin(cmd, args, input) {
19
+ return new Promise((resolve, reject) => {
20
+ const child = (0, node_child_process_1.spawn)(cmd, args, { stdio: ['pipe', 'pipe', 'pipe'] });
21
+ let stdout = '';
22
+ let stderr = '';
23
+ child.stdout.on('data', (data) => {
24
+ stdout += data.toString();
25
+ });
26
+ child.stderr.on('data', (data) => {
27
+ stderr += data.toString();
28
+ });
29
+ child.on('error', reject);
30
+ child.on('close', code => {
31
+ if (code !== 0) {
32
+ const error = new Error(`Process exited with code ${code}`);
33
+ error.code = code ?? 1;
34
+ error.stderr = stderr;
35
+ reject(error);
36
+ return;
37
+ }
38
+ resolve({ stdout, stderr });
39
+ });
40
+ child.stdin.write(`${input}\n`);
41
+ child.stdin.end();
42
+ });
43
+ },
44
+ };
@@ -0,0 +1,11 @@
1
+ /// <reference types="node" />
2
+ import type { IProcessRunner, ISecureStorage, SecureStorageBackend } from './types';
3
+ export declare class LinuxSecureStorage implements ISecureStorage {
4
+ private readonly runner;
5
+ constructor(runner?: IProcessRunner);
6
+ getBackendType(): SecureStorageBackend;
7
+ set(key: string, value: Buffer): Promise<void>;
8
+ get(key: string): Promise<Buffer | null>;
9
+ delete(key: string): Promise<void>;
10
+ private isItemNotFound;
11
+ }
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LinuxSecureStorage = void 0;
4
+ const process_utils_1 = require("./process-utils");
5
+ const SERVICE_NAME = 'onekey-hw-cli';
6
+ const SECRET_LABEL = 'OneKey HW CLI Secret';
7
+ class LinuxSecureStorage {
8
+ constructor(runner = process_utils_1.defaultProcessRunner) {
9
+ this.runner = runner;
10
+ }
11
+ getBackendType() {
12
+ return 'linux-secret-service';
13
+ }
14
+ async set(key, value) {
15
+ await this.runner.spawnWithStdin('secret-tool', ['store', '--label', SECRET_LABEL, 'service', SERVICE_NAME, 'account', key], value.toString('hex'));
16
+ }
17
+ async get(key) {
18
+ try {
19
+ const { stdout } = await this.runner.execFileAsync('secret-tool', [
20
+ 'lookup',
21
+ 'service',
22
+ SERVICE_NAME,
23
+ 'account',
24
+ key,
25
+ ]);
26
+ const hex = stdout.trim();
27
+ return hex ? Buffer.from(hex, 'hex') : null;
28
+ }
29
+ catch (error) {
30
+ if (this.isItemNotFound(error))
31
+ return null;
32
+ throw error;
33
+ }
34
+ }
35
+ async delete(key) {
36
+ try {
37
+ await this.runner.execFileAsync('secret-tool', [
38
+ 'clear',
39
+ 'service',
40
+ SERVICE_NAME,
41
+ 'account',
42
+ key,
43
+ ]);
44
+ }
45
+ catch (error) {
46
+ if (this.isItemNotFound(error))
47
+ return;
48
+ throw error;
49
+ }
50
+ }
51
+ isItemNotFound(error) {
52
+ const err = error;
53
+ const stderr = err.stderr ?? err.message ?? '';
54
+ return (stderr.includes('No such secret item') ||
55
+ stderr.includes('Object does not exist') ||
56
+ stderr.includes('could not find'));
57
+ }
58
+ }
59
+ exports.LinuxSecureStorage = LinuxSecureStorage;
@@ -0,0 +1,11 @@
1
+ /// <reference types="node" />
2
+ import type { IProcessRunner, ISecureStorage, SecureStorageBackend } from './types';
3
+ export declare class MacOSSecureStorage implements ISecureStorage {
4
+ private readonly runner;
5
+ constructor(runner?: IProcessRunner);
6
+ getBackendType(): SecureStorageBackend;
7
+ set(key: string, value: Buffer): Promise<void>;
8
+ get(key: string): Promise<Buffer | null>;
9
+ delete(key: string): Promise<void>;
10
+ private isItemNotFound;
11
+ }
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MacOSSecureStorage = void 0;
4
+ const process_utils_1 = require("./process-utils");
5
+ const SERVICE_NAME = 'onekey-hw-cli';
6
+ class MacOSSecureStorage {
7
+ constructor(runner = process_utils_1.defaultProcessRunner) {
8
+ this.runner = runner;
9
+ }
10
+ getBackendType() {
11
+ return 'macos-keychain';
12
+ }
13
+ async set(key, value) {
14
+ const hex = value.toString('hex');
15
+ // Use `security -i` (interactive/batch mode): the tool parses commands
16
+ // from stdin internally instead of re-spawning a sub-process per command,
17
+ // so the password argument never appears in /proc or `ps aux` output.
18
+ //
19
+ // Keys are of the form `onekey-hw:<deviceId>/<slot>` and hex values only
20
+ // contain 0-9a-f, so neither contains shell metacharacters that would
21
+ // break the simple quoting security's parser expects.
22
+ const cmd = `add-generic-password -s "${SERVICE_NAME}" -a "${key}" -w "${hex}" -U`;
23
+ await this.runner.spawnWithStdin('security', ['-i'], cmd);
24
+ }
25
+ async get(key) {
26
+ try {
27
+ const { stdout } = await this.runner.execFileAsync('security', [
28
+ 'find-generic-password',
29
+ '-s',
30
+ SERVICE_NAME,
31
+ '-a',
32
+ key,
33
+ '-w',
34
+ ]);
35
+ const hex = stdout.trim();
36
+ return hex ? Buffer.from(hex, 'hex') : null;
37
+ }
38
+ catch (error) {
39
+ if (this.isItemNotFound(error))
40
+ return null;
41
+ throw error;
42
+ }
43
+ }
44
+ async delete(key) {
45
+ try {
46
+ await this.runner.execFileAsync('security', [
47
+ 'delete-generic-password',
48
+ '-s',
49
+ SERVICE_NAME,
50
+ '-a',
51
+ key,
52
+ ]);
53
+ }
54
+ catch (error) {
55
+ if (this.isItemNotFound(error))
56
+ return;
57
+ throw error;
58
+ }
59
+ }
60
+ isItemNotFound(error) {
61
+ const err = error;
62
+ return err.code === 44 || err.stderr?.includes('could not be found') === true;
63
+ }
64
+ }
65
+ exports.MacOSSecureStorage = MacOSSecureStorage;
@@ -0,0 +1,3 @@
1
+ /// <reference types="node" />
2
+ import type { ISecureStorage } from './types';
3
+ export declare function createSecureStorage(platform?: NodeJS.Platform): ISecureStorage;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createSecureStorage = void 0;
4
+ const secure_storage_linux_1 = require("./secure-storage.linux");
5
+ const secure_storage_macos_1 = require("./secure-storage.macos");
6
+ function createSecureStorage(platform = process.platform) {
7
+ if (platform === 'darwin')
8
+ return new secure_storage_macos_1.MacOSSecureStorage();
9
+ if (platform === 'linux')
10
+ return new secure_storage_linux_1.LinuxSecureStorage();
11
+ throw new Error(`Secure storage is not supported on platform "${platform}". ` +
12
+ 'Use macOS Keychain or Linux Secret Service.');
13
+ }
14
+ exports.createSecureStorage = createSecureStorage;
@@ -0,0 +1,18 @@
1
+ /// <reference types="node" />
2
+ export type SecureStorageBackend = 'macos-keychain' | 'linux-secret-service';
3
+ export interface ISecureStorage {
4
+ getBackendType(): SecureStorageBackend;
5
+ get(key: string): Promise<Buffer | null>;
6
+ set(key: string, value: Buffer): Promise<void>;
7
+ delete(key: string): Promise<void>;
8
+ }
9
+ export interface IProcessRunner {
10
+ execFileAsync(cmd: string, args: string[]): Promise<{
11
+ stdout: string;
12
+ stderr: string;
13
+ }>;
14
+ spawnWithStdin(cmd: string, args: string[], input: string): Promise<{
15
+ stdout: string;
16
+ stderr: string;
17
+ }>;
18
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@onekeyfe/hardware-cli",
3
- "version": "1.1.26-alpha.106",
4
- "description": "OneKey hardware wallet CLI for AI agent integration",
3
+ "version": "1.1.26-alpha.4",
4
+ "description": "OneKey hardware wallet CLI for testing device communication",
5
5
  "author": "OneKey",
6
6
  "license": "Apache-2.0",
7
7
  "homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
@@ -18,20 +18,22 @@
18
18
  "access": "public"
19
19
  },
20
20
  "scripts": {
21
- "dev": "rimraf dist && rollup -c rollup.config.js -w",
22
- "build": "rimraf dist && rollup -c rollup.config.js && node -e \"const f='dist/cli.js';const c=require('fs').readFileSync(f,'utf8');require('fs').writeFileSync(f,'#!/usr/bin/env node\\n'+c)\"",
21
+ "build": "tsc && node -e \"const f='dist/cli.js';const c=require('fs').readFileSync(f,'utf8');if(!c.startsWith('#!'))require('fs').writeFileSync(f,'#!/usr/bin/env node\\n'+c)\"",
22
+ "prestart": "tsc",
23
+ "start": "node dist/cli.js",
24
+ "search": "node dist/cli.js search",
25
+ "get-features": "node dist/cli.js get-features",
26
+ "get-address": "node dist/cli.js get-address",
27
+ "ping": "node dist/cli.js ping",
23
28
  "lint": "eslint .",
24
29
  "lint:fix": "eslint . --fix"
25
30
  },
26
31
  "dependencies": {
27
- "@onekeyfe/hd-common-connect-sdk": "1.1.26-alpha.106",
28
- "@onekeyfe/hd-core": "1.1.26-alpha.106",
29
- "@onekeyfe/hd-shared": "1.1.26-alpha.106",
30
- "@onekeyfe/hd-transport-usb": "1.1.26-alpha.106",
31
- "commander": "^12.0.0",
32
- "eventemitter2": "^6.4.9",
33
- "lodash": "^4.17.21",
34
- "tslib": "^2.6.0"
32
+ "@onekeyfe/hd-common-connect-sdk": "1.1.26-alpha.4",
33
+ "@onekeyfe/hd-core": "1.1.26-alpha.4",
34
+ "@onekeyfe/hd-shared": "1.1.26-alpha.4",
35
+ "@onekeyfe/hd-transport-usb": "1.1.26-alpha.4",
36
+ "commander": "^12.0.0"
35
37
  },
36
- "gitHead": "545b9e1a312bbdd6878ed347a9986603762a41dc"
38
+ "gitHead": "c03e3a11a9871dc22b711589ad4962399381c92e"
37
39
  }