@onekeyfe/hd-core 1.2.2-alpha.8 → 1.2.3-alpha.1

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 (40) hide show
  1. package/__tests__/DeviceCommands.test.ts +254 -1
  2. package/__tests__/device-lifecycle-events.test.ts +83 -14
  3. package/__tests__/logBlockEvent.test.ts +45 -122
  4. package/__tests__/open-wallet-session.test.ts +139 -5
  5. package/__tests__/protocol-v2.test.ts +81 -2
  6. package/__tests__/sol-sign-offchain-message.test.ts +72 -0
  7. package/dist/api/FirmwareUpdateV4.d.ts +1 -0
  8. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  9. package/dist/api/UploadPortfolio.d.ts +1 -0
  10. package/dist/api/UploadPortfolio.d.ts.map +1 -1
  11. package/dist/api/solana/SolSignOffchainMessage.d.ts.map +1 -1
  12. package/dist/core/RequestQueue.d.ts +2 -0
  13. package/dist/core/RequestQueue.d.ts.map +1 -1
  14. package/dist/core/index.d.ts +2 -1
  15. package/dist/core/index.d.ts.map +1 -1
  16. package/dist/core/uiPromiseRegistry.d.ts +1 -1
  17. package/dist/device/DeviceCommands.d.ts +5 -4
  18. package/dist/device/DeviceCommands.d.ts.map +1 -1
  19. package/dist/events/logBlockEvent.d.ts.map +1 -1
  20. package/dist/index.d.ts +19 -12
  21. package/dist/index.js +171 -141
  22. package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
  23. package/dist/types/api/protocolV2.d.ts +3 -4
  24. package/dist/types/api/protocolV2.d.ts.map +1 -1
  25. package/dist/types/api/solSignOffchainMessage.d.ts +1 -0
  26. package/dist/types/api/solSignOffchainMessage.d.ts.map +1 -1
  27. package/dist/utils/patch.d.ts +1 -1
  28. package/package.json +4 -4
  29. package/src/api/FirmwareUpdateV4.ts +9 -4
  30. package/src/api/UploadPortfolio.ts +5 -4
  31. package/src/api/solana/SolSignOffchainMessage.ts +44 -4
  32. package/src/core/RequestQueue.ts +16 -1
  33. package/src/core/index.ts +43 -20
  34. package/src/data/messages/messages-protocol-v2.json +28 -33
  35. package/src/data/messages/messages.json +8 -5
  36. package/src/device/DeviceCommands.ts +29 -2
  37. package/src/events/logBlockEvent.ts +6 -75
  38. package/src/protocols/protocol-v2/walletSession.ts +11 -2
  39. package/src/types/api/protocolV2.ts +3 -4
  40. package/src/types/api/solSignOffchainMessage.ts +2 -0
package/dist/index.js CHANGED
@@ -13203,7 +13203,8 @@ var nested$2 = {
13203
13203
  },
13204
13204
  SolanaOffChainMessageVersion: {
13205
13205
  values: {
13206
- MESSAGE_VERSION_0: 0
13206
+ MESSAGE_VERSION_0: 0,
13207
+ MESSAGE_VERSION_1: 1
13207
13208
  }
13208
13209
  },
13209
13210
  SolanaOffChainMessageFormat: {
@@ -13236,14 +13237,16 @@ var nested$2 = {
13236
13237
  },
13237
13238
  message_format: {
13238
13239
  type: "SolanaOffChainMessageFormat",
13239
- id: 4,
13240
- options: {
13241
- "default": "V0_RESTRICTED_ASCII"
13242
- }
13240
+ id: 4
13243
13241
  },
13244
13242
  application_domain: {
13245
13243
  type: "bytes",
13246
13244
  id: 5
13245
+ },
13246
+ required_signers: {
13247
+ rule: "repeated",
13248
+ type: "bytes",
13249
+ id: 7
13247
13250
  }
13248
13251
  }
13249
13252
  },
@@ -31499,10 +31502,6 @@ var nested = {
31499
31502
  request_id: {
31500
31503
  type: "bytes",
31501
31504
  id: 5
31502
- },
31503
- source_fingerprint: {
31504
- type: "uint32",
31505
- id: 6
31506
31505
  }
31507
31506
  }
31508
31507
  },
@@ -31758,10 +31757,6 @@ var nested = {
31758
31757
  expected_address: {
31759
31758
  type: "bytes",
31760
31759
  id: 12
31761
- },
31762
- source_fingerprint: {
31763
- type: "uint32",
31764
- id: 13
31765
31760
  }
31766
31761
  }
31767
31762
  },
@@ -31846,10 +31841,6 @@ var nested = {
31846
31841
  expected_address: {
31847
31842
  type: "bytes",
31848
31843
  id: 12
31849
- },
31850
- source_fingerprint: {
31851
- type: "uint32",
31852
- id: 13
31853
31844
  }
31854
31845
  }
31855
31846
  },
@@ -31997,7 +31988,29 @@ var nested = {
31997
31988
  type: "EthereumAuthorizationSignature",
31998
31989
  id: 10
31999
31990
  }
32000
- }
31991
+ },
31992
+ reserved: [
31993
+ [
31994
+ 5,
31995
+ 5
31996
+ ],
31997
+ [
31998
+ 6,
31999
+ 6
32000
+ ],
32001
+ [
32002
+ 7,
32003
+ 7
32004
+ ],
32005
+ [
32006
+ 8,
32007
+ 8
32008
+ ],
32009
+ [
32010
+ 9,
32011
+ 9
32012
+ ]
32013
+ ]
32001
32014
  },
32002
32015
  EthereumTxAckOneKey: {
32003
32016
  fields: {
@@ -32026,10 +32039,6 @@ var nested = {
32026
32039
  chain_id: {
32027
32040
  type: "uint64",
32028
32041
  id: 3
32029
- },
32030
- source_fingerprint: {
32031
- type: "uint32",
32032
- id: 4
32033
32042
  }
32034
32043
  }
32035
32044
  },
@@ -36027,7 +36036,8 @@ var nested = {
36027
36036
  },
36028
36037
  SolanaOffChainMessageVersion: {
36029
36038
  values: {
36030
- MESSAGE_VERSION_0: 0
36039
+ MESSAGE_VERSION_0: 0,
36040
+ MESSAGE_VERSION_1: 1
36031
36041
  }
36032
36042
  },
36033
36043
  SolanaOffChainMessageFormat: {
@@ -36075,10 +36085,6 @@ var nested = {
36075
36085
  rule: "required",
36076
36086
  type: "bytes",
36077
36087
  id: 2
36078
- },
36079
- source_fingerprint: {
36080
- type: "uint32",
36081
- id: 3
36082
36088
  }
36083
36089
  }
36084
36090
  },
@@ -36115,17 +36121,15 @@ var nested = {
36115
36121
  },
36116
36122
  message_format: {
36117
36123
  type: "SolanaOffChainMessageFormat",
36118
- id: 4,
36119
- options: {
36120
- "default": "V0_RESTRICTED_ASCII"
36121
- }
36124
+ id: 4
36122
36125
  },
36123
36126
  application_domain: {
36124
36127
  type: "bytes",
36125
36128
  id: 5
36126
36129
  },
36127
- source_fingerprint: {
36128
- type: "uint32",
36130
+ required_signers: {
36131
+ rule: "repeated",
36132
+ type: "bytes",
36129
36133
  id: 6
36130
36134
  }
36131
36135
  }
@@ -36144,10 +36148,6 @@ var nested = {
36144
36148
  rule: "required",
36145
36149
  type: "bytes",
36146
36150
  id: 2
36147
- },
36148
- source_fingerprint: {
36149
- type: "uint32",
36150
- id: 3
36151
36151
  }
36152
36152
  }
36153
36153
  },
@@ -38963,6 +38963,10 @@ var nested = {
38963
38963
  manufacture_time: {
38964
38964
  type: "DeviceFactoryInfoManufactureTime",
38965
38965
  id: 5
38966
+ },
38967
+ data: {
38968
+ type: "bytes",
38969
+ id: 100
38966
38970
  }
38967
38971
  }
38968
38972
  },
@@ -38972,11 +38976,19 @@ var nested = {
38972
38976
  rule: "required",
38973
38977
  type: "DeviceFactoryInfo",
38974
38978
  id: 1
38979
+ },
38980
+ full_data: {
38981
+ type: "bool",
38982
+ id: 2
38975
38983
  }
38976
38984
  }
38977
38985
  },
38978
38986
  DeviceFactoryInfoGet: {
38979
38987
  fields: {
38988
+ full_data: {
38989
+ type: "bool",
38990
+ id: 1
38991
+ }
38980
38992
  }
38981
38993
  },
38982
38994
  DeviceFactoryPermanentLock: {
@@ -41663,61 +41675,13 @@ const LogBlockEvent = new Set([
41663
41675
  UI_RESPONSE.RECEIVE_PIN,
41664
41676
  UI_RESPONSE.RECEIVE_PASSPHRASE,
41665
41677
  ]);
41666
- const LogLabelMethod = new Set([
41667
- 'openWalletSession',
41678
+ const LogPayloadBlockMethod = new Set([
41668
41679
  'deviceUploadNft',
41669
41680
  'deviceUploadWallpaper',
41670
41681
  'uploadPortfolio',
41671
41682
  'fileWrite',
41672
41683
  'fileRead',
41673
41684
  ]);
41674
- const LogPayloadBlockMethod = new Set([
41675
- 'deviceUploadNft',
41676
- 'deviceUploadWallpaper',
41677
- 'uploadPortfolio',
41678
- ]);
41679
- const SensitiveLogKeys = new Set([
41680
- 'devicestate',
41681
- 'entropy',
41682
- 'expectedpassphrasestate',
41683
- 'mnemonic',
41684
- 'passphrase',
41685
- 'passphrasestate',
41686
- 'password',
41687
- 'pin',
41688
- 'privatekey',
41689
- 'seed',
41690
- 'session',
41691
- 'sessionid',
41692
- 'walletsessionid',
41693
- 'xprv',
41694
- ]);
41695
- const normalizeLogKey = (key) => key.replace(/[_-]/g, '').toLowerCase();
41696
- const isSigningMethod = (methodName) => /sign/i.test(methodName);
41697
- const redactLogValue = (value, seen) => {
41698
- if (ArrayBuffer.isView(value)) {
41699
- return `[BINARY:${value.byteLength}]`;
41700
- }
41701
- if (value instanceof ArrayBuffer) {
41702
- return `[BINARY:${value.byteLength}]`;
41703
- }
41704
- if (Array.isArray(value)) {
41705
- return value.map(item => redactLogValue(item, seen));
41706
- }
41707
- if (!value || typeof value !== 'object')
41708
- return value;
41709
- if (seen.has(value))
41710
- return '[CIRCULAR]';
41711
- seen.add(value);
41712
- const redacted = Object.fromEntries(Object.entries(value).map(([key, item]) => [
41713
- key,
41714
- SensitiveLogKeys.has(normalizeLogKey(key)) && item !== null && item !== undefined
41715
- ? '[REDACTED]'
41716
- : redactLogValue(item, seen),
41717
- ]));
41718
- seen.delete(value);
41719
- return redacted;
41720
- };
41721
41685
  function getLogBlockLabel(message) {
41722
41686
  if (!message || typeof message !== 'object')
41723
41687
  return undefined;
@@ -41726,26 +41690,16 @@ function getLogBlockLabel(message) {
41726
41690
  return type;
41727
41691
  }
41728
41692
  const methodName = method !== null && method !== void 0 ? method : payload === null || payload === void 0 ? void 0 : payload.method;
41729
- if (methodName && (LogLabelMethod.has(methodName) || isSigningMethod(methodName))) {
41693
+ if (methodName && LogPayloadBlockMethod.has(methodName)) {
41730
41694
  return methodName;
41731
41695
  }
41732
41696
  return undefined;
41733
41697
  }
41734
41698
  function getSafeLogPayload(value, blockLabel) {
41735
- if (blockLabel &&
41736
- (LogBlockEvent.has(blockLabel) ||
41737
- LogPayloadBlockMethod.has(blockLabel) ||
41738
- isSigningMethod(blockLabel))) {
41699
+ if (blockLabel) {
41739
41700
  return { method: blockLabel, payload: '[REDACTED]' };
41740
41701
  }
41741
- const redactedValue = redactLogValue(value, new WeakSet());
41742
- if (blockLabel &&
41743
- redactedValue &&
41744
- typeof redactedValue === 'object' &&
41745
- !Array.isArray(redactedValue)) {
41746
- return Object.assign(Object.assign({}, redactedValue), { method: blockLabel });
41747
- }
41748
- return redactedValue;
41702
+ return value;
41749
41703
  }
41750
41704
  function formatLogMethodLabel(label, methodName) {
41751
41705
  return methodName ? `${label} [${methodName}]` : label;
@@ -41869,7 +41823,7 @@ const selectDeviceSession = (device, expectedPassphraseState, deriveCardano, onS
41869
41823
  return getDeviceSession(device, buildDeviceSessionGetRequest());
41870
41824
  });
41871
41825
  function getProtocolV2WalletSession(device, options) {
41872
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
41826
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
41873
41827
  return __awaiter(this, void 0, void 0, function* () {
41874
41828
  const forceWalletSelection = (options === null || options === void 0 ? void 0 : options.forceWalletSelection) === true || (options === null || options === void 0 ? void 0 : options.initSession) === true;
41875
41829
  const readCurrentAttachPinSession = (options === null || options === void 0 ? void 0 : options.readCurrentAttachPinSession) === true;
@@ -41909,6 +41863,10 @@ function getProtocolV2WalletSession(device, options) {
41909
41863
  const markWalletStatusRefreshed = () => {
41910
41864
  walletStatusRefreshed = true;
41911
41865
  };
41866
+ if ((options === null || options === void 0 ? void 0 : options.onlyMainPin) && options.mainPinSelected !== true) {
41867
+ yield refreshProtocolV2DeviceStatus(device);
41868
+ markWalletStatusRefreshed();
41869
+ }
41912
41870
  let mainPinAuthenticated = (options === null || options === void 0 ? void 0 : options.mainPinSelected) === true ||
41913
41871
  ((options === null || options === void 0 ? void 0 : options.onlyMainPin) === true &&
41914
41872
  ((_d = device.features) === null || _d === void 0 ? void 0 : _d.unlocked) === true &&
@@ -41936,7 +41894,7 @@ function getProtocolV2WalletSession(device, options) {
41936
41894
  return keepAttachPin ? Object.assign(session, { viaAttachPin: true }) : session;
41937
41895
  });
41938
41896
  const rejectMismatchedAttachPinWallet = () => __awaiter(this, void 0, void 0, function* () {
41939
- var _m;
41897
+ var _o;
41940
41898
  const features = yield refreshProtocolV2DeviceStatus(device);
41941
41899
  markWalletStatusRefreshed();
41942
41900
  if (features.unlockedAttachPin !== true) {
@@ -41945,10 +41903,10 @@ function getProtocolV2WalletSession(device, options) {
41945
41903
  try {
41946
41904
  yield device.lockDevice();
41947
41905
  }
41948
- catch (_o) {
41906
+ catch (_p) {
41949
41907
  }
41950
41908
  if (options === null || options === void 0 ? void 0 : options.rejectAttachPinForMainWallet) {
41951
- (_m = device.clearStandardInternalState) === null || _m === void 0 ? void 0 : _m.call(device);
41909
+ (_o = device.clearStandardInternalState) === null || _o === void 0 ? void 0 : _o.call(device);
41952
41910
  device.clearInternalState();
41953
41911
  }
41954
41912
  else {
@@ -41957,11 +41915,11 @@ function getProtocolV2WalletSession(device, options) {
41957
41915
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckUnlockTypeError);
41958
41916
  });
41959
41917
  const lockAttachPinBeforePassphraseSelection = () => __awaiter(this, void 0, void 0, function* () {
41960
- var _p;
41918
+ var _q;
41961
41919
  if (readCurrentAttachPinSession || (options === null || options === void 0 ? void 0 : options.onlyMainPin)) {
41962
41920
  return;
41963
41921
  }
41964
- if (((_p = device.features) === null || _p === void 0 ? void 0 : _p.unlockedAttachPin) !== true) {
41922
+ if (((_q = device.features) === null || _q === void 0 ? void 0 : _q.unlockedAttachPin) !== true) {
41965
41923
  return;
41966
41924
  }
41967
41925
  yield rejectMismatchedAttachPinWallet();
@@ -41982,8 +41940,8 @@ function getProtocolV2WalletSession(device, options) {
41982
41940
  }
41983
41941
  });
41984
41942
  const selectStandardWallet = (forceMainPin = false) => __awaiter(this, void 0, void 0, function* () {
41985
- var _q;
41986
- if (((_q = device.features) === null || _q === void 0 ? void 0 : _q.passphraseProtection) === true) {
41943
+ var _r;
41944
+ if (((_r = device.features) === null || _r === void 0 ? void 0 : _r.passphraseProtection) === true) {
41987
41945
  yield selectMainPin();
41988
41946
  yield askDevicePassphrase(device, {
41989
41947
  passphrase: '',
@@ -42048,6 +42006,9 @@ function getProtocolV2WalletSession(device, options) {
42048
42006
  throw error;
42049
42007
  }
42050
42008
  resumed = false;
42009
+ if (((_g = device.features) === null || _g === void 0 ? void 0 : _g.unlockedAttachPin) === true) {
42010
+ response = yield getDeviceSession(device, sessionGetRequest());
42011
+ }
42051
42012
  }
42052
42013
  }
42053
42014
  else if (expectedPassphraseState) {
@@ -42076,7 +42037,7 @@ function getProtocolV2WalletSession(device, options) {
42076
42037
  }
42077
42038
  catch (error) {
42078
42039
  if (options === null || options === void 0 ? void 0 : options.onlyMainPin) {
42079
- (_g = device.clearStandardInternalState) === null || _g === void 0 ? void 0 : _g.call(device);
42040
+ (_h = device.clearStandardInternalState) === null || _h === void 0 ? void 0 : _h.call(device);
42080
42041
  }
42081
42042
  else {
42082
42043
  device.clearInternalState();
@@ -42091,7 +42052,7 @@ function getProtocolV2WalletSession(device, options) {
42091
42052
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.WalletSessionInvalid);
42092
42053
  }
42093
42054
  if (options === null || options === void 0 ? void 0 : options.onlyMainPin) {
42094
- (_h = device.clearStandardInternalState) === null || _h === void 0 ? void 0 : _h.call(device);
42055
+ (_j = device.clearStandardInternalState) === null || _j === void 0 ? void 0 : _j.call(device);
42095
42056
  yield selectStandardWallet(true);
42096
42057
  response = yield getDeviceSession(device, sessionGetRequest());
42097
42058
  }
@@ -42106,7 +42067,7 @@ function getProtocolV2WalletSession(device, options) {
42106
42067
  }
42107
42068
  catch (error) {
42108
42069
  if (options === null || options === void 0 ? void 0 : options.onlyMainPin) {
42109
- (_j = device.clearStandardInternalState) === null || _j === void 0 ? void 0 : _j.call(device);
42070
+ (_k = device.clearStandardInternalState) === null || _k === void 0 ? void 0 : _k.call(device);
42110
42071
  }
42111
42072
  else {
42112
42073
  device.clearInternalState();
@@ -42129,7 +42090,7 @@ function getProtocolV2WalletSession(device, options) {
42129
42090
  if (sessionIsAttachPinWallet(response)) {
42130
42091
  response = yield askEmptyPassphraseAndGet({ deriveCardano: true, keepAttachPin: true });
42131
42092
  }
42132
- else if (((_k = device.features) === null || _k === void 0 ? void 0 : _k.passphraseProtection) === false) {
42093
+ else if (((_l = device.features) === null || _l === void 0 ? void 0 : _l.passphraseProtection) === false) {
42133
42094
  response = yield getDeviceSession(device, buildDeviceSessionGetRequest());
42134
42095
  }
42135
42096
  else if (options === null || options === void 0 ? void 0 : options.onlyMainPin) {
@@ -42146,7 +42107,7 @@ function getProtocolV2WalletSession(device, options) {
42146
42107
  }
42147
42108
  catch (error) {
42148
42109
  if (options === null || options === void 0 ? void 0 : options.onlyMainPin) {
42149
- (_l = device.clearStandardInternalState) === null || _l === void 0 ? void 0 : _l.call(device);
42110
+ (_m = device.clearStandardInternalState) === null || _m === void 0 ? void 0 : _m.call(device);
42150
42111
  }
42151
42112
  else {
42152
42113
  device.clearInternalState();
@@ -43951,6 +43912,7 @@ class DeviceCommands {
43951
43912
  var _a, _b;
43952
43913
  return __awaiter(this, void 0, void 0, function* () {
43953
43914
  this.disposed = true;
43915
+ this.disposalToken = {};
43954
43916
  yield ((_b = (_a = this.transport).cancel) === null || _b === void 0 ? void 0 : _b.call(_a));
43955
43917
  });
43956
43918
  }
@@ -44124,7 +44086,24 @@ class DeviceCommands {
44124
44086
  }
44125
44087
  _commonCall(type, msg, options) {
44126
44088
  return __awaiter(this, void 0, void 0, function* () {
44127
- const resp = yield this.call(type, msg, options);
44089
+ const { disposalToken } = this;
44090
+ let resp = yield this.call(type, msg, options);
44091
+ for (let retry = 0; retry < 3 &&
44092
+ this.device.isProtocolV2() &&
44093
+ DEVICE_SESSION_CALLS.has(type) &&
44094
+ resp.type === 'Failure' &&
44095
+ resp.message.code === 'Failure_ProcessError' &&
44096
+ resp.message.subcode === hdTransport.DeviceSessionErrorCode.DeviceSessionError_Busy; retry += 1) {
44097
+ yield wait(100);
44098
+ if (this.device.wasInterruptedByUser()) {
44099
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInterruptedFromUser);
44100
+ }
44101
+ this.checkDisposed();
44102
+ if (this.disposalToken !== disposalToken) {
44103
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'DeviceCommands lifecycle changed');
44104
+ }
44105
+ resp = yield this.call(type, msg, options);
44106
+ }
44128
44107
  return this._filterCommonTypes(resp, type, options);
44129
44108
  });
44130
44109
  }
@@ -52646,6 +52625,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52646
52625
  this.protocolV2InstallDisconnectObserved = false;
52647
52626
  this.protocolV2InstallTerminalSuccessObserved = false;
52648
52627
  this.protocolV2LastTransferProgressAt = 0;
52628
+ this.protocolV2LastTransferredBytes = 0;
52649
52629
  }
52650
52630
  getSupportedProtocols() {
52651
52631
  return ['V2'];
@@ -53808,6 +53788,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53808
53788
  this.postTipMessage(exports.FirmwareUpdateTipMessage.StartTransferData);
53809
53789
  this.protocolV2LastTransferProgress = undefined;
53810
53790
  this.protocolV2LastTransferProgressAt = 0;
53791
+ this.protocolV2LastTransferredBytes = 0;
53811
53792
  const transferStartedAt = Date.now();
53812
53793
  let processedSize = 0;
53813
53794
  for (const resource of resourcesToSync) {
@@ -53890,13 +53871,15 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53890
53871
  const now = Date.now();
53891
53872
  const elapsedMs = Math.max(now - transferStartedAt, 0);
53892
53873
  const progress = Math.min(Math.ceil((transferredBytes / totalSize) * 100), 99);
53893
- const shouldPostProgress = progress !== this.protocolV2LastTransferProgress ||
53894
- now - this.protocolV2LastTransferProgressAt >=
53895
- PROTOCOL_V2_TRANSFER_PROGRESS_HEARTBEAT_MS ||
53896
- chunkEnd === source.size;
53874
+ const shouldPostProgress = transferredBytes >= this.protocolV2LastTransferredBytes &&
53875
+ (progress !== this.protocolV2LastTransferProgress ||
53876
+ now - this.protocolV2LastTransferProgressAt >=
53877
+ PROTOCOL_V2_TRANSFER_PROGRESS_HEARTBEAT_MS ||
53878
+ chunkEnd === source.size);
53897
53879
  if (shouldPostProgress) {
53898
53880
  this.protocolV2LastTransferProgress = progress;
53899
53881
  this.protocolV2LastTransferProgressAt = now;
53882
+ this.protocolV2LastTransferredBytes = transferredBytes;
53900
53883
  this.postProgressMessage(progress, 'transferData', {
53901
53884
  transferredBytes,
53902
53885
  totalBytes: totalSize,
@@ -55455,16 +55438,16 @@ const FILESYSTEM_FILE_WRITE_MESSAGE_TYPE = 60805;
55455
55438
  const PORTFOLIO_UPDATE_MESSAGE_TYPE = 61400;
55456
55439
  class UploadPortfolio extends FileWrite {
55457
55440
  init() {
55458
- const { packageBase64, timeoutMs } = this.payload;
55441
+ const { packageBase64, timeoutMs, uiMode = 'silent' } = this.payload;
55459
55442
  const packageBytes = decodeCanonicalBase64({
55460
55443
  value: packageBase64,
55461
55444
  parameterName: 'packageBase64',
55462
55445
  maxBytes: PORTFOLIO_PACKAGE_MAX_BYTES,
55463
55446
  });
55464
- 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 });
55447
+ 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 });
55465
55448
  super.init();
55466
55449
  this.unlockPolicy = 'none';
55467
- this.protocolV2UiMode = 'none';
55450
+ this.protocolV2UiMode = uiMode === 'progress' ? 'auto' : 'none';
55468
55451
  }
55469
55452
  run() {
55470
55453
  const _super = Object.create(null, {
@@ -59510,6 +59493,23 @@ class SolSignTransaction extends BaseMethod {
59510
59493
  }
59511
59494
  }
59512
59495
 
59496
+ const SOLANA_PUBLIC_KEY_LENGTH = 32;
59497
+ const SOLANA_APPLICATION_DOMAIN_LENGTH = 32;
59498
+ const normalizeRequiredSigners = (requiredSigners = []) => {
59499
+ const normalized = requiredSigners.map((signer, index) => {
59500
+ if (typeof signer !== 'string' ||
59501
+ !isHexString(addHexPrefix(signer), SOLANA_PUBLIC_KEY_LENGTH)) {
59502
+ throw invalidParameter(`Parameter [requiredSigners][${index}] must be a ${SOLANA_PUBLIC_KEY_LENGTH}-byte hex public key.`);
59503
+ }
59504
+ return stripHexPrefix(signer).toLowerCase();
59505
+ });
59506
+ for (let index = 1; index < normalized.length; index += 1) {
59507
+ if (normalized[index - 1] >= normalized[index]) {
59508
+ throw invalidParameter('Parameter [requiredSigners] must be strictly sorted and unique.');
59509
+ }
59510
+ }
59511
+ return normalized;
59512
+ };
59513
59513
  class SolSignOffchainMessage extends BaseMethod {
59514
59514
  getSupportedProtocols() {
59515
59515
  return ['V1', 'V2'];
@@ -59524,15 +59524,21 @@ class SolSignOffchainMessage extends BaseMethod {
59524
59524
  { name: 'messageVersion', type: 'number', required: false },
59525
59525
  { name: 'messageFormat', type: 'number', required: false },
59526
59526
  { name: 'applicationDomainHex', type: 'hexString', required: false },
59527
+ { name: 'requiredSigners', type: 'array', required: false, allowEmpty: true },
59527
59528
  ]);
59528
- const { path, messageHex, messageVersion, messageFormat, applicationDomainHex } = this.payload;
59529
+ const { path, messageHex, messageVersion, messageFormat, applicationDomainHex, requiredSigners, } = this.payload;
59529
59530
  const addressN = validatePath(path, 3);
59531
+ if (applicationDomainHex !== undefined &&
59532
+ !isHexString(addHexPrefix(applicationDomainHex), SOLANA_APPLICATION_DOMAIN_LENGTH)) {
59533
+ throw invalidParameter('Parameter [applicationDomainHex] must be 32 bytes.');
59534
+ }
59530
59535
  this.params = {
59531
59536
  address_n: addressN,
59532
59537
  message: stripHexPrefix(messageHex),
59533
59538
  message_version: messageVersion !== null && messageVersion !== void 0 ? messageVersion : undefined,
59534
59539
  message_format: messageFormat !== null && messageFormat !== void 0 ? messageFormat : undefined,
59535
- application_domain: applicationDomainHex !== null && applicationDomainHex !== void 0 ? applicationDomainHex : undefined,
59540
+ application_domain: applicationDomainHex ? stripHexPrefix(applicationDomainHex) : undefined,
59541
+ required_signers: normalizeRequiredSigners(requiredSigners),
59536
59542
  };
59537
59543
  }
59538
59544
  getVersionRange() {
@@ -65591,10 +65597,17 @@ class RequestQueue {
65591
65597
  }
65592
65598
  return false;
65593
65599
  }
65600
+ isRequestForConnectId(request, connectId) {
65601
+ var _a, _b;
65602
+ const { method } = request;
65603
+ return (method.connectId === connectId ||
65604
+ ((_a = method.device) === null || _a === void 0 ? void 0 : _a.mainId) === connectId ||
65605
+ ((_b = method.device) === null || _b === void 0 ? void 0 : _b.getConnectId()) === connectId);
65606
+ }
65594
65607
  abortRequestsByConnectId(connectId) {
65595
65608
  let count = 0;
65596
65609
  this.requestQueue.forEach((request, _) => {
65597
- if (request.abortController && request.method.connectId === connectId) {
65610
+ if (request.abortController && this.isRequestForConnectId(request, connectId)) {
65598
65611
  request.abortController.abort();
65599
65612
  request.abortController = undefined;
65600
65613
  count++;
@@ -65602,6 +65615,11 @@ class RequestQueue {
65602
65615
  });
65603
65616
  return count;
65604
65617
  }
65618
+ getRequestTasksIdByConnectId(connectId) {
65619
+ return Array.from(this.requestQueue.values())
65620
+ .filter(request => this.isRequestForConnectId(request, connectId))
65621
+ .map(request => request.id);
65622
+ }
65605
65623
  abortAllRequests() {
65606
65624
  let count = 0;
65607
65625
  this.requestQueue.forEach(request => {
@@ -66364,11 +66382,15 @@ function isRetryableBleProtocolV2ProbeError(method, error) {
66364
66382
  message.includes('did not respond to expected protocol'));
66365
66383
  }
66366
66384
  function isRetryableBleConnectionError(method, error) {
66367
- var _a;
66385
+ var _a, _b;
66368
66386
  if ((_a = method.device) === null || _a === void 0 ? void 0 : _a.wasInterruptedByUser()) {
66369
66387
  return false;
66370
66388
  }
66371
66389
  const typedError = error;
66390
+ if ((typedError === null || typedError === void 0 ? void 0 : typedError.errorCode) === hdShared.HardwareErrorCode.BleTimeoutError &&
66391
+ ((_b = typedError.params) === null || _b === void 0 ? void 0 : _b.acquireDeadlineExceeded) === true) {
66392
+ return false;
66393
+ }
66372
66394
  return ((typedError === null || typedError === void 0 ? void 0 : typedError.errorCode) === hdShared.HardwareErrorCode.BleTimeoutError ||
66373
66395
  (typedError === null || typedError === void 0 ? void 0 : typedError.errorCode) === hdShared.HardwareErrorCode.BleConnectedError ||
66374
66396
  isRetryableBleProtocolV2ProbeError(method, error) ||
@@ -66381,10 +66403,11 @@ function isMissingDetectedProtocolV2Error(method, error) {
66381
66403
  typeof typedError.message === 'string' &&
66382
66404
  typedError.message.includes('Device protocol has not been detected'));
66383
66405
  }
66384
- function isProtocolV2PeerRemovedPairingError(method, error) {
66385
- return (method.payload.connectProtocol === 'V2' &&
66386
- (error === null || error === void 0 ? void 0 : error.errorCode) ===
66387
- hdShared.HardwareErrorCode.BlePeerRemovedPairingInformation);
66406
+ function isTerminalBleStaleBondError(error) {
66407
+ return hdShared.isBleStaleBondHardwareError(error);
66408
+ }
66409
+ function isDeviceIdentityMismatchError(error) {
66410
+ return ((error === null || error === void 0 ? void 0 : error.errorCode) === hdShared.HardwareErrorCode.DeviceCheckDeviceIdError);
66388
66411
  }
66389
66412
  const BLE_ACQUIRE_DEADLINE_MS = 60 * 1000;
66390
66413
  function raceBleAcquire(acquirePromise, abortSignal) {
@@ -66399,7 +66422,7 @@ function raceBleAcquire(acquirePromise, abortSignal) {
66399
66422
  fn();
66400
66423
  };
66401
66424
  const onAbort = () => settle(() => reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallQueueActionCancelled)));
66402
- const deadline = setTimeout(() => settle(() => reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleTimeoutError, `BLE acquire exceeded ${BLE_ACQUIRE_DEADLINE_MS}ms deadline`))), BLE_ACQUIRE_DEADLINE_MS);
66425
+ 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);
66403
66426
  acquirePromise.then(value => settle(() => resolve(value)), error => settle(() => reject(error)));
66404
66427
  if (abortSignal) {
66405
66428
  if (abortSignal.aborted) {
@@ -66616,7 +66639,8 @@ const ensureConnected = (_context, method, connectId, pollingId, abortSignal) =>
66616
66639
  hdShared.HardwareErrorCode.DeviceInterruptedFromUser,
66617
66640
  hdShared.HardwareErrorCode.CallQueueActionCancelled,
66618
66641
  ].includes(error.errorCode) ||
66619
- isProtocolV2PeerRemovedPairingError(method, error)) {
66642
+ isTerminalBleStaleBondError(error) ||
66643
+ isDeviceIdentityMismatchError(error)) {
66620
66644
  reject(error);
66621
66645
  return;
66622
66646
  }
@@ -66644,14 +66668,14 @@ const ensureConnected = (_context, method, connectId, pollingId, abortSignal) =>
66644
66668
  return poll();
66645
66669
  });
66646
66670
  const cancel = (context, connectId) => {
66647
- var _a, _b, _c;
66671
+ var _a, _b;
66648
66672
  const { requestQueue, setPrePendingCallPromise } = context;
66649
66673
  if (connectId) {
66650
66674
  try {
66651
66675
  requestQueue.cancelCallbackTasks(connectId);
66652
- const requestIds = requestQueue.getRequestTasksId();
66676
+ const requestIds = requestQueue.getRequestTasksIdByConnectId(connectId);
66653
66677
  Log.debug(`Cancel Api connect requestQueues: length:${requestIds.length} requestIds:${requestIds.join(',')}`);
66654
- requestQueue.abortAllRequests();
66678
+ requestQueue.abortRequestsByConnectId(connectId);
66655
66679
  const canceledDevices = [];
66656
66680
  const interruptDevice = (device, deviceConnectId) => {
66657
66681
  if (!device || canceledDevices.includes(device)) {
@@ -66664,7 +66688,7 @@ const cancel = (context, connectId) => {
66664
66688
  const task = requestQueue.getTask(requestId);
66665
66689
  Log.debug('Cancel Api connect task: ', task);
66666
66690
  if (task) {
66667
- interruptDevice((_a = task.method) === null || _a === void 0 ? void 0 : _a.device, (_b = task.method.connectId) !== null && _b !== void 0 ? _b : connectId);
66691
+ interruptDevice((_a = task.method) === null || _a === void 0 ? void 0 : _a.device, connectId);
66668
66692
  interruptDevice(deviceCacheMap.get(connectId), connectId);
66669
66693
  requestQueue.rejectRequest(requestId, hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallQueueActionCancelled));
66670
66694
  }
@@ -66678,9 +66702,9 @@ const cancel = (context, connectId) => {
66678
66702
  }
66679
66703
  else {
66680
66704
  const env = DataManager.getSettings('env');
66705
+ requestQueue.abortAllRequests();
66681
66706
  if (DataManager.isBleConnect(env)) {
66682
66707
  Log.debug('Cancel Api all _deviceList: ');
66683
- requestQueue.abortAllRequests();
66684
66708
  const canceledDevices = [];
66685
66709
  const interruptDevice = (device) => {
66686
66710
  if (!device || canceledDevices.includes(device)) {
@@ -66693,7 +66717,7 @@ const cancel = (context, connectId) => {
66693
66717
  const task = requestQueue.getTask(requestId);
66694
66718
  Log.debug('Cancel Api connect task: ', task);
66695
66719
  if (task) {
66696
- interruptDevice((_c = task.method) === null || _c === void 0 ? void 0 : _c.device);
66720
+ interruptDevice((_b = task.method) === null || _b === void 0 ? void 0 : _b.device);
66697
66721
  if (task.method.connectId) {
66698
66722
  interruptDevice(deviceCacheMap.get(task.method.connectId));
66699
66723
  pollingManager.stop(task.method.connectId);
@@ -66716,8 +66740,10 @@ const cancel = (context, connectId) => {
66716
66740
  });
66717
66741
  }
66718
66742
  }
66719
- cleanup();
66720
- closePopup();
66743
+ cleanup(connectId);
66744
+ if (!connectId || _uiPromises.length === 0) {
66745
+ closePopup();
66746
+ }
66721
66747
  };
66722
66748
  const checkPassphraseEnableState = (method, features) => {
66723
66749
  if (!method.useDevicePassphraseState)
@@ -66747,9 +66773,13 @@ const shouldCheckPassphraseState = (method, device) => {
66747
66773
  }
66748
66774
  return device.hasUsePassphrase();
66749
66775
  };
66750
- const cleanup = () => {
66751
- const pendingUiPromises = _uiPromises;
66752
- _uiPromises = [];
66776
+ const cleanup = (connectId) => {
66777
+ const pendingUiPromises = connectId
66778
+ ? _uiPromises.filter(uiPromise => { var _a, _b; return ((_a = uiPromise.data) === null || _a === void 0 ? void 0 : _a.mainId) === connectId || ((_b = uiPromise.data) === null || _b === void 0 ? void 0 : _b.getConnectId()) === connectId; })
66779
+ : _uiPromises;
66780
+ _uiPromises = connectId
66781
+ ? _uiPromises.filter(uiPromise => !pendingUiPromises.includes(uiPromise))
66782
+ : [];
66753
66783
  rejectUiPromises(pendingUiPromises, hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.ActionCancelled, 'UI request was cancelled'));
66754
66784
  };
66755
66785
  const removeDeviceListener = (device) => {