@onekeyfe/hd-core 1.2.0-alpha.130 → 1.2.0-alpha.131

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.
@@ -800,7 +800,13 @@ describe('DeviceCommands cancellation', () => {
800
800
  try {
801
801
  const commands = createCommands();
802
802
  commands.disposed = false;
803
+ commands.mainId = 'main-id';
803
804
  commands.callPromise = new Promise(() => {});
805
+ const disconnect = jest.fn().mockResolvedValue(undefined);
806
+ commands.transport = {
807
+ name: 'ReactNativeBleTransport',
808
+ disconnect,
809
+ } as any;
804
810
  const dispose = jest.fn().mockResolvedValue(undefined);
805
811
  commands.dispose = dispose;
806
812
 
@@ -810,6 +816,7 @@ describe('DeviceCommands cancellation', () => {
810
816
 
811
817
  await expect(cancellation).resolves.toBeUndefined();
812
818
  expect(dispose).toHaveBeenCalledWith(true);
819
+ expect(disconnect).toHaveBeenCalledWith('main-id');
813
820
  expect(commands.callPromise).toBeUndefined();
814
821
  } finally {
815
822
  jest.useRealTimers();
@@ -82,6 +82,23 @@ describe('public device lifecycle events', () => {
82
82
  expect(DevicePool.emitter.listenerCount(DEVICE.DISCONNECT)).toBe(1);
83
83
  });
84
84
 
85
+ test('isolates pending cancellation cleanup by connect id', () => {
86
+ core = initCore();
87
+ const context = (core as any).getCoreContext();
88
+ const firstCleanup = createDeferred<void>();
89
+ const replacementCleanup = createDeferred<void>();
90
+
91
+ context.setPrePendingCallPromise('device-a', firstCleanup.promise);
92
+
93
+ expect(context.getPrePendingCallPromise('device-a')).toBe(firstCleanup.promise);
94
+ expect(context.getPrePendingCallPromise('device-b')).toBeUndefined();
95
+
96
+ context.setPrePendingCallPromise('device-a', replacementCleanup.promise);
97
+ context.removePrePendingCallPromise('device-a', firstCleanup.promise);
98
+
99
+ expect(context.getPrePendingCallPromise('device-a')).toBe(replacementCleanup.promise);
100
+ });
101
+
85
102
  test('keeps shared device lifecycle listeners across a device cache reset', () => {
86
103
  jest.spyOn(DataManager, 'getSettings').mockReturnValue('react-native' as never);
87
104
  core = initCore();
@@ -14,7 +14,7 @@ export default class Core extends EventEmitter {
14
14
  readonly sdkInstanceId: string;
15
15
  private requestQueue;
16
16
  private disposePromise?;
17
- private prePendingCallPromise;
17
+ private prePendingCallPromises;
18
18
  private methodSynchronize;
19
19
  constructor();
20
20
  private getCoreContext;
@@ -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;AAWhC,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAmE7D,eAAO,MAAM,OAAO,YAAmB,WAAW,WAAW,WAAW,iBAoFvE,CAAC;AAg5BF,eAAO,MAAM,MAAM,YAAa,WAAW,cAAc,MAAM,SAkF9D,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,qBAAqB,CAA4B;IAEzD,OAAO,CAAC,iBAAiB,CAAoB;;IAS7C,OAAO,CAAC,cAAc;IAoBhB,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;AAYhC,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAmE7D,eAAO,MAAM,OAAO,YAAmB,WAAW,WAAW,WAAW,iBAoFvE,CAAC;AAw6BF,eAAO,MAAM,MAAM,YAAa,WAAW,cAAc,MAAM,SAqF9D,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 +1 @@
1
- {"version":3,"file":"DeviceCommands.d.ts","sourceRoot":"","sources":["../../src/device/DeviceCommands.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DeviceCommands.d.ts","sourceRoot":"","sources":["../../src/device/DeviceCommands.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1093,7 +1093,7 @@ declare class Core extends EventEmitter {
1093
1093
  readonly sdkInstanceId: string;
1094
1094
  private requestQueue;
1095
1095
  private disposePromise?;
1096
- private prePendingCallPromise;
1096
+ private prePendingCallPromises;
1097
1097
  private methodSynchronize;
1098
1098
  constructor();
1099
1099
  private getCoreContext;
package/dist/index.js CHANGED
@@ -43679,6 +43679,7 @@ class DeviceCommands {
43679
43679
  }
43680
43680
  const activeCall = this.callPromise;
43681
43681
  let timer;
43682
+ let timedOut = false;
43682
43683
  const cancellation = (() => __awaiter(this, void 0, void 0, function* () {
43683
43684
  yield this.dispose(true);
43684
43685
  yield (activeCall === null || activeCall === void 0 ? void 0 : activeCall.catch(() => undefined));
@@ -43687,13 +43688,23 @@ class DeviceCommands {
43687
43688
  yield Promise.race([
43688
43689
  cancellation,
43689
43690
  new Promise(resolve => {
43690
- timer = setTimeout(resolve, 10 * 1000);
43691
+ timer = setTimeout(() => {
43692
+ timedOut = true;
43693
+ resolve();
43694
+ }, 10 * 1000);
43691
43695
  }),
43692
43696
  ]);
43693
43697
  }
43694
43698
  finally {
43695
43699
  if (timer)
43696
43700
  clearTimeout(timer);
43701
+ if (timedOut &&
43702
+ this.transport.name === 'ReactNativeBleTransport' &&
43703
+ this.transport.disconnect) {
43704
+ yield this.transport.disconnect(this.mainId).catch(error => {
43705
+ Log$h.debug('BLE cancellation timeout disconnect error (ignored)', error);
43706
+ });
43707
+ }
43697
43708
  if (this.callPromise === activeCall) {
43698
43709
  this.callPromise = undefined;
43699
43710
  }
@@ -65014,6 +65025,7 @@ const createUiProgressMessageFilter = (intervalMs = DEFAULT_UI_PROGRESS_INTERVAL
65014
65025
 
65015
65026
  const Log = getLogger(exports.LoggerNames.Core);
65016
65027
  const PRE_INITIALIZE_TTL_MS = 60 * 1000;
65028
+ const PRE_PENDING_CALL_TIMEOUT_MS = 15 * 1000;
65017
65029
  const preWarmInflight = new Map();
65018
65030
  const preWarmDoneAt = new Map();
65019
65031
  function hasDeriveCardano(method) {
@@ -65169,23 +65181,40 @@ const handlePreWarmSignal = (context, message, method) => __awaiter(void 0, void
65169
65181
  }
65170
65182
  }
65171
65183
  });
65172
- const waitForPendingPromise = (getPrePendingCallPromise, removePrePendingCallPromise) => __awaiter(void 0, void 0, void 0, function* () {
65173
- const pendingPromise = getPrePendingCallPromise();
65184
+ const waitForPendingPromise = (connectId, getPrePendingCallPromise, removePrePendingCallPromise) => __awaiter(void 0, void 0, void 0, function* () {
65185
+ const pendingPromise = getPrePendingCallPromise(connectId);
65174
65186
  if (pendingPromise) {
65175
65187
  Log.debug('pre pending call promise before call method, wait for it');
65188
+ let timer;
65189
+ let timedOut = false;
65176
65190
  try {
65177
- yield pendingPromise;
65191
+ yield Promise.race([
65192
+ pendingPromise,
65193
+ new Promise(resolve => {
65194
+ timer = setTimeout(() => {
65195
+ timedOut = true;
65196
+ resolve();
65197
+ }, PRE_PENDING_CALL_TIMEOUT_MS);
65198
+ }),
65199
+ ]);
65178
65200
  }
65179
65201
  catch (error) {
65180
65202
  }
65181
- removePrePendingCallPromise === null || removePrePendingCallPromise === void 0 ? void 0 : removePrePendingCallPromise(pendingPromise);
65203
+ finally {
65204
+ if (timer)
65205
+ clearTimeout(timer);
65206
+ removePrePendingCallPromise === null || removePrePendingCallPromise === void 0 ? void 0 : removePrePendingCallPromise(connectId, pendingPromise);
65207
+ }
65208
+ if (timedOut) {
65209
+ Log.warn('pre pending call promise timed out before call method', { connectId });
65210
+ }
65182
65211
  Log.debug('pre pending call promise before call method done');
65183
65212
  }
65184
65213
  });
65185
65214
  const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, void 0, function* () {
65186
- var _d, _e, _f, _g, _h;
65215
+ var _d, _e, _f, _g, _h, _j, _k;
65187
65216
  let messageResponse;
65188
- const { requestQueue, getPrePendingCallPromise, setPrePendingCallPromise } = context;
65217
+ const { requestQueue, getPrePendingCallPromise, removePrePendingCallPromise } = context;
65189
65218
  updateMethodRequestContext(method, { status: 'running' });
65190
65219
  const normalizePassphraseState = (s) => s || '';
65191
65220
  const connectStateChange = normalizePassphraseState(preConnectCache.passphraseState) !==
@@ -65200,7 +65229,7 @@ const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, voi
65200
65229
  if (method.connectId) {
65201
65230
  yield context.waitForCallbackTasks(method.connectId);
65202
65231
  }
65203
- yield waitForPendingPromise(getPrePendingCallPromise, setPrePendingCallPromise);
65232
+ yield waitForPendingPromise((_d = method.connectId) !== null && _d !== void 0 ? _d : '', getPrePendingCallPromise, removePrePendingCallPromise);
65204
65233
  const task = requestQueue.createTask(method);
65205
65234
  let preWarmCallbackTask;
65206
65235
  if (method.isPreWarmSignal && method.connectId) {
@@ -65209,9 +65238,9 @@ const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, voi
65209
65238
  }
65210
65239
  let device;
65211
65240
  try {
65212
- const connectId = (_d = method.connectId) !== null && _d !== void 0 ? _d : '';
65241
+ const connectId = (_e = method.connectId) !== null && _e !== void 0 ? _e : '';
65213
65242
  const pollingId = pollingManager.start(connectId);
65214
- device = yield ensureConnected(context, method, connectId, pollingId, (_e = task.abortController) === null || _e === void 0 ? void 0 : _e.signal);
65243
+ device = yield ensureConnected(context, method, connectId, pollingId, (_f = task.abortController) === null || _f === void 0 ? void 0 : _f.signal);
65215
65244
  }
65216
65245
  catch (e) {
65217
65246
  preWarmCallbackTask === null || preWarmCallbackTask === void 0 ? void 0 : preWarmCallbackTask.resolve();
@@ -65226,17 +65255,17 @@ const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, voi
65226
65255
  requestQueue.releaseTask(method.responseID);
65227
65256
  return createResponseMessage(method.responseID, false, { error: e });
65228
65257
  }
65229
- if ((_f = method.payload) === null || _f === void 0 ? void 0 : _f.onlyConnectBleDevice) {
65258
+ if ((_g = method.payload) === null || _g === void 0 ? void 0 : _g.onlyConnectBleDevice) {
65230
65259
  preWarmCallbackTask === null || preWarmCallbackTask === void 0 ? void 0 : preWarmCallbackTask.resolve();
65231
65260
  Log.debug('Call API - only connect ble device: ', device === null || device === void 0 ? void 0 : device.mainId);
65232
65261
  return createResponseMessage(method.responseID, true, null);
65233
65262
  }
65234
65263
  Log.debug('Call API - setDevice: ', device.mainId);
65235
- (_g = method.setDevice) === null || _g === void 0 ? void 0 : _g.call(method, device);
65264
+ (_h = method.setDevice) === null || _h === void 0 ? void 0 : _h.call(method, device);
65236
65265
  method.context = context;
65237
65266
  updateMethodRequestContext(method, {
65238
65267
  deviceInstanceId: device.instanceId,
65239
- commandsInstanceId: (_h = device.commands) === null || _h === void 0 ? void 0 : _h.instanceId,
65268
+ commandsInstanceId: (_j = device.commands) === null || _j === void 0 ? void 0 : _j.instanceId,
65240
65269
  });
65241
65270
  const activeRequests = getActiveRequestsByDeviceInstance(device.instanceId);
65242
65271
  if (activeRequests.length > 0) {
@@ -65265,14 +65294,14 @@ const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, voi
65265
65294
  if (method.connectId) {
65266
65295
  yield context.waitForCallbackTasks(method.connectId, preWarmCallbackTask);
65267
65296
  }
65268
- yield waitForPendingPromise(getPrePendingCallPromise, setPrePendingCallPromise);
65297
+ yield waitForPendingPromise((_k = method.connectId) !== null && _k !== void 0 ? _k : '', getPrePendingCallPromise, removePrePendingCallPromise);
65269
65298
  const inner = () => __awaiter(void 0, void 0, void 0, function* () {
65270
- var _j, _k;
65299
+ var _l, _m;
65271
65300
  method.assertProtocolSupported(device.getProtocol(), device.getCurrentFirmwareType());
65272
65301
  protocolV2Operation = device.isProtocolV2();
65273
65302
  const versionRange = device.getCurrentMethodVersionRange(type => method.getVersionRange()[type]);
65274
- const currentFirmwareVersion = (_j = device.getCurrentFirmwareVersionString()) !== null && _j !== void 0 ? _j : '0.0.0';
65275
- const currentBleVersion = (_k = device.getCurrentBLEFirmwareVersionString()) !== null && _k !== void 0 ? _k : '0.0.0';
65303
+ const currentFirmwareVersion = (_l = device.getCurrentFirmwareVersionString()) !== null && _l !== void 0 ? _l : '0.0.0';
65304
+ const currentBleVersion = (_m = device.getCurrentBLEFirmwareVersionString()) !== null && _m !== void 0 ? _m : '0.0.0';
65276
65305
  const deviceFirmwareType = device.getCurrentFirmwareType();
65277
65306
  let newVersionStatus;
65278
65307
  if (device.features && !device.isProtocolV2()) {
@@ -65350,7 +65379,7 @@ const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, voi
65350
65379
  }
65351
65380
  },
65352
65381
  prepare: () => __awaiter(void 0, void 0, void 0, function* () {
65353
- var _l, _m, _o, _p, _q;
65382
+ var _o, _p, _q, _r, _s;
65354
65383
  if (method.deviceId && method.checkDeviceId && !deviceIdCheckedDuringUnlockPreflight) {
65355
65384
  const isSameDeviceID = yield checkLiveDeviceId(device, method.deviceId);
65356
65385
  if (!isSameDeviceID) {
@@ -65370,7 +65399,7 @@ const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, voi
65370
65399
  require: support.require,
65371
65400
  });
65372
65401
  }
65373
- const passphraseStateSafety = yield device.checkPassphraseStateSafety((_l = method.payload) === null || _l === void 0 ? void 0 : _l.passphraseState, (_m = method.payload) === null || _m === void 0 ? void 0 : _m.useEmptyPassphrase, (_o = method.payload) === null || _o === void 0 ? void 0 : _o.skipPassphraseCheck, hasDeriveCardano(method));
65402
+ const passphraseStateSafety = yield device.checkPassphraseStateSafety((_o = method.payload) === null || _o === void 0 ? void 0 : _o.passphraseState, (_p = method.payload) === null || _p === void 0 ? void 0 : _p.useEmptyPassphrase, (_q = method.payload) === null || _q === void 0 ? void 0 : _q.skipPassphraseCheck, hasDeriveCardano(method));
65374
65403
  checkPassphraseEnableState(method, device.features);
65375
65404
  if (!passphraseStateSafety) {
65376
65405
  DevicePool.clearDeviceCache(method.payload.connectId);
@@ -65388,7 +65417,7 @@ const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, voi
65388
65417
  ? e
65389
65418
  : hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'open safety check failed.');
65390
65419
  }
65391
- (_q = (_p = method.device) === null || _p === void 0 ? void 0 : _p.commands) === null || _q === void 0 ? void 0 : _q.checkDisposed();
65420
+ (_s = (_r = method.device) === null || _r === void 0 ? void 0 : _r.commands) === null || _s === void 0 ? void 0 : _s.checkDisposed();
65392
65421
  }),
65393
65422
  });
65394
65423
  messageResponse = createResponseMessage(method.responseID, true, response);
@@ -65656,7 +65685,7 @@ const ensureConnected = (_context, method, connectId, pollingId, abortSignal) =>
65656
65685
  Log.debug(`EnsureConnected function start, MAX_RETRY_COUNT=${MAX_RETRY_COUNT}, POLL_INTERVAL_TIME=${POLL_INTERVAL_TIME} `);
65657
65686
  const poll = (time = POLL_INTERVAL_TIME) => __awaiter(void 0, void 0, void 0, function* () {
65658
65687
  return new Promise((resolve, reject) => __awaiter(void 0, void 0, void 0, function* () {
65659
- var _r;
65688
+ var _t;
65660
65689
  const abort = () => {
65661
65690
  if (abortSignal && abortSignal.aborted) {
65662
65691
  if (timer) {
@@ -65771,7 +65800,7 @@ const ensureConnected = (_context, method, connectId, pollingId, abortSignal) =>
65771
65800
  clearTimeout(timer);
65772
65801
  }
65773
65802
  Log.debug('EnsureConnected get to max try count, will return: ', tryCount);
65774
- if (DataManager.isBrowserWebUsb(env) && !((_r = method.payload) === null || _r === void 0 ? void 0 : _r.skipWebDevicePrompt)) {
65803
+ if (DataManager.isBrowserWebUsb(env) && !((_t = method.payload) === null || _t === void 0 ? void 0 : _t.skipWebDevicePrompt)) {
65775
65804
  postMessage(createUiMessage(UI_REQUEST.WEB_DEVICE_PROMPT_ACCESS_PERMISSION));
65776
65805
  reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.WebDeviceNotFoundOrNeedsPermission));
65777
65806
  }
@@ -65789,7 +65818,7 @@ const ensureConnected = (_context, method, connectId, pollingId, abortSignal) =>
65789
65818
  return poll();
65790
65819
  });
65791
65820
  const cancel = (context, connectId) => {
65792
- var _a, _b;
65821
+ var _a, _b, _c;
65793
65822
  const { requestQueue, setPrePendingCallPromise } = context;
65794
65823
  if (connectId) {
65795
65824
  try {
@@ -65803,7 +65832,7 @@ const cancel = (context, connectId) => {
65803
65832
  if (task && ((_a = task.method) === null || _a === void 0 ? void 0 : _a.device)) {
65804
65833
  if (!canceledDevices.includes(task.method.device)) {
65805
65834
  const { device } = task.method;
65806
- setPrePendingCallPromise(device === null || device === void 0 ? void 0 : device.interruptionFromUser());
65835
+ setPrePendingCallPromise((_b = task.method.connectId) !== null && _b !== void 0 ? _b : connectId, device.interruptionFromUser());
65807
65836
  canceledDevices.push(device);
65808
65837
  }
65809
65838
  requestQueue.rejectRequest(requestId, hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallQueueActionCancelled));
@@ -65823,7 +65852,7 @@ const cancel = (context, connectId) => {
65823
65852
  for (const requestId of requestQueue.getRequestTasksId()) {
65824
65853
  const task = requestQueue.getTask(requestId);
65825
65854
  Log.debug('Cancel Api connect task: ', task);
65826
- if (task && ((_b = task.method) === null || _b === void 0 ? void 0 : _b.device)) {
65855
+ if (task && ((_c = task.method) === null || _c === void 0 ? void 0 : _c.device)) {
65827
65856
  if (!canceledDevices.includes(task.method.device)) {
65828
65857
  const { device } = task.method;
65829
65858
  device === null || device === void 0 ? void 0 : device.interruptionFromUser();
@@ -66012,6 +66041,7 @@ class Core extends events.exports {
66012
66041
  constructor() {
66013
66042
  super();
66014
66043
  this.requestQueue = new RequestQueue();
66044
+ this.prePendingCallPromises = new Map();
66015
66045
  this.methodSynchronize = getSynchronize();
66016
66046
  this.tracingContext = createSdkTracingContext();
66017
66047
  this.sdkInstanceId = this.tracingContext.sdkInstanceId;
@@ -66023,9 +66053,18 @@ class Core extends events.exports {
66023
66053
  tracingContext: this.tracingContext,
66024
66054
  requestQueue: this.requestQueue,
66025
66055
  methodSynchronize: this.methodSynchronize,
66026
- getPrePendingCallPromise: () => this.prePendingCallPromise,
66027
- setPrePendingCallPromise: (promise) => {
66028
- this.prePendingCallPromise = promise;
66056
+ getPrePendingCallPromise: (connectId) => this.prePendingCallPromises.get(connectId),
66057
+ setPrePendingCallPromise: (connectId, promise) => {
66058
+ if (!promise) {
66059
+ this.prePendingCallPromises.delete(connectId);
66060
+ return;
66061
+ }
66062
+ this.prePendingCallPromises.set(connectId, promise);
66063
+ },
66064
+ removePrePendingCallPromise: (connectId, promise) => {
66065
+ if (this.prePendingCallPromises.get(connectId) === promise) {
66066
+ this.prePendingCallPromises.delete(connectId);
66067
+ }
66029
66068
  },
66030
66069
  registerCallbackTask: (connectId, callbackPromise) => {
66031
66070
  this.requestQueue.registerPendingCallbackTask(connectId, callbackPromise);
@@ -66119,7 +66158,7 @@ class Core extends events.exports {
66119
66158
  preWarmInflight.clear();
66120
66159
  preWarmDoneAt.clear();
66121
66160
  preConnectCache = { passphraseState: undefined };
66122
- this.prePendingCallPromise = undefined;
66161
+ this.prePendingCallPromises.clear();
66123
66162
  this.removeAllListeners();
66124
66163
  cleanupSdkInstance(this.sdkInstanceId);
66125
66164
  if (_core === this)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/hd-core",
3
- "version": "1.2.0-alpha.130",
3
+ "version": "1.2.0-alpha.131",
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.130",
29
- "@onekeyfe/hd-transport": "1.2.0-alpha.130",
28
+ "@onekeyfe/hd-shared": "1.2.0-alpha.131",
29
+ "@onekeyfe/hd-transport": "1.2.0-alpha.131",
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": "287003096bc4df3a5824f2bea77e50f7fdc20565"
49
+ "gitHead": "81b472e983e80e6aa771b991dc9c0c9b1bdcf07b"
50
50
  }
package/src/core/index.ts CHANGED
@@ -83,6 +83,7 @@ import type { BaseMethod } from '../api/BaseMethod';
83
83
 
84
84
  const Log = getLogger(LoggerNames.Core);
85
85
  const PRE_INITIALIZE_TTL_MS = 60 * 1000;
86
+ const PRE_PENDING_CALL_TIMEOUT_MS = 15 * 1000;
86
87
 
87
88
  // Dedup/coalesce state for "pre-warm signal" methods (isPreWarmSignal),
88
89
  // keyed by getPreWarmKey(): coalesce in-flight, skip if warmed within TTL.
@@ -297,18 +298,34 @@ const handlePreWarmSignal = async (
297
298
  };
298
299
 
299
300
  const waitForPendingPromise = async (
300
- getPrePendingCallPromise: () => Promise<void> | undefined,
301
- removePrePendingCallPromise?: (promise: Promise<void> | undefined) => void
301
+ connectId: string,
302
+ getPrePendingCallPromise: (connectId: string) => Promise<void> | undefined,
303
+ removePrePendingCallPromise?: (connectId: string, promise: Promise<void>) => void
302
304
  ) => {
303
- const pendingPromise = getPrePendingCallPromise();
305
+ const pendingPromise = getPrePendingCallPromise(connectId);
304
306
  if (pendingPromise) {
305
307
  Log.debug('pre pending call promise before call method, wait for it');
308
+ let timer: ReturnType<typeof setTimeout> | undefined;
309
+ let timedOut = false;
306
310
  try {
307
- await pendingPromise;
311
+ await Promise.race([
312
+ pendingPromise,
313
+ new Promise<void>(resolve => {
314
+ timer = setTimeout(() => {
315
+ timedOut = true;
316
+ resolve();
317
+ }, PRE_PENDING_CALL_TIMEOUT_MS);
318
+ }),
319
+ ]);
308
320
  } catch (error) {
309
- // Cancellation is best-effort, but its teardown must settle before reuse.
321
+ // Cancellation is best-effort; the transport teardown owns recovery.
322
+ } finally {
323
+ if (timer) clearTimeout(timer);
324
+ removePrePendingCallPromise?.(connectId, pendingPromise);
325
+ }
326
+ if (timedOut) {
327
+ Log.warn('pre pending call promise timed out before call method', { connectId });
310
328
  }
311
- removePrePendingCallPromise?.(pendingPromise);
312
329
  Log.debug('pre pending call promise before call method done');
313
330
  }
314
331
  };
@@ -320,7 +337,7 @@ const onCallDevice = async (
320
337
  ): Promise<any> => {
321
338
  let messageResponse: any;
322
339
 
323
- const { requestQueue, getPrePendingCallPromise, setPrePendingCallPromise } = context;
340
+ const { requestQueue, getPrePendingCallPromise, removePrePendingCallPromise } = context;
324
341
 
325
342
  updateMethodRequestContext(method, { status: 'running' });
326
343
 
@@ -348,7 +365,11 @@ const onCallDevice = async (
348
365
  await context.waitForCallbackTasks(method.connectId);
349
366
  }
350
367
 
351
- await waitForPendingPromise(getPrePendingCallPromise, setPrePendingCallPromise);
368
+ await waitForPendingPromise(
369
+ method.connectId ?? '',
370
+ getPrePendingCallPromise,
371
+ removePrePendingCallPromise
372
+ );
352
373
 
353
374
  const task = requestQueue.createTask(method);
354
375
 
@@ -447,7 +468,11 @@ const onCallDevice = async (
447
468
  await context.waitForCallbackTasks(method.connectId, preWarmCallbackTask);
448
469
  }
449
470
 
450
- await waitForPendingPromise(getPrePendingCallPromise, setPrePendingCallPromise);
471
+ await waitForPendingPromise(
472
+ method.connectId ?? '',
473
+ getPrePendingCallPromise,
474
+ removePrePendingCallPromise
475
+ );
451
476
 
452
477
  const inner = async (): Promise<void> => {
453
478
  // Protocol is established from an active device response during acquire/initialize.
@@ -1181,7 +1206,10 @@ export const cancel = (context: CoreContext, connectId?: string) => {
1181
1206
  if (task && task.method?.device) {
1182
1207
  if (!canceledDevices.includes(task.method.device)) {
1183
1208
  const { device } = task.method;
1184
- setPrePendingCallPromise(device?.interruptionFromUser());
1209
+ setPrePendingCallPromise(
1210
+ task.method.connectId ?? connectId,
1211
+ device.interruptionFromUser()
1212
+ );
1185
1213
  canceledDevices.push(device);
1186
1214
  }
1187
1215
  requestQueue.rejectRequest(
@@ -1535,7 +1563,7 @@ export default class Core extends EventEmitter {
1535
1563
  private disposePromise?: Promise<void>;
1536
1564
 
1537
1565
  // background task
1538
- private prePendingCallPromise: Promise<void> | undefined;
1566
+ private prePendingCallPromises = new Map<string, Promise<void>>();
1539
1567
 
1540
1568
  private methodSynchronize = getSynchronize();
1541
1569
 
@@ -1552,9 +1580,18 @@ export default class Core extends EventEmitter {
1552
1580
  tracingContext: this.tracingContext,
1553
1581
  requestQueue: this.requestQueue,
1554
1582
  methodSynchronize: this.methodSynchronize,
1555
- getPrePendingCallPromise: () => this.prePendingCallPromise,
1556
- setPrePendingCallPromise: (promise: Promise<void> | undefined) => {
1557
- this.prePendingCallPromise = promise;
1583
+ getPrePendingCallPromise: (connectId: string) => this.prePendingCallPromises.get(connectId),
1584
+ setPrePendingCallPromise: (connectId: string, promise?: Promise<void>) => {
1585
+ if (!promise) {
1586
+ this.prePendingCallPromises.delete(connectId);
1587
+ return;
1588
+ }
1589
+ this.prePendingCallPromises.set(connectId, promise);
1590
+ },
1591
+ removePrePendingCallPromise: (connectId: string, promise: Promise<void>) => {
1592
+ if (this.prePendingCallPromises.get(connectId) === promise) {
1593
+ this.prePendingCallPromises.delete(connectId);
1594
+ }
1558
1595
  },
1559
1596
  // callback 任务管理
1560
1597
  registerCallbackTask: (connectId: string, callbackPromise: Deferred<any>) => {
@@ -1669,7 +1706,7 @@ export default class Core extends EventEmitter {
1669
1706
  preWarmInflight.clear();
1670
1707
  preWarmDoneAt.clear();
1671
1708
  preConnectCache = { passphraseState: undefined };
1672
- this.prePendingCallPromise = undefined;
1709
+ this.prePendingCallPromises.clear();
1673
1710
  this.removeAllListeners();
1674
1711
  cleanupSdkInstance(this.sdkInstanceId);
1675
1712
  if (_core === this) _core = undefined;
@@ -264,6 +264,7 @@ export class DeviceCommands {
264
264
  }
265
265
  const activeCall = this.callPromise;
266
266
  let timer: ReturnType<typeof setTimeout> | undefined;
267
+ let timedOut = false;
267
268
  const cancellation = (async () => {
268
269
  await this.dispose(true);
269
270
  await activeCall?.catch(() => undefined);
@@ -273,11 +274,23 @@ export class DeviceCommands {
273
274
  await Promise.race([
274
275
  cancellation,
275
276
  new Promise<void>(resolve => {
276
- timer = setTimeout(resolve, 10 * 1000);
277
+ timer = setTimeout(() => {
278
+ timedOut = true;
279
+ resolve();
280
+ }, 10 * 1000);
277
281
  }),
278
282
  ]);
279
283
  } finally {
280
284
  if (timer) clearTimeout(timer);
285
+ if (
286
+ timedOut &&
287
+ this.transport.name === 'ReactNativeBleTransport' &&
288
+ this.transport.disconnect
289
+ ) {
290
+ await this.transport.disconnect(this.mainId).catch(error => {
291
+ Log.debug('BLE cancellation timeout disconnect error (ignored)', error);
292
+ });
293
+ }
281
294
  if (this.callPromise === activeCall) {
282
295
  this.callPromise = undefined;
283
296
  }