@onekeyfe/hd-shared 1.2.0-alpha.99 → 1.2.0

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.
@@ -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;
@@ -124,6 +125,8 @@ export declare const HardwareErrorCode: {
124
125
  };
125
126
  export declare const HardwareErrorCodeMessage: HardwareErrorCodeMessageMapping;
126
127
  export declare const TypedError: (hardwareError: ErrorCodeUnion | string, message?: string, params?: any) => HardwareError;
128
+ export declare const isBleStaleBondHardwareError: (error: unknown) => boolean;
129
+ export declare const isBleStaleBondErrorText: (text: string) => boolean;
127
130
  export declare const serializeError: (payload: any) => any;
128
131
  export declare const CreateErrorByMessage: (message: string) => HardwareError;
129
132
  export declare const CreateHardwareErrorByBridgeError: (raw: string) => HardwareError;
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwbpB,CAAC;AAEX,eAAO,MAAM,wBAAwB,EAAE,+BAoJ7B,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"}
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,2BAA2B,UAAW,OAAO,KAAG,OAM5D,CAAC;AAEF,eAAO,MAAM,uBAAuB,SAAU,MAAM,KAAG,OAQtD,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"}
@@ -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;
@@ -42,11 +46,23 @@ export declare enum EOneKeyBleMessageKeys {
42
46
  NOBLE_BLE_MTU_CHANGED = "$onekey-noble-ble-mtu-changed",
43
47
  NOBLE_BLE_CANCEL_PAIRING = "$onekey-noble-ble-cancel-pairing"
44
48
  }
49
+ export declare enum EBleDisconnectReason {
50
+ DeviceDisconnected = "device-disconnected",
51
+ IdleKeepAlive = "idle-keep-alive"
52
+ }
45
53
  export declare const ONEKEY_SERVICE_UUID = "00000001-0000-1000-8000-00805f9b34fb";
46
54
  export declare const ONEKEY_WRITE_CHARACTERISTIC_UUID = "00000002-0000-1000-8000-00805f9b34fb";
47
55
  export declare const ONEKEY_NOTIFY_CHARACTERISTIC_UUID = "00000003-0000-1000-8000-00805f9b34fb";
48
56
  export declare const isHeaderChunk: (chunk: Buffer | Uint8Array) => boolean;
49
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;
50
66
  type BluetoothDeviceIdentity = {
51
67
  id?: string;
52
68
  name?: string | null;
@@ -57,7 +73,11 @@ export declare const normalizeBleUuid: (uuid?: string | null) => string;
57
73
  export declare const createKnownBleUuidAliases: (uuid: string) => ReadonlySet<string>;
58
74
  export declare const matchesKnownBleUuid: (actualUuid: string | null | undefined, aliases: ReadonlySet<string>) => boolean;
59
75
  export declare const isPro2FindMyAdvertisementName: (value?: string | null) => boolean;
76
+ export declare const normalizePro2FindMyAdvertisementName: (value: string) => string;
77
+ export declare const canonicalizePro2BleAdvertisementName: (value: string) => string;
78
+ export declare const isSameOnekeyBleName: (left?: string | null, right?: string | null) => boolean;
60
79
  export declare const hasOnekeyCommunicationService: (serviceUuids: Array<string | null | undefined> | null | undefined) => boolean;
80
+ export declare const isPro2FamilyBleName: (value?: string | null) => boolean;
61
81
  export declare const isOnekeyBluetoothDevice: ({ id, name, localName, serviceUuids, }: BluetoothDeviceIdentity) => boolean;
62
82
  export {};
63
83
  //# sourceMappingURL=constants.d.ts.map
@@ -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;AAEF,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,OAuBjE,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;AAK/C,eAAO,MAAM,6BAA6B,WAAY,MAAM,GAAG,IAAI,YAGlE,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"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -7,6 +7,11 @@ 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;
@@ -49,11 +54,33 @@ declare enum EOneKeyBleMessageKeys {
49
54
  NOBLE_BLE_MTU_CHANGED = "$onekey-noble-ble-mtu-changed",
50
55
  NOBLE_BLE_CANCEL_PAIRING = "$onekey-noble-ble-cancel-pairing"
51
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
+ }
52
71
  declare const ONEKEY_SERVICE_UUID = "00000001-0000-1000-8000-00805f9b34fb";
53
72
  declare const ONEKEY_WRITE_CHARACTERISTIC_UUID = "00000002-0000-1000-8000-00805f9b34fb";
54
73
  declare const ONEKEY_NOTIFY_CHARACTERISTIC_UUID = "00000003-0000-1000-8000-00805f9b34fb";
55
74
  declare const isHeaderChunk: (chunk: Buffer | Uint8Array) => boolean;
56
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;
57
84
  type BluetoothDeviceIdentity = {
58
85
  id?: string;
59
86
  name?: string | null;
@@ -64,7 +91,24 @@ declare const normalizeBleUuid: (uuid?: string | null) => string;
64
91
  declare const createKnownBleUuidAliases: (uuid: string) => ReadonlySet<string>;
65
92
  declare const matchesKnownBleUuid: (actualUuid: string | null | undefined, aliases: ReadonlySet<string>) => boolean;
66
93
  declare const isPro2FindMyAdvertisementName: (value?: string | null) => boolean;
94
+ declare const normalizePro2FindMyAdvertisementName: (value: string) => string;
95
+ /**
96
+ * Current Pro2 advertisements use "Pro 2 XXXX". Older firmware used "Pro2 XXXX".
97
+ * Discovery and DeviceInfo both go through this helper so the public BLE name
98
+ * stays on the spaced form without changing OneKey Pro / Neo names.
99
+ *
100
+ * Match the compact Pro2 form first. A leading "Pro 2" regex would also eat the
101
+ * first digit of a OneKey Pro suffix such as "Pro 22D8" or "Pro 2D8F".
102
+ */
103
+ declare const canonicalizePro2BleAdvertisementName: (value: string) => string;
104
+ declare const isSameOnekeyBleName: (left?: string | null, right?: string | null) => boolean;
67
105
  declare const hasOnekeyCommunicationService: (serviceUuids: Array<string | null | undefined> | null | undefined) => boolean;
106
+ /**
107
+ * Protocol V2 family (Pro2 / Neo) by advertised BLE name. Callers use it to
108
+ * pick a connection strategy: this family also advertises under Find My names
109
+ * that carry no OneKey service UUID, so a scan cannot always see it.
110
+ */
111
+ declare const isPro2FamilyBleName: (value?: string | null) => boolean;
68
112
  declare const isOnekeyBluetoothDevice: ({ id, name, localName, serviceUuids, }: BluetoothDeviceIdentity) => boolean;
69
113
 
70
114
  type Deferred<T, I = any, D = any> = {
@@ -316,6 +360,7 @@ declare const HardwareErrorCode: {
316
360
  readonly BleDeviceDisconnected: 720;
317
361
  readonly BlePoweredOff: 721;
318
362
  readonly BleUnsupported: 722;
363
+ readonly BleUnavailableWhileUsbConnected: 723;
319
364
  /**
320
365
  * Hardware runtiome errors
321
366
  */
@@ -458,6 +503,8 @@ declare const HardwareErrorCode: {
458
503
  };
459
504
  declare const HardwareErrorCodeMessage: HardwareErrorCodeMessageMapping;
460
505
  declare const TypedError: (hardwareError: ErrorCodeUnion | string, message?: string, params?: any) => HardwareError;
506
+ declare const isBleStaleBondHardwareError: (error: unknown) => boolean;
507
+ declare const isBleStaleBondErrorText: (text: string) => boolean;
461
508
  declare const serializeError: (payload: any) => any;
462
509
  declare const CreateErrorByMessage: (message: string) => HardwareError;
463
510
  declare const CreateHardwareErrorByBridgeError: (raw: string) => HardwareError;
@@ -493,6 +540,8 @@ declare const HardwareError$1_HardwareError: typeof HardwareError;
493
540
  declare const HardwareError$1_HardwareErrorCode: typeof HardwareErrorCode;
494
541
  declare const HardwareError$1_HardwareErrorCodeMessage: typeof HardwareErrorCodeMessage;
495
542
  declare const HardwareError$1_TypedError: typeof TypedError;
543
+ declare const HardwareError$1_isBleStaleBondHardwareError: typeof isBleStaleBondHardwareError;
544
+ declare const HardwareError$1_isBleStaleBondErrorText: typeof isBleStaleBondErrorText;
496
545
  declare const HardwareError$1_serializeError: typeof serializeError;
497
546
  declare const HardwareError$1_CreateErrorByMessage: typeof CreateErrorByMessage;
498
547
  declare const HardwareError$1_CreateHardwareErrorByBridgeError: typeof CreateHardwareErrorByBridgeError;
@@ -509,6 +558,8 @@ declare namespace HardwareError$1 {
509
558
  HardwareError$1_HardwareErrorCode as HardwareErrorCode,
510
559
  HardwareError$1_HardwareErrorCodeMessage as HardwareErrorCodeMessage,
511
560
  HardwareError$1_TypedError as TypedError,
561
+ HardwareError$1_isBleStaleBondHardwareError as isBleStaleBondHardwareError,
562
+ HardwareError$1_isBleStaleBondErrorText as isBleStaleBondErrorText,
512
563
  HardwareError$1_serializeError as serializeError,
513
564
  HardwareError$1_CreateErrorByMessage as CreateErrorByMessage,
514
565
  HardwareError$1_CreateHardwareErrorByBridgeError as CreateHardwareErrorByBridgeError,
@@ -529,4 +580,4 @@ declare enum EDeviceType {
529
580
  Neo = "neo"
530
581
  }
531
582
 
532
- 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, createKnownBleUuidAliases, createNeedUpgradeFirmwareHardwareError, createNewFirmwareForceUpdateHardwareError, createNewFirmwareUnReleaseHardwareError, hasOnekeyCommunicationService, isHeaderChunk, isKnownTrezorWebUsbDevice, isOnekeyBluetoothDevice, isOnekeyDevice, isPro2FindMyAdvertisementName, matchesKnownBleUuid, normalizeBleUuid, serializeError, wait };
583
+ 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, canonicalizePro2BleAdvertisementName, createDefectiveFirmwareError, createDeferred, createDeprecatedHardwareError, createDeviceNotSupportMethodError, createKnownBleUuidAliases, createNeedUpgradeFirmwareHardwareError, createNewFirmwareForceUpdateHardwareError, createNewFirmwareUnReleaseHardwareError, hasOnekeyCommunicationService, inferProtocolHintFromUsbId, isBleStaleBondErrorText, isBleStaleBondHardwareError, isHeaderChunk, isKnownTrezorWebUsbDevice, isOnekeyBluetoothDevice, isOnekeyDevice, isPro2FamilyBleName, isPro2FindMyAdvertisementName, isSameOnekeyBleName, 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,
@@ -242,6 +243,7 @@ const HardwareErrorCodeMessage = {
242
243
  [HardwareErrorCode.BleDeviceDisconnected]: 'Device disconnected',
243
244
  [HardwareErrorCode.BlePoweredOff]: 'Bluetooth is turned off',
244
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.',
245
247
  [HardwareErrorCode.RuntimeError]: 'Runtime error',
246
248
  [HardwareErrorCode.PinInvalid]: 'Pin invalid',
247
249
  [HardwareErrorCode.PinCancelled]: 'Pin cancelled',
@@ -284,6 +286,18 @@ const TypedError = (hardwareError, message, params) => {
284
286
  }
285
287
  return new HardwareError({ errorCode: hardwareError, message: message !== null && message !== void 0 ? message : '', params });
286
288
  };
289
+ const isBleStaleBondHardwareError = (error) => {
290
+ const code = error === null || error === void 0 ? void 0 : error.errorCode;
291
+ return (code === HardwareErrorCode.BleDeviceBondError ||
292
+ code === HardwareErrorCode.BlePeerRemovedPairingInformation);
293
+ };
294
+ const isBleStaleBondErrorText = (text) => {
295
+ const value = text.toLowerCase();
296
+ return (value.includes('encryption is insufficient') ||
297
+ value.includes('insufficient encryption') ||
298
+ value.includes('peer removed pairing information') ||
299
+ value.includes('gatt_insuf_authentication'));
300
+ };
287
301
  const serializeError = (payload) => {
288
302
  if (payload && payload.error instanceof HardwareError) {
289
303
  return {
@@ -375,6 +389,8 @@ var HardwareError$1 = /*#__PURE__*/Object.freeze({
375
389
  HardwareErrorCode: HardwareErrorCode,
376
390
  HardwareErrorCodeMessage: HardwareErrorCodeMessage,
377
391
  TypedError: TypedError,
392
+ isBleStaleBondHardwareError: isBleStaleBondHardwareError,
393
+ isBleStaleBondErrorText: isBleStaleBondErrorText,
378
394
  serializeError: serializeError,
379
395
  CreateErrorByMessage: CreateErrorByMessage,
380
396
  CreateHardwareErrorByBridgeError: CreateHardwareErrorByBridgeError,
@@ -397,6 +413,7 @@ const ONEKEY_WEBUSB_FILTER = [
397
413
  { vendorId: 0x1209, productId: 0x4f4b },
398
414
  { vendorId: 0x1209, productId: 0x4f4c },
399
415
  ];
416
+ const ONEKEY_PROTOCOL_V2_USB_IDS = [{ vendorId: 0x1209, productId: 0x4f4c }];
400
417
  const TREZOR_WEBUSB_MANUFACTURER_NAMES = new Set(['trezor', 'trezor company', 'satoshilabs']);
401
418
  const isKnownTrezorWebUsbDevice = (descriptor) => {
402
419
  var _a;
@@ -447,6 +464,11 @@ exports.EOneKeyBleMessageKeys = void 0;
447
464
  EOneKeyBleMessageKeys["NOBLE_BLE_MTU_CHANGED"] = "$onekey-noble-ble-mtu-changed";
448
465
  EOneKeyBleMessageKeys["NOBLE_BLE_CANCEL_PAIRING"] = "$onekey-noble-ble-cancel-pairing";
449
466
  })(exports.EOneKeyBleMessageKeys || (exports.EOneKeyBleMessageKeys = {}));
467
+ exports.EBleDisconnectReason = void 0;
468
+ (function (EBleDisconnectReason) {
469
+ EBleDisconnectReason["DeviceDisconnected"] = "device-disconnected";
470
+ EBleDisconnectReason["IdleKeepAlive"] = "idle-keep-alive";
471
+ })(exports.EBleDisconnectReason || (exports.EBleDisconnectReason = {}));
450
472
  const ONEKEY_SERVICE_UUID = '00000001-0000-1000-8000-00805f9b34fb';
451
473
  const ONEKEY_WRITE_CHARACTERISTIC_UUID = '00000002-0000-1000-8000-00805f9b34fb';
452
474
  const ONEKEY_NOTIFY_CHARACTERISTIC_UUID = '00000003-0000-1000-8000-00805f9b34fb';
@@ -493,12 +515,36 @@ const isOnekeyDevice = (name, id) => {
493
515
  return true;
494
516
  if (normalizedName.startsWith('touch ') ||
495
517
  normalizedName.startsWith('pro ') ||
496
- normalizedName.startsWith('pro2 ') ||
497
- normalizedName.startsWith('neo ')) {
518
+ normalizedName.startsWith('pro2') ||
519
+ normalizedName.startsWith('neo')) {
520
+ return true;
521
+ }
522
+ const compactName = compactBleName(normalizedName);
523
+ if (PRO2_COMPACT_NAME_PATTERN.test(compactName) || NEO_COMPACT_NAME_PATTERN.test(compactName)) {
498
524
  return true;
499
525
  }
500
526
  return isOneKeyShortName(normalizedName);
501
527
  };
528
+ const inferProtocolHintFromUsbId = (vendorId, productId) => ONEKEY_PROTOCOL_V2_USB_IDS.some(id => id.vendorId === vendorId && id.productId === productId)
529
+ ? 'V2'
530
+ : undefined;
531
+ const resolveOneKeyUsbDevicePath = (device) => {
532
+ var _a, _b, _c, _d;
533
+ const serial = (_a = device.serialNumber) === null || _a === void 0 ? void 0 : _a.trim();
534
+ if (serial)
535
+ return serial;
536
+ if (device.vendorId == null && device.productId == null && !device.productName) {
537
+ return undefined;
538
+ }
539
+ const vendorId = ((_b = device.vendorId) !== null && _b !== void 0 ? _b : 0).toString(16).padStart(4, '0');
540
+ const productId = ((_c = device.productId) !== null && _c !== void 0 ? _c : 0).toString(16).padStart(4, '0');
541
+ const product = ((_d = device.productName) !== null && _d !== void 0 ? _d : 'onekey')
542
+ .trim()
543
+ .toLowerCase()
544
+ .replace(/\s+/g, '-')
545
+ .replace(/[^a-z0-9-]/g, '');
546
+ return `usb-${vendorId}-${productId}-${product || 'onekey'}`;
547
+ };
502
548
  const BLUETOOTH_BASE_UUID_SUFFIX = '00001000800000805f9b34fb';
503
549
  const normalizeBleUuid = (uuid) => (uuid !== null && uuid !== void 0 ? uuid : '').replace(/-/g, '').toLowerCase();
504
550
  const createKnownBleUuidAliases = (uuid) => {
@@ -517,12 +563,95 @@ const createKnownBleUuidAliases = (uuid) => {
517
563
  const matchesKnownBleUuid = (actualUuid, aliases) => aliases.has(normalizeBleUuid(actualUuid));
518
564
  const ONEKEY_COMMUNICATION_SERVICE_ALIASES = createKnownBleUuidAliases(ONEKEY_SERVICE_UUID);
519
565
  const FIDO_SERVICE_ALIASES = createKnownBleUuidAliases('0000fffd-0000-1000-8000-00805f9b34fb');
566
+ const PRO2_COMPACT_NAME_PATTERN = /^(?:onekey)?pro2[a-f0-9]{4}$/i;
567
+ const NEO_COMPACT_NAME_PATTERN = /^(?:onekey)?neo[a-f0-9]{4}$/i;
568
+ const FIND_MY_COMPACT_SUFFIXES = [
569
+ 'findemy',
570
+ 'findem',
571
+ 'finde',
572
+ 'findmy',
573
+ 'findm',
574
+ 'find',
575
+ 'fin',
576
+ ];
577
+ const COMPLETE_FIND_MY_COMPACT_SUFFIXES = ['findemy', 'findmy'];
578
+ const compactBleName = (value) => Array.from(value)
579
+ .filter(character => character !== '-' && character.trim() !== '')
580
+ .join('')
581
+ .toLowerCase();
582
+ const getFindMyCompactSuffix = (compactName) => FIND_MY_COMPACT_SUFFIXES.find(candidate => compactName.endsWith(candidate));
583
+ const getPro2FindMyBaseLength = (value) => {
584
+ const compactName = compactBleName(value);
585
+ const suffix = getFindMyCompactSuffix(compactName);
586
+ if (!suffix)
587
+ return undefined;
588
+ const compactBaseName = compactName.slice(0, -suffix.length);
589
+ return PRO2_COMPACT_NAME_PATTERN.test(compactBaseName) ? compactBaseName.length : undefined;
590
+ };
520
591
  const isPro2FindMyAdvertisementName = (value) => {
521
- var _a;
522
- const normalizedName = (_a = value === null || value === void 0 ? void 0 : value.trim().toLowerCase()) !== null && _a !== void 0 ? _a : '';
523
- return /\bpro\s*2\b/.test(normalizedName) && /\bfinde?\s+my\b/.test(normalizedName);
592
+ if (!value)
593
+ return false;
594
+ if (getPro2FindMyBaseLength(value) !== undefined)
595
+ return true;
596
+ const compactName = compactBleName(value);
597
+ const suffix = COMPLETE_FIND_MY_COMPACT_SUFFIXES.find(candidate => compactName.endsWith(candidate));
598
+ if (!suffix)
599
+ return false;
600
+ return compactName.slice(0, -suffix.length).includes('pro2');
601
+ };
602
+ const normalizePro2FindMyAdvertisementName = (value) => {
603
+ const baseLength = getPro2FindMyBaseLength(value);
604
+ if (baseLength === undefined)
605
+ return value;
606
+ let compactLength = 0;
607
+ for (let index = 0; index < value.length; index += 1) {
608
+ const character = value[index];
609
+ if (character !== '-' && character.trim() !== '') {
610
+ compactLength += 1;
611
+ if (compactLength === baseLength) {
612
+ return value.slice(0, index + 1).trimEnd();
613
+ }
614
+ }
615
+ }
616
+ return value;
617
+ };
618
+ const canonicalizePro2BleAdvertisementName = (value) => {
619
+ const withoutFindMy = normalizePro2FindMyAdvertisementName(value);
620
+ const compact = compactBleName(withoutFindMy);
621
+ if (!PRO2_COMPACT_NAME_PATTERN.test(compact))
622
+ return withoutFindMy;
623
+ const match = withoutFindMy.match(/^(onekey\s*)?pro\s*2\s*/i);
624
+ if (!match)
625
+ return withoutFindMy;
626
+ const rest = withoutFindMy.slice(match[0].length);
627
+ const prefix = match[1] ? 'OneKey Pro 2' : 'Pro 2';
628
+ return rest ? `${prefix} ${rest}` : prefix;
629
+ };
630
+ const isSameOnekeyBleName = (left, right) => {
631
+ if (!left || !right)
632
+ return false;
633
+ if (left === right)
634
+ return true;
635
+ return (compactBleName(canonicalizePro2BleAdvertisementName(left)) ===
636
+ compactBleName(canonicalizePro2BleAdvertisementName(right)));
524
637
  };
525
638
  const hasOnekeyCommunicationService = (serviceUuids) => (serviceUuids !== null && serviceUuids !== void 0 ? serviceUuids : []).some(uuid => matchesKnownBleUuid(uuid, ONEKEY_COMMUNICATION_SERVICE_ALIASES));
639
+ const isPro2FamilyBleName = (value) => {
640
+ if (!value) {
641
+ return false;
642
+ }
643
+ const normalized = value.trim().toLowerCase();
644
+ if (!normalized) {
645
+ return false;
646
+ }
647
+ if (normalized.startsWith('pro2') || normalized.startsWith('neo')) {
648
+ return true;
649
+ }
650
+ const compact = compactBleName(normalized);
651
+ return (PRO2_COMPACT_NAME_PATTERN.test(compact) ||
652
+ NEO_COMPACT_NAME_PATTERN.test(compact) ||
653
+ isPro2FindMyAdvertisementName(value));
654
+ };
526
655
  const isOnekeyBluetoothDevice = ({ id, name, localName, serviceUuids, }) => {
527
656
  const advertisedServiceUuids = serviceUuids !== null && serviceUuids !== void 0 ? serviceUuids : [];
528
657
  if (hasOnekeyCommunicationService(advertisedServiceUuids)) {
@@ -621,10 +750,12 @@ exports.HardwareError = HardwareError;
621
750
  exports.HardwareErrorCode = HardwareErrorCode;
622
751
  exports.HardwareErrorCodeMessage = HardwareErrorCodeMessage;
623
752
  exports.ONEKEY_NOTIFY_CHARACTERISTIC_UUID = ONEKEY_NOTIFY_CHARACTERISTIC_UUID;
753
+ exports.ONEKEY_PROTOCOL_V2_USB_IDS = ONEKEY_PROTOCOL_V2_USB_IDS;
624
754
  exports.ONEKEY_SERVICE_UUID = ONEKEY_SERVICE_UUID;
625
755
  exports.ONEKEY_WEBUSB_FILTER = ONEKEY_WEBUSB_FILTER;
626
756
  exports.ONEKEY_WRITE_CHARACTERISTIC_UUID = ONEKEY_WRITE_CHARACTERISTIC_UUID;
627
757
  exports.TypedError = TypedError;
758
+ exports.canonicalizePro2BleAdvertisementName = canonicalizePro2BleAdvertisementName;
628
759
  exports.createDefectiveFirmwareError = createDefectiveFirmwareError;
629
760
  exports.createDeferred = createDeferred;
630
761
  exports.createDeprecatedHardwareError = createDeprecatedHardwareError;
@@ -634,12 +765,19 @@ exports.createNeedUpgradeFirmwareHardwareError = createNeedUpgradeFirmwareHardwa
634
765
  exports.createNewFirmwareForceUpdateHardwareError = createNewFirmwareForceUpdateHardwareError;
635
766
  exports.createNewFirmwareUnReleaseHardwareError = createNewFirmwareUnReleaseHardwareError;
636
767
  exports.hasOnekeyCommunicationService = hasOnekeyCommunicationService;
768
+ exports.inferProtocolHintFromUsbId = inferProtocolHintFromUsbId;
769
+ exports.isBleStaleBondErrorText = isBleStaleBondErrorText;
770
+ exports.isBleStaleBondHardwareError = isBleStaleBondHardwareError;
637
771
  exports.isHeaderChunk = isHeaderChunk;
638
772
  exports.isKnownTrezorWebUsbDevice = isKnownTrezorWebUsbDevice;
639
773
  exports.isOnekeyBluetoothDevice = isOnekeyBluetoothDevice;
640
774
  exports.isOnekeyDevice = isOnekeyDevice;
775
+ exports.isPro2FamilyBleName = isPro2FamilyBleName;
641
776
  exports.isPro2FindMyAdvertisementName = isPro2FindMyAdvertisementName;
777
+ exports.isSameOnekeyBleName = isSameOnekeyBleName;
642
778
  exports.matchesKnownBleUuid = matchesKnownBleUuid;
643
779
  exports.normalizeBleUuid = normalizeBleUuid;
780
+ exports.normalizePro2FindMyAdvertisementName = normalizePro2FindMyAdvertisementName;
781
+ exports.resolveOneKeyUsbDevicePath = resolveOneKeyUsbDevicePath;
644
782
  exports.serializeError = serializeError;
645
783
  exports.wait = wait;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/hd-shared",
3
- "version": "1.2.0-alpha.99",
3
+ "version": "1.2.0",
4
4
  "description": "Hardware SDK's shared tool library",
5
5
  "keywords": [
6
6
  "Hardware-SDK",
@@ -26,5 +26,5 @@
26
26
  "lint": "eslint .",
27
27
  "lint:fix": "eslint . --fix"
28
28
  },
29
- "gitHead": "8924c0e509f84675a2c33c0062166967f5bcb2d0"
29
+ "gitHead": "cc51df0a415bead21304ad1d8bc92b5312c91344"
30
30
  }
@@ -1,4 +1,9 @@
1
- import { HardwareErrorCode } from './HardwareError';
1
+ import {
2
+ HardwareErrorCode,
3
+ HardwareErrorCodeMessage,
4
+ TypedError,
5
+ serializeError,
6
+ } from './HardwareError';
2
7
 
3
8
  describe('HardwareErrorCode compatibility', () => {
4
9
  test('preserves published Protocol V2 values while leaving code 829 unused', () => {
@@ -6,4 +11,26 @@ describe('HardwareErrorCode compatibility', () => {
6
11
  expect(HardwareErrorCode.DeviceLocked).toBe(830);
7
12
  expect(HardwareErrorCode.WalletSessionInvalid).toBe(831);
8
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
+ });
9
36
  });
@@ -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
@@ -619,6 +620,8 @@ export const HardwareErrorCodeMessage: HardwareErrorCodeMessageMapping = {
619
620
  [HardwareErrorCode.BleDeviceDisconnected]: 'Device disconnected',
620
621
  [HardwareErrorCode.BlePoweredOff]: 'Bluetooth is turned off',
621
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.',
622
625
 
623
626
  /**
624
627
  * Runtime Error
@@ -679,6 +682,24 @@ export const TypedError = (
679
682
  return new HardwareError({ errorCode: hardwareError, message: message ?? '', params });
680
683
  };
681
684
 
685
+ export const isBleStaleBondHardwareError = (error: unknown): boolean => {
686
+ const code = (error as { errorCode?: unknown })?.errorCode;
687
+ return (
688
+ code === HardwareErrorCode.BleDeviceBondError ||
689
+ code === HardwareErrorCode.BlePeerRemovedPairingInformation
690
+ );
691
+ };
692
+
693
+ export const isBleStaleBondErrorText = (text: string): boolean => {
694
+ const value = text.toLowerCase();
695
+ return (
696
+ value.includes('encryption is insufficient') ||
697
+ value.includes('insufficient encryption') ||
698
+ value.includes('peer removed pairing information') ||
699
+ value.includes('gatt_insuf_authentication')
700
+ );
701
+ };
702
+
682
703
  export const serializeError = (payload: any) => {
683
704
  if (payload && payload.error instanceof HardwareError) {
684
705
  return {
@@ -1,10 +1,16 @@
1
1
  import {
2
+ canonicalizePro2BleAdvertisementName,
2
3
  createKnownBleUuidAliases,
3
4
  hasOnekeyCommunicationService,
5
+ inferProtocolHintFromUsbId,
4
6
  isKnownTrezorWebUsbDevice,
5
7
  isOnekeyBluetoothDevice,
6
8
  isOnekeyDevice,
9
+ isPro2FindMyAdvertisementName,
10
+ isSameOnekeyBleName,
7
11
  matchesKnownBleUuid,
12
+ normalizePro2FindMyAdvertisementName,
13
+ resolveOneKeyUsbDevicePath,
8
14
  } from './constants';
9
15
 
10
16
  describe('hardware device identity filters', () => {
@@ -12,6 +18,11 @@ describe('hardware device identity filters', () => {
12
18
  expect(isOnekeyDevice('Touch A1B2')).toBe(true);
13
19
  expect(isOnekeyDevice('Pro A1B2')).toBe(true);
14
20
  expect(isOnekeyDevice('Neo A1B2')).toBe(true);
21
+ expect(isOnekeyDevice('Pro2A1B2')).toBe(true);
22
+ expect(isOnekeyDevice('Pro 2 A1B2')).toBe(true);
23
+ expect(isOnekeyDevice('OneKeyPro2A1B2')).toBe(true);
24
+ expect(isOnekeyDevice('OneKey Pro 2 A1B2')).toBe(true);
25
+ expect(isOnekeyDevice('Neo22D8')).toBe(true);
15
26
  expect(isOnekeyDevice('K1234')).toBe(true);
16
27
  expect(isOnekeyDevice('S8')).toBe(true);
17
28
  });
@@ -35,6 +46,12 @@ describe('hardware device identity filters', () => {
35
46
  serviceUuids: ['0001', 'fffd'],
36
47
  })
37
48
  ).toBe(true);
49
+ expect(
50
+ isOnekeyBluetoothDevice({
51
+ name: 'Pro 2 A1B2',
52
+ serviceUuids: ['0001', 'fffd'],
53
+ })
54
+ ).toBe(true);
38
55
  expect(
39
56
  isOnekeyBluetoothDevice({
40
57
  localName: 'Pro2 A1B2 - Find My',
@@ -67,6 +84,63 @@ describe('hardware device identity filters', () => {
67
84
  serviceUuids: ['fffd'],
68
85
  })
69
86
  ).toBe(false);
87
+ expect(isOnekeyBluetoothDevice({ name: 'Pro2 - Find My' })).toBe(false);
88
+ expect(isOnekeyBluetoothDevice({ name: 'Pro2 G12Z - Find My' })).toBe(false);
89
+ });
90
+
91
+ it('uses a broad Find My guard without broadening public name normalization', () => {
92
+ expect(isPro2FindMyAdvertisementName('Pro2 Griffin - Find My')).toBe(true);
93
+ expect(isPro2FindMyAdvertisementName('Pro2 Griffin')).toBe(false);
94
+ expect(isPro2FindMyAdvertisementName('Pro2 22D8 - Find My')).toBe(true);
95
+ expect(normalizePro2FindMyAdvertisementName('Pro2 Griffin - Find My')).toBe(
96
+ 'Pro2 Griffin - Find My'
97
+ );
98
+ expect(normalizePro2FindMyAdvertisementName('Pro2 22D8 - Find My')).toBe('Pro2 22D8');
99
+ });
100
+
101
+ it.each([
102
+ ['Pro2 A1B2 - Find My', 'Pro2 A1B2'],
103
+ ['Pro2 5E9D - Finde My', 'Pro2 5E9D'],
104
+ [' OneKey Pro 2 A1B2 Find My ', ' OneKey Pro 2 A1B2'],
105
+ ['OneKey Pro-2 22D8--Find-My', 'OneKey Pro-2 22D8'],
106
+ ['Pro2 22D8FindMy', 'Pro2 22D8'],
107
+ ['Pro2 22D8 - Fin', 'Pro2 22D8'],
108
+ ['Pro2 22D8FindM', 'Pro2 22D8'],
109
+ [`Pro2 22D8${'\t'.repeat(10_000)}Find My`, 'Pro2 22D8'],
110
+ ['Pro2 A1B2', 'Pro2 A1B2'],
111
+ ['Pro2 Griffin', 'Pro2 Griffin'],
112
+ ['Find My', 'Find My'],
113
+ ])('normalizes the public Pro2 advertisement name %s', (name, expected) => {
114
+ expect(normalizePro2FindMyAdvertisementName(name)).toBe(expected);
115
+ });
116
+
117
+ it.each([
118
+ ['Pro2 A1B2', 'Pro 2 A1B2'],
119
+ ['Pro2A1B2', 'Pro 2 A1B2'],
120
+ ['Pro 2 A1B2', 'Pro 2 A1B2'],
121
+ ['Pro 2 0088', 'Pro 2 0088'],
122
+ ['Pro2 22D8 - Find My', 'Pro 2 22D8'],
123
+ ['Pro 2 A1B2 - Find My', 'Pro 2 A1B2'],
124
+ ['OneKeyPro2A1B2', 'OneKey Pro 2 A1B2'],
125
+ ['OneKey Pro 2 A1B2', 'OneKey Pro 2 A1B2'],
126
+ ['OneKey Pro 2', 'OneKey Pro 2'],
127
+ ['Pro A1B2', 'Pro A1B2'],
128
+ ['Pro 22D8', 'Pro 22D8'],
129
+ ['Pro 2D8F', 'Pro 2D8F'],
130
+ ['OneKey Pro 22D8', 'OneKey Pro 22D8'],
131
+ ['Neo 22D8', 'Neo 22D8'],
132
+ ])('canonicalizes the public Pro2 advertisement name %s', (name, expected) => {
133
+ expect(canonicalizePro2BleAdvertisementName(name)).toBe(expected);
134
+ });
135
+
136
+ it('treats compact and spaced Pro2 BLE names as the same device', () => {
137
+ expect(isSameOnekeyBleName('Pro2 6136', 'Pro 2 6136')).toBe(true);
138
+ expect(isSameOnekeyBleName('Pro2 6136 - Find My', 'Pro 2 6136')).toBe(true);
139
+ expect(isSameOnekeyBleName('Pro 2 6136', 'Pro 2 0088')).toBe(false);
140
+ expect(isSameOnekeyBleName('Pro A1B2', 'Pro 2 A1B2')).toBe(false);
141
+ expect(isSameOnekeyBleName('Pro 22D8', 'Pro 22D8')).toBe(true);
142
+ expect(isSameOnekeyBleName('Pro 22D8', 'Pro2 22D8')).toBe(false);
143
+ expect(isSameOnekeyBleName('Pro 22D8', 'Pro 2 22D8')).toBe(false);
70
144
  });
71
145
 
72
146
  it('keeps OneKey discovery on the communication service', () => {
@@ -106,6 +180,32 @@ describe('hardware device identity filters', () => {
106
180
  expect(hasOnekeyCommunicationService(['abcd0001-1234-5678-9012-abcdefabcdef'])).toBe(false);
107
181
  });
108
182
 
183
+ it('hints Protocol V2 from the current Pro2/Neo USB ID only', () => {
184
+ expect(inferProtocolHintFromUsbId(0x1209, 0x4f4c)).toBe('V2');
185
+ expect(inferProtocolHintFromUsbId(0x1209, 0x53c1)).toBeUndefined();
186
+ expect(inferProtocolHintFromUsbId(0x1209, 0x4f4a)).toBeUndefined();
187
+ expect(inferProtocolHintFromUsbId(0x1209, 0x4f4b)).toBeUndefined();
188
+ });
189
+
190
+ it('uses the USB serial when present and synthesizes a path when firmware omits it', () => {
191
+ expect(
192
+ resolveOneKeyUsbDevicePath({
193
+ vendorId: 0x1209,
194
+ productId: 0x4f4c,
195
+ productName: 'OneKey Pro 2',
196
+ serialNumber: 'PRO2-SERIAL',
197
+ })
198
+ ).toBe('PRO2-SERIAL');
199
+ expect(
200
+ resolveOneKeyUsbDevicePath({
201
+ vendorId: 0x1209,
202
+ productId: 0x4f4c,
203
+ productName: 'OneKey Neo',
204
+ serialNumber: '',
205
+ })
206
+ ).toBe('usb-1209-4f4c-onekey-neo');
207
+ });
208
+
109
209
  it('only filters WebUSB descriptors that are explicitly identified as Trezor', () => {
110
210
  expect(
111
211
  isKnownTrezorWebUsbDevice({
package/src/constants.ts CHANGED
@@ -13,10 +13,13 @@ export const ONEKEY_WEBUSB_FILTER = [
13
13
  { vendorId: 0x1209, productId: 0x53c1 }, // Classic/Classic1s/Mini/Pro/Touch firmware and legacy Pro2; keep for existing devices
14
14
  { vendorId: 0x1209, productId: 0x4f4a }, // Pro bootloader, Touch bootloader, Pro2
15
15
  { vendorId: 0x1209, productId: 0x4f4b }, // Pro/Touch firmware (Trezor not implemented), Pro2
16
- { vendorId: 0x1209, productId: 0x4f4c }, // Pro board and Pro2 with the new firmware PID
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;
@@ -98,6 +101,21 @@ export enum EOneKeyBleMessageKeys {
98
101
  NOBLE_BLE_CANCEL_PAIRING = '$onekey-noble-ble-cancel-pairing',
99
102
  }
100
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
+
101
119
  export const ONEKEY_SERVICE_UUID = '00000001-0000-1000-8000-00805f9b34fb';
102
120
  export const ONEKEY_WRITE_CHARACTERISTIC_UUID = '00000002-0000-1000-8000-00805f9b34fb';
103
121
  export const ONEKEY_NOTIFY_CHARACTERISTIC_UUID = '00000003-0000-1000-8000-00805f9b34fb';
@@ -152,14 +170,47 @@ export const isOnekeyDevice = (name: string | null, id?: string): boolean => {
152
170
  if (
153
171
  normalizedName.startsWith('touch ') ||
154
172
  normalizedName.startsWith('pro ') ||
155
- normalizedName.startsWith('pro2 ') ||
156
- normalizedName.startsWith('neo ')
173
+ normalizedName.startsWith('pro2') ||
174
+ normalizedName.startsWith('neo')
157
175
  ) {
158
176
  return true;
159
177
  }
178
+ const compactName = compactBleName(normalizedName);
179
+ if (PRO2_COMPACT_NAME_PATTERN.test(compactName) || NEO_COMPACT_NAME_PATTERN.test(compactName)) {
180
+ return true;
181
+ }
160
182
  return isOneKeyShortName(normalizedName);
161
183
  };
162
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
+
163
214
  type BluetoothDeviceIdentity = {
164
215
  id?: string;
165
216
  name?: string | null;
@@ -195,10 +246,95 @@ export const matchesKnownBleUuid = (
195
246
 
196
247
  const ONEKEY_COMMUNICATION_SERVICE_ALIASES = createKnownBleUuidAliases(ONEKEY_SERVICE_UUID);
197
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
+ };
198
279
 
199
280
  export const isPro2FindMyAdvertisementName = (value?: string | null) => {
200
- const normalizedName = value?.trim().toLowerCase() ?? '';
201
- return /\bpro\s*2\b/.test(normalizedName) && /\bfinde?\s+my\b/.test(normalizedName);
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
+ /**
311
+ * Current Pro2 advertisements use "Pro 2 XXXX". Older firmware used "Pro2 XXXX".
312
+ * Discovery and DeviceInfo both go through this helper so the public BLE name
313
+ * stays on the spaced form without changing OneKey Pro / Neo names.
314
+ *
315
+ * Match the compact Pro2 form first. A leading "Pro 2" regex would also eat the
316
+ * first digit of a OneKey Pro suffix such as "Pro 22D8" or "Pro 2D8F".
317
+ */
318
+ export const canonicalizePro2BleAdvertisementName = (value: string) => {
319
+ const withoutFindMy = normalizePro2FindMyAdvertisementName(value);
320
+ const compact = compactBleName(withoutFindMy);
321
+ if (!PRO2_COMPACT_NAME_PATTERN.test(compact)) return withoutFindMy;
322
+
323
+ const match = withoutFindMy.match(/^(onekey\s*)?pro\s*2\s*/i);
324
+ if (!match) return withoutFindMy;
325
+
326
+ const rest = withoutFindMy.slice(match[0].length);
327
+ const prefix = match[1] ? 'OneKey Pro 2' : 'Pro 2';
328
+ return rest ? `${prefix} ${rest}` : prefix;
329
+ };
330
+
331
+ export const isSameOnekeyBleName = (left?: string | null, right?: string | null) => {
332
+ if (!left || !right) return false;
333
+ if (left === right) return true;
334
+ return (
335
+ compactBleName(canonicalizePro2BleAdvertisementName(left)) ===
336
+ compactBleName(canonicalizePro2BleAdvertisementName(right))
337
+ );
202
338
  };
203
339
 
204
340
  export const hasOnekeyCommunicationService = (
@@ -208,6 +344,30 @@ export const hasOnekeyCommunicationService = (
208
344
  matchesKnownBleUuid(uuid, ONEKEY_COMMUNICATION_SERVICE_ALIASES)
209
345
  );
210
346
 
347
+ /**
348
+ * Protocol V2 family (Pro2 / Neo) by advertised BLE name. Callers use it to
349
+ * pick a connection strategy: this family also advertises under Find My names
350
+ * that carry no OneKey service UUID, so a scan cannot always see it.
351
+ */
352
+ export const isPro2FamilyBleName = (value?: string | null): boolean => {
353
+ if (!value) {
354
+ return false;
355
+ }
356
+ const normalized = value.trim().toLowerCase();
357
+ if (!normalized) {
358
+ return false;
359
+ }
360
+ if (normalized.startsWith('pro2') || normalized.startsWith('neo')) {
361
+ return true;
362
+ }
363
+ const compact = compactBleName(normalized);
364
+ return (
365
+ PRO2_COMPACT_NAME_PATTERN.test(compact) ||
366
+ NEO_COMPACT_NAME_PATTERN.test(compact) ||
367
+ isPro2FindMyAdvertisementName(value)
368
+ );
369
+ };
370
+
211
371
  export const isOnekeyBluetoothDevice = ({
212
372
  id,
213
373
  name,