@onekeyfe/hd-shared 1.2.0-alpha.15 → 1.2.0-alpha.150
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/HardwareError.d.ts +4 -1
- package/dist/HardwareError.d.ts.map +1 -1
- package/dist/constants.d.ts +27 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/deviceType.d.ts +2 -1
- package/dist/deviceType.d.ts.map +1 -1
- package/dist/index.d.ts +295 -3
- package/dist/index.js +131 -2
- package/jest.config.js +5 -0
- package/package.json +3 -2
- package/src/HardwareError.test.ts +36 -0
- package/src/HardwareError.ts +19 -1
- package/src/constants.test.ts +155 -1
- package/src/constants.ts +173 -5
- package/src/deviceType.ts +1 -0
package/dist/HardwareError.d.ts
CHANGED
|
@@ -86,6 +86,7 @@ export declare const HardwareErrorCode: {
|
|
|
86
86
|
readonly BleDeviceDisconnected: 720;
|
|
87
87
|
readonly BlePoweredOff: 721;
|
|
88
88
|
readonly BleUnsupported: 722;
|
|
89
|
+
readonly BleUnavailableWhileUsbConnected: 723;
|
|
89
90
|
readonly RuntimeError: 800;
|
|
90
91
|
readonly PinInvalid: 801;
|
|
91
92
|
readonly PinCancelled: 802;
|
|
@@ -115,7 +116,9 @@ export declare const HardwareErrorCode: {
|
|
|
115
116
|
readonly DeviceSettingsLanguageNotSupport: 826;
|
|
116
117
|
readonly TooManyInputs: 827;
|
|
117
118
|
readonly PinMismatch: 828;
|
|
118
|
-
readonly DeviceLocked:
|
|
119
|
+
readonly DeviceLocked: 830;
|
|
120
|
+
readonly WalletSessionInvalid: 831;
|
|
121
|
+
readonly NftStorageLimitReached: 832;
|
|
119
122
|
readonly LowlevelTrasnportConnectError: 900;
|
|
120
123
|
readonly WebDeviceNotFoundOrNeedsPermission: 901;
|
|
121
124
|
readonly WebDevicePromptAccessError: 902;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HardwareError.d.ts","sourceRoot":"","sources":["../src/HardwareError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,OAAO,CAAC,OAAO,iBAAiB,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,GAAG,CAAC;CACd;AAED,KAAK,OAAO,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAE5C,KAAK,+BAA+B,GAAG;KAAG,CAAC,IAAI,OAAO,CAAC,OAAO,iBAAiB,CAAC,GAAG,MAAM;CAAE,CAAC;AAE5F,KAAK,cAAc,GAAG,OAAO,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAsCxD,qBAAa,aAAc,SAAQ,KAAK;IACtC,SAAS,EAAE,cAAc,CAAkC;IAE3D,OAAO,SAAM;IAEb,MAAM,EAAE,GAAG,CAAM;gBAEL,aAAa,EAAE,cAAc,GAAG,MAAM;CAmBnD;AAED,eAAO,MAAM,iBAAiB
|
|
1
|
+
{"version":3,"file":"HardwareError.d.ts","sourceRoot":"","sources":["../src/HardwareError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,OAAO,CAAC,OAAO,iBAAiB,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,GAAG,CAAC;CACd;AAED,KAAK,OAAO,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAE5C,KAAK,+BAA+B,GAAG;KAAG,CAAC,IAAI,OAAO,CAAC,OAAO,iBAAiB,CAAC,GAAG,MAAM;CAAE,CAAC;AAE5F,KAAK,cAAc,GAAG,OAAO,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAsCxD,qBAAa,aAAc,SAAQ,KAAK;IACtC,SAAS,EAAE,cAAc,CAAkC;IAE3D,OAAO,SAAM;IAEb,MAAM,EAAE,GAAG,CAAM;gBAEL,aAAa,EAAE,cAAc,GAAG,MAAM;CAmBnD;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAybpB,CAAC;AAEX,eAAO,MAAM,wBAAwB,EAAE,+BAsJ7B,CAAC;AAEX,eAAO,MAAM,UAAU,kBACN,cAAc,GAAG,MAAM,YAC5B,MAAM,WACP,GAAG,kBAMb,CAAC;AAEF,eAAO,MAAM,cAAc,YAAa,GAAG,QAe1C,CAAC;AAEF,eAAO,MAAM,oBAAoB,YAAa,MAAM,KAAG,aAOtD,CAAC;AAGF,eAAO,MAAM,gCAAgC,QAAS,MAAM,KAAG,aAQ9D,CAAC;AAEF,QAAA,MAAM,uCAAuC;oBAM3B,MAAM;oBACN,MAAM;;;mBAcvB,CAAC;AAEF,QAAA,MAAM,sCAAsC;oBAM1B,MAAM;oBACN,MAAM;;;mBAcvB,CAAC;AAEF,QAAA,MAAM,yCAAyC,cAClC,MAAM,GAAG,SAAS,YACnB,MAAM,GAAG,SAAS,iBACb,CAAC,UAAU,GAAG,KAAK,CAAC,EAAE,oBACnB;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,kBAsBF,CAAC;AAEF,QAAA,MAAM,6BAA6B,mBACjB,MAAM,qBACH,MAAM,eACZ,MAAM,kBAQpB,CAAC;AAEF,QAAA,MAAM,4BAA4B,aACtB,MAAM,aACL,MAAM,cACL,MAAM,cACN,MAAM,aACP,MAAM,kBAWlB,CAAC;AAEF,QAAA,MAAM,iCAAiC,eAAgB,MAAM,gBAAgB,aAAa,kBAItF,CAAC;AAEL,OAAO,EACL,uCAAuC,EACvC,sCAAsC,EACtC,yCAAyC,EACzC,6BAA6B,EAC7B,4BAA4B,EAC5B,iCAAiC,GAClC,CAAC"}
|
package/dist/constants.d.ts
CHANGED
|
@@ -8,6 +8,10 @@ export declare const ONEKEY_WEBUSB_FILTER: {
|
|
|
8
8
|
vendorId: number;
|
|
9
9
|
productId: number;
|
|
10
10
|
}[];
|
|
11
|
+
export declare const ONEKEY_PROTOCOL_V2_USB_IDS: readonly [{
|
|
12
|
+
readonly vendorId: 4617;
|
|
13
|
+
readonly productId: 20300;
|
|
14
|
+
}];
|
|
11
15
|
type WebUsbIdentityDescriptor = {
|
|
12
16
|
vendorId?: number;
|
|
13
17
|
productId?: number;
|
|
@@ -33,11 +37,13 @@ export declare enum EOneKeyBleMessageKeys {
|
|
|
33
37
|
NOBLE_BLE_STOP_SCAN = "$onekey-noble-ble-stop-scan",
|
|
34
38
|
NOBLE_BLE_GET_DEVICE = "$onekey-noble-ble-get-device",
|
|
35
39
|
NOBLE_BLE_CONNECT = "$onekey-noble-ble-connect",
|
|
40
|
+
NOBLE_BLE_RELEASE = "$onekey-noble-ble-release",
|
|
36
41
|
NOBLE_BLE_DISCONNECT = "$onekey-noble-ble-disconnect",
|
|
37
42
|
NOBLE_BLE_WRITE = "$onekey-noble-ble-write",
|
|
38
43
|
NOBLE_BLE_SUBSCRIBE = "$onekey-noble-ble-subscribe",
|
|
39
44
|
NOBLE_BLE_UNSUBSCRIBE = "$onekey-noble-ble-unsubscribe",
|
|
40
45
|
NOBLE_BLE_NOTIFICATION = "$onekey-noble-ble-notification",
|
|
46
|
+
NOBLE_BLE_MTU_CHANGED = "$onekey-noble-ble-mtu-changed",
|
|
41
47
|
NOBLE_BLE_CANCEL_PAIRING = "$onekey-noble-ble-cancel-pairing"
|
|
42
48
|
}
|
|
43
49
|
export declare const ONEKEY_SERVICE_UUID = "00000001-0000-1000-8000-00805f9b34fb";
|
|
@@ -45,5 +51,26 @@ export declare const ONEKEY_WRITE_CHARACTERISTIC_UUID = "00000002-0000-1000-8000
|
|
|
45
51
|
export declare const ONEKEY_NOTIFY_CHARACTERISTIC_UUID = "00000003-0000-1000-8000-00805f9b34fb";
|
|
46
52
|
export declare const isHeaderChunk: (chunk: Buffer | Uint8Array) => boolean;
|
|
47
53
|
export declare const isOnekeyDevice: (name: string | null, id?: string) => boolean;
|
|
54
|
+
export declare const inferProtocolHintFromUsbId: (vendorId?: number | null, productId?: number | null) => "V2" | undefined;
|
|
55
|
+
type UsbDevicePathInput = {
|
|
56
|
+
serialNumber?: string | null;
|
|
57
|
+
vendorId?: number;
|
|
58
|
+
productId?: number;
|
|
59
|
+
productName?: string | null;
|
|
60
|
+
};
|
|
61
|
+
export declare const resolveOneKeyUsbDevicePath: (device: UsbDevicePathInput) => string | undefined;
|
|
62
|
+
type BluetoothDeviceIdentity = {
|
|
63
|
+
id?: string;
|
|
64
|
+
name?: string | null;
|
|
65
|
+
localName?: string | null;
|
|
66
|
+
serviceUuids?: Array<string | null | undefined> | null;
|
|
67
|
+
};
|
|
68
|
+
export declare const normalizeBleUuid: (uuid?: string | null) => string;
|
|
69
|
+
export declare const createKnownBleUuidAliases: (uuid: string) => ReadonlySet<string>;
|
|
70
|
+
export declare const matchesKnownBleUuid: (actualUuid: string | null | undefined, aliases: ReadonlySet<string>) => boolean;
|
|
71
|
+
export declare const isPro2FindMyAdvertisementName: (value?: string | null) => boolean;
|
|
72
|
+
export declare const normalizePro2FindMyAdvertisementName: (value: string) => string;
|
|
73
|
+
export declare const hasOnekeyCommunicationService: (serviceUuids: Array<string | null | undefined> | null | undefined) => boolean;
|
|
74
|
+
export declare const isOnekeyBluetoothDevice: ({ id, name, localName, serviceUuids, }: BluetoothDeviceIdentity) => boolean;
|
|
48
75
|
export {};
|
|
49
76
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";AAEA,eAAO,MAAM,yBAAyB;;;CAG5B,CAAC;AAEX,MAAM,MAAM,uBAAuB,GACjC,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,OAAO,yBAAyB,CAAC,CAAC;AAE7E,eAAO,MAAM,oBAAoB;;;GAOhC,CAAC;
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";AAEA,eAAO,MAAM,yBAAyB;;;CAG5B,CAAC;AAEX,MAAM,MAAM,uBAAuB,GACjC,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,OAAO,yBAAyB,CAAC,CAAC;AAE7E,eAAO,MAAM,oBAAoB;;;GAOhC,CAAC;AAGF,eAAO,MAAM,0BAA0B;;;EAAqD,CAAC;AAE7F,KAAK,wBAAwB,GAAG;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC,CAAC;AAIF,eAAO,MAAM,yBAAyB,eAAgB,wBAAwB,KAAG,OAQhF,CAAC;AAMF,eAAO,MAAM,2BAA2B,mDAS9B,CAAC;AAMX,eAAO,MAAM,8BAA8B,qBAGjC,CAAC;AAGX,oBAAY,qBAAqB;IAE/B,UAAU,uBAAuB;IACjC,iBAAiB,8BAA8B;IAC/C,aAAa,0BAA0B;IACvC,kBAAkB,+BAA+B;IACjD,cAAc,2BAA2B;IACzC,oBAAoB,iCAAiC;IAGrD,mBAAmB,gCAAgC;IACnD,oBAAoB,iCAAiC;IAGrD,aAAa,0BAA0B;IACvC,oBAAoB,iCAAiC;IAGrD,uBAAuB,oCAAoC;IAC3D,sBAAsB,mCAAmC;IAGzD,mBAAmB,gCAAgC;IACnD,mBAAmB,gCAAgC;IACnD,oBAAoB,iCAAiC;IACrD,iBAAiB,8BAA8B;IAG/C,iBAAiB,8BAA8B;IAC/C,oBAAoB,iCAAiC;IACrD,eAAe,4BAA4B;IAC3C,mBAAmB,gCAAgC;IACnD,qBAAqB,kCAAkC;IACvD,sBAAsB,mCAAmC;IACzD,qBAAqB,kCAAkC;IACvD,wBAAwB,qCAAqC;CAC9D;AAED,eAAO,MAAM,mBAAmB,yCAAyC,CAAC;AAC1E,eAAO,MAAM,gCAAgC,yCAAyC,CAAC;AACvF,eAAO,MAAM,iCAAiC,yCAAyC,CAAC;AAIxF,eAAO,MAAM,aAAa,UAAW,MAAM,GAAG,UAAU,KAAG,OAa1D,CAAC;AAkBF,eAAO,MAAM,cAAc,SAAU,MAAM,GAAG,IAAI,OAAO,MAAM,KAAG,OA2BjE,CAAC;AAEF,eAAO,MAAM,0BAA0B,cAAe,MAAM,GAAG,IAAI,cAAc,MAAM,GAAG,IAAI,qBAG/E,CAAC;AAEhB,KAAK,kBAAkB,GAAG;IACxB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,CAAC;AAEF,eAAO,MAAM,0BAA0B,WAAY,kBAAkB,KAAG,MAAM,GAAG,SAehF,CAAC;AAEF,KAAK,uBAAuB,GAAG;IAC7B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC;CACxD,CAAC;AAIF,eAAO,MAAM,gBAAgB,UAAW,MAAM,GAAG,IAAI,WACP,CAAC;AAE/C,eAAO,MAAM,yBAAyB,SAAU,MAAM,KAAG,YAAY,MAAM,CAc1E,CAAC;AAEF,eAAO,MAAM,mBAAmB,eAClB,MAAM,GAAG,IAAI,GAAG,SAAS,WAC5B,YAAY,MAAM,CAAC,YACgB,CAAC;AAmC/C,eAAO,MAAM,6BAA6B,WAAY,MAAM,GAAG,IAAI,YAWlE,CAAC;AAEF,eAAO,MAAM,oCAAoC,UAAW,MAAM,WAejE,CAAC;AAEF,eAAO,MAAM,6BAA6B,iBAC1B,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,IAAI,GAAG,SAAS,YAIhE,CAAC;AAEJ,eAAO,MAAM,uBAAuB,2CAKjC,uBAAuB,KAAG,OAiB5B,CAAC"}
|
package/dist/deviceType.d.ts
CHANGED
package/dist/deviceType.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deviceType.d.ts","sourceRoot":"","sources":["../src/deviceType.ts"],"names":[],"mappings":"AAAA,oBAAY,WAAW;IACrB,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,SAAS,cAAc;IACvB,WAAW,gBAAgB;IAC3B,IAAI,SAAS;IACb,KAAK,UAAU;IACf,GAAG,QAAQ;IACX,IAAI,SAAS;
|
|
1
|
+
{"version":3,"file":"deviceType.d.ts","sourceRoot":"","sources":["../src/deviceType.ts"],"names":[],"mappings":"AAAA,oBAAY,WAAW;IACrB,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,SAAS,cAAc;IACvB,WAAW,gBAAgB;IAC3B,IAAI,SAAS;IACb,KAAK,UAAU;IACf,GAAG,QAAQ;IACX,IAAI,SAAS;IACb,GAAG,QAAQ;CACZ"}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,13 +7,26 @@ declare const ONEKEY_WEBUSB_FILTER: {
|
|
|
7
7
|
vendorId: number;
|
|
8
8
|
productId: number;
|
|
9
9
|
}[];
|
|
10
|
+
/** USB IDs whose first probe should be Protocol V2. Shared Pro/Touch PIDs stay unhinted. */
|
|
11
|
+
declare const ONEKEY_PROTOCOL_V2_USB_IDS: readonly [{
|
|
12
|
+
readonly vendorId: 4617;
|
|
13
|
+
readonly productId: 20300;
|
|
14
|
+
}];
|
|
10
15
|
type WebUsbIdentityDescriptor = {
|
|
11
16
|
vendorId?: number;
|
|
12
17
|
productId?: number;
|
|
13
18
|
manufacturerName?: string | null;
|
|
14
19
|
};
|
|
15
20
|
declare const isKnownTrezorWebUsbDevice: (descriptor: WebUsbIdentityDescriptor) => boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Error codes that require device release after occurrence
|
|
23
|
+
* These errors indicate the device is in an invalid state and needs to be released
|
|
24
|
+
*/
|
|
16
25
|
declare const ERROR_CODES_REQUIRE_RELEASE: readonly [106, 107, 109, 112, 805, 801, 802, 812];
|
|
26
|
+
/**
|
|
27
|
+
* Error codes that require device disconnect before release
|
|
28
|
+
* These errors indicate a communication failure that requires full reconnection
|
|
29
|
+
*/
|
|
17
30
|
declare const ERROR_CODES_REQUIRE_DISCONNECT: readonly [106, 805];
|
|
18
31
|
declare enum EOneKeyBleMessageKeys {
|
|
19
32
|
BLE_SELECT = "$onekey-ble-select",
|
|
@@ -32,11 +45,13 @@ declare enum EOneKeyBleMessageKeys {
|
|
|
32
45
|
NOBLE_BLE_STOP_SCAN = "$onekey-noble-ble-stop-scan",
|
|
33
46
|
NOBLE_BLE_GET_DEVICE = "$onekey-noble-ble-get-device",
|
|
34
47
|
NOBLE_BLE_CONNECT = "$onekey-noble-ble-connect",
|
|
48
|
+
NOBLE_BLE_RELEASE = "$onekey-noble-ble-release",
|
|
35
49
|
NOBLE_BLE_DISCONNECT = "$onekey-noble-ble-disconnect",
|
|
36
50
|
NOBLE_BLE_WRITE = "$onekey-noble-ble-write",
|
|
37
51
|
NOBLE_BLE_SUBSCRIBE = "$onekey-noble-ble-subscribe",
|
|
38
52
|
NOBLE_BLE_UNSUBSCRIBE = "$onekey-noble-ble-unsubscribe",
|
|
39
53
|
NOBLE_BLE_NOTIFICATION = "$onekey-noble-ble-notification",
|
|
54
|
+
NOBLE_BLE_MTU_CHANGED = "$onekey-noble-ble-mtu-changed",
|
|
40
55
|
NOBLE_BLE_CANCEL_PAIRING = "$onekey-noble-ble-cancel-pairing"
|
|
41
56
|
}
|
|
42
57
|
declare const ONEKEY_SERVICE_UUID = "00000001-0000-1000-8000-00805f9b34fb";
|
|
@@ -44,6 +59,27 @@ declare const ONEKEY_WRITE_CHARACTERISTIC_UUID = "00000002-0000-1000-8000-00805f
|
|
|
44
59
|
declare const ONEKEY_NOTIFY_CHARACTERISTIC_UUID = "00000003-0000-1000-8000-00805f9b34fb";
|
|
45
60
|
declare const isHeaderChunk: (chunk: Buffer | Uint8Array) => boolean;
|
|
46
61
|
declare const isOnekeyDevice: (name: string | null, id?: string) => boolean;
|
|
62
|
+
declare const inferProtocolHintFromUsbId: (vendorId?: number | null, productId?: number | null) => "V2" | undefined;
|
|
63
|
+
type UsbDevicePathInput = {
|
|
64
|
+
serialNumber?: string | null;
|
|
65
|
+
vendorId?: number;
|
|
66
|
+
productId?: number;
|
|
67
|
+
productName?: string | null;
|
|
68
|
+
};
|
|
69
|
+
declare const resolveOneKeyUsbDevicePath: (device: UsbDevicePathInput) => string | undefined;
|
|
70
|
+
type BluetoothDeviceIdentity = {
|
|
71
|
+
id?: string;
|
|
72
|
+
name?: string | null;
|
|
73
|
+
localName?: string | null;
|
|
74
|
+
serviceUuids?: Array<string | null | undefined> | null;
|
|
75
|
+
};
|
|
76
|
+
declare const normalizeBleUuid: (uuid?: string | null) => string;
|
|
77
|
+
declare const createKnownBleUuidAliases: (uuid: string) => ReadonlySet<string>;
|
|
78
|
+
declare const matchesKnownBleUuid: (actualUuid: string | null | undefined, aliases: ReadonlySet<string>) => boolean;
|
|
79
|
+
declare const isPro2FindMyAdvertisementName: (value?: string | null) => boolean;
|
|
80
|
+
declare const normalizePro2FindMyAdvertisementName: (value: string) => string;
|
|
81
|
+
declare const hasOnekeyCommunicationService: (serviceUuids: Array<string | null | undefined> | null | undefined) => boolean;
|
|
82
|
+
declare const isOnekeyBluetoothDevice: ({ id, name, localName, serviceUuids, }: BluetoothDeviceIdentity) => boolean;
|
|
47
83
|
|
|
48
84
|
type Deferred<T, I = any, D = any> = {
|
|
49
85
|
id?: I;
|
|
@@ -76,53 +112,201 @@ declare class HardwareError extends Error {
|
|
|
76
112
|
constructor(hardwareError: IHardwareError | string);
|
|
77
113
|
}
|
|
78
114
|
declare const HardwareErrorCode: {
|
|
115
|
+
/**
|
|
116
|
+
* This error can be thrown when unexpected error occurred and in most cases it is related to implementation bug.
|
|
117
|
+
* Original message is available in message property.
|
|
118
|
+
*/
|
|
79
119
|
readonly UnknownError: 0;
|
|
120
|
+
/**
|
|
121
|
+
* Firmware version mismatch
|
|
122
|
+
*/
|
|
80
123
|
readonly DeviceFwException: 101;
|
|
124
|
+
/**
|
|
125
|
+
* Device unexpected mode
|
|
126
|
+
*/
|
|
81
127
|
readonly DeviceUnexpectedMode: 102;
|
|
128
|
+
/**
|
|
129
|
+
* Device list is not initialized
|
|
130
|
+
*/
|
|
82
131
|
readonly DeviceListNotInitialized: 103;
|
|
132
|
+
/**
|
|
133
|
+
* Please select the connected device
|
|
134
|
+
*/
|
|
83
135
|
readonly SelectDevice: 104;
|
|
136
|
+
/**
|
|
137
|
+
* Device not found
|
|
138
|
+
*/
|
|
84
139
|
readonly DeviceNotFound: 105;
|
|
140
|
+
/**
|
|
141
|
+
* Device is not initialized
|
|
142
|
+
*/
|
|
85
143
|
readonly DeviceInitializeFailed: 106;
|
|
144
|
+
/**
|
|
145
|
+
* Device interrupted from another operation
|
|
146
|
+
*/
|
|
86
147
|
readonly DeviceInterruptedFromOutside: 107;
|
|
148
|
+
/**
|
|
149
|
+
* Device should be in bootloader mode
|
|
150
|
+
*/
|
|
87
151
|
readonly RequiredButInBootloaderMode: 108;
|
|
152
|
+
/**
|
|
153
|
+
* Device interrupted from user
|
|
154
|
+
*/
|
|
88
155
|
readonly DeviceInterruptedFromUser: 109;
|
|
156
|
+
/**
|
|
157
|
+
* Check device id is same
|
|
158
|
+
*/
|
|
89
159
|
readonly DeviceCheckDeviceIdError: 110;
|
|
160
|
+
/**
|
|
161
|
+
* Do not support passphrase
|
|
162
|
+
* @params: { require: string }
|
|
163
|
+
*/
|
|
90
164
|
readonly DeviceNotSupportPassphrase: 111;
|
|
91
165
|
readonly DeviceCheckPassphraseStateError: 112;
|
|
166
|
+
/**
|
|
167
|
+
* use passphrase, but passphrase is not opened
|
|
168
|
+
*/
|
|
92
169
|
readonly DeviceNotOpenedPassphrase: 113;
|
|
170
|
+
/**
|
|
171
|
+
* not use passphrase, but passphrase is opened
|
|
172
|
+
*/
|
|
93
173
|
readonly DeviceOpenedPassphrase: 114;
|
|
174
|
+
/**
|
|
175
|
+
* Detect hardware that is in bootloader mode and return an error.
|
|
176
|
+
*/
|
|
94
177
|
readonly DeviceDetectInBootloaderMode: 115;
|
|
178
|
+
/**
|
|
179
|
+
* Device not allow in bootloader mode
|
|
180
|
+
*/
|
|
95
181
|
readonly NotAllowInBootloaderMode: 116;
|
|
182
|
+
/**
|
|
183
|
+
* Device is busy
|
|
184
|
+
*/
|
|
96
185
|
readonly DeviceBusy: 117;
|
|
186
|
+
/**
|
|
187
|
+
* Device check unlock type not match error
|
|
188
|
+
*/
|
|
97
189
|
readonly DeviceCheckUnlockTypeError: 118;
|
|
190
|
+
/**
|
|
191
|
+
* Not initialized
|
|
192
|
+
*/
|
|
98
193
|
readonly NotInitialized: 200;
|
|
194
|
+
/**
|
|
195
|
+
* Iframe not initialized
|
|
196
|
+
*/
|
|
99
197
|
readonly IFrameNotInitialized: 300;
|
|
198
|
+
/**
|
|
199
|
+
* iframe repeat initialization
|
|
200
|
+
*/
|
|
100
201
|
readonly IFrameAleradyInitialized: 301;
|
|
202
|
+
/**
|
|
203
|
+
* iframe load failure
|
|
204
|
+
*/
|
|
101
205
|
readonly IFrameLoadFail: 302;
|
|
206
|
+
/**
|
|
207
|
+
* init iframe time out
|
|
208
|
+
*/
|
|
102
209
|
readonly IframeTimeout: 303;
|
|
210
|
+
/**
|
|
211
|
+
* iframe blocked
|
|
212
|
+
*/
|
|
103
213
|
readonly IframeBlocked: 304;
|
|
214
|
+
/**
|
|
215
|
+
* iframe host not trust
|
|
216
|
+
*/
|
|
104
217
|
readonly IframeDistrust: 305;
|
|
218
|
+
/**
|
|
219
|
+
* Runtime errors during method execution
|
|
220
|
+
*/
|
|
105
221
|
readonly CallMethodError: 400;
|
|
222
|
+
/**
|
|
223
|
+
* Method does not responding
|
|
224
|
+
*/
|
|
106
225
|
readonly CallMethodNotResponse: 404;
|
|
226
|
+
/**
|
|
227
|
+
* Call method invalid parameter
|
|
228
|
+
*/
|
|
107
229
|
readonly CallMethodInvalidParameter: 405;
|
|
230
|
+
/**
|
|
231
|
+
* firmware update download failed
|
|
232
|
+
*/
|
|
108
233
|
readonly FirmwareUpdateDownloadFailed: 406;
|
|
234
|
+
/**
|
|
235
|
+
* Call method not supported, need update firmware
|
|
236
|
+
* @params: { current: string, require: string }
|
|
237
|
+
*/
|
|
109
238
|
readonly CallMethodNeedUpgradeFirmware: 407;
|
|
239
|
+
/**
|
|
240
|
+
* Call method not supported, is deprecated
|
|
241
|
+
* @params: { current: string, deprecated: string }
|
|
242
|
+
*/
|
|
110
243
|
readonly CallMethodDeprecated: 408;
|
|
244
|
+
/**
|
|
245
|
+
* Only one device can be connected during firmware upgrade
|
|
246
|
+
*/
|
|
111
247
|
readonly FirmwareUpdateLimitOneDevice: 409;
|
|
248
|
+
/**
|
|
249
|
+
* You need to manually enter boot
|
|
250
|
+
*/
|
|
112
251
|
readonly FirmwareUpdateManuallyEnterBoot: 410;
|
|
252
|
+
/**
|
|
253
|
+
* Manual entry fails. You must manually enter the boot
|
|
254
|
+
*/
|
|
113
255
|
readonly FirmwareUpdateAutoEnterBootFailure: 411;
|
|
256
|
+
/**
|
|
257
|
+
* The new firmware has not been released yet
|
|
258
|
+
*/
|
|
114
259
|
readonly NewFirmwareUnRelease: 412;
|
|
260
|
+
/**
|
|
261
|
+
* use OneKey desktop client to update the firmware
|
|
262
|
+
* because need copy resource file to Touch
|
|
263
|
+
*/
|
|
115
264
|
readonly UseDesktopToUpdateFirmware: 413;
|
|
265
|
+
/**
|
|
266
|
+
* Mandatory firmware update
|
|
267
|
+
* @params:{ connectId: string? , deviceId: string? }
|
|
268
|
+
*/
|
|
116
269
|
readonly NewFirmwareForceUpdate: 414;
|
|
270
|
+
/**
|
|
271
|
+
* Device not support this method
|
|
272
|
+
*/
|
|
117
273
|
readonly DeviceNotSupportMethod: 415;
|
|
274
|
+
/**
|
|
275
|
+
* Forbidden key path
|
|
276
|
+
*/
|
|
118
277
|
readonly ForbiddenKeyPath: 416;
|
|
278
|
+
/**
|
|
279
|
+
* Repeat unlocking
|
|
280
|
+
* all network get address by loop need repeat unlocking
|
|
281
|
+
*/
|
|
119
282
|
readonly RepeatUnlocking: 417;
|
|
283
|
+
/**
|
|
284
|
+
* Defective firmware detected
|
|
285
|
+
*/
|
|
120
286
|
readonly DefectiveFirmware: 418;
|
|
287
|
+
/**
|
|
288
|
+
* Netword request error
|
|
289
|
+
*/
|
|
121
290
|
readonly NetworkError: 500;
|
|
291
|
+
/**
|
|
292
|
+
* Transport not configured
|
|
293
|
+
*/
|
|
122
294
|
readonly TransportNotConfigured: 600;
|
|
295
|
+
/**
|
|
296
|
+
* Transport call in progress
|
|
297
|
+
*/
|
|
123
298
|
readonly TransportCallInProgress: 601;
|
|
299
|
+
/**
|
|
300
|
+
* Transport not found
|
|
301
|
+
*/
|
|
124
302
|
readonly TransportNotFound: 602;
|
|
303
|
+
/**
|
|
304
|
+
* Transport invalid protobuf
|
|
305
|
+
*/
|
|
125
306
|
readonly TransportInvalidProtobuf: 603;
|
|
307
|
+
/**
|
|
308
|
+
* Bluetooth error code
|
|
309
|
+
*/
|
|
126
310
|
readonly BleScanError: 700;
|
|
127
311
|
readonly BlePermissionError: 701;
|
|
128
312
|
readonly BleLocationError: 702;
|
|
@@ -146,38 +330,145 @@ declare const HardwareErrorCode: {
|
|
|
146
330
|
readonly BleDeviceDisconnected: 720;
|
|
147
331
|
readonly BlePoweredOff: 721;
|
|
148
332
|
readonly BleUnsupported: 722;
|
|
333
|
+
readonly BleUnavailableWhileUsbConnected: 723;
|
|
334
|
+
/**
|
|
335
|
+
* Hardware runtiome errors
|
|
336
|
+
*/
|
|
149
337
|
readonly RuntimeError: 800;
|
|
338
|
+
/**
|
|
339
|
+
* invalid pin
|
|
340
|
+
*/
|
|
150
341
|
readonly PinInvalid: 801;
|
|
342
|
+
/**
|
|
343
|
+
* pin cancelled by user
|
|
344
|
+
*/
|
|
151
345
|
readonly PinCancelled: 802;
|
|
346
|
+
/**
|
|
347
|
+
* Action cancelled by user
|
|
348
|
+
*/
|
|
152
349
|
readonly ActionCancelled: 803;
|
|
350
|
+
/**
|
|
351
|
+
* Firmware installation failed
|
|
352
|
+
*/
|
|
153
353
|
readonly FirmwareError: 804;
|
|
354
|
+
/**
|
|
355
|
+
* transport response unexpect error
|
|
356
|
+
*/
|
|
154
357
|
readonly ResponseUnexpectTypeError: 805;
|
|
358
|
+
/**
|
|
359
|
+
* bridge network error
|
|
360
|
+
*/
|
|
155
361
|
readonly BridgeNetworkError: 806;
|
|
362
|
+
/**
|
|
363
|
+
* Bridge network timeout
|
|
364
|
+
*/
|
|
156
365
|
readonly BridgeTimeoutError: 807;
|
|
366
|
+
/**
|
|
367
|
+
* Bridge not installed
|
|
368
|
+
*/
|
|
157
369
|
readonly BridgeNotInstalled: 808;
|
|
370
|
+
/**
|
|
371
|
+
* ensure connect timeout
|
|
372
|
+
*/
|
|
158
373
|
readonly PollingTimeout: 809;
|
|
374
|
+
/**
|
|
375
|
+
* ensure connect stop polling
|
|
376
|
+
*/
|
|
159
377
|
readonly PollingStop: 810;
|
|
378
|
+
/**
|
|
379
|
+
* Device does not open blid sign
|
|
380
|
+
*/
|
|
160
381
|
readonly BlindSignDisabled: 811;
|
|
161
382
|
readonly UnexpectPassphrase: 812;
|
|
383
|
+
/**
|
|
384
|
+
* NFT file already exists
|
|
385
|
+
*/
|
|
162
386
|
readonly FileAlreadyExists: 813;
|
|
387
|
+
/**
|
|
388
|
+
* check file length error
|
|
389
|
+
*/
|
|
163
390
|
readonly CheckDownloadFileError: 814;
|
|
391
|
+
/**
|
|
392
|
+
* not in signing mode
|
|
393
|
+
*/
|
|
164
394
|
readonly NotInSigningMode: 815;
|
|
395
|
+
/**
|
|
396
|
+
* not in signing mode
|
|
397
|
+
*/
|
|
165
398
|
readonly DataOverload: 816;
|
|
399
|
+
/**
|
|
400
|
+
* device disconnected during action
|
|
401
|
+
*/
|
|
166
402
|
readonly BridgeDeviceDisconnected: 817;
|
|
403
|
+
/**
|
|
404
|
+
* BTC PSBT too many utxos
|
|
405
|
+
* @params:{ count: number }
|
|
406
|
+
*/
|
|
167
407
|
readonly BTCPsbtTooManyUtxos: 818;
|
|
408
|
+
/**
|
|
409
|
+
* EMMC file write firmware error
|
|
410
|
+
*/
|
|
168
411
|
readonly EmmcFileWriteFirmwareError: 819;
|
|
412
|
+
/**
|
|
413
|
+
* Firmware verification failed (e.g., bootloader file verify failed)
|
|
414
|
+
*/
|
|
169
415
|
readonly FirmwareVerificationFailed: 820;
|
|
416
|
+
/**
|
|
417
|
+
* Web bridge coonect needs permission
|
|
418
|
+
*/
|
|
170
419
|
readonly BridgeNeedsPermission: 821;
|
|
171
420
|
readonly CallQueueActionCancelled: 822;
|
|
421
|
+
/**
|
|
422
|
+
* Firmware downgrade not allowed
|
|
423
|
+
*/
|
|
172
424
|
readonly FirmwareDowngradeNotAllowed: 823;
|
|
425
|
+
/**
|
|
426
|
+
* Cosmos invalid JSON message, Only support Amino msgs.
|
|
427
|
+
*/
|
|
173
428
|
readonly CosmosInvalidJsonMessage: 824;
|
|
429
|
+
/**
|
|
430
|
+
* No setting provided
|
|
431
|
+
*/
|
|
174
432
|
readonly DeviceSettingsNotProvided: 825;
|
|
433
|
+
/**
|
|
434
|
+
* Language not supported
|
|
435
|
+
*/
|
|
175
436
|
readonly DeviceSettingsLanguageNotSupport: 826;
|
|
437
|
+
/**
|
|
438
|
+
* Too many inputs
|
|
439
|
+
* @params: { count?: string }
|
|
440
|
+
*/
|
|
176
441
|
readonly TooManyInputs: 827;
|
|
442
|
+
/**
|
|
443
|
+
* The two PIN entries did not match while setting/changing PIN on device
|
|
444
|
+
*/
|
|
177
445
|
readonly PinMismatch: 828;
|
|
178
|
-
|
|
446
|
+
/**
|
|
447
|
+
* Protocol V2 device must be unlocked before the requested operation.
|
|
448
|
+
* @params: { failureCode?: string; subcode?: number; firmwareMessage?: string }
|
|
449
|
+
*/
|
|
450
|
+
readonly DeviceLocked: 830;
|
|
451
|
+
/**
|
|
452
|
+
* The cached wallet session is invalid or has expired.
|
|
453
|
+
* @params: { failureCode?: string; subcode?: number; firmwareMessage?: string }
|
|
454
|
+
*/
|
|
455
|
+
readonly WalletSessionInvalid: 831;
|
|
456
|
+
/**
|
|
457
|
+
* Pro2 NFT storage has reached its item limit.
|
|
458
|
+
* @params: { count: number; limit: number }
|
|
459
|
+
*/
|
|
460
|
+
readonly NftStorageLimitReached: 832;
|
|
461
|
+
/**
|
|
462
|
+
* Lowlevel transport connect error
|
|
463
|
+
*/
|
|
179
464
|
readonly LowlevelTrasnportConnectError: 900;
|
|
465
|
+
/**
|
|
466
|
+
* Web USB or Web Bluetooth device not found or needs permission
|
|
467
|
+
*/
|
|
180
468
|
readonly WebDeviceNotFoundOrNeedsPermission: 901;
|
|
469
|
+
/**
|
|
470
|
+
* Web USB or Web Bluetooth device prompt access error
|
|
471
|
+
*/
|
|
181
472
|
readonly WebDevicePromptAccessError: 902;
|
|
182
473
|
};
|
|
183
474
|
declare const HardwareErrorCodeMessage: HardwareErrorCodeMessageMapping;
|
|
@@ -249,7 +540,8 @@ declare enum EDeviceType {
|
|
|
249
540
|
Mini = "mini",
|
|
250
541
|
Touch = "touch",
|
|
251
542
|
Pro = "pro",
|
|
252
|
-
Pro2 = "pro2"
|
|
543
|
+
Pro2 = "pro2",
|
|
544
|
+
Neo = "neo"
|
|
253
545
|
}
|
|
254
546
|
|
|
255
|
-
export { CreateErrorByMessage, CreateHardwareErrorByBridgeError, Deferred, EDeviceType, EFirmwareType, EOneKeyBleMessageKeys, HardwareError$1 as ERRORS, ERROR_CODES_REQUIRE_DISCONNECT, ERROR_CODES_REQUIRE_RELEASE, HARDWARE_CONNECT_PROTOCOL, HardwareConnectProtocol, HardwareError, HardwareErrorCode, HardwareErrorCodeMessage, IHardwareError, ONEKEY_NOTIFY_CHARACTERISTIC_UUID, ONEKEY_SERVICE_UUID, ONEKEY_WEBUSB_FILTER, ONEKEY_WRITE_CHARACTERISTIC_UUID, TypedError, createDefectiveFirmwareError, createDeferred, createDeprecatedHardwareError, createDeviceNotSupportMethodError, createNeedUpgradeFirmwareHardwareError, createNewFirmwareForceUpdateHardwareError, createNewFirmwareUnReleaseHardwareError, isHeaderChunk, isKnownTrezorWebUsbDevice, isOnekeyDevice, serializeError, wait };
|
|
547
|
+
export { CreateErrorByMessage, CreateHardwareErrorByBridgeError, Deferred, EDeviceType, EFirmwareType, EOneKeyBleMessageKeys, HardwareError$1 as ERRORS, ERROR_CODES_REQUIRE_DISCONNECT, ERROR_CODES_REQUIRE_RELEASE, HARDWARE_CONNECT_PROTOCOL, HardwareConnectProtocol, HardwareError, HardwareErrorCode, HardwareErrorCodeMessage, IHardwareError, ONEKEY_NOTIFY_CHARACTERISTIC_UUID, ONEKEY_PROTOCOL_V2_USB_IDS, ONEKEY_SERVICE_UUID, ONEKEY_WEBUSB_FILTER, ONEKEY_WRITE_CHARACTERISTIC_UUID, TypedError, createDefectiveFirmwareError, createDeferred, createDeprecatedHardwareError, createDeviceNotSupportMethodError, createKnownBleUuidAliases, createNeedUpgradeFirmwareHardwareError, createNewFirmwareForceUpdateHardwareError, createNewFirmwareUnReleaseHardwareError, hasOnekeyCommunicationService, inferProtocolHintFromUsbId, isHeaderChunk, isKnownTrezorWebUsbDevice, isOnekeyBluetoothDevice, isOnekeyDevice, isPro2FindMyAdvertisementName, matchesKnownBleUuid, normalizeBleUuid, normalizePro2FindMyAdvertisementName, resolveOneKeyUsbDevicePath, serializeError, wait };
|
package/dist/index.js
CHANGED
|
@@ -135,6 +135,7 @@ const HardwareErrorCode = {
|
|
|
135
135
|
BleDeviceDisconnected: 720,
|
|
136
136
|
BlePoweredOff: 721,
|
|
137
137
|
BleUnsupported: 722,
|
|
138
|
+
BleUnavailableWhileUsbConnected: 723,
|
|
138
139
|
RuntimeError: 800,
|
|
139
140
|
PinInvalid: 801,
|
|
140
141
|
PinCancelled: 802,
|
|
@@ -164,7 +165,9 @@ const HardwareErrorCode = {
|
|
|
164
165
|
DeviceSettingsLanguageNotSupport: 826,
|
|
165
166
|
TooManyInputs: 827,
|
|
166
167
|
PinMismatch: 828,
|
|
167
|
-
DeviceLocked:
|
|
168
|
+
DeviceLocked: 830,
|
|
169
|
+
WalletSessionInvalid: 831,
|
|
170
|
+
NftStorageLimitReached: 832,
|
|
168
171
|
LowlevelTrasnportConnectError: 900,
|
|
169
172
|
WebDeviceNotFoundOrNeedsPermission: 901,
|
|
170
173
|
WebDevicePromptAccessError: 902,
|
|
@@ -240,6 +243,7 @@ const HardwareErrorCodeMessage = {
|
|
|
240
243
|
[HardwareErrorCode.BleDeviceDisconnected]: 'Device disconnected',
|
|
241
244
|
[HardwareErrorCode.BlePoweredOff]: 'Bluetooth is turned off',
|
|
242
245
|
[HardwareErrorCode.BleUnsupported]: 'Bluetooth is not supported on this device',
|
|
246
|
+
[HardwareErrorCode.BleUnavailableWhileUsbConnected]: 'Bluetooth is unavailable while USB is connected. Unplug USB and try again.',
|
|
243
247
|
[HardwareErrorCode.RuntimeError]: 'Runtime error',
|
|
244
248
|
[HardwareErrorCode.PinInvalid]: 'Pin invalid',
|
|
245
249
|
[HardwareErrorCode.PinCancelled]: 'Pin cancelled',
|
|
@@ -270,6 +274,8 @@ const HardwareErrorCodeMessage = {
|
|
|
270
274
|
[HardwareErrorCode.TooManyInputs]: 'Too many inputs',
|
|
271
275
|
[HardwareErrorCode.PinMismatch]: 'PIN mismatch',
|
|
272
276
|
[HardwareErrorCode.DeviceLocked]: 'Device locked',
|
|
277
|
+
[HardwareErrorCode.WalletSessionInvalid]: 'Wallet session is invalid or expired',
|
|
278
|
+
[HardwareErrorCode.NftStorageLimitReached]: 'NFT storage limit reached. Remove an NFT from the device and try again.',
|
|
273
279
|
[HardwareErrorCode.LowlevelTrasnportConnectError]: 'Lowlevel transport connect error',
|
|
274
280
|
[HardwareErrorCode.WebDeviceNotFoundOrNeedsPermission]: 'Web-USB or Web-Bluetooth device not found or needs permission',
|
|
275
281
|
[HardwareErrorCode.WebDevicePromptAccessError]: 'Web-USB or Web-Bluetooth device prompt access error',
|
|
@@ -393,6 +399,7 @@ const ONEKEY_WEBUSB_FILTER = [
|
|
|
393
399
|
{ vendorId: 0x1209, productId: 0x4f4b },
|
|
394
400
|
{ vendorId: 0x1209, productId: 0x4f4c },
|
|
395
401
|
];
|
|
402
|
+
const ONEKEY_PROTOCOL_V2_USB_IDS = [{ vendorId: 0x1209, productId: 0x4f4c }];
|
|
396
403
|
const TREZOR_WEBUSB_MANUFACTURER_NAMES = new Set(['trezor', 'trezor company', 'satoshilabs']);
|
|
397
404
|
const isKnownTrezorWebUsbDevice = (descriptor) => {
|
|
398
405
|
var _a;
|
|
@@ -434,11 +441,13 @@ exports.EOneKeyBleMessageKeys = void 0;
|
|
|
434
441
|
EOneKeyBleMessageKeys["NOBLE_BLE_STOP_SCAN"] = "$onekey-noble-ble-stop-scan";
|
|
435
442
|
EOneKeyBleMessageKeys["NOBLE_BLE_GET_DEVICE"] = "$onekey-noble-ble-get-device";
|
|
436
443
|
EOneKeyBleMessageKeys["NOBLE_BLE_CONNECT"] = "$onekey-noble-ble-connect";
|
|
444
|
+
EOneKeyBleMessageKeys["NOBLE_BLE_RELEASE"] = "$onekey-noble-ble-release";
|
|
437
445
|
EOneKeyBleMessageKeys["NOBLE_BLE_DISCONNECT"] = "$onekey-noble-ble-disconnect";
|
|
438
446
|
EOneKeyBleMessageKeys["NOBLE_BLE_WRITE"] = "$onekey-noble-ble-write";
|
|
439
447
|
EOneKeyBleMessageKeys["NOBLE_BLE_SUBSCRIBE"] = "$onekey-noble-ble-subscribe";
|
|
440
448
|
EOneKeyBleMessageKeys["NOBLE_BLE_UNSUBSCRIBE"] = "$onekey-noble-ble-unsubscribe";
|
|
441
449
|
EOneKeyBleMessageKeys["NOBLE_BLE_NOTIFICATION"] = "$onekey-noble-ble-notification";
|
|
450
|
+
EOneKeyBleMessageKeys["NOBLE_BLE_MTU_CHANGED"] = "$onekey-noble-ble-mtu-changed";
|
|
442
451
|
EOneKeyBleMessageKeys["NOBLE_BLE_CANCEL_PAIRING"] = "$onekey-noble-ble-cancel-pairing";
|
|
443
452
|
})(exports.EOneKeyBleMessageKeys || (exports.EOneKeyBleMessageKeys = {}));
|
|
444
453
|
const ONEKEY_SERVICE_UUID = '00000001-0000-1000-8000-00805f9b34fb';
|
|
@@ -487,11 +496,120 @@ const isOnekeyDevice = (name, id) => {
|
|
|
487
496
|
return true;
|
|
488
497
|
if (normalizedName.startsWith('touch ') ||
|
|
489
498
|
normalizedName.startsWith('pro ') ||
|
|
490
|
-
normalizedName.startsWith('pro2
|
|
499
|
+
normalizedName.startsWith('pro2') ||
|
|
500
|
+
normalizedName.startsWith('neo')) {
|
|
501
|
+
return true;
|
|
502
|
+
}
|
|
503
|
+
const compactName = compactBleName(normalizedName);
|
|
504
|
+
if (PRO2_COMPACT_NAME_PATTERN.test(compactName) || NEO_COMPACT_NAME_PATTERN.test(compactName)) {
|
|
491
505
|
return true;
|
|
492
506
|
}
|
|
493
507
|
return isOneKeyShortName(normalizedName);
|
|
494
508
|
};
|
|
509
|
+
const inferProtocolHintFromUsbId = (vendorId, productId) => ONEKEY_PROTOCOL_V2_USB_IDS.some(id => id.vendorId === vendorId && id.productId === productId)
|
|
510
|
+
? 'V2'
|
|
511
|
+
: undefined;
|
|
512
|
+
const resolveOneKeyUsbDevicePath = (device) => {
|
|
513
|
+
var _a, _b, _c, _d;
|
|
514
|
+
const serial = (_a = device.serialNumber) === null || _a === void 0 ? void 0 : _a.trim();
|
|
515
|
+
if (serial)
|
|
516
|
+
return serial;
|
|
517
|
+
if (device.vendorId == null && device.productId == null && !device.productName) {
|
|
518
|
+
return undefined;
|
|
519
|
+
}
|
|
520
|
+
const vendorId = ((_b = device.vendorId) !== null && _b !== void 0 ? _b : 0).toString(16).padStart(4, '0');
|
|
521
|
+
const productId = ((_c = device.productId) !== null && _c !== void 0 ? _c : 0).toString(16).padStart(4, '0');
|
|
522
|
+
const product = ((_d = device.productName) !== null && _d !== void 0 ? _d : 'onekey')
|
|
523
|
+
.trim()
|
|
524
|
+
.toLowerCase()
|
|
525
|
+
.replace(/\s+/g, '-')
|
|
526
|
+
.replace(/[^a-z0-9-]/g, '');
|
|
527
|
+
return `usb-${vendorId}-${productId}-${product || 'onekey'}`;
|
|
528
|
+
};
|
|
529
|
+
const BLUETOOTH_BASE_UUID_SUFFIX = '00001000800000805f9b34fb';
|
|
530
|
+
const normalizeBleUuid = (uuid) => (uuid !== null && uuid !== void 0 ? uuid : '').replace(/-/g, '').toLowerCase();
|
|
531
|
+
const createKnownBleUuidAliases = (uuid) => {
|
|
532
|
+
const normalized = normalizeBleUuid(uuid);
|
|
533
|
+
const aliases = new Set([normalized]);
|
|
534
|
+
if (normalized.length !== 32 || !normalized.endsWith(BLUETOOTH_BASE_UUID_SUFFIX)) {
|
|
535
|
+
return aliases;
|
|
536
|
+
}
|
|
537
|
+
const assignedNumber = normalized.slice(0, 8);
|
|
538
|
+
aliases.add(assignedNumber);
|
|
539
|
+
if (assignedNumber.startsWith('0000')) {
|
|
540
|
+
aliases.add(assignedNumber.slice(4));
|
|
541
|
+
}
|
|
542
|
+
return aliases;
|
|
543
|
+
};
|
|
544
|
+
const matchesKnownBleUuid = (actualUuid, aliases) => aliases.has(normalizeBleUuid(actualUuid));
|
|
545
|
+
const ONEKEY_COMMUNICATION_SERVICE_ALIASES = createKnownBleUuidAliases(ONEKEY_SERVICE_UUID);
|
|
546
|
+
const FIDO_SERVICE_ALIASES = createKnownBleUuidAliases('0000fffd-0000-1000-8000-00805f9b34fb');
|
|
547
|
+
const PRO2_COMPACT_NAME_PATTERN = /^(?:onekey)?pro2[a-f0-9]{4}$/i;
|
|
548
|
+
const NEO_COMPACT_NAME_PATTERN = /^(?:onekey)?neo[a-f0-9]{4}$/i;
|
|
549
|
+
const FIND_MY_COMPACT_SUFFIXES = [
|
|
550
|
+
'findemy',
|
|
551
|
+
'findem',
|
|
552
|
+
'finde',
|
|
553
|
+
'findmy',
|
|
554
|
+
'findm',
|
|
555
|
+
'find',
|
|
556
|
+
'fin',
|
|
557
|
+
];
|
|
558
|
+
const COMPLETE_FIND_MY_COMPACT_SUFFIXES = ['findemy', 'findmy'];
|
|
559
|
+
const compactBleName = (value) => Array.from(value)
|
|
560
|
+
.filter(character => character !== '-' && character.trim() !== '')
|
|
561
|
+
.join('')
|
|
562
|
+
.toLowerCase();
|
|
563
|
+
const getFindMyCompactSuffix = (compactName) => FIND_MY_COMPACT_SUFFIXES.find(candidate => compactName.endsWith(candidate));
|
|
564
|
+
const getPro2FindMyBaseLength = (value) => {
|
|
565
|
+
const compactName = compactBleName(value);
|
|
566
|
+
const suffix = getFindMyCompactSuffix(compactName);
|
|
567
|
+
if (!suffix)
|
|
568
|
+
return undefined;
|
|
569
|
+
const compactBaseName = compactName.slice(0, -suffix.length);
|
|
570
|
+
return PRO2_COMPACT_NAME_PATTERN.test(compactBaseName) ? compactBaseName.length : undefined;
|
|
571
|
+
};
|
|
572
|
+
const isPro2FindMyAdvertisementName = (value) => {
|
|
573
|
+
if (!value)
|
|
574
|
+
return false;
|
|
575
|
+
if (getPro2FindMyBaseLength(value) !== undefined)
|
|
576
|
+
return true;
|
|
577
|
+
const compactName = compactBleName(value);
|
|
578
|
+
const suffix = COMPLETE_FIND_MY_COMPACT_SUFFIXES.find(candidate => compactName.endsWith(candidate));
|
|
579
|
+
if (!suffix)
|
|
580
|
+
return false;
|
|
581
|
+
return compactName.slice(0, -suffix.length).includes('pro2');
|
|
582
|
+
};
|
|
583
|
+
const normalizePro2FindMyAdvertisementName = (value) => {
|
|
584
|
+
const baseLength = getPro2FindMyBaseLength(value);
|
|
585
|
+
if (baseLength === undefined)
|
|
586
|
+
return value;
|
|
587
|
+
let compactLength = 0;
|
|
588
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
589
|
+
const character = value[index];
|
|
590
|
+
if (character !== '-' && character.trim() !== '') {
|
|
591
|
+
compactLength += 1;
|
|
592
|
+
if (compactLength === baseLength) {
|
|
593
|
+
return value.slice(0, index + 1).trimEnd();
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
return value;
|
|
598
|
+
};
|
|
599
|
+
const hasOnekeyCommunicationService = (serviceUuids) => (serviceUuids !== null && serviceUuids !== void 0 ? serviceUuids : []).some(uuid => matchesKnownBleUuid(uuid, ONEKEY_COMMUNICATION_SERVICE_ALIASES));
|
|
600
|
+
const isOnekeyBluetoothDevice = ({ id, name, localName, serviceUuids, }) => {
|
|
601
|
+
const advertisedServiceUuids = serviceUuids !== null && serviceUuids !== void 0 ? serviceUuids : [];
|
|
602
|
+
if (hasOnekeyCommunicationService(advertisedServiceUuids)) {
|
|
603
|
+
return true;
|
|
604
|
+
}
|
|
605
|
+
if (isPro2FindMyAdvertisementName(name) || isPro2FindMyAdvertisementName(localName)) {
|
|
606
|
+
return false;
|
|
607
|
+
}
|
|
608
|
+
if (advertisedServiceUuids.some(uuid => matchesKnownBleUuid(uuid, FIDO_SERVICE_ALIASES))) {
|
|
609
|
+
return false;
|
|
610
|
+
}
|
|
611
|
+
return isOnekeyDevice(name !== null && name !== void 0 ? name : null, id) || isOnekeyDevice(localName !== null && localName !== void 0 ? localName : null, id);
|
|
612
|
+
};
|
|
495
613
|
|
|
496
614
|
/******************************************************************************
|
|
497
615
|
Copyright (c) Microsoft Corporation.
|
|
@@ -564,6 +682,7 @@ exports.EDeviceType = void 0;
|
|
|
564
682
|
EDeviceType["Touch"] = "touch";
|
|
565
683
|
EDeviceType["Pro"] = "pro";
|
|
566
684
|
EDeviceType["Pro2"] = "pro2";
|
|
685
|
+
EDeviceType["Neo"] = "neo";
|
|
567
686
|
})(exports.EDeviceType || (exports.EDeviceType = {}));
|
|
568
687
|
|
|
569
688
|
exports.CreateErrorByMessage = CreateErrorByMessage;
|
|
@@ -576,6 +695,7 @@ exports.HardwareError = HardwareError;
|
|
|
576
695
|
exports.HardwareErrorCode = HardwareErrorCode;
|
|
577
696
|
exports.HardwareErrorCodeMessage = HardwareErrorCodeMessage;
|
|
578
697
|
exports.ONEKEY_NOTIFY_CHARACTERISTIC_UUID = ONEKEY_NOTIFY_CHARACTERISTIC_UUID;
|
|
698
|
+
exports.ONEKEY_PROTOCOL_V2_USB_IDS = ONEKEY_PROTOCOL_V2_USB_IDS;
|
|
579
699
|
exports.ONEKEY_SERVICE_UUID = ONEKEY_SERVICE_UUID;
|
|
580
700
|
exports.ONEKEY_WEBUSB_FILTER = ONEKEY_WEBUSB_FILTER;
|
|
581
701
|
exports.ONEKEY_WRITE_CHARACTERISTIC_UUID = ONEKEY_WRITE_CHARACTERISTIC_UUID;
|
|
@@ -584,11 +704,20 @@ exports.createDefectiveFirmwareError = createDefectiveFirmwareError;
|
|
|
584
704
|
exports.createDeferred = createDeferred;
|
|
585
705
|
exports.createDeprecatedHardwareError = createDeprecatedHardwareError;
|
|
586
706
|
exports.createDeviceNotSupportMethodError = createDeviceNotSupportMethodError;
|
|
707
|
+
exports.createKnownBleUuidAliases = createKnownBleUuidAliases;
|
|
587
708
|
exports.createNeedUpgradeFirmwareHardwareError = createNeedUpgradeFirmwareHardwareError;
|
|
588
709
|
exports.createNewFirmwareForceUpdateHardwareError = createNewFirmwareForceUpdateHardwareError;
|
|
589
710
|
exports.createNewFirmwareUnReleaseHardwareError = createNewFirmwareUnReleaseHardwareError;
|
|
711
|
+
exports.hasOnekeyCommunicationService = hasOnekeyCommunicationService;
|
|
712
|
+
exports.inferProtocolHintFromUsbId = inferProtocolHintFromUsbId;
|
|
590
713
|
exports.isHeaderChunk = isHeaderChunk;
|
|
591
714
|
exports.isKnownTrezorWebUsbDevice = isKnownTrezorWebUsbDevice;
|
|
715
|
+
exports.isOnekeyBluetoothDevice = isOnekeyBluetoothDevice;
|
|
592
716
|
exports.isOnekeyDevice = isOnekeyDevice;
|
|
717
|
+
exports.isPro2FindMyAdvertisementName = isPro2FindMyAdvertisementName;
|
|
718
|
+
exports.matchesKnownBleUuid = matchesKnownBleUuid;
|
|
719
|
+
exports.normalizeBleUuid = normalizeBleUuid;
|
|
720
|
+
exports.normalizePro2FindMyAdvertisementName = normalizePro2FindMyAdvertisementName;
|
|
721
|
+
exports.resolveOneKeyUsbDevicePath = resolveOneKeyUsbDevicePath;
|
|
593
722
|
exports.serializeError = serializeError;
|
|
594
723
|
exports.wait = wait;
|
package/jest.config.js
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-shared",
|
|
3
|
-
"version": "1.2.0-alpha.
|
|
3
|
+
"version": "1.2.0-alpha.150",
|
|
4
4
|
"description": "Hardware SDK's shared tool library",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Hardware-SDK",
|
|
@@ -22,8 +22,9 @@
|
|
|
22
22
|
"scripts": {
|
|
23
23
|
"dev": "rimraf dist && rollup -c ../../build/rollup.config.js -w",
|
|
24
24
|
"build": "rimraf dist && rollup -c ../../build/rollup.config.js",
|
|
25
|
+
"test": "jest",
|
|
25
26
|
"lint": "eslint .",
|
|
26
27
|
"lint:fix": "eslint . --fix"
|
|
27
28
|
},
|
|
28
|
-
"gitHead": "
|
|
29
|
+
"gitHead": "08359528e71933964694eb49793e555635350104"
|
|
29
30
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {
|
|
2
|
+
HardwareErrorCode,
|
|
3
|
+
HardwareErrorCodeMessage,
|
|
4
|
+
TypedError,
|
|
5
|
+
serializeError,
|
|
6
|
+
} from './HardwareError';
|
|
7
|
+
|
|
8
|
+
describe('HardwareErrorCode compatibility', () => {
|
|
9
|
+
test('preserves published Protocol V2 values while leaving code 829 unused', () => {
|
|
10
|
+
expect(HardwareErrorCode).not.toHaveProperty('KaspaPrevTxIdMismatch');
|
|
11
|
+
expect(HardwareErrorCode.DeviceLocked).toBe(830);
|
|
12
|
+
expect(HardwareErrorCode.WalletSessionInvalid).toBe(831);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test('reserves the BLE and USB conflict code for app error mapping', () => {
|
|
16
|
+
expect(HardwareErrorCode.BleUnavailableWhileUsbConnected).toBe(723);
|
|
17
|
+
expect(HardwareErrorCodeMessage[HardwareErrorCode.BleUnavailableWhileUsbConnected]).toBe(
|
|
18
|
+
'Bluetooth is unavailable while USB is connected. Unplug USB and try again.'
|
|
19
|
+
);
|
|
20
|
+
expect(
|
|
21
|
+
serializeError({
|
|
22
|
+
error: TypedError(HardwareErrorCode.BleUnavailableWhileUsbConnected, undefined, {
|
|
23
|
+
failureCode: 'Failure_ProcessError',
|
|
24
|
+
firmwareMessage: 'link disabled',
|
|
25
|
+
}),
|
|
26
|
+
})
|
|
27
|
+
).toEqual({
|
|
28
|
+
code: 723,
|
|
29
|
+
error: 'Bluetooth is unavailable while USB is connected. Unplug USB and try again.',
|
|
30
|
+
params: {
|
|
31
|
+
failureCode: 'Failure_ProcessError',
|
|
32
|
+
firmwareMessage: 'link disabled',
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
});
|
package/src/HardwareError.ts
CHANGED
|
@@ -345,6 +345,7 @@ export const HardwareErrorCode = {
|
|
|
345
345
|
BleDeviceDisconnected: 720,
|
|
346
346
|
BlePoweredOff: 721,
|
|
347
347
|
BleUnsupported: 722,
|
|
348
|
+
BleUnavailableWhileUsbConnected: 723,
|
|
348
349
|
|
|
349
350
|
/**
|
|
350
351
|
* Hardware runtiome errors
|
|
@@ -488,7 +489,19 @@ export const HardwareErrorCode = {
|
|
|
488
489
|
* Protocol V2 device must be unlocked before the requested operation.
|
|
489
490
|
* @params: { failureCode?: string; subcode?: number; firmwareMessage?: string }
|
|
490
491
|
*/
|
|
491
|
-
DeviceLocked:
|
|
492
|
+
DeviceLocked: 830,
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
* The cached wallet session is invalid or has expired.
|
|
496
|
+
* @params: { failureCode?: string; subcode?: number; firmwareMessage?: string }
|
|
497
|
+
*/
|
|
498
|
+
WalletSessionInvalid: 831,
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Pro2 NFT storage has reached its item limit.
|
|
502
|
+
* @params: { count: number; limit: number }
|
|
503
|
+
*/
|
|
504
|
+
NftStorageLimitReached: 832,
|
|
492
505
|
|
|
493
506
|
/**
|
|
494
507
|
* Lowlevel transport connect error
|
|
@@ -607,6 +620,8 @@ export const HardwareErrorCodeMessage: HardwareErrorCodeMessageMapping = {
|
|
|
607
620
|
[HardwareErrorCode.BleDeviceDisconnected]: 'Device disconnected',
|
|
608
621
|
[HardwareErrorCode.BlePoweredOff]: 'Bluetooth is turned off',
|
|
609
622
|
[HardwareErrorCode.BleUnsupported]: 'Bluetooth is not supported on this device',
|
|
623
|
+
[HardwareErrorCode.BleUnavailableWhileUsbConnected]:
|
|
624
|
+
'Bluetooth is unavailable while USB is connected. Unplug USB and try again.',
|
|
610
625
|
|
|
611
626
|
/**
|
|
612
627
|
* Runtime Error
|
|
@@ -642,6 +657,9 @@ export const HardwareErrorCodeMessage: HardwareErrorCodeMessageMapping = {
|
|
|
642
657
|
[HardwareErrorCode.TooManyInputs]: 'Too many inputs',
|
|
643
658
|
[HardwareErrorCode.PinMismatch]: 'PIN mismatch',
|
|
644
659
|
[HardwareErrorCode.DeviceLocked]: 'Device locked',
|
|
660
|
+
[HardwareErrorCode.WalletSessionInvalid]: 'Wallet session is invalid or expired',
|
|
661
|
+
[HardwareErrorCode.NftStorageLimitReached]:
|
|
662
|
+
'NFT storage limit reached. Remove an NFT from the device and try again.',
|
|
645
663
|
|
|
646
664
|
/**
|
|
647
665
|
* Lowlevel transport
|
package/src/constants.test.ts
CHANGED
|
@@ -1,9 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
createKnownBleUuidAliases,
|
|
3
|
+
hasOnekeyCommunicationService,
|
|
4
|
+
inferProtocolHintFromUsbId,
|
|
5
|
+
isKnownTrezorWebUsbDevice,
|
|
6
|
+
isOnekeyBluetoothDevice,
|
|
7
|
+
isOnekeyDevice,
|
|
8
|
+
isPro2FindMyAdvertisementName,
|
|
9
|
+
matchesKnownBleUuid,
|
|
10
|
+
normalizePro2FindMyAdvertisementName,
|
|
11
|
+
resolveOneKeyUsbDevicePath,
|
|
12
|
+
} from './constants';
|
|
2
13
|
|
|
3
14
|
describe('hardware device identity filters', () => {
|
|
4
15
|
it('accepts known OneKey BLE names', () => {
|
|
5
16
|
expect(isOnekeyDevice('Touch A1B2')).toBe(true);
|
|
6
17
|
expect(isOnekeyDevice('Pro A1B2')).toBe(true);
|
|
18
|
+
expect(isOnekeyDevice('Neo A1B2')).toBe(true);
|
|
19
|
+
expect(isOnekeyDevice('Pro2A1B2')).toBe(true);
|
|
20
|
+
expect(isOnekeyDevice('OneKeyPro2A1B2')).toBe(true);
|
|
21
|
+
expect(isOnekeyDevice('Neo22D8')).toBe(true);
|
|
7
22
|
expect(isOnekeyDevice('K1234')).toBe(true);
|
|
8
23
|
expect(isOnekeyDevice('S8')).toBe(true);
|
|
9
24
|
});
|
|
@@ -13,6 +28,145 @@ describe('hardware device identity filters', () => {
|
|
|
13
28
|
expect(isOnekeyDevice('Ledger Nano X')).toBe(false);
|
|
14
29
|
});
|
|
15
30
|
|
|
31
|
+
it('does not identify an FFFD-only advertisement as OneKey', () => {
|
|
32
|
+
expect(isOnekeyBluetoothDevice({ name: 'Find My', serviceUuids: ['fffd'] })).toBe(false);
|
|
33
|
+
expect(
|
|
34
|
+
isOnekeyBluetoothDevice({ serviceUuids: ['0000fffd-0000-1000-8000-00805f9b34fb'] })
|
|
35
|
+
).toBe(false);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('identifies Pro2 communication advertisements independently of their display name', () => {
|
|
39
|
+
expect(
|
|
40
|
+
isOnekeyBluetoothDevice({
|
|
41
|
+
name: 'Pro2 A1B2',
|
|
42
|
+
serviceUuids: ['0001', 'fffd'],
|
|
43
|
+
})
|
|
44
|
+
).toBe(true);
|
|
45
|
+
expect(
|
|
46
|
+
isOnekeyBluetoothDevice({
|
|
47
|
+
localName: 'Pro2 A1B2 - Find My',
|
|
48
|
+
serviceUuids: ['0001', 'fffd'],
|
|
49
|
+
})
|
|
50
|
+
).toBe(true);
|
|
51
|
+
expect(
|
|
52
|
+
isOnekeyBluetoothDevice({
|
|
53
|
+
name: 'Pro2 5E9D - Finde My',
|
|
54
|
+
serviceUuids: ['0001', 'fffd'],
|
|
55
|
+
})
|
|
56
|
+
).toBe(true);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('rejects Pro2 Find My entries when the communication service is absent', () => {
|
|
60
|
+
expect(
|
|
61
|
+
isOnekeyBluetoothDevice({
|
|
62
|
+
name: 'Pro2 A1B2 - Find My',
|
|
63
|
+
})
|
|
64
|
+
).toBe(false);
|
|
65
|
+
expect(
|
|
66
|
+
isOnekeyBluetoothDevice({
|
|
67
|
+
localName: 'OneKey Pro 2 A1B2 - Find My',
|
|
68
|
+
serviceUuids: [],
|
|
69
|
+
})
|
|
70
|
+
).toBe(false);
|
|
71
|
+
expect(
|
|
72
|
+
isOnekeyBluetoothDevice({
|
|
73
|
+
name: 'Pro2 5E9D - Finde My',
|
|
74
|
+
serviceUuids: ['fffd'],
|
|
75
|
+
})
|
|
76
|
+
).toBe(false);
|
|
77
|
+
expect(isOnekeyBluetoothDevice({ name: 'Pro2 - Find My' })).toBe(false);
|
|
78
|
+
expect(isOnekeyBluetoothDevice({ name: 'Pro2 G12Z - Find My' })).toBe(false);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('uses a broad Find My guard without broadening public name normalization', () => {
|
|
82
|
+
expect(isPro2FindMyAdvertisementName('Pro2 Griffin - Find My')).toBe(true);
|
|
83
|
+
expect(isPro2FindMyAdvertisementName('Pro2 Griffin')).toBe(false);
|
|
84
|
+
expect(isPro2FindMyAdvertisementName('Pro2 22D8 - Find My')).toBe(true);
|
|
85
|
+
expect(normalizePro2FindMyAdvertisementName('Pro2 Griffin - Find My')).toBe(
|
|
86
|
+
'Pro2 Griffin - Find My'
|
|
87
|
+
);
|
|
88
|
+
expect(normalizePro2FindMyAdvertisementName('Pro2 22D8 - Find My')).toBe('Pro2 22D8');
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it.each([
|
|
92
|
+
['Pro2 A1B2 - Find My', 'Pro2 A1B2'],
|
|
93
|
+
['Pro2 5E9D - Finde My', 'Pro2 5E9D'],
|
|
94
|
+
[' OneKey Pro 2 A1B2 Find My ', ' OneKey Pro 2 A1B2'],
|
|
95
|
+
['OneKey Pro-2 22D8--Find-My', 'OneKey Pro-2 22D8'],
|
|
96
|
+
['Pro2 22D8FindMy', 'Pro2 22D8'],
|
|
97
|
+
['Pro2 22D8 - Fin', 'Pro2 22D8'],
|
|
98
|
+
['Pro2 22D8FindM', 'Pro2 22D8'],
|
|
99
|
+
[`Pro2 22D8${'\t'.repeat(10_000)}Find My`, 'Pro2 22D8'],
|
|
100
|
+
['Pro2 A1B2', 'Pro2 A1B2'],
|
|
101
|
+
['Pro2 Griffin', 'Pro2 Griffin'],
|
|
102
|
+
['Find My', 'Find My'],
|
|
103
|
+
])('normalizes the public Pro2 advertisement name %s', (name, expected) => {
|
|
104
|
+
expect(normalizePro2FindMyAdvertisementName(name)).toBe(expected);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('keeps OneKey discovery on the communication service', () => {
|
|
108
|
+
expect(
|
|
109
|
+
isOnekeyBluetoothDevice({
|
|
110
|
+
name: 'OneKey Pro 2',
|
|
111
|
+
serviceUuids: ['00000001-0000-1000-8000-00805f9b34fb'],
|
|
112
|
+
})
|
|
113
|
+
).toBe(true);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('only aliases standard Bluetooth Base UUID representations', () => {
|
|
117
|
+
const aliases = createKnownBleUuidAliases('00000001-0000-1000-8000-00805f9b34fb');
|
|
118
|
+
|
|
119
|
+
expect(matchesKnownBleUuid('0001', aliases)).toBe(true);
|
|
120
|
+
expect(matchesKnownBleUuid('00000001', aliases)).toBe(true);
|
|
121
|
+
expect(matchesKnownBleUuid('abcd0001-1234-5678-9012-abcdefabcdef', aliases)).toBe(false);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('does not treat vendor-specific UUID fragments as communication or FIDO services', () => {
|
|
125
|
+
expect(
|
|
126
|
+
isOnekeyBluetoothDevice({
|
|
127
|
+
name: 'OneKey Pro 2',
|
|
128
|
+
serviceUuids: ['abcdfffd-1234-5678-9012-abcdefabcdef'],
|
|
129
|
+
})
|
|
130
|
+
).toBe(true);
|
|
131
|
+
expect(
|
|
132
|
+
isOnekeyBluetoothDevice({
|
|
133
|
+
serviceUuids: ['abcd0001-1234-5678-9012-abcdefabcdef'],
|
|
134
|
+
})
|
|
135
|
+
).toBe(false);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('requires an explicitly advertised communication service for strict discovery', () => {
|
|
139
|
+
expect(hasOnekeyCommunicationService([])).toBe(false);
|
|
140
|
+
expect(hasOnekeyCommunicationService(['0001'])).toBe(true);
|
|
141
|
+
expect(hasOnekeyCommunicationService(['abcd0001-1234-5678-9012-abcdefabcdef'])).toBe(false);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it('hints Protocol V2 from the current Pro2/Neo USB ID only', () => {
|
|
145
|
+
expect(inferProtocolHintFromUsbId(0x1209, 0x4f4c)).toBe('V2');
|
|
146
|
+
expect(inferProtocolHintFromUsbId(0x1209, 0x53c1)).toBeUndefined();
|
|
147
|
+
expect(inferProtocolHintFromUsbId(0x1209, 0x4f4a)).toBeUndefined();
|
|
148
|
+
expect(inferProtocolHintFromUsbId(0x1209, 0x4f4b)).toBeUndefined();
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('uses the USB serial when present and synthesizes a path when firmware omits it', () => {
|
|
152
|
+
expect(
|
|
153
|
+
resolveOneKeyUsbDevicePath({
|
|
154
|
+
vendorId: 0x1209,
|
|
155
|
+
productId: 0x4f4c,
|
|
156
|
+
productName: 'OneKey Pro 2',
|
|
157
|
+
serialNumber: 'PRO2-SERIAL',
|
|
158
|
+
})
|
|
159
|
+
).toBe('PRO2-SERIAL');
|
|
160
|
+
expect(
|
|
161
|
+
resolveOneKeyUsbDevicePath({
|
|
162
|
+
vendorId: 0x1209,
|
|
163
|
+
productId: 0x4f4c,
|
|
164
|
+
productName: 'OneKey Neo',
|
|
165
|
+
serialNumber: '',
|
|
166
|
+
})
|
|
167
|
+
).toBe('usb-1209-4f4c-onekey-neo');
|
|
168
|
+
});
|
|
169
|
+
|
|
16
170
|
it('only filters WebUSB descriptors that are explicitly identified as Trezor', () => {
|
|
17
171
|
expect(
|
|
18
172
|
isKnownTrezorWebUsbDevice({
|
package/src/constants.ts
CHANGED
|
@@ -10,13 +10,16 @@ export type HardwareConnectProtocol =
|
|
|
10
10
|
|
|
11
11
|
export const ONEKEY_WEBUSB_FILTER = [
|
|
12
12
|
{ vendorId: 0x1209, productId: 0x53c0 }, // Classic Boot、Classic1s Boot、Mini Boot
|
|
13
|
-
{ vendorId: 0x1209, productId: 0x53c1 }, // Classic
|
|
14
|
-
{ vendorId: 0x1209, productId: 0x4f4a }, // Pro
|
|
15
|
-
{ vendorId: 0x1209, productId: 0x4f4b }, // Pro
|
|
16
|
-
{ vendorId: 0x1209, productId: 0x4f4c }, //
|
|
13
|
+
{ vendorId: 0x1209, productId: 0x53c1 }, // Classic/Classic1s/Mini/Pro/Touch firmware and legacy Pro2; keep for existing devices
|
|
14
|
+
{ vendorId: 0x1209, productId: 0x4f4a }, // Pro bootloader, Touch bootloader, Pro2
|
|
15
|
+
{ vendorId: 0x1209, productId: 0x4f4b }, // Pro/Touch firmware (Trezor not implemented), Pro2
|
|
16
|
+
{ vendorId: 0x1209, productId: 0x4f4c }, // Pro2 / Neo current firmware, all modes
|
|
17
17
|
// { vendorId: 0x1209, productId: 0x4f50 }, // Touch Board
|
|
18
18
|
];
|
|
19
19
|
|
|
20
|
+
/** USB IDs whose first probe should be Protocol V2. Shared Pro/Touch PIDs stay unhinted. */
|
|
21
|
+
export const ONEKEY_PROTOCOL_V2_USB_IDS = [{ vendorId: 0x1209, productId: 0x4f4c }] as const;
|
|
22
|
+
|
|
20
23
|
type WebUsbIdentityDescriptor = {
|
|
21
24
|
vendorId?: number;
|
|
22
25
|
productId?: number;
|
|
@@ -86,11 +89,15 @@ export enum EOneKeyBleMessageKeys {
|
|
|
86
89
|
NOBLE_BLE_STOP_SCAN = '$onekey-noble-ble-stop-scan',
|
|
87
90
|
NOBLE_BLE_GET_DEVICE = '$onekey-noble-ble-get-device',
|
|
88
91
|
NOBLE_BLE_CONNECT = '$onekey-noble-ble-connect',
|
|
92
|
+
// Logical end-of-operation from the renderer (keep-alive): the physical link
|
|
93
|
+
// stays up but the main process starts its idle-disconnect countdown.
|
|
94
|
+
NOBLE_BLE_RELEASE = '$onekey-noble-ble-release',
|
|
89
95
|
NOBLE_BLE_DISCONNECT = '$onekey-noble-ble-disconnect',
|
|
90
96
|
NOBLE_BLE_WRITE = '$onekey-noble-ble-write',
|
|
91
97
|
NOBLE_BLE_SUBSCRIBE = '$onekey-noble-ble-subscribe',
|
|
92
98
|
NOBLE_BLE_UNSUBSCRIBE = '$onekey-noble-ble-unsubscribe',
|
|
93
99
|
NOBLE_BLE_NOTIFICATION = '$onekey-noble-ble-notification',
|
|
100
|
+
NOBLE_BLE_MTU_CHANGED = '$onekey-noble-ble-mtu-changed',
|
|
94
101
|
NOBLE_BLE_CANCEL_PAIRING = '$onekey-noble-ble-cancel-pairing',
|
|
95
102
|
}
|
|
96
103
|
|
|
@@ -148,9 +155,170 @@ export const isOnekeyDevice = (name: string | null, id?: string): boolean => {
|
|
|
148
155
|
if (
|
|
149
156
|
normalizedName.startsWith('touch ') ||
|
|
150
157
|
normalizedName.startsWith('pro ') ||
|
|
151
|
-
normalizedName.startsWith('pro2
|
|
158
|
+
normalizedName.startsWith('pro2') ||
|
|
159
|
+
normalizedName.startsWith('neo')
|
|
152
160
|
) {
|
|
153
161
|
return true;
|
|
154
162
|
}
|
|
163
|
+
const compactName = compactBleName(normalizedName);
|
|
164
|
+
if (PRO2_COMPACT_NAME_PATTERN.test(compactName) || NEO_COMPACT_NAME_PATTERN.test(compactName)) {
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
155
167
|
return isOneKeyShortName(normalizedName);
|
|
156
168
|
};
|
|
169
|
+
|
|
170
|
+
export const inferProtocolHintFromUsbId = (vendorId?: number | null, productId?: number | null) =>
|
|
171
|
+
ONEKEY_PROTOCOL_V2_USB_IDS.some(id => id.vendorId === vendorId && id.productId === productId)
|
|
172
|
+
? ('V2' as const)
|
|
173
|
+
: undefined;
|
|
174
|
+
|
|
175
|
+
type UsbDevicePathInput = {
|
|
176
|
+
serialNumber?: string | null;
|
|
177
|
+
vendorId?: number;
|
|
178
|
+
productId?: number;
|
|
179
|
+
productName?: string | null;
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
export const resolveOneKeyUsbDevicePath = (device: UsbDevicePathInput): string | undefined => {
|
|
183
|
+
const serial = device.serialNumber?.trim();
|
|
184
|
+
if (serial) return serial;
|
|
185
|
+
if (device.vendorId == null && device.productId == null && !device.productName) {
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const vendorId = (device.vendorId ?? 0).toString(16).padStart(4, '0');
|
|
190
|
+
const productId = (device.productId ?? 0).toString(16).padStart(4, '0');
|
|
191
|
+
const product = (device.productName ?? 'onekey')
|
|
192
|
+
.trim()
|
|
193
|
+
.toLowerCase()
|
|
194
|
+
.replace(/\s+/g, '-')
|
|
195
|
+
.replace(/[^a-z0-9-]/g, '');
|
|
196
|
+
return `usb-${vendorId}-${productId}-${product || 'onekey'}`;
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
type BluetoothDeviceIdentity = {
|
|
200
|
+
id?: string;
|
|
201
|
+
name?: string | null;
|
|
202
|
+
localName?: string | null;
|
|
203
|
+
serviceUuids?: Array<string | null | undefined> | null;
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
const BLUETOOTH_BASE_UUID_SUFFIX = '00001000800000805f9b34fb';
|
|
207
|
+
|
|
208
|
+
export const normalizeBleUuid = (uuid?: string | null) =>
|
|
209
|
+
(uuid ?? '').replace(/-/g, '').toLowerCase();
|
|
210
|
+
|
|
211
|
+
export const createKnownBleUuidAliases = (uuid: string): ReadonlySet<string> => {
|
|
212
|
+
const normalized = normalizeBleUuid(uuid);
|
|
213
|
+
const aliases = new Set([normalized]);
|
|
214
|
+
|
|
215
|
+
if (normalized.length !== 32 || !normalized.endsWith(BLUETOOTH_BASE_UUID_SUFFIX)) {
|
|
216
|
+
return aliases;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const assignedNumber = normalized.slice(0, 8);
|
|
220
|
+
aliases.add(assignedNumber);
|
|
221
|
+
if (assignedNumber.startsWith('0000')) {
|
|
222
|
+
aliases.add(assignedNumber.slice(4));
|
|
223
|
+
}
|
|
224
|
+
return aliases;
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
export const matchesKnownBleUuid = (
|
|
228
|
+
actualUuid: string | null | undefined,
|
|
229
|
+
aliases: ReadonlySet<string>
|
|
230
|
+
) => aliases.has(normalizeBleUuid(actualUuid));
|
|
231
|
+
|
|
232
|
+
const ONEKEY_COMMUNICATION_SERVICE_ALIASES = createKnownBleUuidAliases(ONEKEY_SERVICE_UUID);
|
|
233
|
+
const FIDO_SERVICE_ALIASES = createKnownBleUuidAliases('0000fffd-0000-1000-8000-00805f9b34fb');
|
|
234
|
+
const PRO2_COMPACT_NAME_PATTERN = /^(?:onekey)?pro2[a-f0-9]{4}$/i;
|
|
235
|
+
const NEO_COMPACT_NAME_PATTERN = /^(?:onekey)?neo[a-f0-9]{4}$/i;
|
|
236
|
+
const FIND_MY_COMPACT_SUFFIXES = [
|
|
237
|
+
'findemy',
|
|
238
|
+
'findem',
|
|
239
|
+
'finde',
|
|
240
|
+
'findmy',
|
|
241
|
+
'findm',
|
|
242
|
+
'find',
|
|
243
|
+
'fin',
|
|
244
|
+
] as const;
|
|
245
|
+
const COMPLETE_FIND_MY_COMPACT_SUFFIXES = ['findemy', 'findmy'] as const;
|
|
246
|
+
|
|
247
|
+
const compactBleName = (value: string) =>
|
|
248
|
+
Array.from(value)
|
|
249
|
+
.filter(character => character !== '-' && character.trim() !== '')
|
|
250
|
+
.join('')
|
|
251
|
+
.toLowerCase();
|
|
252
|
+
|
|
253
|
+
const getFindMyCompactSuffix = (compactName: string) =>
|
|
254
|
+
FIND_MY_COMPACT_SUFFIXES.find(candidate => compactName.endsWith(candidate));
|
|
255
|
+
|
|
256
|
+
const getPro2FindMyBaseLength = (value: string) => {
|
|
257
|
+
const compactName = compactBleName(value);
|
|
258
|
+
const suffix = getFindMyCompactSuffix(compactName);
|
|
259
|
+
if (!suffix) return undefined;
|
|
260
|
+
|
|
261
|
+
const compactBaseName = compactName.slice(0, -suffix.length);
|
|
262
|
+
return PRO2_COMPACT_NAME_PATTERN.test(compactBaseName) ? compactBaseName.length : undefined;
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
export const isPro2FindMyAdvertisementName = (value?: string | null) => {
|
|
266
|
+
if (!value) return false;
|
|
267
|
+
if (getPro2FindMyBaseLength(value) !== undefined) return true;
|
|
268
|
+
|
|
269
|
+
const compactName = compactBleName(value);
|
|
270
|
+
const suffix = COMPLETE_FIND_MY_COMPACT_SUFFIXES.find(candidate =>
|
|
271
|
+
compactName.endsWith(candidate)
|
|
272
|
+
);
|
|
273
|
+
if (!suffix) return false;
|
|
274
|
+
|
|
275
|
+
return compactName.slice(0, -suffix.length).includes('pro2');
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
export const normalizePro2FindMyAdvertisementName = (value: string) => {
|
|
279
|
+
const baseLength = getPro2FindMyBaseLength(value);
|
|
280
|
+
if (baseLength === undefined) return value;
|
|
281
|
+
|
|
282
|
+
let compactLength = 0;
|
|
283
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
284
|
+
const character = value[index];
|
|
285
|
+
if (character !== '-' && character.trim() !== '') {
|
|
286
|
+
compactLength += 1;
|
|
287
|
+
if (compactLength === baseLength) {
|
|
288
|
+
return value.slice(0, index + 1).trimEnd();
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return value;
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
export const hasOnekeyCommunicationService = (
|
|
296
|
+
serviceUuids: Array<string | null | undefined> | null | undefined
|
|
297
|
+
) =>
|
|
298
|
+
(serviceUuids ?? []).some(uuid =>
|
|
299
|
+
matchesKnownBleUuid(uuid, ONEKEY_COMMUNICATION_SERVICE_ALIASES)
|
|
300
|
+
);
|
|
301
|
+
|
|
302
|
+
export const isOnekeyBluetoothDevice = ({
|
|
303
|
+
id,
|
|
304
|
+
name,
|
|
305
|
+
localName,
|
|
306
|
+
serviceUuids,
|
|
307
|
+
}: BluetoothDeviceIdentity): boolean => {
|
|
308
|
+
const advertisedServiceUuids = serviceUuids ?? [];
|
|
309
|
+
if (hasOnekeyCommunicationService(advertisedServiceUuids)) {
|
|
310
|
+
return true;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Android can return a connected Find My peripheral without its advertised
|
|
314
|
+
// services. Do not let the Pro2-looking name fall through to name discovery.
|
|
315
|
+
if (isPro2FindMyAdvertisementName(name) || isPro2FindMyAdvertisementName(localName)) {
|
|
316
|
+
return false;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
if (advertisedServiceUuids.some(uuid => matchesKnownBleUuid(uuid, FIDO_SERVICE_ALIASES))) {
|
|
320
|
+
return false;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
return isOnekeyDevice(name ?? null, id) || isOnekeyDevice(localName ?? null, id);
|
|
324
|
+
};
|