@onekeyfe/hardware-cli 1.1.27-alpha.4 → 1.1.27-alpha.40
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.js +41 -5
- package/jest.config.js +1 -0
- package/package.json +6 -6
- package/src/cli.ts +58 -5
package/dist/cli.js
CHANGED
|
@@ -5,6 +5,30 @@ const commander_1 = require("commander");
|
|
|
5
5
|
const sdk_1 = require("./sdk");
|
|
6
6
|
const session_1 = require("./session");
|
|
7
7
|
const chains_1 = require("./chains");
|
|
8
|
+
function extractPassphraseSession(payload) {
|
|
9
|
+
if (typeof payload === 'string') {
|
|
10
|
+
return { passphraseState: payload };
|
|
11
|
+
}
|
|
12
|
+
if (!payload || typeof payload !== 'object') {
|
|
13
|
+
return {};
|
|
14
|
+
}
|
|
15
|
+
const statePayload = payload;
|
|
16
|
+
let passphraseState;
|
|
17
|
+
if (typeof statePayload.passphrase_state === 'string') {
|
|
18
|
+
passphraseState = statePayload.passphrase_state;
|
|
19
|
+
}
|
|
20
|
+
else if (typeof statePayload.passphraseState === 'string') {
|
|
21
|
+
passphraseState = statePayload.passphraseState;
|
|
22
|
+
}
|
|
23
|
+
let sessionId;
|
|
24
|
+
if (typeof statePayload.session_id === 'string') {
|
|
25
|
+
sessionId = statePayload.session_id;
|
|
26
|
+
}
|
|
27
|
+
else if (typeof statePayload.sessionId === 'string') {
|
|
28
|
+
sessionId = statePayload.sessionId;
|
|
29
|
+
}
|
|
30
|
+
return { passphraseState, sessionId };
|
|
31
|
+
}
|
|
8
32
|
const program = new commander_1.Command();
|
|
9
33
|
program
|
|
10
34
|
.name('onekey-hw')
|
|
@@ -537,7 +561,14 @@ sessionCmd
|
|
|
537
561
|
outputResult(globalOpts, psResult);
|
|
538
562
|
return;
|
|
539
563
|
}
|
|
540
|
-
const passphraseState = psResult.payload;
|
|
564
|
+
const { passphraseState, sessionId: passphraseSessionId } = extractPassphraseSession(psResult.payload);
|
|
565
|
+
if (!passphraseState) {
|
|
566
|
+
outputResult(globalOpts, {
|
|
567
|
+
success: false,
|
|
568
|
+
payload: { error: 'getPassphraseState did not return passphraseState' },
|
|
569
|
+
});
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
541
572
|
// 4. Get address to verify + extract deviceId
|
|
542
573
|
const addrResult = await sdk.evmGetAddress(connectId, device.deviceId || '', {
|
|
543
574
|
path: "m/44'/60'/0'/0/0",
|
|
@@ -560,7 +591,7 @@ sessionCmd
|
|
|
560
591
|
});
|
|
561
592
|
const featPayload = featResult?.success ? featResult.payload : undefined;
|
|
562
593
|
const deviceId = featPayload?.device_id || device.deviceId || '';
|
|
563
|
-
const sessionId = featPayload?.session_id || '';
|
|
594
|
+
const sessionId = passphraseSessionId || featPayload?.session_id || '';
|
|
564
595
|
// 6. Save to keychain
|
|
565
596
|
if (passphraseState && deviceId && sessionId) {
|
|
566
597
|
await (0, session_1.saveSessionToKeychain)(deviceId, passphraseState, sessionId);
|
|
@@ -691,6 +722,7 @@ globalOpts) {
|
|
|
691
722
|
// getFeatures failures here are non-fatal — we fall through to Step 3
|
|
692
723
|
// which will fail with a clearer error if the device is truly unreachable.
|
|
693
724
|
let deviceId = device.features?.device_id || device.deviceId || '';
|
|
725
|
+
let deviceType = device.features?.onekey_device_type;
|
|
694
726
|
let unlocked = device.features?.unlocked;
|
|
695
727
|
let passphraseProtection = device.features?.passphrase_protection;
|
|
696
728
|
if (!deviceId || unlocked == null || passphraseProtection == null) {
|
|
@@ -698,6 +730,7 @@ globalOpts) {
|
|
|
698
730
|
const featResult = await sdk.getFeatures(connectId);
|
|
699
731
|
if (featResult?.success && featResult.payload) {
|
|
700
732
|
deviceId = featResult.payload.device_id || deviceId;
|
|
733
|
+
deviceType = featResult.payload.onekey_device_type || deviceType;
|
|
701
734
|
unlocked = featResult.payload.unlocked;
|
|
702
735
|
passphraseProtection = featResult.payload.passphrase_protection;
|
|
703
736
|
}
|
|
@@ -723,7 +756,7 @@ globalOpts) {
|
|
|
723
756
|
globalOpts.deviceId = deviceId;
|
|
724
757
|
}
|
|
725
758
|
// ── Step 4: Check passphrase protection ──────────────────────────
|
|
726
|
-
if (passphraseProtection === false) {
|
|
759
|
+
if (passphraseProtection === false && deviceType !== 'pro2' && deviceType !== 'PRO2') {
|
|
727
760
|
return undefined;
|
|
728
761
|
}
|
|
729
762
|
// ── Step 5: Try keychain session reuse ───────────────────────────
|
|
@@ -742,7 +775,10 @@ globalOpts) {
|
|
|
742
775
|
useEmptyPassphrase: false,
|
|
743
776
|
});
|
|
744
777
|
if (psResult.success && psResult.payload) {
|
|
745
|
-
const passphraseState = psResult.payload;
|
|
778
|
+
const { passphraseState, sessionId: passphraseSessionId } = extractPassphraseSession(psResult.payload);
|
|
779
|
+
if (!passphraseState) {
|
|
780
|
+
return undefined;
|
|
781
|
+
}
|
|
746
782
|
globalOpts.passphraseState = passphraseState;
|
|
747
783
|
// Save session to keychain for next invocation.
|
|
748
784
|
//
|
|
@@ -755,7 +791,7 @@ globalOpts) {
|
|
|
755
791
|
passphraseState,
|
|
756
792
|
skipPassphraseCheck: true,
|
|
757
793
|
});
|
|
758
|
-
const sessionId = featAfter?.success ? featAfter.payload?.session_id : undefined;
|
|
794
|
+
const sessionId = passphraseSessionId || (featAfter?.success ? featAfter.payload?.session_id : undefined);
|
|
759
795
|
if (sessionId) {
|
|
760
796
|
await (0, session_1.saveSessionToKeychain)(deviceId, passphraseState, sessionId);
|
|
761
797
|
await (0, session_1.preloadSessionFromKeychain)(deviceId);
|
package/jest.config.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hardware-cli",
|
|
3
|
-
"version": "1.1.27-alpha.
|
|
3
|
+
"version": "1.1.27-alpha.40",
|
|
4
4
|
"description": "OneKey hardware wallet CLI for testing device communication",
|
|
5
5
|
"author": "OneKey",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -30,11 +30,11 @@
|
|
|
30
30
|
"test": "jest"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@onekeyfe/hd-common-connect-sdk": "1.1.27-alpha.
|
|
34
|
-
"@onekeyfe/hd-core": "1.1.27-alpha.
|
|
35
|
-
"@onekeyfe/hd-shared": "1.1.27-alpha.
|
|
36
|
-
"@onekeyfe/hd-transport-usb": "1.1.27-alpha.
|
|
33
|
+
"@onekeyfe/hd-common-connect-sdk": "1.1.27-alpha.40",
|
|
34
|
+
"@onekeyfe/hd-core": "1.1.27-alpha.40",
|
|
35
|
+
"@onekeyfe/hd-shared": "1.1.27-alpha.40",
|
|
36
|
+
"@onekeyfe/hd-transport-usb": "1.1.27-alpha.40",
|
|
37
37
|
"commander": "^12.0.0"
|
|
38
38
|
},
|
|
39
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "484f6253dd8c776fc4037f5da171c8f2226baea6"
|
|
40
40
|
}
|
package/src/cli.ts
CHANGED
|
@@ -25,6 +25,41 @@ import type {
|
|
|
25
25
|
/** SearchDevice enriched with features fetched after discovery */
|
|
26
26
|
type EnrichedSearchDevice = SearchDevice & { features?: Features };
|
|
27
27
|
|
|
28
|
+
function extractPassphraseSession(payload: unknown): {
|
|
29
|
+
passphraseState?: string;
|
|
30
|
+
sessionId?: string;
|
|
31
|
+
} {
|
|
32
|
+
if (typeof payload === 'string') {
|
|
33
|
+
return { passphraseState: payload };
|
|
34
|
+
}
|
|
35
|
+
if (!payload || typeof payload !== 'object') {
|
|
36
|
+
return {};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const statePayload = payload as {
|
|
40
|
+
passphrase_state?: unknown;
|
|
41
|
+
passphraseState?: unknown;
|
|
42
|
+
session_id?: unknown;
|
|
43
|
+
sessionId?: unknown;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
let passphraseState: string | undefined;
|
|
47
|
+
if (typeof statePayload.passphrase_state === 'string') {
|
|
48
|
+
passphraseState = statePayload.passphrase_state;
|
|
49
|
+
} else if (typeof statePayload.passphraseState === 'string') {
|
|
50
|
+
passphraseState = statePayload.passphraseState;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
let sessionId: string | undefined;
|
|
54
|
+
if (typeof statePayload.session_id === 'string') {
|
|
55
|
+
sessionId = statePayload.session_id;
|
|
56
|
+
} else if (typeof statePayload.sessionId === 'string') {
|
|
57
|
+
sessionId = statePayload.sessionId;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return { passphraseState, sessionId };
|
|
61
|
+
}
|
|
62
|
+
|
|
28
63
|
const program = new Command();
|
|
29
64
|
|
|
30
65
|
program
|
|
@@ -687,7 +722,16 @@ sessionCmd
|
|
|
687
722
|
outputResult(globalOpts, psResult);
|
|
688
723
|
return;
|
|
689
724
|
}
|
|
690
|
-
const passphraseState =
|
|
725
|
+
const { passphraseState, sessionId: passphraseSessionId } = extractPassphraseSession(
|
|
726
|
+
psResult.payload
|
|
727
|
+
);
|
|
728
|
+
if (!passphraseState) {
|
|
729
|
+
outputResult(globalOpts, {
|
|
730
|
+
success: false,
|
|
731
|
+
payload: { error: 'getPassphraseState did not return passphraseState' },
|
|
732
|
+
});
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
691
735
|
|
|
692
736
|
// 4. Get address to verify + extract deviceId
|
|
693
737
|
const addrResult = await sdk.evmGetAddress(connectId, device.deviceId || '', {
|
|
@@ -712,7 +756,7 @@ sessionCmd
|
|
|
712
756
|
});
|
|
713
757
|
const featPayload = featResult?.success ? featResult.payload : undefined;
|
|
714
758
|
const deviceId = featPayload?.device_id || device.deviceId || '';
|
|
715
|
-
const sessionId = featPayload?.session_id || '';
|
|
759
|
+
const sessionId = passphraseSessionId || featPayload?.session_id || '';
|
|
716
760
|
|
|
717
761
|
// 6. Save to keychain
|
|
718
762
|
if (passphraseState && deviceId && sessionId) {
|
|
@@ -869,6 +913,7 @@ async function prepareSession(
|
|
|
869
913
|
deviceId?: string;
|
|
870
914
|
features?: {
|
|
871
915
|
device_id?: string;
|
|
916
|
+
onekey_device_type?: string;
|
|
872
917
|
session_id?: string;
|
|
873
918
|
passphrase_protection?: boolean | null;
|
|
874
919
|
unlocked?: boolean | null;
|
|
@@ -883,6 +928,7 @@ async function prepareSession(
|
|
|
883
928
|
// getFeatures failures here are non-fatal — we fall through to Step 3
|
|
884
929
|
// which will fail with a clearer error if the device is truly unreachable.
|
|
885
930
|
let deviceId = device.features?.device_id || device.deviceId || '';
|
|
931
|
+
let deviceType = device.features?.onekey_device_type;
|
|
886
932
|
let unlocked = device.features?.unlocked;
|
|
887
933
|
let passphraseProtection = device.features?.passphrase_protection;
|
|
888
934
|
|
|
@@ -891,6 +937,7 @@ async function prepareSession(
|
|
|
891
937
|
const featResult = await sdk.getFeatures(connectId);
|
|
892
938
|
if (featResult?.success && featResult.payload) {
|
|
893
939
|
deviceId = featResult.payload.device_id || deviceId;
|
|
940
|
+
deviceType = featResult.payload.onekey_device_type || deviceType;
|
|
894
941
|
unlocked = featResult.payload.unlocked;
|
|
895
942
|
passphraseProtection = featResult.payload.passphrase_protection;
|
|
896
943
|
}
|
|
@@ -918,7 +965,7 @@ async function prepareSession(
|
|
|
918
965
|
}
|
|
919
966
|
|
|
920
967
|
// ── Step 4: Check passphrase protection ──────────────────────────
|
|
921
|
-
if (passphraseProtection === false) {
|
|
968
|
+
if (passphraseProtection === false && deviceType !== 'pro2' && deviceType !== 'PRO2') {
|
|
922
969
|
return undefined;
|
|
923
970
|
}
|
|
924
971
|
|
|
@@ -940,7 +987,12 @@ async function prepareSession(
|
|
|
940
987
|
});
|
|
941
988
|
|
|
942
989
|
if (psResult.success && psResult.payload) {
|
|
943
|
-
const passphraseState =
|
|
990
|
+
const { passphraseState, sessionId: passphraseSessionId } = extractPassphraseSession(
|
|
991
|
+
psResult.payload
|
|
992
|
+
);
|
|
993
|
+
if (!passphraseState) {
|
|
994
|
+
return undefined;
|
|
995
|
+
}
|
|
944
996
|
globalOpts.passphraseState = passphraseState;
|
|
945
997
|
|
|
946
998
|
// Save session to keychain for next invocation.
|
|
@@ -954,7 +1006,8 @@ async function prepareSession(
|
|
|
954
1006
|
passphraseState,
|
|
955
1007
|
skipPassphraseCheck: true,
|
|
956
1008
|
});
|
|
957
|
-
const sessionId =
|
|
1009
|
+
const sessionId =
|
|
1010
|
+
passphraseSessionId || (featAfter?.success ? featAfter.payload?.session_id : undefined);
|
|
958
1011
|
if (sessionId) {
|
|
959
1012
|
await saveSessionToKeychain(deviceId, passphraseState, sessionId);
|
|
960
1013
|
await preloadSessionFromKeychain(deviceId);
|