@onekeyfe/hd-core 1.2.0-alpha.150 → 1.2.0-alpha.151

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":";AACA,OAAO,YAAY,MAAM,QAAQ,CAAC;AAoClC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAsB1C,OAAO,eAAe,MAAM,2BAA2B,CAAC;AAYxD,OAAO,KAAK,EAAE,eAAe,EAAyB,MAAM,UAAU,CAAC;AACvE,OAAO,KAAK,EAAE,WAAW,EAAmD,MAAM,WAAW,CAAC;AAI9F,OAAO,KAAK,EACV,6BAA6B,EAG9B,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAWpD,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAmE7D,eAAO,MAAM,OAAO,YAAmB,WAAW,WAAW,WAAW,iBAoFvE,CAAC;AAiqBF,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,WAWpF;AAED,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,WAW/E;AAED,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,WAQlF;AA0PD,eAAO,MAAM,MAAM,YAAa,WAAW,cAAc,MAAM,SAoG9D,CAAC;AAmGF,eAAO,MAAM,qBAAqB,gFAejC,CAAC;AAiLF,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,YAAY;IAC5C,OAAO,CAAC,cAAc,CAAoB;IAE1C,SAAgB,aAAa,EAAE,MAAM,CAAC;IAEtC,OAAO,CAAC,YAAY,CAAsB;IAE1C,OAAO,CAAC,cAAc,CAAC,CAAgB;IAGvC,OAAO,CAAC,sBAAsB,CAAoC;IAElE,OAAO,CAAC,iBAAiB,CAAoB;;IAS7C,OAAO,CAAC,cAAc;IA6BhB,aAAa,CAAC,OAAO,EAAE,WAAW;IAuExC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YAOV,gBAAgB;CAiC/B;AAED,eAAO,MAAM,QAAQ,YAIpB,CAAC;AAEF,eAAO,MAAM,aAAa,uBAYzB,CAAC;AAMF,eAAO,MAAM,IAAI,aACL,eAAe,aACd,GAAG,WACL,6BAA6B,8BAiBvC,CAAC;AAEF,eAAO,MAAM,eAAe;SAKrB,eAAe,CAAC,KAAK,CAAC;eAChB,GAAG;;UASf,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":";AACA,OAAO,YAAY,MAAM,QAAQ,CAAC;AAoClC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAsB1C,OAAO,eAAe,MAAM,2BAA2B,CAAC;AAYxD,OAAO,KAAK,EAAE,eAAe,EAAyB,MAAM,UAAU,CAAC;AACvE,OAAO,KAAK,EAAE,WAAW,EAAmD,MAAM,WAAW,CAAC;AAI9F,OAAO,KAAK,EACV,6BAA6B,EAG9B,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAWpD,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAmE7D,eAAO,MAAM,OAAO,YAAmB,WAAW,WAAW,WAAW,iBAoFvE,CAAC;AAqqBF,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,WAWpF;AAED,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,WAW/E;AAED,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,WAQlF;AAiVD,eAAO,MAAM,MAAM,YAAa,WAAW,cAAc,MAAM,SAoG9D,CAAC;AAmGF,eAAO,MAAM,qBAAqB,gFAejC,CAAC;AAiLF,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,YAAY;IAC5C,OAAO,CAAC,cAAc,CAAoB;IAE1C,SAAgB,aAAa,EAAE,MAAM,CAAC;IAEtC,OAAO,CAAC,YAAY,CAAsB;IAE1C,OAAO,CAAC,cAAc,CAAC,CAAgB;IAGvC,OAAO,CAAC,sBAAsB,CAAoC;IAElE,OAAO,CAAC,iBAAiB,CAAoB;;IAS7C,OAAO,CAAC,cAAc;IA6BhB,aAAa,CAAC,OAAO,EAAE,WAAW;IAuExC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YAOV,gBAAgB;CAiC/B;AAED,eAAO,MAAM,QAAQ,YAIpB,CAAC;AAEF,eAAO,MAAM,aAAa,uBAYzB,CAAC;AAMF,eAAO,MAAM,IAAI,aACL,eAAe,aACd,GAAG,WACL,6BAA6B,8BAiBvC,CAAC;AAEF,eAAO,MAAM,eAAe;SAKrB,eAAe,CAAC,KAAK,CAAC;eAChB,GAAG;;UASf,CAAC"}
package/dist/index.js CHANGED
@@ -65216,6 +65216,7 @@ const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, voi
65216
65216
  if ((_g = method.payload) === null || _g === void 0 ? void 0 : _g.onlyConnectBleDevice) {
65217
65217
  preWarmCallbackTask === null || preWarmCallbackTask === void 0 ? void 0 : preWarmCallbackTask.resolve();
65218
65218
  Log.debug('Call API - only connect ble device: ', device === null || device === void 0 ? void 0 : device.mainId);
65219
+ requestQueue.releaseTask(method.responseID);
65219
65220
  return createResponseMessage(method.responseID, true, null);
65220
65221
  }
65221
65222
  Log.debug('Call API - setDevice: ', device.mainId);
@@ -65591,7 +65592,31 @@ function isMissingDetectedProtocolV2Error(method, error) {
65591
65592
  typeof typedError.message === 'string' &&
65592
65593
  typedError.message.includes('Device protocol has not been detected'));
65593
65594
  }
65594
- function connectDeviceForBle(method, device, retryCount = 0) {
65595
+ const BLE_ACQUIRE_DEADLINE_MS = 60 * 1000;
65596
+ function raceBleAcquire(acquirePromise, abortSignal) {
65597
+ return new Promise((resolve, reject) => {
65598
+ let settled = false;
65599
+ const settle = (fn) => {
65600
+ if (settled)
65601
+ return;
65602
+ settled = true;
65603
+ clearTimeout(deadline);
65604
+ abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.removeEventListener('abort', onAbort);
65605
+ fn();
65606
+ };
65607
+ const onAbort = () => settle(() => reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallQueueActionCancelled)));
65608
+ const deadline = setTimeout(() => settle(() => reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleTimeoutError, `BLE acquire exceeded ${BLE_ACQUIRE_DEADLINE_MS}ms deadline`))), BLE_ACQUIRE_DEADLINE_MS);
65609
+ acquirePromise.then(value => settle(() => resolve(value)), error => settle(() => reject(error)));
65610
+ if (abortSignal) {
65611
+ if (abortSignal.aborted) {
65612
+ onAbort();
65613
+ return;
65614
+ }
65615
+ abortSignal.addEventListener('abort', onAbort);
65616
+ }
65617
+ });
65618
+ }
65619
+ function connectDeviceForBle(method, device, abortSignal, retryCount = 0) {
65595
65620
  var _a;
65596
65621
  return __awaiter(this, void 0, void 0, function* () {
65597
65622
  try {
@@ -65606,9 +65631,31 @@ function connectDeviceForBle(method, device, retryCount = 0) {
65606
65631
  !device.commands ||
65607
65632
  device.commands.disposed;
65608
65633
  if (shouldAcquire) {
65609
- yield device.acquire(method.payload.connectProtocol, {
65610
- forceProtocolDetection: method.payload.forceProtocolDetection,
65611
- });
65634
+ const useAcquireGuards = DataManager.getSettings('env') === 'desktop-web-ble';
65635
+ if (useAcquireGuards && (abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.aborted)) {
65636
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallQueueActionCancelled);
65637
+ }
65638
+ if (!useAcquireGuards) {
65639
+ yield device.acquire(method.payload.connectProtocol, {
65640
+ forceProtocolDetection: method.payload.forceProtocolDetection,
65641
+ });
65642
+ }
65643
+ else {
65644
+ try {
65645
+ yield raceBleAcquire(device.acquire(method.payload.connectProtocol, {
65646
+ forceProtocolDetection: method.payload.forceProtocolDetection,
65647
+ }), abortSignal);
65648
+ }
65649
+ catch (err) {
65650
+ if (err.errorCode === hdShared.HardwareErrorCode.BleTimeoutError &&
65651
+ device.mainId &&
65652
+ device.deviceConnector) {
65653
+ yield device.deviceConnector.disconnect(device.mainId).catch(() => undefined);
65654
+ device.markTransportDisconnected();
65655
+ }
65656
+ throw err;
65657
+ }
65658
+ }
65612
65659
  }
65613
65660
  if ((_a = method.payload) === null || _a === void 0 ? void 0 : _a.onlyConnectBleDevice) {
65614
65661
  if (shouldAcquire) {
@@ -65639,7 +65686,7 @@ function connectDeviceForBle(method, device, retryCount = 0) {
65639
65686
  const nextRetry = retryCount + 1;
65640
65687
  Log.debug(`Bluetooth connection will retry, retry count: ${nextRetry}`);
65641
65688
  yield wait(3000);
65642
- yield connectDeviceForBle(method, device, nextRetry);
65689
+ yield connectDeviceForBle(method, device, abortSignal, nextRetry);
65643
65690
  }
65644
65691
  else {
65645
65692
  throw err;
@@ -65724,7 +65771,7 @@ const ensureConnected = (_context, method, connectId, pollingId, abortSignal) =>
65724
65771
  if (tryCount === 1) {
65725
65772
  device.beginConnectionAttempt();
65726
65773
  }
65727
- yield connectDeviceForBle(method, device);
65774
+ yield connectDeviceForBle(method, device, abortSignal);
65728
65775
  }
65729
65776
  resolve(device);
65730
65777
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/hd-core",
3
- "version": "1.2.0-alpha.150",
3
+ "version": "1.2.0-alpha.151",
4
4
  "description": "Core processes and APIs for communicating with OneKey hardware devices.",
5
5
  "author": "OneKey",
6
6
  "homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
@@ -25,8 +25,8 @@
25
25
  "url": "https://github.com/OneKeyHQ/hardware-js-sdk/issues"
26
26
  },
27
27
  "dependencies": {
28
- "@onekeyfe/hd-shared": "1.2.0-alpha.150",
29
- "@onekeyfe/hd-transport": "1.2.0-alpha.150",
28
+ "@onekeyfe/hd-shared": "1.2.0-alpha.151",
29
+ "@onekeyfe/hd-transport": "1.2.0-alpha.151",
30
30
  "axios": "1.15.2",
31
31
  "bignumber.js": "^9.0.2",
32
32
  "buffer": "^6.0.3",
@@ -46,5 +46,5 @@
46
46
  "@types/w3c-web-usb": "^1.0.10",
47
47
  "@types/web-bluetooth": "^0.0.21"
48
48
  },
49
- "gitHead": "08359528e71933964694eb49793e555635350104"
49
+ "gitHead": "d1fa81c92deb1bfa3903e3963a82edd6384d568a"
50
50
  }
package/src/core/index.ts CHANGED
@@ -415,6 +415,10 @@ const onCallDevice = async (
415
415
  if (method.payload?.onlyConnectBleDevice) {
416
416
  preWarmCallbackTask?.resolve();
417
417
  Log.debug('Call API - only connect ble device: ', device?.mainId);
418
+ // This early return bypasses the normal-path releaseTask at the end of the
419
+ // call; without it the task leaks and haunts every later queue snapshot
420
+ // and cancel sweep (field log: a completed task lingered for 6 minutes).
421
+ requestQueue.releaseTask(method.responseID);
418
422
  return createResponseMessage(method.responseID, true, null);
419
423
  }
420
424
 
@@ -954,7 +958,60 @@ export function isMissingDetectedProtocolV2Error(method: BaseMethod, error: unkn
954
958
  * If the Bluetooth connection times out, retry up to 6 times
955
959
  * @param retryCount - Current retry count (default 0)
956
960
  */
957
- async function connectDeviceForBle(method: BaseMethod, device: Device, retryCount = 0) {
961
+ // device.acquire awaits a transport reply with no deadline of its own; a
962
+ // transport that never settles (field case: Electron main lost an IPC reply,
963
+ // "reply was never sent" after 5 minutes) hangs the call forever and cancel()
964
+ // only takes effect at poll checkpoints. Race acquire against a deadline and
965
+ // the caller's abort signal so the hang is bounded and cancel is immediate.
966
+ const BLE_ACQUIRE_DEADLINE_MS = 60 * 1000;
967
+
968
+ function raceBleAcquire<T>(acquirePromise: Promise<T>, abortSignal?: AbortSignal): Promise<T> {
969
+ return new Promise<T>((resolve, reject) => {
970
+ let settled = false;
971
+ const settle = (fn: () => void) => {
972
+ if (settled) return;
973
+ settled = true;
974
+ clearTimeout(deadline);
975
+ abortSignal?.removeEventListener('abort', onAbort);
976
+ fn();
977
+ };
978
+ const onAbort = () =>
979
+ settle(() => reject(ERRORS.TypedError(HardwareErrorCode.CallQueueActionCancelled)));
980
+ const deadline = setTimeout(
981
+ () =>
982
+ settle(() =>
983
+ reject(
984
+ ERRORS.TypedError(
985
+ HardwareErrorCode.BleTimeoutError,
986
+ `BLE acquire exceeded ${BLE_ACQUIRE_DEADLINE_MS}ms deadline`
987
+ )
988
+ )
989
+ ),
990
+ BLE_ACQUIRE_DEADLINE_MS
991
+ );
992
+ // Attach before any early return so a late settlement of acquirePromise
993
+ // is always consumed — an abort or deadline must never leave the acquire
994
+ // rejection unhandled.
995
+ acquirePromise.then(
996
+ value => settle(() => resolve(value)),
997
+ error => settle(() => reject(error))
998
+ );
999
+ if (abortSignal) {
1000
+ if (abortSignal.aborted) {
1001
+ onAbort();
1002
+ return;
1003
+ }
1004
+ abortSignal.addEventListener('abort', onAbort);
1005
+ }
1006
+ });
1007
+ }
1008
+
1009
+ async function connectDeviceForBle(
1010
+ method: BaseMethod,
1011
+ device: Device,
1012
+ abortSignal?: AbortSignal,
1013
+ retryCount = 0
1014
+ ) {
958
1015
  try {
959
1016
  if (device.wasInterruptedByUser()) {
960
1017
  throw ERRORS.TypedError(HardwareErrorCode.DeviceInterruptedFromUser);
@@ -968,9 +1025,43 @@ async function connectDeviceForBle(method: BaseMethod, device: Device, retryCoun
968
1025
  !device.commands ||
969
1026
  device.commands.disposed;
970
1027
  if (shouldAcquire) {
971
- await device.acquire(method.payload.connectProtocol, {
972
- forceProtocolDetection: method.payload.forceProtocolDetection,
973
- });
1028
+ // The deadline/abort guards are scoped to the desktop electron
1029
+ // transport: its IPC acquire is the only path with a proven
1030
+ // never-settling failure mode, while react-native/lowlevel acquire may
1031
+ // legitimately block on a user-driven system bonding prompt for longer
1032
+ // than any sane deadline. Other envs keep the plain acquire unchanged.
1033
+ const useAcquireGuards = DataManager.getSettings('env') === 'desktop-web-ble';
1034
+ // A cancel landing during the retry backoff must not start a new acquire.
1035
+ if (useAcquireGuards && abortSignal?.aborted) {
1036
+ throw ERRORS.TypedError(HardwareErrorCode.CallQueueActionCancelled);
1037
+ }
1038
+ if (!useAcquireGuards) {
1039
+ await device.acquire(method.payload.connectProtocol, {
1040
+ forceProtocolDetection: method.payload.forceProtocolDetection,
1041
+ });
1042
+ } else {
1043
+ try {
1044
+ await raceBleAcquire(
1045
+ device.acquire(method.payload.connectProtocol, {
1046
+ forceProtocolDetection: method.payload.forceProtocolDetection,
1047
+ }),
1048
+ abortSignal
1049
+ );
1050
+ } catch (err) {
1051
+ // A deadline hit means the transport is wedged mid-acquire; drop the
1052
+ // link before the retry so it cold-connects instead of stacking a
1053
+ // second connect onto the half-open one.
1054
+ if (
1055
+ err.errorCode === HardwareErrorCode.BleTimeoutError &&
1056
+ device.mainId &&
1057
+ device.deviceConnector
1058
+ ) {
1059
+ await device.deviceConnector.disconnect(device.mainId).catch(() => undefined);
1060
+ device.markTransportDisconnected();
1061
+ }
1062
+ throw err;
1063
+ }
1064
+ }
974
1065
  }
975
1066
  if (method.payload?.onlyConnectBleDevice) {
976
1067
  if (shouldAcquire) {
@@ -1010,7 +1101,7 @@ async function connectDeviceForBle(method: BaseMethod, device: Device, retryCoun
1010
1101
  const nextRetry = retryCount + 1;
1011
1102
  Log.debug(`Bluetooth connection will retry, retry count: ${nextRetry}`);
1012
1103
  await wait(3000);
1013
- await connectDeviceForBle(method, device, nextRetry);
1104
+ await connectDeviceForBle(method, device, abortSignal, nextRetry);
1014
1105
  } else {
1015
1106
  throw err;
1016
1107
  }
@@ -1120,7 +1211,7 @@ const ensureConnected = async (
1120
1211
  if (tryCount === 1) {
1121
1212
  device.beginConnectionAttempt();
1122
1213
  }
1123
- await connectDeviceForBle(method, device);
1214
+ await connectDeviceForBle(method, device, abortSignal);
1124
1215
  }
1125
1216
  resolve(device);
1126
1217
  return;