@onekeyfe/hd-core 1.2.2-alpha.12 → 1.2.2-alpha.122

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.
Files changed (75) hide show
  1. package/README.md +1 -1
  2. package/__tests__/AllNetworkGetAddressBase.tracing.test.ts +503 -10
  3. package/__tests__/DeviceCommands.test.ts +254 -1
  4. package/__tests__/core-error-output.test.ts +169 -1
  5. package/__tests__/device-lifecycle-events.test.ts +379 -15
  6. package/__tests__/open-wallet-session-error-response.test.ts +2 -2
  7. package/__tests__/open-wallet-session.test.ts +8 -411
  8. package/__tests__/protocol-v2.test.ts +86 -0
  9. package/__tests__/public-device-state-api.test.ts +2 -7
  10. package/__tests__/search-devices.test.ts +196 -8
  11. package/__tests__/sol-sign-offchain-message.test.ts +64 -0
  12. package/dist/api/GetFeatures.d.ts.map +1 -1
  13. package/dist/api/GetPassphraseState.d.ts.map +1 -1
  14. package/dist/api/OpenWalletSession.d.ts.map +1 -1
  15. package/dist/api/SearchDevices.d.ts +2 -15
  16. package/dist/api/SearchDevices.d.ts.map +1 -1
  17. package/dist/api/UploadPortfolio.d.ts +1 -0
  18. package/dist/api/UploadPortfolio.d.ts.map +1 -1
  19. package/dist/api/allnetwork/AllNetworkGetAddress.d.ts +2 -0
  20. package/dist/api/allnetwork/AllNetworkGetAddress.d.ts.map +1 -1
  21. package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts +7 -1
  22. package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
  23. package/dist/api/allnetwork/AllNetworkGetAddressByLoop.d.ts.map +1 -1
  24. package/dist/api/device/DeviceVerify.d.ts.map +1 -1
  25. package/dist/api/solana/SolSignOffchainMessage.d.ts.map +1 -1
  26. package/dist/core/RequestQueue.d.ts +1 -0
  27. package/dist/core/RequestQueue.d.ts.map +1 -1
  28. package/dist/core/index.d.ts +3 -1
  29. package/dist/core/index.d.ts.map +1 -1
  30. package/dist/core/uiPromiseRegistry.d.ts +1 -1
  31. package/dist/data-manager/TransportManager.d.ts +2 -0
  32. package/dist/data-manager/TransportManager.d.ts.map +1 -1
  33. package/dist/device/Device.d.ts +2 -0
  34. package/dist/device/Device.d.ts.map +1 -1
  35. package/dist/device/DeviceCommands.d.ts +5 -4
  36. package/dist/device/DeviceCommands.d.ts.map +1 -1
  37. package/dist/index.d.ts +35 -30
  38. package/dist/index.js +558 -234
  39. package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
  40. package/dist/types/api/getFeatures.d.ts.map +1 -1
  41. package/dist/types/api/getPassphraseState.d.ts.map +1 -1
  42. package/dist/types/api/openWalletSession.d.ts +1 -10
  43. package/dist/types/api/openWalletSession.d.ts.map +1 -1
  44. package/dist/types/api/protocolV2.d.ts +3 -4
  45. package/dist/types/api/protocolV2.d.ts.map +1 -1
  46. package/dist/types/api/solSignOffchainMessage.d.ts +1 -0
  47. package/dist/types/api/solSignOffchainMessage.d.ts.map +1 -1
  48. package/dist/types/params.d.ts.map +1 -1
  49. package/dist/utils/patch.d.ts +1 -1
  50. package/dist/utils/patch.d.ts.map +1 -1
  51. package/package.json +4 -4
  52. package/src/api/GetFeatures.ts +1 -0
  53. package/src/api/GetPassphraseState.ts +1 -0
  54. package/src/api/OpenWalletSession.ts +7 -77
  55. package/src/api/SearchDevices.ts +121 -27
  56. package/src/api/UploadPortfolio.ts +5 -4
  57. package/src/api/allnetwork/AllNetworkGetAddress.ts +79 -45
  58. package/src/api/allnetwork/AllNetworkGetAddressBase.ts +95 -24
  59. package/src/api/allnetwork/AllNetworkGetAddressByLoop.ts +3 -0
  60. package/src/api/device/DeviceVerify.ts +8 -0
  61. package/src/api/solana/SolSignOffchainMessage.ts +44 -4
  62. package/src/core/RequestQueue.ts +20 -0
  63. package/src/core/index.ts +156 -50
  64. package/src/data/messages/messages-protocol-v2.json +49 -33
  65. package/src/data/messages/messages.json +8 -5
  66. package/src/data-manager/TransportManager.ts +14 -3
  67. package/src/device/Device.ts +58 -27
  68. package/src/device/DeviceCommands.ts +29 -2
  69. package/src/protocols/protocol-v2/walletSession.ts +7 -0
  70. package/src/types/api/getFeatures.ts +2 -1
  71. package/src/types/api/getPassphraseState.ts +2 -5
  72. package/src/types/api/openWalletSession.ts +7 -19
  73. package/src/types/api/protocolV2.ts +3 -4
  74. package/src/types/api/solSignOffchainMessage.ts +2 -0
  75. package/src/types/params.ts +7 -0
package/dist/index.js CHANGED
@@ -291,7 +291,6 @@ const writeFirmwareByteSource = ({ source, chunkSize, write, }) => __awaiter(voi
291
291
  const OpenWalletSessionMode = {
292
292
  Standard: 'standard',
293
293
  SelectHidden: 'select-hidden',
294
- ResumeHidden: 'resume-hidden',
295
294
  };
296
295
 
297
296
  exports.EOneKeyDeviceMode = void 0;
@@ -13203,7 +13202,8 @@ var nested$2 = {
13203
13202
  },
13204
13203
  SolanaOffChainMessageVersion: {
13205
13204
  values: {
13206
- MESSAGE_VERSION_0: 0
13205
+ MESSAGE_VERSION_0: 0,
13206
+ MESSAGE_VERSION_1: 1
13207
13207
  }
13208
13208
  },
13209
13209
  SolanaOffChainMessageFormat: {
@@ -13236,14 +13236,16 @@ var nested$2 = {
13236
13236
  },
13237
13237
  message_format: {
13238
13238
  type: "SolanaOffChainMessageFormat",
13239
- id: 4,
13240
- options: {
13241
- "default": "V0_RESTRICTED_ASCII"
13242
- }
13239
+ id: 4
13243
13240
  },
13244
13241
  application_domain: {
13245
13242
  type: "bytes",
13246
13243
  id: 5
13244
+ },
13245
+ required_signers: {
13246
+ rule: "repeated",
13247
+ type: "bytes",
13248
+ id: 7
13247
13249
  }
13248
13250
  }
13249
13251
  },
@@ -31499,10 +31501,6 @@ var nested = {
31499
31501
  request_id: {
31500
31502
  type: "bytes",
31501
31503
  id: 5
31502
- },
31503
- source_fingerprint: {
31504
- type: "uint32",
31505
- id: 6
31506
31504
  }
31507
31505
  }
31508
31506
  },
@@ -31758,10 +31756,6 @@ var nested = {
31758
31756
  expected_address: {
31759
31757
  type: "bytes",
31760
31758
  id: 12
31761
- },
31762
- source_fingerprint: {
31763
- type: "uint32",
31764
- id: 13
31765
31759
  }
31766
31760
  }
31767
31761
  },
@@ -31846,10 +31840,6 @@ var nested = {
31846
31840
  expected_address: {
31847
31841
  type: "bytes",
31848
31842
  id: 12
31849
- },
31850
- source_fingerprint: {
31851
- type: "uint32",
31852
- id: 13
31853
31843
  }
31854
31844
  }
31855
31845
  },
@@ -31997,7 +31987,29 @@ var nested = {
31997
31987
  type: "EthereumAuthorizationSignature",
31998
31988
  id: 10
31999
31989
  }
32000
- }
31990
+ },
31991
+ reserved: [
31992
+ [
31993
+ 5,
31994
+ 5
31995
+ ],
31996
+ [
31997
+ 6,
31998
+ 6
31999
+ ],
32000
+ [
32001
+ 7,
32002
+ 7
32003
+ ],
32004
+ [
32005
+ 8,
32006
+ 8
32007
+ ],
32008
+ [
32009
+ 9,
32010
+ 9
32011
+ ]
32012
+ ]
32001
32013
  },
32002
32014
  EthereumTxAckOneKey: {
32003
32015
  fields: {
@@ -32026,10 +32038,6 @@ var nested = {
32026
32038
  chain_id: {
32027
32039
  type: "uint64",
32028
32040
  id: 3
32029
- },
32030
- source_fingerprint: {
32031
- type: "uint32",
32032
- id: 4
32033
32041
  }
32034
32042
  }
32035
32043
  },
@@ -36027,7 +36035,8 @@ var nested = {
36027
36035
  },
36028
36036
  SolanaOffChainMessageVersion: {
36029
36037
  values: {
36030
- MESSAGE_VERSION_0: 0
36038
+ MESSAGE_VERSION_0: 0,
36039
+ MESSAGE_VERSION_1: 1
36031
36040
  }
36032
36041
  },
36033
36042
  SolanaOffChainMessageFormat: {
@@ -36075,10 +36084,6 @@ var nested = {
36075
36084
  rule: "required",
36076
36085
  type: "bytes",
36077
36086
  id: 2
36078
- },
36079
- source_fingerprint: {
36080
- type: "uint32",
36081
- id: 3
36082
36087
  }
36083
36088
  }
36084
36089
  },
@@ -36115,17 +36120,15 @@ var nested = {
36115
36120
  },
36116
36121
  message_format: {
36117
36122
  type: "SolanaOffChainMessageFormat",
36118
- id: 4,
36119
- options: {
36120
- "default": "V0_RESTRICTED_ASCII"
36121
- }
36123
+ id: 4
36122
36124
  },
36123
36125
  application_domain: {
36124
36126
  type: "bytes",
36125
36127
  id: 5
36126
36128
  },
36127
- source_fingerprint: {
36128
- type: "uint32",
36129
+ required_signers: {
36130
+ rule: "repeated",
36131
+ type: "bytes",
36129
36132
  id: 6
36130
36133
  }
36131
36134
  }
@@ -36144,10 +36147,6 @@ var nested = {
36144
36147
  rule: "required",
36145
36148
  type: "bytes",
36146
36149
  id: 2
36147
- },
36148
- source_fingerprint: {
36149
- type: "uint32",
36150
- id: 3
36151
36150
  }
36152
36151
  }
36153
36152
  },
@@ -38564,6 +38563,7 @@ var nested = {
38564
38563
  MessageType_DeviceFindMyTokenState: 60450,
38565
38564
  MessageType_DeviceFindMyTokenUpdate: 60451,
38566
38565
  MessageType_DeviceFindMyTokenStateGet: 60452,
38566
+ MessageType_DeviceAnimationControl: 60461,
38567
38567
  MessageType_DeviceInfoGet: 60600,
38568
38568
  MessageType_DeviceInfo: 60601,
38569
38569
  MessageType_DeviceStatusGet: 60602,
@@ -38902,6 +38902,26 @@ var nested = {
38902
38902
  }
38903
38903
  }
38904
38904
  },
38905
+ DeviceAnimationAction: {
38906
+ values: {
38907
+ AnimationAction_Unknown: 0,
38908
+ AnimationAction_Start: 1,
38909
+ AnimationAction_Stop: 2
38910
+ }
38911
+ },
38912
+ DeviceAnimationControl: {
38913
+ fields: {
38914
+ action: {
38915
+ rule: "required",
38916
+ type: "DeviceAnimationAction",
38917
+ id: 1
38918
+ },
38919
+ timeout_ms: {
38920
+ type: "uint32",
38921
+ id: 2
38922
+ }
38923
+ }
38924
+ },
38905
38925
  DeviceFactoryAck: {
38906
38926
  values: {
38907
38927
  FACTORY_ACK_SUCCESS: 0,
@@ -38963,6 +38983,10 @@ var nested = {
38963
38983
  manufacture_time: {
38964
38984
  type: "DeviceFactoryInfoManufactureTime",
38965
38985
  id: 5
38986
+ },
38987
+ data: {
38988
+ type: "bytes",
38989
+ id: 100
38966
38990
  }
38967
38991
  }
38968
38992
  },
@@ -38972,11 +38996,19 @@ var nested = {
38972
38996
  rule: "required",
38973
38997
  type: "DeviceFactoryInfo",
38974
38998
  id: 1
38999
+ },
39000
+ full_data: {
39001
+ type: "bool",
39002
+ id: 2
38975
39003
  }
38976
39004
  }
38977
39005
  },
38978
39006
  DeviceFactoryInfoGet: {
38979
39007
  fields: {
39008
+ full_data: {
39009
+ type: "bool",
39010
+ id: 1
39011
+ }
38980
39012
  }
38981
39013
  },
38982
39014
  DeviceFactoryPermanentLock: {
@@ -41846,6 +41878,7 @@ function getProtocolV2WalletSession(device, options) {
41846
41878
  ? device.getInternalState()
41847
41879
  : undefined;
41848
41880
  let response;
41881
+ let walletSelectionRequested = false;
41849
41882
  let resumed = false;
41850
41883
  let walletStatusRefreshed = false;
41851
41884
  const markWalletStatusRefreshed = () => {
@@ -42017,6 +42050,7 @@ function getProtocolV2WalletSession(device, options) {
42017
42050
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.WalletSessionInvalid);
42018
42051
  }
42019
42052
  yield lockAttachPinBeforePassphraseSelection();
42053
+ walletSelectionRequested = true;
42020
42054
  response = yield selectDeviceSession(device, expectedPassphraseState, options === null || options === void 0 ? void 0 : options.deriveCardano, markWalletStatusRefreshed);
42021
42055
  }
42022
42056
  let { message } = response;
@@ -42039,6 +42073,10 @@ function getProtocolV2WalletSession(device, options) {
42039
42073
  device.clearInternalState();
42040
42074
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.WalletSessionInvalid);
42041
42075
  }
42076
+ if (walletSelectionRequested) {
42077
+ clearCurrentWalletSession();
42078
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckPassphraseStateError);
42079
+ }
42042
42080
  if (options === null || options === void 0 ? void 0 : options.onlyMainPin) {
42043
42081
  (_j = device.clearStandardInternalState) === null || _j === void 0 ? void 0 : _j.call(device);
42044
42082
  yield selectStandardWallet(true);
@@ -43667,6 +43705,18 @@ class TransportManager {
43667
43705
  this.defaultMessages = DataManager.getProtobufMessages();
43668
43706
  this.currentMessages = this.defaultMessages;
43669
43707
  this.protocolV1MessageSchema = 'v1CurrentSchema';
43708
+ this.webUsbInit = false;
43709
+ }
43710
+ static ensureInitialized() {
43711
+ return __awaiter(this, void 0, void 0, function* () {
43712
+ const env = DataManager.getSettings('env');
43713
+ if (env !== 'webusb' && env !== 'desktop-webusb')
43714
+ return;
43715
+ if (this.webUsbInit)
43716
+ return;
43717
+ yield this.transport.init(WebUsbLogger, DevicePool.emitter);
43718
+ this.webUsbInit = true;
43719
+ });
43670
43720
  }
43671
43721
  static configure() {
43672
43722
  return __awaiter(this, void 0, void 0, function* () {
@@ -43695,7 +43745,7 @@ class TransportManager {
43695
43745
  yield this.transport.init(WebBleLogger, DevicePool.emitter);
43696
43746
  }
43697
43747
  else if (env === 'webusb' || env === 'desktop-webusb') {
43698
- yield this.transport.init(WebUsbLogger, DevicePool.emitter);
43748
+ yield this.ensureInitialized();
43699
43749
  }
43700
43750
  else {
43701
43751
  yield this.transport.init(HttpLogger);
@@ -43778,6 +43828,7 @@ class TransportManager {
43778
43828
  }
43779
43829
  }
43780
43830
  TransportManager.reactNativeInit = false;
43831
+ TransportManager.webUsbInit = false;
43781
43832
  TransportManager.protocolV1MessageSchema = 'v1CurrentSchema';
43782
43833
  TransportManager.plugin = null;
43783
43834
 
@@ -43900,6 +43951,7 @@ class DeviceCommands {
43900
43951
  var _a, _b;
43901
43952
  return __awaiter(this, void 0, void 0, function* () {
43902
43953
  this.disposed = true;
43954
+ this.disposalToken = {};
43903
43955
  yield ((_b = (_a = this.transport).cancel) === null || _b === void 0 ? void 0 : _b.call(_a));
43904
43956
  });
43905
43957
  }
@@ -44073,7 +44125,24 @@ class DeviceCommands {
44073
44125
  }
44074
44126
  _commonCall(type, msg, options) {
44075
44127
  return __awaiter(this, void 0, void 0, function* () {
44076
- const resp = yield this.call(type, msg, options);
44128
+ const { disposalToken } = this;
44129
+ let resp = yield this.call(type, msg, options);
44130
+ for (let retry = 0; retry < 3 &&
44131
+ this.device.isProtocolV2() &&
44132
+ DEVICE_SESSION_CALLS.has(type) &&
44133
+ resp.type === 'Failure' &&
44134
+ resp.message.code === 'Failure_ProcessError' &&
44135
+ resp.message.subcode === hdTransport.DeviceSessionErrorCode.DeviceSessionError_Busy; retry += 1) {
44136
+ yield wait(100);
44137
+ if (this.device.wasInterruptedByUser()) {
44138
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInterruptedFromUser);
44139
+ }
44140
+ this.checkDisposed();
44141
+ if (this.disposalToken !== disposalToken) {
44142
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'DeviceCommands lifecycle changed');
44143
+ }
44144
+ resp = yield this.call(type, msg, options);
44145
+ }
44077
44146
  return this._filterCommonTypes(resp, type, options);
44078
44147
  });
44079
44148
  }
@@ -46294,6 +46363,10 @@ class Device extends events.exports {
46294
46363
  }
46295
46364
  this.invalidateProtocolV2RuntimeState();
46296
46365
  }
46366
+ waitForRunCleanup() {
46367
+ var _a;
46368
+ return (_a = this.runCleanupPromise) !== null && _a !== void 0 ? _a : Promise.resolve();
46369
+ }
46297
46370
  run(fn, options) {
46298
46371
  return __awaiter(this, void 0, void 0, function* () {
46299
46372
  if (this.runPromise) {
@@ -46411,44 +46484,68 @@ class Device extends events.exports {
46411
46484
  });
46412
46485
  }
46413
46486
  interruptionFromUser() {
46414
- var _a, _b, _c, _d;
46415
- return __awaiter(this, void 0, void 0, function* () {
46416
- const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInterruptedFromUser);
46417
- this.interruptedAttempt = this.connectionAttempt;
46418
- const cleanupPromise = this.runCleanupPromise;
46419
- const { cancelableAction } = this;
46420
- if (cancelableAction) {
46421
- yield cancelableAction(error);
46422
- }
46423
- else if (this.shouldSendFallbackProtocolCancel()) {
46424
- yield ((_b = (_a = this.commands) === null || _a === void 0 ? void 0 : _a.cancelDevice) === null || _b === void 0 ? void 0 : _b.call(_a).catch(cancelError => {
46425
- Log$h.debug('Protocol V2 fallback cancel error', cancelError);
46426
- }));
46487
+ var _a;
46488
+ const attempt = this.connectionAttempt;
46489
+ if (((_a = this.userInterruption) === null || _a === void 0 ? void 0 : _a.attempt) === attempt) {
46490
+ return this.userInterruption.promise;
46491
+ }
46492
+ const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInterruptedFromUser);
46493
+ this.interruptedAttempt = attempt;
46494
+ const cleanupPromise = this.runCleanupPromise;
46495
+ const { cancelableAction, commands, runPromise, deviceConnector, mainId } = this;
46496
+ const sendFallbackCancel = this.shouldSendFallbackProtocolCancel();
46497
+ const acquired = this.hasDeviceAcquire();
46498
+ const promise = (() => __awaiter(this, void 0, void 0, function* () {
46499
+ var _b;
46500
+ try {
46501
+ if (cancelableAction) {
46502
+ yield cancelableAction(error);
46503
+ }
46504
+ else if (sendFallbackCancel) {
46505
+ yield ((_b = commands === null || commands === void 0 ? void 0 : commands.cancelDevice) === null || _b === void 0 ? void 0 : _b.call(commands).catch(cancelError => {
46506
+ Log$h.debug('Protocol V2 fallback cancel error', cancelError);
46507
+ }));
46508
+ }
46509
+ else if (!acquired) {
46510
+ if (mainId && (deviceConnector === null || deviceConnector === void 0 ? void 0 : deviceConnector.disconnect)) {
46511
+ Log$h.debug('interruptionFromUser: disconnecting device without acquire, mainId:', mainId);
46512
+ yield deviceConnector.disconnect(mainId);
46513
+ }
46514
+ if (this.connectionAttempt === attempt)
46515
+ this.markTransportDisconnected();
46516
+ }
46517
+ yield (commands === null || commands === void 0 ? void 0 : commands.cancel());
46427
46518
  }
46428
- else if (!this.hasDeviceAcquire()) {
46429
- if (this.mainId && ((_c = this.deviceConnector) === null || _c === void 0 ? void 0 : _c.disconnect)) {
46430
- yield this.deviceConnector.disconnect(this.mainId).catch(disconnectError => {
46431
- Log$h.debug('Ignored disconnect during user cancel without acquire', disconnectError);
46519
+ catch (cleanupError) {
46520
+ Log$h.warn('User cancellation cleanup failed; disconnecting device', cleanupError);
46521
+ if (mainId && (deviceConnector === null || deviceConnector === void 0 ? void 0 : deviceConnector.disconnect)) {
46522
+ yield deviceConnector.disconnect(mainId).catch(disconnectError => {
46523
+ Log$h.debug('User cancellation fallback disconnect failed', disconnectError);
46432
46524
  });
46433
46525
  }
46434
- this.markTransportDisconnected();
46526
+ if (this.connectionAttempt === attempt)
46527
+ this.markTransportDisconnected();
46435
46528
  }
46436
- yield ((_d = this.commands) === null || _d === void 0 ? void 0 : _d.cancel());
46437
- if (this.runPromise) {
46438
- this.runPromise.reject(error);
46439
- this.runPromise = null;
46529
+ finally {
46530
+ runPromise === null || runPromise === void 0 ? void 0 : runPromise.reject(error);
46531
+ if (this.runPromise === runPromise)
46532
+ this.runPromise = null;
46533
+ yield (cleanupPromise === null || cleanupPromise === void 0 ? void 0 : cleanupPromise.catch(() => undefined));
46440
46534
  }
46441
- yield (cleanupPromise === null || cleanupPromise === void 0 ? void 0 : cleanupPromise.catch(() => undefined));
46442
- });
46535
+ }))();
46536
+ this.userInterruption = { attempt, promise };
46537
+ return promise;
46443
46538
  }
46444
46539
  setCancelableAction(callback) {
46445
- this.cancelableAction = (e) => callback(e)
46540
+ const action = (e) => callback(e)
46446
46541
  .catch(e2 => {
46447
46542
  Log$h.debug('cancelableAction error', e2);
46448
46543
  })
46449
46544
  .finally(() => {
46450
- this.clearCancelableAction();
46545
+ if (this.cancelableAction === action)
46546
+ this.clearCancelableAction();
46451
46547
  });
46548
+ this.cancelableAction = action;
46452
46549
  }
46453
46550
  clearCancelableAction() {
46454
46551
  this.cancelableAction = undefined;
@@ -47180,6 +47277,48 @@ class PreInitialize extends BaseMethod {
47180
47277
  }
47181
47278
 
47182
47279
  const Log$e = getLogger(exports.LoggerNames.DevicePool);
47280
+ const getDescriptorKeys = (descriptor) => [descriptor.path, descriptor.id].filter((key) => typeof key === 'string' && key.length > 0);
47281
+ const isOwnedByActiveWebUsbRequest = (descriptor, requestQueue) => {
47282
+ if (!requestQueue)
47283
+ return false;
47284
+ return getDescriptorKeys(descriptor).some(key => requestQueue.getRequestTasksIdByConnectId(key).length > 0);
47285
+ };
47286
+ const getUsbHandle = (descriptor) => descriptor === null || descriptor === void 0 ? void 0 : descriptor.device;
47287
+ const getOwningRequestDevice = (descriptor, requestQueue) => {
47288
+ var _a, _b;
47289
+ if (!requestQueue)
47290
+ return undefined;
47291
+ const usbHandle = getUsbHandle(descriptor);
47292
+ if (usbHandle === undefined)
47293
+ return undefined;
47294
+ for (const key of getDescriptorKeys(descriptor)) {
47295
+ for (const requestId of requestQueue.getRequestTasksIdByConnectId(key)) {
47296
+ const device = (_a = requestQueue.getTask(requestId)) === null || _a === void 0 ? void 0 : _a.method.device;
47297
+ if ((device === null || device === void 0 ? void 0 : device.features) &&
47298
+ (device.mainId === key || ((_b = device.originalDescriptor) === null || _b === void 0 ? void 0 : _b.path) === key) &&
47299
+ getUsbHandle(device.originalDescriptor) === usbHandle) {
47300
+ return device;
47301
+ }
47302
+ }
47303
+ }
47304
+ return undefined;
47305
+ };
47306
+ const toSearchDeviceFromDescriptor = (descriptor) => {
47307
+ const connectId = descriptor.path || descriptor.id || null;
47308
+ return {
47309
+ connectId,
47310
+ uuid: '',
47311
+ serialNo: null,
47312
+ deviceId: null,
47313
+ deviceType: hdShared.EDeviceType.Unknown,
47314
+ name: descriptor.name || connectId || '',
47315
+ commType: descriptor.commType,
47316
+ };
47317
+ };
47318
+ const toSearchDevice = (device) => {
47319
+ const message = device.toMessageObject();
47320
+ return message ? message : null;
47321
+ };
47183
47322
  class SearchDevices extends BaseMethod {
47184
47323
  init() {
47185
47324
  this.useDevice = false;
@@ -47187,20 +47326,32 @@ class SearchDevices extends BaseMethod {
47187
47326
  this.skipForceUpdateCheck = true;
47188
47327
  }
47189
47328
  run() {
47190
- var _a, _b, _c, _d, _e;
47329
+ var _a, _b, _c, _d, _e, _f, _g;
47191
47330
  return __awaiter(this, void 0, void 0, function* () {
47192
- yield TransportManager.configure();
47193
- const deviceDiff = yield ((_a = this.connector) === null || _a === void 0 ? void 0 : _a.enumerate());
47194
- const devicesDescriptor = (_b = deviceDiff === null || deviceDiff === void 0 ? void 0 : deviceDiff.descriptors) !== null && _b !== void 0 ? _b : [];
47195
47331
  const env = DataManager.getSettings('env');
47332
+ const isWebUsb = env === 'webusb' || env === 'desktop-webusb';
47333
+ const requestQueue = (_a = this.context) === null || _a === void 0 ? void 0 : _a.requestQueue;
47334
+ const hasActiveWebUsbRequest = isWebUsb && ((_b = requestQueue === null || requestQueue === void 0 ? void 0 : requestQueue.getRequestTasksId().length) !== null && _b !== void 0 ? _b : 0) > 0;
47335
+ if (isWebUsb) {
47336
+ try {
47337
+ yield TransportManager.ensureInitialized();
47338
+ }
47339
+ catch (error) {
47340
+ Log$e.debug('WebUSB bring-up unavailable', error);
47341
+ }
47342
+ }
47343
+ if (!hasActiveWebUsbRequest)
47344
+ yield TransportManager.configure();
47345
+ const deviceDiff = yield ((_c = this.connector) === null || _c === void 0 ? void 0 : _c.enumerate());
47346
+ const devicesDescriptor = (_d = deviceDiff === null || deviceDiff === void 0 ? void 0 : deviceDiff.descriptors) !== null && _d !== void 0 ? _d : [];
47196
47347
  if (DataManager.isBleConnect(env)) {
47197
47348
  const devices = [];
47198
47349
  const seenIds = new Set();
47199
47350
  for (const device of devicesDescriptor) {
47200
- const lowerId = (_c = device.id) === null || _c === void 0 ? void 0 : _c.toLowerCase();
47351
+ const lowerId = (_e = device.id) === null || _e === void 0 ? void 0 : _e.toLowerCase();
47201
47352
  if (!seenIds.has(lowerId)) {
47202
47353
  seenIds.add(lowerId);
47203
- const rawBleName = (_e = (_d = device.name) !== null && _d !== void 0 ? _d : device.localName) !== null && _e !== void 0 ? _e : '';
47354
+ const rawBleName = (_g = (_f = device.name) !== null && _f !== void 0 ? _f : device.localName) !== null && _g !== void 0 ? _g : '';
47204
47355
  const bleName = hdShared.canonicalizePro2BleAdvertisementName(rawBleName);
47205
47356
  devices.push(Object.assign(Object.assign({}, device), { connectId: device.id, serialNo: null, uuid: '', deviceId: null, name: bleName || device.name, deviceType: getDeviceTypeByBleName(bleName) }));
47206
47357
  }
@@ -47209,22 +47360,34 @@ class SearchDevices extends BaseMethod {
47209
47360
  }
47210
47361
  const deviceList = [];
47211
47362
  for (const descriptor of devicesDescriptor) {
47212
- try {
47213
- const result = yield DevicePool.getDevices([descriptor], descriptor.path, {
47214
- connectProtocol: undefined,
47215
- forceProtocolDetection: true,
47216
- refreshRuntimeState: true,
47217
- });
47218
- deviceList.push(...result.deviceList);
47363
+ if (hasActiveWebUsbRequest && isOwnedByActiveWebUsbRequest(descriptor, requestQueue)) {
47364
+ const cached = DevicePool.getDeviceByPath(descriptor.path);
47365
+ const known = (cached === null || cached === void 0 ? void 0 : cached.features) ? cached : getOwningRequestDevice(descriptor, requestQueue);
47366
+ const message = known ? toSearchDevice(known) : null;
47367
+ deviceList.push(message !== null && message !== void 0 ? message : toSearchDeviceFromDescriptor(descriptor));
47219
47368
  }
47220
- catch (error) {
47221
- const errorCode = error && typeof error === 'object' && 'errorCode' in error
47222
- ? error.errorCode
47223
- : undefined;
47224
- Log$e.debug('Skip unavailable device during search', Object.assign({ path: descriptor.path }, (errorCode !== undefined ? { errorCode } : {})));
47369
+ else {
47370
+ try {
47371
+ const result = yield DevicePool.getDevices([descriptor], descriptor.path, {
47372
+ connectProtocol: undefined,
47373
+ forceProtocolDetection: true,
47374
+ refreshRuntimeState: true,
47375
+ });
47376
+ for (const device of result.deviceList) {
47377
+ const message = toSearchDevice(device);
47378
+ if (message)
47379
+ deviceList.push(message);
47380
+ }
47381
+ }
47382
+ catch (error) {
47383
+ const errorCode = error && typeof error === 'object' && 'errorCode' in error
47384
+ ? error.errorCode
47385
+ : undefined;
47386
+ Log$e.debug('Skip unavailable device during search', Object.assign({ path: descriptor.path }, (errorCode !== undefined ? { errorCode } : {})));
47387
+ }
47225
47388
  }
47226
47389
  }
47227
- return deviceList.map(device => device.toMessageObject());
47390
+ return deviceList;
47228
47391
  });
47229
47392
  }
47230
47393
  }
@@ -47558,15 +47721,6 @@ function validateResult(result, nonNullableFields, options) {
47558
47721
  }
47559
47722
  }
47560
47723
 
47561
- const requiredString = (value, name) => {
47562
- if (value === undefined || value === null) {
47563
- throw invalidParameter(`Missing required parameter: ${name}`);
47564
- }
47565
- if (typeof value !== 'string' || !value.trim()) {
47566
- throw invalidParameter(`Parameter [${name}] must be a non-empty string.`);
47567
- }
47568
- return value.trim();
47569
- };
47570
47724
  const wasResumed = (session) => !!session &&
47571
47725
  typeof session === 'object' &&
47572
47726
  'resumed' in session &&
@@ -47588,25 +47742,16 @@ const normalizeParams = (payload) => {
47588
47742
  throw invalidParameter('Parameter [mode] is required.');
47589
47743
  }
47590
47744
  if (payload.mode !== OpenWalletSessionMode.Standard &&
47591
- payload.mode !== OpenWalletSessionMode.SelectHidden &&
47592
- payload.mode !== OpenWalletSessionMode.ResumeHidden) {
47593
- throw invalidParameter('Parameter [mode] must be one of standard, select-hidden, or resume-hidden.');
47745
+ payload.mode !== OpenWalletSessionMode.SelectHidden) {
47746
+ throw invalidParameter('Parameter [mode] must be one of standard or select-hidden.');
47594
47747
  }
47595
47748
  if (payload.useEmptyPassphrase !== undefined || payload.initSession !== undefined) {
47596
47749
  throw invalidParameter('Legacy parameters [useEmptyPassphrase] and [initSession] are not supported by openWalletSession.');
47597
47750
  }
47598
- if (payload.mode === OpenWalletSessionMode.Standard ||
47599
- payload.mode === OpenWalletSessionMode.SelectHidden) {
47600
- if (payload.deviceId !== undefined || payload.passphraseState !== undefined) {
47601
- throw invalidParameter('Parameters [deviceId] and [passphraseState] are only allowed with mode [resume-hidden].');
47602
- }
47603
- return { mode: payload.mode };
47751
+ if (payload.deviceId !== undefined || payload.passphraseState !== undefined) {
47752
+ throw invalidParameter('Parameters [deviceId] and [passphraseState] are not supported by openWalletSession. Pass passphraseState on later address and signing calls.');
47604
47753
  }
47605
- return {
47606
- mode: OpenWalletSessionMode.ResumeHidden,
47607
- deviceId: requiredString(payload.deviceId, 'deviceId'),
47608
- passphraseState: requiredString(payload.passphraseState, 'passphraseState'),
47609
- };
47754
+ return { mode: payload.mode };
47610
47755
  };
47611
47756
  class OpenWalletSession extends BaseMethod {
47612
47757
  getSupportedProtocols() {
@@ -47709,43 +47854,6 @@ class OpenWalletSession extends BaseMethod {
47709
47854
  resumed: wasResumed(session),
47710
47855
  };
47711
47856
  }
47712
- if (this.params.mode === OpenWalletSessionMode.ResumeHidden) {
47713
- if (isProtocolV2) {
47714
- yield ensureProtocolV2WalletStatus();
47715
- const refreshedDeviceId = requireDeviceId();
47716
- if (refreshedDeviceId !== this.params.deviceId) {
47717
- deviceWalletSessionStore.delete(this.params.deviceId, this.params.passphraseState);
47718
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckDeviceIdError);
47719
- }
47720
- }
47721
- else if (requireDeviceId() !== this.params.deviceId) {
47722
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckDeviceIdError);
47723
- }
47724
- this.device.passphraseState = this.params.passphraseState;
47725
- const cachedSessionId = deviceWalletSessionStore.get(this.params.deviceId, this.params.passphraseState);
47726
- if (!cachedSessionId && !isProtocolV2) {
47727
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.WalletSessionInvalid);
47728
- }
47729
- if (!isProtocolV2) {
47730
- yield this.device.initialize({
47731
- deviceId: this.params.deviceId,
47732
- passphraseState: this.params.passphraseState,
47733
- });
47734
- }
47735
- const session = isProtocolV2
47736
- ? yield getProtocolV2WalletSession(this.device, {
47737
- expectedPassphraseState: this.params.passphraseState,
47738
- })
47739
- : yield getPassphraseStateWithRefreshDeviceInfo(this.device, {
47740
- expectPassphraseState: this.params.passphraseState,
47741
- });
47742
- const deviceId = requireDeviceId();
47743
- if (session.passphraseState !== this.params.passphraseState) {
47744
- this.device.clearInternalState();
47745
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckPassphraseStateError);
47746
- }
47747
- return Object.assign(Object.assign({ protocol, walletType: 'hidden', deviceId }, requireHiddenWalletResponse(session)), { resumed: wasResumed(session) || (!isProtocolV2 && session.newSession === cachedSessionId) });
47748
- }
47749
47857
  this.device.passphraseState = undefined;
47750
47858
  const walletStatus = yield ensureProtocolV2WalletStatus();
47751
47859
  if (isProtocolV2 && walletStatus.status.passphraseProtection !== true) {
@@ -49156,6 +49264,14 @@ class DeviceVerify extends BaseMethod {
49156
49264
  this.unlockPolicy = 'unlock-before-run';
49157
49265
  this.protocolV2PreUnlockPinType = hdTransport.DeviceSessionPinType.Any;
49158
49266
  this.useDevicePassphraseState = false;
49267
+ this.protocolV2UiInteraction = {
49268
+ request: 'button',
49269
+ source: 'method-lifecycle',
49270
+ reason: 'device-management',
49271
+ completion: 'operation-completed',
49272
+ deviceOnly: true,
49273
+ operation: 'deviceVerify',
49274
+ };
49159
49275
  validateParams(this.payload, [{ name: 'dataHex', type: 'hexString' }]);
49160
49276
  this.params = {
49161
49277
  data: formatAnyHex(this.payload.dataHex),
@@ -55408,16 +55524,16 @@ const FILESYSTEM_FILE_WRITE_MESSAGE_TYPE = 60805;
55408
55524
  const PORTFOLIO_UPDATE_MESSAGE_TYPE = 61400;
55409
55525
  class UploadPortfolio extends FileWrite {
55410
55526
  init() {
55411
- const { packageBase64, timeoutMs } = this.payload;
55527
+ const { packageBase64, timeoutMs, uiMode = 'silent' } = this.payload;
55412
55528
  const packageBytes = decodeCanonicalBase64({
55413
55529
  value: packageBase64,
55414
55530
  parameterName: 'packageBase64',
55415
55531
  maxBytes: PORTFOLIO_PACKAGE_MAX_BYTES,
55416
55532
  });
55417
- this.payload = Object.assign(Object.assign({}, this.payload), { path: PORTFOLIO_PENDING_PATH, offset: 0, data: packageBytes, chunkSize: PORTFOLIO_CHUNK_SIZE, overwrite: true, append: false, emitProgress: false, timeoutMs });
55533
+ this.payload = Object.assign(Object.assign({}, this.payload), { path: PORTFOLIO_PENDING_PATH, offset: 0, data: packageBytes, chunkSize: PORTFOLIO_CHUNK_SIZE, overwrite: true, append: false, emitProgress: uiMode === 'progress', timeoutMs });
55418
55534
  super.init();
55419
55535
  this.unlockPolicy = 'none';
55420
- this.protocolV2UiMode = 'none';
55536
+ this.protocolV2UiMode = uiMode === 'progress' ? 'auto' : 'none';
55421
55537
  }
55422
55538
  run() {
55423
55539
  const _super = Object.create(null, {
@@ -55878,6 +55994,8 @@ class AllNetworkGetAddressBase extends BaseMethod {
55878
55994
  constructor() {
55879
55995
  super(...arguments);
55880
55996
  this.abortController = null;
55997
+ this.loadingCleanupInBackground = false;
55998
+ this.protocolV2ResumedSeedDomains = new Set();
55881
55999
  }
55882
56000
  getSupportedProtocols() {
55883
56001
  return ['V1', 'V2'];
@@ -55913,7 +56031,20 @@ class AllNetworkGetAddressBase extends BaseMethod {
55913
56031
  _originalIndex: originalIndex,
55914
56032
  };
55915
56033
  }
55916
- callMethod(methodName, params, rootFingerprint) {
56034
+ hasProtocolV2WalletResume(deriveCardano) {
56035
+ if (deriveCardano) {
56036
+ return this.protocolV2ResumedSeedDomains.has('cardano');
56037
+ }
56038
+ return (this.protocolV2ResumedSeedDomains.has('standard') ||
56039
+ this.protocolV2ResumedSeedDomains.has('cardano'));
56040
+ }
56041
+ markProtocolV2WalletResumed(deriveCardano) {
56042
+ this.protocolV2ResumedSeedDomains.add('standard');
56043
+ if (deriveCardano) {
56044
+ this.protocolV2ResumedSeedDomains.add('cardano');
56045
+ }
56046
+ }
56047
+ callMethod(methodName, params, rootFingerprint, postMessage = this.postMessage) {
55917
56048
  var _a, _b, _c;
55918
56049
  return __awaiter(this, void 0, void 0, function* () {
55919
56050
  const method = findMethod({
@@ -55922,7 +56053,7 @@ class AllNetworkGetAddressBase extends BaseMethod {
55922
56053
  payload: Object.assign({ connectId: this.payload.connectId, deviceId: this.payload.deviceId, method: methodName }, params),
55923
56054
  });
55924
56055
  method.connector = this.connector;
55925
- method.postMessage = this.postMessage;
56056
+ method.postMessage = postMessage;
55926
56057
  if (this.context) {
55927
56058
  (_a = method.setContext) === null || _a === void 0 ? void 0 : _a.call(method, this.context);
55928
56059
  }
@@ -55975,11 +56106,14 @@ class AllNetworkGetAddressBase extends BaseMethod {
55975
56106
  const useEmptyPassphrase = this.payload.useEmptyPassphrase === true;
55976
56107
  const deriveCardano = method.name.startsWith('cardano') ? true : undefined;
55977
56108
  const shouldResumeWalletSession = useEmptyPassphrase || !!this.payload.passphraseState;
55978
- if (this.device.isProtocolV2() && shouldResumeWalletSession) {
56109
+ if (this.device.isProtocolV2() &&
56110
+ shouldResumeWalletSession &&
56111
+ !this.hasProtocolV2WalletResume(deriveCardano)) {
55979
56112
  const passphraseStateSafety = yield this.device.checkPassphraseStateSafety(this.payload.passphraseState, useEmptyPassphrase, this.payload.skipPassphraseCheck, deriveCardano, (_d = this.protocolV2UnlockContext) === null || _d === void 0 ? void 0 : _d.preflightMainPinSelected);
55980
56113
  if (!passphraseStateSafety) {
55981
56114
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckPassphraseStateError);
55982
56115
  }
56116
+ this.markProtocolV2WalletResumed(deriveCardano);
55983
56117
  }
55984
56118
  }),
55985
56119
  });
@@ -56015,27 +56149,63 @@ class AllNetworkGetAddressBase extends BaseMethod {
56015
56149
  return result;
56016
56150
  });
56017
56151
  }
56018
- run() {
56152
+ stopAllNetworkLoading(canSend = true) {
56019
56153
  return __awaiter(this, void 0, void 0, function* () {
56020
- const res = yield this.device.commands.typedCall('GetPublicKey', 'PublicKey', {
56021
- address_n: [toHardened(44), toHardened(1), toHardened(0)],
56022
- coin_name: 'Testnet',
56023
- script_type: 'SPENDADDRESS',
56024
- show_display: false,
56025
- });
56026
- if (!this.device.isProtocolV2()) {
56027
- this.postMessage(createUiMessage(UI_REQUEST.CLOSE_UI_PIN_WINDOW));
56154
+ const commands = this.loadingCommands;
56155
+ this.loadingCommands = undefined;
56156
+ if (!canSend || !commands || commands.disposed || commands !== this.device.commands)
56157
+ return;
56158
+ try {
56159
+ yield commands.typedCall('DeviceAnimationControl', 'Success', {
56160
+ action: hdTransport.Messages.DeviceAnimationAction.AnimationAction_Stop,
56161
+ });
56162
+ }
56163
+ catch (_a) {
56028
56164
  }
56029
- if (res.message.root_fingerprint == null) {
56030
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter);
56165
+ });
56166
+ }
56167
+ run() {
56168
+ return __awaiter(this, void 0, void 0, function* () {
56169
+ this.loadingCleanupInBackground = false;
56170
+ try {
56171
+ if (this.device.isProtocolV2() &&
56172
+ (this.device.getCurrentDeviceType() === hdShared.EDeviceType.Pro2 ||
56173
+ this.device.getCurrentDeviceType() === hdShared.EDeviceType.Neo)) {
56174
+ const protocolInfo = yield this.device.ensureProtocolV2RuntimeContext();
56175
+ if (supportsProtocolV2Message(protocolInfo, 60461)) {
56176
+ const { commands } = this.device;
56177
+ yield commands.typedCall('DeviceAnimationControl', 'Success', {
56178
+ action: hdTransport.Messages.DeviceAnimationAction.AnimationAction_Start,
56179
+ });
56180
+ this.loadingCommands = commands;
56181
+ }
56182
+ }
56183
+ const res = yield this.device.commands.typedCall('GetPublicKey', 'PublicKey', {
56184
+ address_n: [toHardened(44), toHardened(1), toHardened(0)],
56185
+ coin_name: 'Testnet',
56186
+ script_type: 'SPENDADDRESS',
56187
+ show_display: false,
56188
+ });
56189
+ if (!this.device.isProtocolV2()) {
56190
+ this.postMessage(createUiMessage(UI_REQUEST.CLOSE_UI_PIN_WINDOW));
56191
+ }
56192
+ if (res.message.root_fingerprint == null) {
56193
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter);
56194
+ }
56195
+ this.abortController = new AbortController();
56196
+ return yield this.getAllNetworkAddress(res.message.root_fingerprint);
56031
56197
  }
56032
- this.abortController = new AbortController();
56033
- return this.getAllNetworkAddress(res.message.root_fingerprint).catch(e => {
56198
+ catch (e) {
56199
+ yield this.stopAllNetworkLoading(false);
56034
56200
  if (e instanceof hdShared.HardwareError && e.errorCode === hdShared.HardwareErrorCode.RepeatUnlocking) {
56035
56201
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RepeatUnlocking, e.message);
56036
56202
  }
56037
56203
  throw e;
56038
- });
56204
+ }
56205
+ finally {
56206
+ if (!this.loadingCleanupInBackground)
56207
+ yield this.stopAllNetworkLoading();
56208
+ }
56039
56209
  });
56040
56210
  }
56041
56211
  }
@@ -56096,57 +56266,83 @@ function handleSkippableHardwareError(e, device, method) {
56096
56266
  }
56097
56267
 
56098
56268
  class AllNetworkGetAddress extends AllNetworkGetAddressBase {
56269
+ checkAborted() {
56270
+ var _a;
56271
+ if ((_a = this.abortController) === null || _a === void 0 ? void 0 : _a.signal.aborted) {
56272
+ throw new Error(hdShared.HardwareErrorCodeMessage[hdShared.HardwareErrorCode.RepeatUnlocking]);
56273
+ }
56274
+ }
56275
+ callAddressGroup(methodName, params, rootFingerprint) {
56276
+ return __awaiter(this, void 0, void 0, function* () {
56277
+ const methodCallParams = { bundle: params.map(param => (Object.assign({}, param.params))) };
56278
+ if (!this.device.isProtocolV2() || params.length === 1) {
56279
+ return this.callMethod(methodName, methodCallParams, rootFingerprint);
56280
+ }
56281
+ const postedAddressCounts = new Map();
56282
+ let runningIndividually = false;
56283
+ const postMessage = message => {
56284
+ var _a;
56285
+ if (message.type === UI_REQUEST.PREVIOUS_ADDRESS_RESULT) {
56286
+ const { path, address } = message.payload.data;
56287
+ const key = JSON.stringify([path, address]);
56288
+ const count = (_a = postedAddressCounts.get(key)) !== null && _a !== void 0 ? _a : 0;
56289
+ if (runningIndividually && count > 0) {
56290
+ postedAddressCounts.set(key, count - 1);
56291
+ return;
56292
+ }
56293
+ if (!runningIndividually)
56294
+ postedAddressCounts.set(key, count + 1);
56295
+ }
56296
+ this.postMessage(message);
56297
+ };
56298
+ if (params.every(param => param._originRequestParams.showOnOneKey === false)) {
56299
+ const response = yield this.callMethod(methodName, methodCallParams, rootFingerprint, postMessage);
56300
+ if (response.some(item => item.success))
56301
+ return response;
56302
+ }
56303
+ runningIndividually = true;
56304
+ const responses = [];
56305
+ for (const param of params) {
56306
+ this.checkAborted();
56307
+ const response = yield this.callMethod(methodName, { bundle: [Object.assign({}, param.params)] }, rootFingerprint, postMessage);
56308
+ responses.push(...response);
56309
+ }
56310
+ return responses;
56311
+ });
56312
+ }
56099
56313
  getAllNetworkAddress(rootFingerprint) {
56100
- var _a, _b, _c, _d;
56101
56314
  return __awaiter(this, void 0, void 0, function* () {
56102
56315
  const responses = [];
56103
- const resultMap = {};
56104
56316
  const { bundle } = this.payload;
56105
56317
  const methodParams = bundle.map((param, index) => this.generateMethodName({
56106
56318
  network: param.network,
56107
56319
  payload: param,
56108
56320
  originalIndex: index,
56109
56321
  }));
56110
- const groupedMethodParams = methodParams.reduce((groups, param) => {
56322
+ const methodGroups = methodParams.reduce((groups, param) => {
56111
56323
  var _a;
56112
56324
  const group = (_a = groups.get(param.methodName)) !== null && _a !== void 0 ? _a : [];
56113
56325
  group.push(param);
56114
56326
  groups.set(param.methodName, group);
56115
56327
  return groups;
56116
56328
  }, new Map());
56117
- const requiresProtocolV2WalletHandoff = this.device.isProtocolV2() &&
56118
- (this.payload.useEmptyPassphrase === true || !!this.payload.passphraseState);
56119
- const methodGroups = requiresProtocolV2WalletHandoff
56120
- ? methodParams.map(param => [param.methodName, [param]])
56121
- : Array.from(groupedMethodParams.entries());
56122
- let i = 0;
56123
- for (const [methodName, params] of methodGroups) {
56124
- const methodParams = {
56125
- bundle: params.map(param => (Object.assign({}, param.params))),
56126
- };
56127
- if ((_a = this.abortController) === null || _a === void 0 ? void 0 : _a.signal.aborted) {
56128
- throw new Error(hdShared.HardwareErrorCodeMessage[hdShared.HardwareErrorCode.RepeatUnlocking]);
56129
- }
56130
- const response = yield this.callMethod(methodName, methodParams, rootFingerprint);
56131
- if ((_b = this.abortController) === null || _b === void 0 ? void 0 : _b.signal.aborted) {
56132
- throw new Error(hdShared.HardwareErrorCodeMessage[hdShared.HardwareErrorCode.RepeatUnlocking]);
56133
- }
56134
- for (let i = 0; i < params.length; i++) {
56135
- const { _originRequestParams, _originalIndex } = params[i];
56136
- const responseKey = `${_originalIndex}`;
56137
- resultMap[responseKey] = Object.assign(Object.assign({}, _originRequestParams), response[i]);
56329
+ let processed = 0;
56330
+ for (const [methodName, params] of methodGroups.entries()) {
56331
+ this.checkAborted();
56332
+ const response = yield this.callAddressGroup(methodName, params, rootFingerprint);
56333
+ this.checkAborted();
56334
+ for (let index = 0; index < params.length; index++) {
56335
+ const { _originRequestParams, _originalIndex } = params[index];
56336
+ responses[_originalIndex] = Object.assign(Object.assign({}, _originRequestParams), response[index]);
56138
56337
  }
56139
- if (((_d = (_c = this.payload) === null || _c === void 0 ? void 0 : _c.bundle) === null || _d === void 0 ? void 0 : _d.length) > 1) {
56140
- const progress = Math.round(((i + 1) / this.payload.bundle.length) * 100);
56338
+ processed += params.length;
56339
+ if (bundle.length > 1) {
56340
+ const progress = Math.round((processed / bundle.length) * 100);
56141
56341
  this.postMessage(createUiMessage(UI_REQUEST.DEVICE_PROGRESS, { progress }));
56142
56342
  }
56143
- i++;
56144
- }
56145
- for (let i = 0; i < bundle.length; i++) {
56146
- responses.push(resultMap[i]);
56147
56343
  }
56148
56344
  this.abortController = null;
56149
- return Promise.resolve(responses);
56345
+ return responses;
56150
56346
  });
56151
56347
  }
56152
56348
  }
@@ -56162,6 +56358,7 @@ class AllNetworkGetAddressByLoop extends AllNetworkGetAddressBase {
56162
56358
  throw new Error('callbackIdFinish is required');
56163
56359
  }
56164
56360
  const bundle = this.payload.bundle || [this.payload];
56361
+ this.loadingCleanupInBackground = true;
56165
56362
  const callbackPromise = this.processCallbacksInBackground(bundle, rootFingerprint, callbackId, callbackIdFinish);
56166
56363
  this.device.pendingCallbackPromise = hdShared.createDeferred(callbackPromise);
56167
56364
  if (this.context && this.payload.connectId) {
@@ -56202,6 +56399,7 @@ class AllNetworkGetAddressByLoop extends AllNetworkGetAddressBase {
56202
56399
  });
56203
56400
  }
56204
56401
  catch (error) {
56402
+ yield this.stopAllNetworkLoading(false);
56205
56403
  let errorCode = error.errorCode || error.code;
56206
56404
  let errorMessage = error.message;
56207
56405
  if (error instanceof hdShared.HardwareError) {
@@ -56229,6 +56427,7 @@ class AllNetworkGetAddressByLoop extends AllNetworkGetAddressBase {
56229
56427
  });
56230
56428
  }
56231
56429
  finally {
56430
+ yield this.stopAllNetworkLoading();
56232
56431
  (_c = this.context) === null || _c === void 0 ? void 0 : _c.cancelCallbackTasks(this.payload.connectId);
56233
56432
  this.abortController = null;
56234
56433
  }
@@ -59463,6 +59662,23 @@ class SolSignTransaction extends BaseMethod {
59463
59662
  }
59464
59663
  }
59465
59664
 
59665
+ const SOLANA_PUBLIC_KEY_LENGTH = 32;
59666
+ const SOLANA_APPLICATION_DOMAIN_LENGTH = 32;
59667
+ const normalizeRequiredSigners = (requiredSigners = []) => {
59668
+ const normalized = requiredSigners.map((signer, index) => {
59669
+ if (typeof signer !== 'string' ||
59670
+ !isHexString(addHexPrefix(signer), SOLANA_PUBLIC_KEY_LENGTH)) {
59671
+ throw invalidParameter(`Parameter [requiredSigners][${index}] must be a ${SOLANA_PUBLIC_KEY_LENGTH}-byte hex public key.`);
59672
+ }
59673
+ return stripHexPrefix(signer).toLowerCase();
59674
+ });
59675
+ for (let index = 1; index < normalized.length; index += 1) {
59676
+ if (normalized[index - 1] >= normalized[index]) {
59677
+ throw invalidParameter('Parameter [requiredSigners] must be strictly sorted and unique.');
59678
+ }
59679
+ }
59680
+ return normalized;
59681
+ };
59466
59682
  class SolSignOffchainMessage extends BaseMethod {
59467
59683
  getSupportedProtocols() {
59468
59684
  return ['V1', 'V2'];
@@ -59477,15 +59693,21 @@ class SolSignOffchainMessage extends BaseMethod {
59477
59693
  { name: 'messageVersion', type: 'number', required: false },
59478
59694
  { name: 'messageFormat', type: 'number', required: false },
59479
59695
  { name: 'applicationDomainHex', type: 'hexString', required: false },
59696
+ { name: 'requiredSigners', type: 'array', required: false, allowEmpty: true },
59480
59697
  ]);
59481
- const { path, messageHex, messageVersion, messageFormat, applicationDomainHex } = this.payload;
59698
+ const { path, messageHex, messageVersion, messageFormat, applicationDomainHex, requiredSigners, } = this.payload;
59482
59699
  const addressN = validatePath(path, 3);
59700
+ if (applicationDomainHex !== undefined &&
59701
+ !isHexString(addHexPrefix(applicationDomainHex), SOLANA_APPLICATION_DOMAIN_LENGTH)) {
59702
+ throw invalidParameter('Parameter [applicationDomainHex] must be 32 bytes.');
59703
+ }
59483
59704
  this.params = {
59484
59705
  address_n: addressN,
59485
59706
  message: stripHexPrefix(messageHex),
59486
59707
  message_version: messageVersion !== null && messageVersion !== void 0 ? messageVersion : undefined,
59487
59708
  message_format: messageFormat !== null && messageFormat !== void 0 ? messageFormat : undefined,
59488
- application_domain: applicationDomainHex !== null && applicationDomainHex !== void 0 ? applicationDomainHex : undefined,
59709
+ application_domain: applicationDomainHex ? stripHexPrefix(applicationDomainHex) : undefined,
59710
+ required_signers: normalizeRequiredSigners(requiredSigners),
59489
59711
  };
59490
59712
  }
59491
59713
  getVersionRange() {
@@ -65531,6 +65753,29 @@ class RequestQueue {
65531
65753
  getTask(requestId) {
65532
65754
  return this.requestQueue.get(requestId);
65533
65755
  }
65756
+ waitForTask(task, pending) {
65757
+ return __awaiter(this, void 0, void 0, function* () {
65758
+ const signal = task.method.abortSignal;
65759
+ const cancellationError = () => hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallQueueActionCancelled);
65760
+ if (signal === null || signal === void 0 ? void 0 : signal.aborted)
65761
+ throw cancellationError();
65762
+ let onAbort;
65763
+ try {
65764
+ const cancelled = new Promise((_, reject) => {
65765
+ onAbort = () => reject(cancellationError());
65766
+ signal === null || signal === void 0 ? void 0 : signal.addEventListener('abort', onAbort, { once: true });
65767
+ });
65768
+ const result = yield Promise.race([pending(), cancelled]);
65769
+ if (signal === null || signal === void 0 ? void 0 : signal.aborted)
65770
+ throw cancellationError();
65771
+ return result;
65772
+ }
65773
+ finally {
65774
+ if (onAbort)
65775
+ signal === null || signal === void 0 ? void 0 : signal.removeEventListener('abort', onAbort);
65776
+ }
65777
+ });
65778
+ }
65534
65779
  getAbortController(requestId) {
65535
65780
  var _a;
65536
65781
  return (_a = this.requestQueue.get(requestId)) === null || _a === void 0 ? void 0 : _a.abortController;
@@ -65730,7 +65975,8 @@ const createUiProgressMessageFilter = (intervalMs = DEFAULT_UI_PROGRESS_INTERVAL
65730
65975
 
65731
65976
  const Log = getLogger(exports.LoggerNames.Core);
65732
65977
  const PRE_INITIALIZE_TTL_MS = 60 * 1000;
65733
- const PRE_PENDING_CALL_TIMEOUT_MS = 15 * 1000;
65978
+ const PRE_PENDING_CALL_TIMEOUT_MS = 5 * 1000;
65979
+ const PRO2_USB_SIGNING_COOLDOWN_MS = 1000;
65734
65980
  const preWarmInflight = new Map();
65735
65981
  const preWarmDoneAt = new Map();
65736
65982
  function resolveDeriveCardano(method) {
@@ -65809,6 +66055,7 @@ const callAPI = (context, message) => __awaiter(void 0, void 0, void 0, function
65809
66055
  }
65810
66056
  };
65811
66057
  (_a = method.setContext) === null || _a === void 0 ? void 0 : _a.call(method, context);
66058
+ method.context = context;
65812
66059
  method.requestContext = createRequestContext(method.responseID, method.name, {
65813
66060
  sdkInstanceId: context.sdkInstanceId,
65814
66061
  connectId: method.connectId,
@@ -65826,7 +66073,11 @@ const callAPI = (context, message) => __awaiter(void 0, void 0, void 0, function
65826
66073
  if (!method.useDevice) {
65827
66074
  updateMethodRequestContext(method, { status: 'running' });
65828
66075
  try {
65829
- const response = yield method.run();
66076
+ const env = DataManager.getSettings('env');
66077
+ const response = method.name === 'searchDevices' &&
66078
+ (DataManager.isBrowserWebUsb(env) || DataManager.isDesktopWebUsb(env))
66079
+ ? yield context.methodSynchronize(() => method.run(), 'webusb-discovery')
66080
+ : yield method.run();
65830
66081
  completeMethodRequestContext(method);
65831
66082
  return createResponseMessage(method.responseID, true, response);
65832
66083
  }
@@ -65898,6 +66149,7 @@ const waitForPendingPromise = (connectId, getPrePendingCallPromise, removePrePen
65898
66149
  Log.debug('pre pending call promise before call method, wait for it');
65899
66150
  let timer;
65900
66151
  let timedOut = false;
66152
+ let completed = false;
65901
66153
  try {
65902
66154
  yield Promise.race([
65903
66155
  pendingPromise,
@@ -65908,13 +66160,13 @@ const waitForPendingPromise = (connectId, getPrePendingCallPromise, removePrePen
65908
66160
  }, PRE_PENDING_CALL_TIMEOUT_MS);
65909
66161
  }),
65910
66162
  ]);
65911
- }
65912
- catch (error) {
66163
+ completed = !timedOut;
65913
66164
  }
65914
66165
  finally {
65915
66166
  if (timer)
65916
66167
  clearTimeout(timer);
65917
- removePrePendingCallPromise === null || removePrePendingCallPromise === void 0 ? void 0 : removePrePendingCallPromise(connectId, pendingPromise);
66168
+ if (timedOut || completed)
66169
+ removePrePendingCallPromise === null || removePrePendingCallPromise === void 0 ? void 0 : removePrePendingCallPromise(connectId, pendingPromise);
65918
66170
  }
65919
66171
  if (timedOut) {
65920
66172
  Log.warn('pre pending call promise timed out before call method', { connectId });
@@ -65922,8 +66174,19 @@ const waitForPendingPromise = (connectId, getPrePendingCallPromise, removePrePen
65922
66174
  Log.debug('pre pending call promise before call method done');
65923
66175
  }
65924
66176
  });
66177
+ function getPostCallPendingPromise(method, device) {
66178
+ const cleanupPromise = device.waitForRunCleanup();
66179
+ const env = DataManager.getSettings('env');
66180
+ const deviceType = device.getCurrentDeviceType();
66181
+ const requiresSigningCooldown = method.name.includes('Sign') &&
66182
+ (deviceType === hdShared.EDeviceType.Pro2 || deviceType === hdShared.EDeviceType.Neo) &&
66183
+ (DataManager.isBrowserWebUsb(env) || DataManager.isDesktopWebUsb(env) || env === 'node-usb');
66184
+ return requiresSigningCooldown
66185
+ ? cleanupPromise.then(() => wait(PRO2_USB_SIGNING_COOLDOWN_MS)).then(() => undefined)
66186
+ : cleanupPromise;
66187
+ }
65925
66188
  const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, void 0, function* () {
65926
- var _d, _e, _f, _g, _h, _j, _k;
66189
+ var _d, _e, _f, _g, _h, _j;
65927
66190
  let messageResponse;
65928
66191
  const { requestQueue, getPrePendingCallPromise, removePrePendingCallPromise } = context;
65929
66192
  updateMethodRequestContext(method, { status: 'running' });
@@ -65937,21 +66200,42 @@ const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, voi
65937
66200
  Log.debug('passphrase state change, clear device cache');
65938
66201
  DevicePool.clearDeviceCache(method.payload.connectId);
65939
66202
  }
65940
- if (method.connectId) {
65941
- yield context.waitForCallbackTasks(method.connectId);
65942
- }
65943
- yield waitForPendingPromise((_d = method.connectId) !== null && _d !== void 0 ? _d : '', getPrePendingCallPromise, removePrePendingCallPromise);
65944
66203
  const task = requestQueue.createTask(method);
65945
66204
  let preWarmCallbackTask;
65946
- if (method.isPreWarmSignal && method.connectId) {
65947
- preWarmCallbackTask = hdShared.createDeferred();
65948
- context.registerCallbackTask(method.connectId, preWarmCallbackTask);
65949
- }
65950
66205
  let device;
65951
66206
  try {
65952
- const connectId = (_e = method.connectId) !== null && _e !== void 0 ? _e : '';
66207
+ const connectId = (_d = method.connectId) !== null && _d !== void 0 ? _d : '';
66208
+ if (connectId) {
66209
+ yield requestQueue.waitForTask(task, () => context.waitForCallbackTasks(connectId));
66210
+ }
66211
+ yield requestQueue.waitForTask(task, () => {
66212
+ var _a;
66213
+ return waitForPendingPromise((_a = method.connectId) !== null && _a !== void 0 ? _a : '', getPrePendingCallPromise, removePrePendingCallPromise);
66214
+ });
66215
+ if (method.isPreWarmSignal && method.connectId) {
66216
+ preWarmCallbackTask = hdShared.createDeferred();
66217
+ context.registerCallbackTask(method.connectId, preWarmCallbackTask);
66218
+ }
65953
66219
  const pollingId = pollingManager.start(connectId);
65954
- device = yield ensureConnected(context, method, connectId, pollingId, (_f = task.abortController) === null || _f === void 0 ? void 0 : _f.signal);
66220
+ const env = DataManager.getSettings('env');
66221
+ const connect = () => ensureConnected(context, method, connectId, pollingId, method.abortSignal);
66222
+ if (DataManager.isBrowserWebUsb(env) || DataManager.isDesktopWebUsb(env)) {
66223
+ const connectPromise = context.methodSynchronize(() => __awaiter(void 0, void 0, void 0, function* () {
66224
+ var _k;
66225
+ if ((_k = method.abortSignal) === null || _k === void 0 ? void 0 : _k.aborted) {
66226
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallQueueActionCancelled);
66227
+ }
66228
+ return connect();
66229
+ }), 'webusb-discovery');
66230
+ connectPromise.catch(() => undefined);
66231
+ device = yield requestQueue.waitForTask(task, () => connectPromise);
66232
+ }
66233
+ else {
66234
+ device = yield connect();
66235
+ }
66236
+ if ((_e = method.abortSignal) === null || _e === void 0 ? void 0 : _e.aborted) {
66237
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallQueueActionCancelled);
66238
+ }
65955
66239
  }
65956
66240
  catch (e) {
65957
66241
  preWarmCallbackTask === null || preWarmCallbackTask === void 0 ? void 0 : preWarmCallbackTask.resolve();
@@ -65966,7 +66250,7 @@ const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, voi
65966
66250
  requestQueue.releaseTask(method.responseID);
65967
66251
  return createResponseMessage(method.responseID, false, { error: e });
65968
66252
  }
65969
- if ((_g = method.payload) === null || _g === void 0 ? void 0 : _g.onlyConnectBleDevice) {
66253
+ if ((_f = method.payload) === null || _f === void 0 ? void 0 : _f.onlyConnectBleDevice) {
65970
66254
  preWarmCallbackTask === null || preWarmCallbackTask === void 0 ? void 0 : preWarmCallbackTask.resolve();
65971
66255
  Log.debug('Call API - only connect ble device: ', device === null || device === void 0 ? void 0 : device.mainId);
65972
66256
  completeMethodRequestContext(method);
@@ -65974,11 +66258,11 @@ const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, voi
65974
66258
  return createResponseMessage(method.responseID, true, null);
65975
66259
  }
65976
66260
  Log.debug('Call API - setDevice: ', device.mainId);
65977
- (_h = method.setDevice) === null || _h === void 0 ? void 0 : _h.call(method, device);
66261
+ (_g = method.setDevice) === null || _g === void 0 ? void 0 : _g.call(method, device);
65978
66262
  method.context = context;
65979
66263
  updateMethodRequestContext(method, {
65980
66264
  deviceInstanceId: device.instanceId,
65981
- commandsInstanceId: (_j = device.commands) === null || _j === void 0 ? void 0 : _j.instanceId,
66265
+ commandsInstanceId: (_h = device.commands) === null || _h === void 0 ? void 0 : _h.instanceId,
65982
66266
  });
65983
66267
  const activeRequests = getActiveRequestsByDeviceInstance(device.instanceId);
65984
66268
  if (activeRequests.length > 0) {
@@ -66004,10 +66288,14 @@ const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, voi
66004
66288
  device.beginProtocolV2UiInteraction();
66005
66289
  device.on(DEVICE.SELECT_DEVICE_FOR_SWITCH_FIRMWARE_WEB_DEVICE, onSelectDeviceForSwitchFirmwareWebDeviceHandler);
66006
66290
  try {
66007
- if (method.connectId) {
66008
- yield context.waitForCallbackTasks(method.connectId, preWarmCallbackTask);
66291
+ const { connectId } = method;
66292
+ if (connectId) {
66293
+ yield requestQueue.waitForTask(task, () => context.waitForCallbackTasks(connectId, preWarmCallbackTask));
66009
66294
  }
66010
- yield waitForPendingPromise((_k = method.connectId) !== null && _k !== void 0 ? _k : '', getPrePendingCallPromise, removePrePendingCallPromise);
66295
+ yield requestQueue.waitForTask(task, () => {
66296
+ var _a;
66297
+ return waitForPendingPromise((_a = method.connectId) !== null && _a !== void 0 ? _a : '', getPrePendingCallPromise, removePrePendingCallPromise);
66298
+ });
66011
66299
  const inner = () => __awaiter(void 0, void 0, void 0, function* () {
66012
66300
  var _l, _m;
66013
66301
  method.assertProtocolSupported(device.getProtocol(), device.getCurrentFirmwareType());
@@ -66134,6 +66422,9 @@ const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, voi
66134
66422
  }),
66135
66423
  });
66136
66424
  messageResponse = createResponseMessage(method.responseID, true, response);
66425
+ if (method.connectId) {
66426
+ context.setPrePendingCallPromise(method.connectId, getPostCallPendingPromise(method, device));
66427
+ }
66137
66428
  requestQueue.resolveRequest(method.responseID, messageResponse);
66138
66429
  completeMethodRequestContext(method);
66139
66430
  }
@@ -66144,6 +66435,9 @@ const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, voi
66144
66435
  }
66145
66436
  Log.debug(`Call API - Inner Method Run Error`, error);
66146
66437
  messageResponse = createResponseMessage(method.responseID, false, { error });
66438
+ if (method.connectId) {
66439
+ context.setPrePendingCallPromise(method.connectId, getPostCallPendingPromise(method, device));
66440
+ }
66147
66441
  requestQueue.resolveRequest(method.responseID, messageResponse);
66148
66442
  completeMethodRequestContext(method, error);
66149
66443
  if (error instanceof hdShared.HardwareError &&
@@ -66162,6 +66456,9 @@ const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, voi
66162
66456
  });
66163
66457
  Log.debug('Call API - Device Run: ', device.mainId);
66164
66458
  const runOptions = Object.assign({ keepSession: method.payload.keepSession, skipInitialize: canSkipInitialize(method, device) }, parseInitOptions(method));
66459
+ if ((_j = method.abortSignal) === null || _j === void 0 ? void 0 : _j.aborted) {
66460
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallQueueActionCancelled);
66461
+ }
66165
66462
  const deviceRun = () => device.run(inner, runOptions);
66166
66463
  task.callPromise = hdShared.createDeferred(deviceRun);
66167
66464
  try {
@@ -66180,6 +66477,7 @@ const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, voi
66180
66477
  requestQueue.rejectRequest(method.responseID, hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodError, error.message));
66181
66478
  Log.debug('Call API - Run Error: ', error);
66182
66479
  completeMethodRequestContext(method, error);
66480
+ return messageResponse;
66183
66481
  }
66184
66482
  finally {
66185
66483
  preWarmCallbackTask === null || preWarmCallbackTask === void 0 ? void 0 : preWarmCallbackTask.resolve();
@@ -66329,11 +66627,15 @@ function isRetryableBleProtocolV2ProbeError(method, error) {
66329
66627
  message.includes('did not respond to expected protocol'));
66330
66628
  }
66331
66629
  function isRetryableBleConnectionError(method, error) {
66332
- var _a;
66630
+ var _a, _b;
66333
66631
  if ((_a = method.device) === null || _a === void 0 ? void 0 : _a.wasInterruptedByUser()) {
66334
66632
  return false;
66335
66633
  }
66336
66634
  const typedError = error;
66635
+ if ((typedError === null || typedError === void 0 ? void 0 : typedError.errorCode) === hdShared.HardwareErrorCode.BleTimeoutError &&
66636
+ ((_b = typedError.params) === null || _b === void 0 ? void 0 : _b.acquireDeadlineExceeded) === true) {
66637
+ return false;
66638
+ }
66337
66639
  return ((typedError === null || typedError === void 0 ? void 0 : typedError.errorCode) === hdShared.HardwareErrorCode.BleTimeoutError ||
66338
66640
  (typedError === null || typedError === void 0 ? void 0 : typedError.errorCode) === hdShared.HardwareErrorCode.BleConnectedError ||
66339
66641
  isRetryableBleProtocolV2ProbeError(method, error) ||
@@ -66346,10 +66648,11 @@ function isMissingDetectedProtocolV2Error(method, error) {
66346
66648
  typeof typedError.message === 'string' &&
66347
66649
  typedError.message.includes('Device protocol has not been detected'));
66348
66650
  }
66349
- function isProtocolV2PeerRemovedPairingError(method, error) {
66350
- return (method.payload.connectProtocol === 'V2' &&
66351
- (error === null || error === void 0 ? void 0 : error.errorCode) ===
66352
- hdShared.HardwareErrorCode.BlePeerRemovedPairingInformation);
66651
+ function isTerminalBleStaleBondError(error) {
66652
+ return hdShared.isBleStaleBondHardwareError(error);
66653
+ }
66654
+ function isDeviceIdentityMismatchError(error) {
66655
+ return ((error === null || error === void 0 ? void 0 : error.errorCode) === hdShared.HardwareErrorCode.DeviceCheckDeviceIdError);
66353
66656
  }
66354
66657
  const BLE_ACQUIRE_DEADLINE_MS = 60 * 1000;
66355
66658
  function raceBleAcquire(acquirePromise, abortSignal) {
@@ -66364,7 +66667,7 @@ function raceBleAcquire(acquirePromise, abortSignal) {
66364
66667
  fn();
66365
66668
  };
66366
66669
  const onAbort = () => settle(() => reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallQueueActionCancelled)));
66367
- const deadline = setTimeout(() => settle(() => reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleTimeoutError, `BLE acquire exceeded ${BLE_ACQUIRE_DEADLINE_MS}ms deadline`))), BLE_ACQUIRE_DEADLINE_MS);
66670
+ const deadline = setTimeout(() => settle(() => reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleTimeoutError, `BLE acquire exceeded ${BLE_ACQUIRE_DEADLINE_MS}ms deadline`, { acquireDeadlineExceeded: true }))), BLE_ACQUIRE_DEADLINE_MS);
66368
66671
  acquirePromise.then(value => settle(() => resolve(value)), error => settle(() => reject(error)));
66369
66672
  if (abortSignal) {
66370
66673
  if (abortSignal.aborted) {
@@ -66379,7 +66682,7 @@ function connectDeviceForBle(method, device, abortSignal, retryCount = 0) {
66379
66682
  var _a;
66380
66683
  return __awaiter(this, void 0, void 0, function* () {
66381
66684
  try {
66382
- if (device.wasInterruptedByUser()) {
66685
+ if ((abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.aborted) || device.wasInterruptedByUser()) {
66383
66686
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInterruptedFromUser);
66384
66687
  }
66385
66688
  if (method.payload.forceProtocolDetection && device.hasDeviceAcquire()) {
@@ -66435,6 +66738,9 @@ function connectDeviceForBle(method, device, abortSignal, retryCount = 0) {
66435
66738
  }
66436
66739
  }
66437
66740
  catch (err) {
66741
+ if ((abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.aborted) || device.wasInterruptedByUser()) {
66742
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInterruptedFromUser);
66743
+ }
66438
66744
  const requiresColdReconnect = isMissingDetectedProtocolV2Error(method, err);
66439
66745
  if ((hdShared.ERROR_CODES_REQUIRE_DISCONNECT.includes(err.errorCode) || requiresColdReconnect) &&
66440
66746
  device.mainId &&
@@ -66467,6 +66773,7 @@ const ensureConnected = (_context, method, connectId, pollingId, abortSignal) =>
66467
66773
  const POLL_INTERVAL_TIME = (method.payload && method.payload.pollIntervalTime) || 1000;
66468
66774
  const TIME_OUT = (method.payload && method.payload.timeout) || 10000;
66469
66775
  let timer = null;
66776
+ let lastInitializeError;
66470
66777
  Log.debug(`EnsureConnected function start, MAX_RETRY_COUNT=${MAX_RETRY_COUNT}, POLL_INTERVAL_TIME=${POLL_INTERVAL_TIME} `);
66471
66778
  const poll = (time = POLL_INTERVAL_TIME) => __awaiter(void 0, void 0, void 0, function* () {
66472
66779
  return new Promise((resolve, reject) => __awaiter(void 0, void 0, void 0, function* () {
@@ -66499,8 +66806,10 @@ const ensureConnected = (_context, method, connectId, pollingId, abortSignal) =>
66499
66806
  Log.debug('EnsureConnected function try count: ', tryCount, ' poll interval time: ', time);
66500
66807
  try {
66501
66808
  yield initDeviceList(method);
66809
+ lastInitializeError = undefined;
66502
66810
  }
66503
66811
  catch (error) {
66812
+ lastInitializeError = error;
66504
66813
  Log.debug('device list error: ', error);
66505
66814
  if ([
66506
66815
  hdShared.HardwareErrorCode.BridgeNotInstalled,
@@ -66513,6 +66822,7 @@ const ensureConnected = (_context, method, connectId, pollingId, abortSignal) =>
66513
66822
  }
66514
66823
  if (error.errorCode === hdShared.HardwareErrorCode.TransportNotConfigured) {
66515
66824
  yield TransportManager.configure();
66825
+ lastInitializeError = undefined;
66516
66826
  }
66517
66827
  }
66518
66828
  if (abort()) {
@@ -66571,6 +66881,7 @@ const ensureConnected = (_context, method, connectId, pollingId, abortSignal) =>
66571
66881
  hdShared.HardwareErrorCode.BleDeviceBondedCanceled,
66572
66882
  hdShared.HardwareErrorCode.BleCharacteristicNotifyError,
66573
66883
  hdShared.HardwareErrorCode.BleTimeoutError,
66884
+ hdShared.HardwareErrorCode.PollingTimeout,
66574
66885
  hdShared.HardwareErrorCode.BleWriteCharacteristicError,
66575
66886
  hdShared.HardwareErrorCode.BleAlreadyConnected,
66576
66887
  hdShared.HardwareErrorCode.FirmwareUpdateLimitOneDevice,
@@ -66581,7 +66892,10 @@ const ensureConnected = (_context, method, connectId, pollingId, abortSignal) =>
66581
66892
  hdShared.HardwareErrorCode.DeviceInterruptedFromUser,
66582
66893
  hdShared.HardwareErrorCode.CallQueueActionCancelled,
66583
66894
  ].includes(error.errorCode) ||
66584
- isProtocolV2PeerRemovedPairingError(method, error)) {
66895
+ (env === 'react-native' &&
66896
+ [hdShared.HardwareErrorCode.BleDeviceDisconnected, hdShared.HardwareErrorCode.PollingTimeout].includes(error.errorCode)) ||
66897
+ isTerminalBleStaleBondError(error) ||
66898
+ isDeviceIdentityMismatchError(error)) {
66585
66899
  reject(error);
66586
66900
  return;
66587
66901
  }
@@ -66591,13 +66905,16 @@ const ensureConnected = (_context, method, connectId, pollingId, abortSignal) =>
66591
66905
  clearTimeout(timer);
66592
66906
  }
66593
66907
  Log.debug('EnsureConnected get to max try count, will return: ', tryCount);
66594
- if (DataManager.isBrowserWebUsb(env) && !((_u = method.payload) === null || _u === void 0 ? void 0 : _u.skipWebDevicePrompt)) {
66908
+ const preserveWebUsbInitError = DataManager.isBrowserWebUsb(env) || DataManager.isDesktopWebUsb(env);
66909
+ const needsPermissionPrompt = DataManager.isBrowserWebUsb(env) && !((_u = method.payload) === null || _u === void 0 ? void 0 : _u.skipWebDevicePrompt);
66910
+ const fallbackError = needsPermissionPrompt
66911
+ ? hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.WebDeviceNotFoundOrNeedsPermission)
66912
+ : hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceNotFound);
66913
+ const errorToReject = preserveWebUsbInitError && lastInitializeError ? lastInitializeError : fallbackError;
66914
+ if (needsPermissionPrompt && errorToReject === fallbackError) {
66595
66915
  postMessage(createUiMessage(UI_REQUEST.WEB_DEVICE_PROMPT_ACCESS_PERMISSION));
66596
- reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.WebDeviceNotFoundOrNeedsPermission));
66597
- }
66598
- else {
66599
- reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceNotFound));
66600
66916
  }
66917
+ reject(errorToReject);
66601
66918
  return;
66602
66919
  }
66603
66920
  if (abort()) {
@@ -66876,7 +67193,14 @@ class Core extends events.exports {
66876
67193
  this.prePendingCallPromises.delete(connectId);
66877
67194
  return;
66878
67195
  }
66879
- this.prePendingCallPromises.set(connectId, promise);
67196
+ const previous = this.prePendingCallPromises.get(connectId);
67197
+ const cleanupPromise = previous && previous !== promise
67198
+ ? Promise.all([previous, promise]).then(() => undefined)
67199
+ : promise;
67200
+ this.prePendingCallPromises.set(connectId, cleanupPromise);
67201
+ cleanupPromise.catch(error => {
67202
+ Log.warn('Device cancellation cleanup failed', { errorCode: error === null || error === void 0 ? void 0 : error.errorCode });
67203
+ });
66880
67204
  },
66881
67205
  removePrePendingCallPromise: (connectId, promise) => {
66882
67206
  if (this.prePendingCallPromises.get(connectId) === promise) {