@onekeyfe/hd-shared 1.2.0-alpha.16 → 1.2.0-alpha.161
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 +31 -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 +309 -3
- package/dist/index.js +136 -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 +188 -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,17 +37,44 @@ 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
|
}
|
|
49
|
+
export declare enum EBleDisconnectReason {
|
|
50
|
+
DeviceDisconnected = "device-disconnected",
|
|
51
|
+
IdleKeepAlive = "idle-keep-alive"
|
|
52
|
+
}
|
|
43
53
|
export declare const ONEKEY_SERVICE_UUID = "00000001-0000-1000-8000-00805f9b34fb";
|
|
44
54
|
export declare const ONEKEY_WRITE_CHARACTERISTIC_UUID = "00000002-0000-1000-8000-00805f9b34fb";
|
|
45
55
|
export declare const ONEKEY_NOTIFY_CHARACTERISTIC_UUID = "00000003-0000-1000-8000-00805f9b34fb";
|
|
46
56
|
export declare const isHeaderChunk: (chunk: Buffer | Uint8Array) => boolean;
|
|
47
57
|
export declare const isOnekeyDevice: (name: string | null, id?: string) => boolean;
|
|
58
|
+
export declare const inferProtocolHintFromUsbId: (vendorId?: number | null, productId?: number | null) => "V2" | undefined;
|
|
59
|
+
type UsbDevicePathInput = {
|
|
60
|
+
serialNumber?: string | null;
|
|
61
|
+
vendorId?: number;
|
|
62
|
+
productId?: number;
|
|
63
|
+
productName?: string | null;
|
|
64
|
+
};
|
|
65
|
+
export declare const resolveOneKeyUsbDevicePath: (device: UsbDevicePathInput) => string | undefined;
|
|
66
|
+
type BluetoothDeviceIdentity = {
|
|
67
|
+
id?: string;
|
|
68
|
+
name?: string | null;
|
|
69
|
+
localName?: string | null;
|
|
70
|
+
serviceUuids?: Array<string | null | undefined> | null;
|
|
71
|
+
};
|
|
72
|
+
export declare const normalizeBleUuid: (uuid?: string | null) => string;
|
|
73
|
+
export declare const createKnownBleUuidAliases: (uuid: string) => ReadonlySet<string>;
|
|
74
|
+
export declare const matchesKnownBleUuid: (actualUuid: string | null | undefined, aliases: ReadonlySet<string>) => boolean;
|
|
75
|
+
export declare const isPro2FindMyAdvertisementName: (value?: string | null) => boolean;
|
|
76
|
+
export declare const normalizePro2FindMyAdvertisementName: (value: string) => string;
|
|
77
|
+
export declare const hasOnekeyCommunicationService: (serviceUuids: Array<string | null | undefined> | null | undefined) => boolean;
|
|
78
|
+
export declare const isOnekeyBluetoothDevice: ({ id, name, localName, serviceUuids, }: BluetoothDeviceIdentity) => boolean;
|
|
48
79
|
export {};
|
|
49
80
|
//# 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;AAUD,oBAAY,oBAAoB;IAE9B,kBAAkB,wBAAwB;IAE1C,aAAa,oBAAoB;CAClC;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,18 +45,55 @@ 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
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Why a BLE link went down, carried on BLE_DEVICE_DISCONNECTED.
|
|
59
|
+
*
|
|
60
|
+
* The main process frees an idle link on its own keep-alive timer, which is an
|
|
61
|
+
* internal optimisation the device knows nothing about — consumers must not
|
|
62
|
+
* treat it as "the device is gone". Only DeviceDisconnected means the
|
|
63
|
+
* peripheral actually dropped.
|
|
64
|
+
*/
|
|
65
|
+
declare enum EBleDisconnectReason {
|
|
66
|
+
/** Unsolicited peripheral drop: powered off, out of range, cable/BLE lost. */
|
|
67
|
+
DeviceDisconnected = "device-disconnected",
|
|
68
|
+
/** Main-process keep-alive timer released an idle link; device still present. */
|
|
69
|
+
IdleKeepAlive = "idle-keep-alive"
|
|
70
|
+
}
|
|
42
71
|
declare const ONEKEY_SERVICE_UUID = "00000001-0000-1000-8000-00805f9b34fb";
|
|
43
72
|
declare const ONEKEY_WRITE_CHARACTERISTIC_UUID = "00000002-0000-1000-8000-00805f9b34fb";
|
|
44
73
|
declare const ONEKEY_NOTIFY_CHARACTERISTIC_UUID = "00000003-0000-1000-8000-00805f9b34fb";
|
|
45
74
|
declare const isHeaderChunk: (chunk: Buffer | Uint8Array) => boolean;
|
|
46
75
|
declare const isOnekeyDevice: (name: string | null, id?: string) => boolean;
|
|
76
|
+
declare const inferProtocolHintFromUsbId: (vendorId?: number | null, productId?: number | null) => "V2" | undefined;
|
|
77
|
+
type UsbDevicePathInput = {
|
|
78
|
+
serialNumber?: string | null;
|
|
79
|
+
vendorId?: number;
|
|
80
|
+
productId?: number;
|
|
81
|
+
productName?: string | null;
|
|
82
|
+
};
|
|
83
|
+
declare const resolveOneKeyUsbDevicePath: (device: UsbDevicePathInput) => string | undefined;
|
|
84
|
+
type BluetoothDeviceIdentity = {
|
|
85
|
+
id?: string;
|
|
86
|
+
name?: string | null;
|
|
87
|
+
localName?: string | null;
|
|
88
|
+
serviceUuids?: Array<string | null | undefined> | null;
|
|
89
|
+
};
|
|
90
|
+
declare const normalizeBleUuid: (uuid?: string | null) => string;
|
|
91
|
+
declare const createKnownBleUuidAliases: (uuid: string) => ReadonlySet<string>;
|
|
92
|
+
declare const matchesKnownBleUuid: (actualUuid: string | null | undefined, aliases: ReadonlySet<string>) => boolean;
|
|
93
|
+
declare const isPro2FindMyAdvertisementName: (value?: string | null) => boolean;
|
|
94
|
+
declare const normalizePro2FindMyAdvertisementName: (value: string) => string;
|
|
95
|
+
declare const hasOnekeyCommunicationService: (serviceUuids: Array<string | null | undefined> | null | undefined) => boolean;
|
|
96
|
+
declare const isOnekeyBluetoothDevice: ({ id, name, localName, serviceUuids, }: BluetoothDeviceIdentity) => boolean;
|
|
47
97
|
|
|
48
98
|
type Deferred<T, I = any, D = any> = {
|
|
49
99
|
id?: I;
|
|
@@ -76,53 +126,201 @@ declare class HardwareError extends Error {
|
|
|
76
126
|
constructor(hardwareError: IHardwareError | string);
|
|
77
127
|
}
|
|
78
128
|
declare const HardwareErrorCode: {
|
|
129
|
+
/**
|
|
130
|
+
* This error can be thrown when unexpected error occurred and in most cases it is related to implementation bug.
|
|
131
|
+
* Original message is available in message property.
|
|
132
|
+
*/
|
|
79
133
|
readonly UnknownError: 0;
|
|
134
|
+
/**
|
|
135
|
+
* Firmware version mismatch
|
|
136
|
+
*/
|
|
80
137
|
readonly DeviceFwException: 101;
|
|
138
|
+
/**
|
|
139
|
+
* Device unexpected mode
|
|
140
|
+
*/
|
|
81
141
|
readonly DeviceUnexpectedMode: 102;
|
|
142
|
+
/**
|
|
143
|
+
* Device list is not initialized
|
|
144
|
+
*/
|
|
82
145
|
readonly DeviceListNotInitialized: 103;
|
|
146
|
+
/**
|
|
147
|
+
* Please select the connected device
|
|
148
|
+
*/
|
|
83
149
|
readonly SelectDevice: 104;
|
|
150
|
+
/**
|
|
151
|
+
* Device not found
|
|
152
|
+
*/
|
|
84
153
|
readonly DeviceNotFound: 105;
|
|
154
|
+
/**
|
|
155
|
+
* Device is not initialized
|
|
156
|
+
*/
|
|
85
157
|
readonly DeviceInitializeFailed: 106;
|
|
158
|
+
/**
|
|
159
|
+
* Device interrupted from another operation
|
|
160
|
+
*/
|
|
86
161
|
readonly DeviceInterruptedFromOutside: 107;
|
|
162
|
+
/**
|
|
163
|
+
* Device should be in bootloader mode
|
|
164
|
+
*/
|
|
87
165
|
readonly RequiredButInBootloaderMode: 108;
|
|
166
|
+
/**
|
|
167
|
+
* Device interrupted from user
|
|
168
|
+
*/
|
|
88
169
|
readonly DeviceInterruptedFromUser: 109;
|
|
170
|
+
/**
|
|
171
|
+
* Check device id is same
|
|
172
|
+
*/
|
|
89
173
|
readonly DeviceCheckDeviceIdError: 110;
|
|
174
|
+
/**
|
|
175
|
+
* Do not support passphrase
|
|
176
|
+
* @params: { require: string }
|
|
177
|
+
*/
|
|
90
178
|
readonly DeviceNotSupportPassphrase: 111;
|
|
91
179
|
readonly DeviceCheckPassphraseStateError: 112;
|
|
180
|
+
/**
|
|
181
|
+
* use passphrase, but passphrase is not opened
|
|
182
|
+
*/
|
|
92
183
|
readonly DeviceNotOpenedPassphrase: 113;
|
|
184
|
+
/**
|
|
185
|
+
* not use passphrase, but passphrase is opened
|
|
186
|
+
*/
|
|
93
187
|
readonly DeviceOpenedPassphrase: 114;
|
|
188
|
+
/**
|
|
189
|
+
* Detect hardware that is in bootloader mode and return an error.
|
|
190
|
+
*/
|
|
94
191
|
readonly DeviceDetectInBootloaderMode: 115;
|
|
192
|
+
/**
|
|
193
|
+
* Device not allow in bootloader mode
|
|
194
|
+
*/
|
|
95
195
|
readonly NotAllowInBootloaderMode: 116;
|
|
196
|
+
/**
|
|
197
|
+
* Device is busy
|
|
198
|
+
*/
|
|
96
199
|
readonly DeviceBusy: 117;
|
|
200
|
+
/**
|
|
201
|
+
* Device check unlock type not match error
|
|
202
|
+
*/
|
|
97
203
|
readonly DeviceCheckUnlockTypeError: 118;
|
|
204
|
+
/**
|
|
205
|
+
* Not initialized
|
|
206
|
+
*/
|
|
98
207
|
readonly NotInitialized: 200;
|
|
208
|
+
/**
|
|
209
|
+
* Iframe not initialized
|
|
210
|
+
*/
|
|
99
211
|
readonly IFrameNotInitialized: 300;
|
|
212
|
+
/**
|
|
213
|
+
* iframe repeat initialization
|
|
214
|
+
*/
|
|
100
215
|
readonly IFrameAleradyInitialized: 301;
|
|
216
|
+
/**
|
|
217
|
+
* iframe load failure
|
|
218
|
+
*/
|
|
101
219
|
readonly IFrameLoadFail: 302;
|
|
220
|
+
/**
|
|
221
|
+
* init iframe time out
|
|
222
|
+
*/
|
|
102
223
|
readonly IframeTimeout: 303;
|
|
224
|
+
/**
|
|
225
|
+
* iframe blocked
|
|
226
|
+
*/
|
|
103
227
|
readonly IframeBlocked: 304;
|
|
228
|
+
/**
|
|
229
|
+
* iframe host not trust
|
|
230
|
+
*/
|
|
104
231
|
readonly IframeDistrust: 305;
|
|
232
|
+
/**
|
|
233
|
+
* Runtime errors during method execution
|
|
234
|
+
*/
|
|
105
235
|
readonly CallMethodError: 400;
|
|
236
|
+
/**
|
|
237
|
+
* Method does not responding
|
|
238
|
+
*/
|
|
106
239
|
readonly CallMethodNotResponse: 404;
|
|
240
|
+
/**
|
|
241
|
+
* Call method invalid parameter
|
|
242
|
+
*/
|
|
107
243
|
readonly CallMethodInvalidParameter: 405;
|
|
244
|
+
/**
|
|
245
|
+
* firmware update download failed
|
|
246
|
+
*/
|
|
108
247
|
readonly FirmwareUpdateDownloadFailed: 406;
|
|
248
|
+
/**
|
|
249
|
+
* Call method not supported, need update firmware
|
|
250
|
+
* @params: { current: string, require: string }
|
|
251
|
+
*/
|
|
109
252
|
readonly CallMethodNeedUpgradeFirmware: 407;
|
|
253
|
+
/**
|
|
254
|
+
* Call method not supported, is deprecated
|
|
255
|
+
* @params: { current: string, deprecated: string }
|
|
256
|
+
*/
|
|
110
257
|
readonly CallMethodDeprecated: 408;
|
|
258
|
+
/**
|
|
259
|
+
* Only one device can be connected during firmware upgrade
|
|
260
|
+
*/
|
|
111
261
|
readonly FirmwareUpdateLimitOneDevice: 409;
|
|
262
|
+
/**
|
|
263
|
+
* You need to manually enter boot
|
|
264
|
+
*/
|
|
112
265
|
readonly FirmwareUpdateManuallyEnterBoot: 410;
|
|
266
|
+
/**
|
|
267
|
+
* Manual entry fails. You must manually enter the boot
|
|
268
|
+
*/
|
|
113
269
|
readonly FirmwareUpdateAutoEnterBootFailure: 411;
|
|
270
|
+
/**
|
|
271
|
+
* The new firmware has not been released yet
|
|
272
|
+
*/
|
|
114
273
|
readonly NewFirmwareUnRelease: 412;
|
|
274
|
+
/**
|
|
275
|
+
* use OneKey desktop client to update the firmware
|
|
276
|
+
* because need copy resource file to Touch
|
|
277
|
+
*/
|
|
115
278
|
readonly UseDesktopToUpdateFirmware: 413;
|
|
279
|
+
/**
|
|
280
|
+
* Mandatory firmware update
|
|
281
|
+
* @params:{ connectId: string? , deviceId: string? }
|
|
282
|
+
*/
|
|
116
283
|
readonly NewFirmwareForceUpdate: 414;
|
|
284
|
+
/**
|
|
285
|
+
* Device not support this method
|
|
286
|
+
*/
|
|
117
287
|
readonly DeviceNotSupportMethod: 415;
|
|
288
|
+
/**
|
|
289
|
+
* Forbidden key path
|
|
290
|
+
*/
|
|
118
291
|
readonly ForbiddenKeyPath: 416;
|
|
292
|
+
/**
|
|
293
|
+
* Repeat unlocking
|
|
294
|
+
* all network get address by loop need repeat unlocking
|
|
295
|
+
*/
|
|
119
296
|
readonly RepeatUnlocking: 417;
|
|
297
|
+
/**
|
|
298
|
+
* Defective firmware detected
|
|
299
|
+
*/
|
|
120
300
|
readonly DefectiveFirmware: 418;
|
|
301
|
+
/**
|
|
302
|
+
* Netword request error
|
|
303
|
+
*/
|
|
121
304
|
readonly NetworkError: 500;
|
|
305
|
+
/**
|
|
306
|
+
* Transport not configured
|
|
307
|
+
*/
|
|
122
308
|
readonly TransportNotConfigured: 600;
|
|
309
|
+
/**
|
|
310
|
+
* Transport call in progress
|
|
311
|
+
*/
|
|
123
312
|
readonly TransportCallInProgress: 601;
|
|
313
|
+
/**
|
|
314
|
+
* Transport not found
|
|
315
|
+
*/
|
|
124
316
|
readonly TransportNotFound: 602;
|
|
317
|
+
/**
|
|
318
|
+
* Transport invalid protobuf
|
|
319
|
+
*/
|
|
125
320
|
readonly TransportInvalidProtobuf: 603;
|
|
321
|
+
/**
|
|
322
|
+
* Bluetooth error code
|
|
323
|
+
*/
|
|
126
324
|
readonly BleScanError: 700;
|
|
127
325
|
readonly BlePermissionError: 701;
|
|
128
326
|
readonly BleLocationError: 702;
|
|
@@ -146,38 +344,145 @@ declare const HardwareErrorCode: {
|
|
|
146
344
|
readonly BleDeviceDisconnected: 720;
|
|
147
345
|
readonly BlePoweredOff: 721;
|
|
148
346
|
readonly BleUnsupported: 722;
|
|
347
|
+
readonly BleUnavailableWhileUsbConnected: 723;
|
|
348
|
+
/**
|
|
349
|
+
* Hardware runtiome errors
|
|
350
|
+
*/
|
|
149
351
|
readonly RuntimeError: 800;
|
|
352
|
+
/**
|
|
353
|
+
* invalid pin
|
|
354
|
+
*/
|
|
150
355
|
readonly PinInvalid: 801;
|
|
356
|
+
/**
|
|
357
|
+
* pin cancelled by user
|
|
358
|
+
*/
|
|
151
359
|
readonly PinCancelled: 802;
|
|
360
|
+
/**
|
|
361
|
+
* Action cancelled by user
|
|
362
|
+
*/
|
|
152
363
|
readonly ActionCancelled: 803;
|
|
364
|
+
/**
|
|
365
|
+
* Firmware installation failed
|
|
366
|
+
*/
|
|
153
367
|
readonly FirmwareError: 804;
|
|
368
|
+
/**
|
|
369
|
+
* transport response unexpect error
|
|
370
|
+
*/
|
|
154
371
|
readonly ResponseUnexpectTypeError: 805;
|
|
372
|
+
/**
|
|
373
|
+
* bridge network error
|
|
374
|
+
*/
|
|
155
375
|
readonly BridgeNetworkError: 806;
|
|
376
|
+
/**
|
|
377
|
+
* Bridge network timeout
|
|
378
|
+
*/
|
|
156
379
|
readonly BridgeTimeoutError: 807;
|
|
380
|
+
/**
|
|
381
|
+
* Bridge not installed
|
|
382
|
+
*/
|
|
157
383
|
readonly BridgeNotInstalled: 808;
|
|
384
|
+
/**
|
|
385
|
+
* ensure connect timeout
|
|
386
|
+
*/
|
|
158
387
|
readonly PollingTimeout: 809;
|
|
388
|
+
/**
|
|
389
|
+
* ensure connect stop polling
|
|
390
|
+
*/
|
|
159
391
|
readonly PollingStop: 810;
|
|
392
|
+
/**
|
|
393
|
+
* Device does not open blid sign
|
|
394
|
+
*/
|
|
160
395
|
readonly BlindSignDisabled: 811;
|
|
161
396
|
readonly UnexpectPassphrase: 812;
|
|
397
|
+
/**
|
|
398
|
+
* NFT file already exists
|
|
399
|
+
*/
|
|
162
400
|
readonly FileAlreadyExists: 813;
|
|
401
|
+
/**
|
|
402
|
+
* check file length error
|
|
403
|
+
*/
|
|
163
404
|
readonly CheckDownloadFileError: 814;
|
|
405
|
+
/**
|
|
406
|
+
* not in signing mode
|
|
407
|
+
*/
|
|
164
408
|
readonly NotInSigningMode: 815;
|
|
409
|
+
/**
|
|
410
|
+
* not in signing mode
|
|
411
|
+
*/
|
|
165
412
|
readonly DataOverload: 816;
|
|
413
|
+
/**
|
|
414
|
+
* device disconnected during action
|
|
415
|
+
*/
|
|
166
416
|
readonly BridgeDeviceDisconnected: 817;
|
|
417
|
+
/**
|
|
418
|
+
* BTC PSBT too many utxos
|
|
419
|
+
* @params:{ count: number }
|
|
420
|
+
*/
|
|
167
421
|
readonly BTCPsbtTooManyUtxos: 818;
|
|
422
|
+
/**
|
|
423
|
+
* EMMC file write firmware error
|
|
424
|
+
*/
|
|
168
425
|
readonly EmmcFileWriteFirmwareError: 819;
|
|
426
|
+
/**
|
|
427
|
+
* Firmware verification failed (e.g., bootloader file verify failed)
|
|
428
|
+
*/
|
|
169
429
|
readonly FirmwareVerificationFailed: 820;
|
|
430
|
+
/**
|
|
431
|
+
* Web bridge coonect needs permission
|
|
432
|
+
*/
|
|
170
433
|
readonly BridgeNeedsPermission: 821;
|
|
171
434
|
readonly CallQueueActionCancelled: 822;
|
|
435
|
+
/**
|
|
436
|
+
* Firmware downgrade not allowed
|
|
437
|
+
*/
|
|
172
438
|
readonly FirmwareDowngradeNotAllowed: 823;
|
|
439
|
+
/**
|
|
440
|
+
* Cosmos invalid JSON message, Only support Amino msgs.
|
|
441
|
+
*/
|
|
173
442
|
readonly CosmosInvalidJsonMessage: 824;
|
|
443
|
+
/**
|
|
444
|
+
* No setting provided
|
|
445
|
+
*/
|
|
174
446
|
readonly DeviceSettingsNotProvided: 825;
|
|
447
|
+
/**
|
|
448
|
+
* Language not supported
|
|
449
|
+
*/
|
|
175
450
|
readonly DeviceSettingsLanguageNotSupport: 826;
|
|
451
|
+
/**
|
|
452
|
+
* Too many inputs
|
|
453
|
+
* @params: { count?: string }
|
|
454
|
+
*/
|
|
176
455
|
readonly TooManyInputs: 827;
|
|
456
|
+
/**
|
|
457
|
+
* The two PIN entries did not match while setting/changing PIN on device
|
|
458
|
+
*/
|
|
177
459
|
readonly PinMismatch: 828;
|
|
178
|
-
|
|
460
|
+
/**
|
|
461
|
+
* Protocol V2 device must be unlocked before the requested operation.
|
|
462
|
+
* @params: { failureCode?: string; subcode?: number; firmwareMessage?: string }
|
|
463
|
+
*/
|
|
464
|
+
readonly DeviceLocked: 830;
|
|
465
|
+
/**
|
|
466
|
+
* The cached wallet session is invalid or has expired.
|
|
467
|
+
* @params: { failureCode?: string; subcode?: number; firmwareMessage?: string }
|
|
468
|
+
*/
|
|
469
|
+
readonly WalletSessionInvalid: 831;
|
|
470
|
+
/**
|
|
471
|
+
* Pro2 NFT storage has reached its item limit.
|
|
472
|
+
* @params: { count: number; limit: number }
|
|
473
|
+
*/
|
|
474
|
+
readonly NftStorageLimitReached: 832;
|
|
475
|
+
/**
|
|
476
|
+
* Lowlevel transport connect error
|
|
477
|
+
*/
|
|
179
478
|
readonly LowlevelTrasnportConnectError: 900;
|
|
479
|
+
/**
|
|
480
|
+
* Web USB or Web Bluetooth device not found or needs permission
|
|
481
|
+
*/
|
|
180
482
|
readonly WebDeviceNotFoundOrNeedsPermission: 901;
|
|
483
|
+
/**
|
|
484
|
+
* Web USB or Web Bluetooth device prompt access error
|
|
485
|
+
*/
|
|
181
486
|
readonly WebDevicePromptAccessError: 902;
|
|
182
487
|
};
|
|
183
488
|
declare const HardwareErrorCodeMessage: HardwareErrorCodeMessageMapping;
|
|
@@ -249,7 +554,8 @@ declare enum EDeviceType {
|
|
|
249
554
|
Mini = "mini",
|
|
250
555
|
Touch = "touch",
|
|
251
556
|
Pro = "pro",
|
|
252
|
-
Pro2 = "pro2"
|
|
557
|
+
Pro2 = "pro2",
|
|
558
|
+
Neo = "neo"
|
|
253
559
|
}
|
|
254
560
|
|
|
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 };
|
|
561
|
+
export { CreateErrorByMessage, CreateHardwareErrorByBridgeError, Deferred, EBleDisconnectReason, 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,13 +441,20 @@ 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 = {}));
|
|
453
|
+
exports.EBleDisconnectReason = void 0;
|
|
454
|
+
(function (EBleDisconnectReason) {
|
|
455
|
+
EBleDisconnectReason["DeviceDisconnected"] = "device-disconnected";
|
|
456
|
+
EBleDisconnectReason["IdleKeepAlive"] = "idle-keep-alive";
|
|
457
|
+
})(exports.EBleDisconnectReason || (exports.EBleDisconnectReason = {}));
|
|
444
458
|
const ONEKEY_SERVICE_UUID = '00000001-0000-1000-8000-00805f9b34fb';
|
|
445
459
|
const ONEKEY_WRITE_CHARACTERISTIC_UUID = '00000002-0000-1000-8000-00805f9b34fb';
|
|
446
460
|
const ONEKEY_NOTIFY_CHARACTERISTIC_UUID = '00000003-0000-1000-8000-00805f9b34fb';
|
|
@@ -487,11 +501,120 @@ const isOnekeyDevice = (name, id) => {
|
|
|
487
501
|
return true;
|
|
488
502
|
if (normalizedName.startsWith('touch ') ||
|
|
489
503
|
normalizedName.startsWith('pro ') ||
|
|
490
|
-
normalizedName.startsWith('pro2
|
|
504
|
+
normalizedName.startsWith('pro2') ||
|
|
505
|
+
normalizedName.startsWith('neo')) {
|
|
506
|
+
return true;
|
|
507
|
+
}
|
|
508
|
+
const compactName = compactBleName(normalizedName);
|
|
509
|
+
if (PRO2_COMPACT_NAME_PATTERN.test(compactName) || NEO_COMPACT_NAME_PATTERN.test(compactName)) {
|
|
491
510
|
return true;
|
|
492
511
|
}
|
|
493
512
|
return isOneKeyShortName(normalizedName);
|
|
494
513
|
};
|
|
514
|
+
const inferProtocolHintFromUsbId = (vendorId, productId) => ONEKEY_PROTOCOL_V2_USB_IDS.some(id => id.vendorId === vendorId && id.productId === productId)
|
|
515
|
+
? 'V2'
|
|
516
|
+
: undefined;
|
|
517
|
+
const resolveOneKeyUsbDevicePath = (device) => {
|
|
518
|
+
var _a, _b, _c, _d;
|
|
519
|
+
const serial = (_a = device.serialNumber) === null || _a === void 0 ? void 0 : _a.trim();
|
|
520
|
+
if (serial)
|
|
521
|
+
return serial;
|
|
522
|
+
if (device.vendorId == null && device.productId == null && !device.productName) {
|
|
523
|
+
return undefined;
|
|
524
|
+
}
|
|
525
|
+
const vendorId = ((_b = device.vendorId) !== null && _b !== void 0 ? _b : 0).toString(16).padStart(4, '0');
|
|
526
|
+
const productId = ((_c = device.productId) !== null && _c !== void 0 ? _c : 0).toString(16).padStart(4, '0');
|
|
527
|
+
const product = ((_d = device.productName) !== null && _d !== void 0 ? _d : 'onekey')
|
|
528
|
+
.trim()
|
|
529
|
+
.toLowerCase()
|
|
530
|
+
.replace(/\s+/g, '-')
|
|
531
|
+
.replace(/[^a-z0-9-]/g, '');
|
|
532
|
+
return `usb-${vendorId}-${productId}-${product || 'onekey'}`;
|
|
533
|
+
};
|
|
534
|
+
const BLUETOOTH_BASE_UUID_SUFFIX = '00001000800000805f9b34fb';
|
|
535
|
+
const normalizeBleUuid = (uuid) => (uuid !== null && uuid !== void 0 ? uuid : '').replace(/-/g, '').toLowerCase();
|
|
536
|
+
const createKnownBleUuidAliases = (uuid) => {
|
|
537
|
+
const normalized = normalizeBleUuid(uuid);
|
|
538
|
+
const aliases = new Set([normalized]);
|
|
539
|
+
if (normalized.length !== 32 || !normalized.endsWith(BLUETOOTH_BASE_UUID_SUFFIX)) {
|
|
540
|
+
return aliases;
|
|
541
|
+
}
|
|
542
|
+
const assignedNumber = normalized.slice(0, 8);
|
|
543
|
+
aliases.add(assignedNumber);
|
|
544
|
+
if (assignedNumber.startsWith('0000')) {
|
|
545
|
+
aliases.add(assignedNumber.slice(4));
|
|
546
|
+
}
|
|
547
|
+
return aliases;
|
|
548
|
+
};
|
|
549
|
+
const matchesKnownBleUuid = (actualUuid, aliases) => aliases.has(normalizeBleUuid(actualUuid));
|
|
550
|
+
const ONEKEY_COMMUNICATION_SERVICE_ALIASES = createKnownBleUuidAliases(ONEKEY_SERVICE_UUID);
|
|
551
|
+
const FIDO_SERVICE_ALIASES = createKnownBleUuidAliases('0000fffd-0000-1000-8000-00805f9b34fb');
|
|
552
|
+
const PRO2_COMPACT_NAME_PATTERN = /^(?:onekey)?pro2[a-f0-9]{4}$/i;
|
|
553
|
+
const NEO_COMPACT_NAME_PATTERN = /^(?:onekey)?neo[a-f0-9]{4}$/i;
|
|
554
|
+
const FIND_MY_COMPACT_SUFFIXES = [
|
|
555
|
+
'findemy',
|
|
556
|
+
'findem',
|
|
557
|
+
'finde',
|
|
558
|
+
'findmy',
|
|
559
|
+
'findm',
|
|
560
|
+
'find',
|
|
561
|
+
'fin',
|
|
562
|
+
];
|
|
563
|
+
const COMPLETE_FIND_MY_COMPACT_SUFFIXES = ['findemy', 'findmy'];
|
|
564
|
+
const compactBleName = (value) => Array.from(value)
|
|
565
|
+
.filter(character => character !== '-' && character.trim() !== '')
|
|
566
|
+
.join('')
|
|
567
|
+
.toLowerCase();
|
|
568
|
+
const getFindMyCompactSuffix = (compactName) => FIND_MY_COMPACT_SUFFIXES.find(candidate => compactName.endsWith(candidate));
|
|
569
|
+
const getPro2FindMyBaseLength = (value) => {
|
|
570
|
+
const compactName = compactBleName(value);
|
|
571
|
+
const suffix = getFindMyCompactSuffix(compactName);
|
|
572
|
+
if (!suffix)
|
|
573
|
+
return undefined;
|
|
574
|
+
const compactBaseName = compactName.slice(0, -suffix.length);
|
|
575
|
+
return PRO2_COMPACT_NAME_PATTERN.test(compactBaseName) ? compactBaseName.length : undefined;
|
|
576
|
+
};
|
|
577
|
+
const isPro2FindMyAdvertisementName = (value) => {
|
|
578
|
+
if (!value)
|
|
579
|
+
return false;
|
|
580
|
+
if (getPro2FindMyBaseLength(value) !== undefined)
|
|
581
|
+
return true;
|
|
582
|
+
const compactName = compactBleName(value);
|
|
583
|
+
const suffix = COMPLETE_FIND_MY_COMPACT_SUFFIXES.find(candidate => compactName.endsWith(candidate));
|
|
584
|
+
if (!suffix)
|
|
585
|
+
return false;
|
|
586
|
+
return compactName.slice(0, -suffix.length).includes('pro2');
|
|
587
|
+
};
|
|
588
|
+
const normalizePro2FindMyAdvertisementName = (value) => {
|
|
589
|
+
const baseLength = getPro2FindMyBaseLength(value);
|
|
590
|
+
if (baseLength === undefined)
|
|
591
|
+
return value;
|
|
592
|
+
let compactLength = 0;
|
|
593
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
594
|
+
const character = value[index];
|
|
595
|
+
if (character !== '-' && character.trim() !== '') {
|
|
596
|
+
compactLength += 1;
|
|
597
|
+
if (compactLength === baseLength) {
|
|
598
|
+
return value.slice(0, index + 1).trimEnd();
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
return value;
|
|
603
|
+
};
|
|
604
|
+
const hasOnekeyCommunicationService = (serviceUuids) => (serviceUuids !== null && serviceUuids !== void 0 ? serviceUuids : []).some(uuid => matchesKnownBleUuid(uuid, ONEKEY_COMMUNICATION_SERVICE_ALIASES));
|
|
605
|
+
const isOnekeyBluetoothDevice = ({ id, name, localName, serviceUuids, }) => {
|
|
606
|
+
const advertisedServiceUuids = serviceUuids !== null && serviceUuids !== void 0 ? serviceUuids : [];
|
|
607
|
+
if (hasOnekeyCommunicationService(advertisedServiceUuids)) {
|
|
608
|
+
return true;
|
|
609
|
+
}
|
|
610
|
+
if (isPro2FindMyAdvertisementName(name) || isPro2FindMyAdvertisementName(localName)) {
|
|
611
|
+
return false;
|
|
612
|
+
}
|
|
613
|
+
if (advertisedServiceUuids.some(uuid => matchesKnownBleUuid(uuid, FIDO_SERVICE_ALIASES))) {
|
|
614
|
+
return false;
|
|
615
|
+
}
|
|
616
|
+
return isOnekeyDevice(name !== null && name !== void 0 ? name : null, id) || isOnekeyDevice(localName !== null && localName !== void 0 ? localName : null, id);
|
|
617
|
+
};
|
|
495
618
|
|
|
496
619
|
/******************************************************************************
|
|
497
620
|
Copyright (c) Microsoft Corporation.
|
|
@@ -564,6 +687,7 @@ exports.EDeviceType = void 0;
|
|
|
564
687
|
EDeviceType["Touch"] = "touch";
|
|
565
688
|
EDeviceType["Pro"] = "pro";
|
|
566
689
|
EDeviceType["Pro2"] = "pro2";
|
|
690
|
+
EDeviceType["Neo"] = "neo";
|
|
567
691
|
})(exports.EDeviceType || (exports.EDeviceType = {}));
|
|
568
692
|
|
|
569
693
|
exports.CreateErrorByMessage = CreateErrorByMessage;
|
|
@@ -576,6 +700,7 @@ exports.HardwareError = HardwareError;
|
|
|
576
700
|
exports.HardwareErrorCode = HardwareErrorCode;
|
|
577
701
|
exports.HardwareErrorCodeMessage = HardwareErrorCodeMessage;
|
|
578
702
|
exports.ONEKEY_NOTIFY_CHARACTERISTIC_UUID = ONEKEY_NOTIFY_CHARACTERISTIC_UUID;
|
|
703
|
+
exports.ONEKEY_PROTOCOL_V2_USB_IDS = ONEKEY_PROTOCOL_V2_USB_IDS;
|
|
579
704
|
exports.ONEKEY_SERVICE_UUID = ONEKEY_SERVICE_UUID;
|
|
580
705
|
exports.ONEKEY_WEBUSB_FILTER = ONEKEY_WEBUSB_FILTER;
|
|
581
706
|
exports.ONEKEY_WRITE_CHARACTERISTIC_UUID = ONEKEY_WRITE_CHARACTERISTIC_UUID;
|
|
@@ -584,11 +709,20 @@ exports.createDefectiveFirmwareError = createDefectiveFirmwareError;
|
|
|
584
709
|
exports.createDeferred = createDeferred;
|
|
585
710
|
exports.createDeprecatedHardwareError = createDeprecatedHardwareError;
|
|
586
711
|
exports.createDeviceNotSupportMethodError = createDeviceNotSupportMethodError;
|
|
712
|
+
exports.createKnownBleUuidAliases = createKnownBleUuidAliases;
|
|
587
713
|
exports.createNeedUpgradeFirmwareHardwareError = createNeedUpgradeFirmwareHardwareError;
|
|
588
714
|
exports.createNewFirmwareForceUpdateHardwareError = createNewFirmwareForceUpdateHardwareError;
|
|
589
715
|
exports.createNewFirmwareUnReleaseHardwareError = createNewFirmwareUnReleaseHardwareError;
|
|
716
|
+
exports.hasOnekeyCommunicationService = hasOnekeyCommunicationService;
|
|
717
|
+
exports.inferProtocolHintFromUsbId = inferProtocolHintFromUsbId;
|
|
590
718
|
exports.isHeaderChunk = isHeaderChunk;
|
|
591
719
|
exports.isKnownTrezorWebUsbDevice = isKnownTrezorWebUsbDevice;
|
|
720
|
+
exports.isOnekeyBluetoothDevice = isOnekeyBluetoothDevice;
|
|
592
721
|
exports.isOnekeyDevice = isOnekeyDevice;
|
|
722
|
+
exports.isPro2FindMyAdvertisementName = isPro2FindMyAdvertisementName;
|
|
723
|
+
exports.matchesKnownBleUuid = matchesKnownBleUuid;
|
|
724
|
+
exports.normalizeBleUuid = normalizeBleUuid;
|
|
725
|
+
exports.normalizePro2FindMyAdvertisementName = normalizePro2FindMyAdvertisementName;
|
|
726
|
+
exports.resolveOneKeyUsbDevicePath = resolveOneKeyUsbDevicePath;
|
|
593
727
|
exports.serializeError = serializeError;
|
|
594
728
|
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.161",
|
|
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": "06316117fc9a7ebaecea1ca583b2d105709361bf"
|
|
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,14 +89,33 @@ 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
|
|
|
104
|
+
/**
|
|
105
|
+
* Why a BLE link went down, carried on BLE_DEVICE_DISCONNECTED.
|
|
106
|
+
*
|
|
107
|
+
* The main process frees an idle link on its own keep-alive timer, which is an
|
|
108
|
+
* internal optimisation the device knows nothing about — consumers must not
|
|
109
|
+
* treat it as "the device is gone". Only DeviceDisconnected means the
|
|
110
|
+
* peripheral actually dropped.
|
|
111
|
+
*/
|
|
112
|
+
export enum EBleDisconnectReason {
|
|
113
|
+
/** Unsolicited peripheral drop: powered off, out of range, cable/BLE lost. */
|
|
114
|
+
DeviceDisconnected = 'device-disconnected',
|
|
115
|
+
/** Main-process keep-alive timer released an idle link; device still present. */
|
|
116
|
+
IdleKeepAlive = 'idle-keep-alive',
|
|
117
|
+
}
|
|
118
|
+
|
|
97
119
|
export const ONEKEY_SERVICE_UUID = '00000001-0000-1000-8000-00805f9b34fb';
|
|
98
120
|
export const ONEKEY_WRITE_CHARACTERISTIC_UUID = '00000002-0000-1000-8000-00805f9b34fb';
|
|
99
121
|
export const ONEKEY_NOTIFY_CHARACTERISTIC_UUID = '00000003-0000-1000-8000-00805f9b34fb';
|
|
@@ -148,9 +170,170 @@ export const isOnekeyDevice = (name: string | null, id?: string): boolean => {
|
|
|
148
170
|
if (
|
|
149
171
|
normalizedName.startsWith('touch ') ||
|
|
150
172
|
normalizedName.startsWith('pro ') ||
|
|
151
|
-
normalizedName.startsWith('pro2
|
|
173
|
+
normalizedName.startsWith('pro2') ||
|
|
174
|
+
normalizedName.startsWith('neo')
|
|
152
175
|
) {
|
|
153
176
|
return true;
|
|
154
177
|
}
|
|
178
|
+
const compactName = compactBleName(normalizedName);
|
|
179
|
+
if (PRO2_COMPACT_NAME_PATTERN.test(compactName) || NEO_COMPACT_NAME_PATTERN.test(compactName)) {
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
155
182
|
return isOneKeyShortName(normalizedName);
|
|
156
183
|
};
|
|
184
|
+
|
|
185
|
+
export const inferProtocolHintFromUsbId = (vendorId?: number | null, productId?: number | null) =>
|
|
186
|
+
ONEKEY_PROTOCOL_V2_USB_IDS.some(id => id.vendorId === vendorId && id.productId === productId)
|
|
187
|
+
? ('V2' as const)
|
|
188
|
+
: undefined;
|
|
189
|
+
|
|
190
|
+
type UsbDevicePathInput = {
|
|
191
|
+
serialNumber?: string | null;
|
|
192
|
+
vendorId?: number;
|
|
193
|
+
productId?: number;
|
|
194
|
+
productName?: string | null;
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
export const resolveOneKeyUsbDevicePath = (device: UsbDevicePathInput): string | undefined => {
|
|
198
|
+
const serial = device.serialNumber?.trim();
|
|
199
|
+
if (serial) return serial;
|
|
200
|
+
if (device.vendorId == null && device.productId == null && !device.productName) {
|
|
201
|
+
return undefined;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const vendorId = (device.vendorId ?? 0).toString(16).padStart(4, '0');
|
|
205
|
+
const productId = (device.productId ?? 0).toString(16).padStart(4, '0');
|
|
206
|
+
const product = (device.productName ?? 'onekey')
|
|
207
|
+
.trim()
|
|
208
|
+
.toLowerCase()
|
|
209
|
+
.replace(/\s+/g, '-')
|
|
210
|
+
.replace(/[^a-z0-9-]/g, '');
|
|
211
|
+
return `usb-${vendorId}-${productId}-${product || 'onekey'}`;
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
type BluetoothDeviceIdentity = {
|
|
215
|
+
id?: string;
|
|
216
|
+
name?: string | null;
|
|
217
|
+
localName?: string | null;
|
|
218
|
+
serviceUuids?: Array<string | null | undefined> | null;
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
const BLUETOOTH_BASE_UUID_SUFFIX = '00001000800000805f9b34fb';
|
|
222
|
+
|
|
223
|
+
export const normalizeBleUuid = (uuid?: string | null) =>
|
|
224
|
+
(uuid ?? '').replace(/-/g, '').toLowerCase();
|
|
225
|
+
|
|
226
|
+
export const createKnownBleUuidAliases = (uuid: string): ReadonlySet<string> => {
|
|
227
|
+
const normalized = normalizeBleUuid(uuid);
|
|
228
|
+
const aliases = new Set([normalized]);
|
|
229
|
+
|
|
230
|
+
if (normalized.length !== 32 || !normalized.endsWith(BLUETOOTH_BASE_UUID_SUFFIX)) {
|
|
231
|
+
return aliases;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const assignedNumber = normalized.slice(0, 8);
|
|
235
|
+
aliases.add(assignedNumber);
|
|
236
|
+
if (assignedNumber.startsWith('0000')) {
|
|
237
|
+
aliases.add(assignedNumber.slice(4));
|
|
238
|
+
}
|
|
239
|
+
return aliases;
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
export const matchesKnownBleUuid = (
|
|
243
|
+
actualUuid: string | null | undefined,
|
|
244
|
+
aliases: ReadonlySet<string>
|
|
245
|
+
) => aliases.has(normalizeBleUuid(actualUuid));
|
|
246
|
+
|
|
247
|
+
const ONEKEY_COMMUNICATION_SERVICE_ALIASES = createKnownBleUuidAliases(ONEKEY_SERVICE_UUID);
|
|
248
|
+
const FIDO_SERVICE_ALIASES = createKnownBleUuidAliases('0000fffd-0000-1000-8000-00805f9b34fb');
|
|
249
|
+
const PRO2_COMPACT_NAME_PATTERN = /^(?:onekey)?pro2[a-f0-9]{4}$/i;
|
|
250
|
+
const NEO_COMPACT_NAME_PATTERN = /^(?:onekey)?neo[a-f0-9]{4}$/i;
|
|
251
|
+
const FIND_MY_COMPACT_SUFFIXES = [
|
|
252
|
+
'findemy',
|
|
253
|
+
'findem',
|
|
254
|
+
'finde',
|
|
255
|
+
'findmy',
|
|
256
|
+
'findm',
|
|
257
|
+
'find',
|
|
258
|
+
'fin',
|
|
259
|
+
] as const;
|
|
260
|
+
const COMPLETE_FIND_MY_COMPACT_SUFFIXES = ['findemy', 'findmy'] as const;
|
|
261
|
+
|
|
262
|
+
const compactBleName = (value: string) =>
|
|
263
|
+
Array.from(value)
|
|
264
|
+
.filter(character => character !== '-' && character.trim() !== '')
|
|
265
|
+
.join('')
|
|
266
|
+
.toLowerCase();
|
|
267
|
+
|
|
268
|
+
const getFindMyCompactSuffix = (compactName: string) =>
|
|
269
|
+
FIND_MY_COMPACT_SUFFIXES.find(candidate => compactName.endsWith(candidate));
|
|
270
|
+
|
|
271
|
+
const getPro2FindMyBaseLength = (value: string) => {
|
|
272
|
+
const compactName = compactBleName(value);
|
|
273
|
+
const suffix = getFindMyCompactSuffix(compactName);
|
|
274
|
+
if (!suffix) return undefined;
|
|
275
|
+
|
|
276
|
+
const compactBaseName = compactName.slice(0, -suffix.length);
|
|
277
|
+
return PRO2_COMPACT_NAME_PATTERN.test(compactBaseName) ? compactBaseName.length : undefined;
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
export const isPro2FindMyAdvertisementName = (value?: string | null) => {
|
|
281
|
+
if (!value) return false;
|
|
282
|
+
if (getPro2FindMyBaseLength(value) !== undefined) return true;
|
|
283
|
+
|
|
284
|
+
const compactName = compactBleName(value);
|
|
285
|
+
const suffix = COMPLETE_FIND_MY_COMPACT_SUFFIXES.find(candidate =>
|
|
286
|
+
compactName.endsWith(candidate)
|
|
287
|
+
);
|
|
288
|
+
if (!suffix) return false;
|
|
289
|
+
|
|
290
|
+
return compactName.slice(0, -suffix.length).includes('pro2');
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
export const normalizePro2FindMyAdvertisementName = (value: string) => {
|
|
294
|
+
const baseLength = getPro2FindMyBaseLength(value);
|
|
295
|
+
if (baseLength === undefined) return value;
|
|
296
|
+
|
|
297
|
+
let compactLength = 0;
|
|
298
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
299
|
+
const character = value[index];
|
|
300
|
+
if (character !== '-' && character.trim() !== '') {
|
|
301
|
+
compactLength += 1;
|
|
302
|
+
if (compactLength === baseLength) {
|
|
303
|
+
return value.slice(0, index + 1).trimEnd();
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return value;
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
export const hasOnekeyCommunicationService = (
|
|
311
|
+
serviceUuids: Array<string | null | undefined> | null | undefined
|
|
312
|
+
) =>
|
|
313
|
+
(serviceUuids ?? []).some(uuid =>
|
|
314
|
+
matchesKnownBleUuid(uuid, ONEKEY_COMMUNICATION_SERVICE_ALIASES)
|
|
315
|
+
);
|
|
316
|
+
|
|
317
|
+
export const isOnekeyBluetoothDevice = ({
|
|
318
|
+
id,
|
|
319
|
+
name,
|
|
320
|
+
localName,
|
|
321
|
+
serviceUuids,
|
|
322
|
+
}: BluetoothDeviceIdentity): boolean => {
|
|
323
|
+
const advertisedServiceUuids = serviceUuids ?? [];
|
|
324
|
+
if (hasOnekeyCommunicationService(advertisedServiceUuids)) {
|
|
325
|
+
return true;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// Android can return a connected Find My peripheral without its advertised
|
|
329
|
+
// services. Do not let the Pro2-looking name fall through to name discovery.
|
|
330
|
+
if (isPro2FindMyAdvertisementName(name) || isPro2FindMyAdvertisementName(localName)) {
|
|
331
|
+
return false;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
if (advertisedServiceUuids.some(uuid => matchesKnownBleUuid(uuid, FIDO_SERVICE_ALIASES))) {
|
|
335
|
+
return false;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
return isOnekeyDevice(name ?? null, id) || isOnekeyDevice(localName ?? null, id);
|
|
339
|
+
};
|