@onekeyfe/hd-core 1.2.0-alpha.35 → 1.2.0-alpha.37

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 (100) hide show
  1. package/__tests__/AllNetworkGetAddressBase.tracing.test.ts +78 -0
  2. package/__tests__/DeviceEventRegistration.test.ts +6 -0
  3. package/__tests__/deviceUploadNft.test.ts +187 -0
  4. package/__tests__/get-device-state.test.ts +104 -12
  5. package/__tests__/homescreen.test.ts +41 -1
  6. package/__tests__/logBlockEvent.test.ts +1 -1
  7. package/__tests__/open-wallet-session.test.ts +259 -18
  8. package/__tests__/pro2Nft.test.ts +108 -0
  9. package/__tests__/protocol-v2-ui-lifecycle.test.ts +56 -0
  10. package/__tests__/protocol-v2-unlock-policy.test.ts +86 -35
  11. package/__tests__/protocol-v2.test.ts +377 -402
  12. package/__tests__/public-pro2-api-boundary.test.ts +1 -0
  13. package/dist/api/BaseMethod.d.ts +3 -1
  14. package/dist/api/BaseMethod.d.ts.map +1 -1
  15. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  16. package/dist/api/GetPassphraseState.d.ts.map +1 -1
  17. package/dist/api/OpenWalletSession.d.ts.map +1 -1
  18. package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
  19. package/dist/api/helpers/protocolV2FileWrite.d.ts +2 -0
  20. package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
  21. package/dist/api/index.d.ts +1 -0
  22. package/dist/api/index.d.ts.map +1 -1
  23. package/dist/api/protocol-v2/DeviceUploadNft.d.ts +30 -0
  24. package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +1 -0
  25. package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts.map +1 -1
  26. package/dist/core/deviceEventRegistration.d.ts +2 -0
  27. package/dist/core/deviceEventRegistration.d.ts.map +1 -1
  28. package/dist/core/index.d.ts.map +1 -1
  29. package/dist/device/Device.d.ts +22 -4
  30. package/dist/device/Device.d.ts.map +1 -1
  31. package/dist/events/device.d.ts +4 -0
  32. package/dist/events/device.d.ts.map +1 -1
  33. package/dist/events/logBlockEvent.d.ts.map +1 -1
  34. package/dist/events/ui-request.d.ts +27 -2
  35. package/dist/events/ui-request.d.ts.map +1 -1
  36. package/dist/index.d.ts +88 -7
  37. package/dist/index.js +937 -604
  38. package/dist/inject.d.ts.map +1 -1
  39. package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
  40. package/dist/protocols/protocol-v2/uiInteraction.d.ts +3 -3
  41. package/dist/protocols/protocol-v2/uiInteraction.d.ts.map +1 -1
  42. package/dist/protocols/protocol-v2/unlockPolicy.d.ts +1 -3
  43. package/dist/protocols/protocol-v2/unlockPolicy.d.ts.map +1 -1
  44. package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts +22 -0
  45. package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts.map +1 -0
  46. package/dist/protocols/protocol-v2/walletSession.d.ts +4 -1
  47. package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
  48. package/dist/types/api/index.d.ts +2 -1
  49. package/dist/types/api/index.d.ts.map +1 -1
  50. package/dist/types/api/protocolV2.d.ts +3 -0
  51. package/dist/types/api/protocolV2.d.ts.map +1 -1
  52. package/dist/utils/deviceFeaturesUtils.d.ts +2 -0
  53. package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
  54. package/dist/utils/homescreen.d.ts +4 -0
  55. package/dist/utils/homescreen.d.ts.map +1 -1
  56. package/dist/utils/index.d.ts +1 -1
  57. package/dist/utils/index.d.ts.map +1 -1
  58. package/dist/utils/patch.d.ts +1 -1
  59. package/dist/utils/patch.d.ts.map +1 -1
  60. package/dist/utils/pro2Nft.d.ts +29 -0
  61. package/dist/utils/pro2Nft.d.ts.map +1 -0
  62. package/dist/utils/pro2Wallpaper.d.ts +10 -0
  63. package/dist/utils/pro2Wallpaper.d.ts.map +1 -1
  64. package/package.json +4 -4
  65. package/src/api/BaseMethod.ts +8 -10
  66. package/src/api/FirmwareUpdateV4.ts +13 -6
  67. package/src/api/GetPassphraseState.ts +7 -1
  68. package/src/api/OpenWalletSession.ts +54 -17
  69. package/src/api/allnetwork/AllNetworkGetAddressBase.ts +32 -11
  70. package/src/api/device/DeviceUnlock.ts +1 -1
  71. package/src/api/helpers/protocolV2FileWrite.ts +11 -4
  72. package/src/api/index.ts +1 -0
  73. package/src/api/protocol-v2/DeviceUploadNft.ts +166 -0
  74. package/src/api/protocol-v2/ProtocolInfoRequest.ts +3 -1
  75. package/src/core/deviceEventRegistration.ts +4 -0
  76. package/src/core/index.ts +111 -74
  77. package/src/data/messages/messages-protocol-v2.json +10 -0
  78. package/src/device/Device.ts +221 -24
  79. package/src/events/device.ts +4 -0
  80. package/src/events/logBlockEvent.ts +1 -0
  81. package/src/events/ui-request.ts +32 -2
  82. package/src/inject.ts +1 -0
  83. package/src/protocols/protocol-v2/features.ts +9 -2
  84. package/src/protocols/protocol-v2/uiInteraction.ts +31 -5
  85. package/src/protocols/protocol-v2/unlockPolicy.ts +1 -105
  86. package/src/protocols/protocol-v2/unlockPolicyRunner.ts +117 -0
  87. package/src/protocols/protocol-v2/walletSession.ts +93 -18
  88. package/src/types/api/index.ts +2 -0
  89. package/src/types/api/protocolV2.ts +13 -0
  90. package/src/utils/deviceFeaturesUtils.ts +4 -0
  91. package/src/utils/homescreen.ts +32 -6
  92. package/src/utils/index.ts +6 -1
  93. package/src/utils/pro2Nft.ts +91 -0
  94. package/src/utils/pro2Wallpaper.ts +35 -8
  95. package/dist/protocols/protocol-v2/lockedError.d.ts +0 -2
  96. package/dist/protocols/protocol-v2/lockedError.d.ts.map +0 -1
  97. package/dist/protocols/protocol-v2/unlockRetry.d.ts +0 -10
  98. package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +0 -1
  99. package/src/protocols/protocol-v2/lockedError.ts +0 -10
  100. package/src/protocols/protocol-v2/unlockRetry.ts +0 -109
package/dist/index.js CHANGED
@@ -8,9 +8,9 @@ var hdShared = require('@onekeyfe/hd-shared');
8
8
  var axios = require('axios');
9
9
  var lodash = require('lodash');
10
10
  var ByteBuffer = require('bytebuffer');
11
- var BigNumber = require('bignumber.js');
12
- var utils = require('@noble/hashes/utils');
13
11
  var blake2s = require('@noble/hashes/blake2s');
12
+ var utils = require('@noble/hashes/utils');
13
+ var BigNumber = require('bignumber.js');
14
14
  var sha256 = require('@noble/hashes/sha256');
15
15
  var JSZip = require('jszip');
16
16
  var sha3 = require('@noble/hashes/sha3');
@@ -146,6 +146,7 @@ const createCoreApi = (call) => ({
146
146
  deviceReboot: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'deviceReboot' })),
147
147
  deviceGetOnboardingStatus: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'deviceGetOnboardingStatus' })),
148
148
  deviceUploadWallpaper: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'deviceUploadWallpaper' })),
149
+ deviceUploadNft: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'deviceUploadNft' })),
149
150
  uploadPortfolio: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'uploadPortfolio' })),
150
151
  deviceRecovery: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'deviceRecovery' })),
151
152
  deviceReset: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'deviceReset' })),
@@ -26271,6 +26272,7 @@ var nested = {
26271
26272
  MessageType_DeviceSessionAskPin: 61202,
26272
26273
  MessageType_DeviceSessionAskPassphrase: 61203,
26273
26274
  MessageType_PortfolioUpdate: 61400,
26275
+ MessageType_NftUpdate: 61500,
26274
26276
  MessageType_OnboardingStatusGet: 61600,
26275
26277
  MessageType_OnboardingStatus: 61601
26276
26278
  },
@@ -38389,6 +38391,15 @@ var nested = {
38389
38391
  }
38390
38392
  }
38391
38393
  },
38394
+ NftUpdate: {
38395
+ fields: {
38396
+ file_name_no_ext: {
38397
+ rule: "required",
38398
+ type: "string",
38399
+ id: 1
38400
+ }
38401
+ }
38402
+ },
38392
38403
  OnboardingStep: {
38393
38404
  values: {
38394
38405
  ONBOARDING_STEP_UNKNOWN: 0,
@@ -39930,6 +39941,8 @@ const DEVICE = {
39930
39941
  LOADING: 'device-loading',
39931
39942
  BUTTON: 'button',
39932
39943
  PIN: 'pin',
39944
+ PIN_ON_DEVICE: 'pin_on_device',
39945
+ PIN_ON_DEVICE_COMPLETE: 'pin_on_device_complete',
39933
39946
  PASSPHRASE: 'passphrase',
39934
39947
  PASSPHRASE_ON_DEVICE: 'passphrase_on_device',
39935
39948
  ATTACH_PIN_ON_DEVICE: 'attach_pin_on_device',
@@ -39965,6 +39978,7 @@ const LogBlockEvent = new Set([
39965
39978
  ]);
39966
39979
  const LogLabelMethod = new Set([
39967
39980
  'openWalletSession',
39981
+ 'deviceUploadNft',
39968
39982
  'deviceUploadWallpaper',
39969
39983
  'uploadPortfolio',
39970
39984
  'fileWrite',
@@ -40087,9 +40101,7 @@ function refreshProtocolV2DeviceStatus(device) {
40087
40101
  });
40088
40102
  }
40089
40103
  const negotiateEventlessWalletSession = (device) => __awaiter(void 0, void 0, void 0, function* () {
40090
- yield device.commands.typedCall('ProtocolInfoRequest', 'ProtocolInfo', {
40091
- eventless_wallet_session: true,
40092
- });
40104
+ yield device.ensureProtocolV2RuntimeContext();
40093
40105
  });
40094
40106
  const getDeviceSession = (device, request) => __awaiter(void 0, void 0, void 0, function* () { return device.commands.typedCall('DeviceSessionGet', 'DeviceSession', request); });
40095
40107
  const askDevicePassphrase = (device, requestPayload) => __awaiter(void 0, void 0, void 0, function* () {
@@ -40097,10 +40109,11 @@ const askDevicePassphrase = (device, requestPayload) => __awaiter(void 0, void 0
40097
40109
  yield refreshProtocolV2DeviceStatus(device);
40098
40110
  });
40099
40111
  const selectDeviceSession = (device, expectedPassphraseState) => __awaiter(void 0, void 0, void 0, function* () {
40100
- var _a;
40112
+ var _a, _b, _c;
40101
40113
  const existsAttachPinUser = ((_a = device.features) === null || _a === void 0 ? void 0 : _a.attachToPinEnabled) === true;
40102
40114
  const metadata = Object.assign({ source: 'wallet-session-coordinator', reason: expectedPassphraseState ? 'session-recovery' : 'open-wallet' }, (expectedPassphraseState ? { expectedPassphraseState } : {}));
40103
- const response = yield device.commands.promptPassphrase(Object.assign({ existsAttachPinUser, deviceOnly: false }, metadata), { cancelDeviceOnReject: false });
40115
+ const passphraseInteraction = (_b = device.createProtocolV2UiPhaseMetadata) === null || _b === void 0 ? void 0 : _b.call(device, 'passphrase', 'start');
40116
+ const response = yield device.commands.promptPassphrase(Object.assign(Object.assign({ existsAttachPinUser, deviceOnly: false }, metadata), (passphraseInteraction ? { interaction: passphraseInteraction } : {})), { cancelDeviceOnReject: false });
40104
40117
  const hostPassphrase = typeof response.passphrase === 'string' ? response.passphrase.normalize('NFKD') : undefined;
40105
40118
  const hasHostPassphrase = typeof hostPassphrase === 'string' && hostPassphrase.length > 0;
40106
40119
  const hostPassphraseByteLength = hasHostPassphrase ? utf8ByteLength(hostPassphrase) : undefined;
@@ -40122,8 +40135,12 @@ const selectDeviceSession = (device, expectedPassphraseState) => __awaiter(void
40122
40135
  if (!existsAttachPinUser) {
40123
40136
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Attach PIN wallet selection is unavailable on this device.');
40124
40137
  }
40125
- device.emit(DEVICE.ATTACH_PIN_ON_DEVICE, device, metadata);
40126
- yield device.unlockDevice(hdTransport.DeviceSessionPinType.AttachToPin);
40138
+ const attachPinInteraction = (_c = device.createProtocolV2UiPhaseMetadata) === null || _c === void 0 ? void 0 : _c.call(device, 'pin', 'start');
40139
+ device.emit(DEVICE.ATTACH_PIN_ON_DEVICE, device, Object.assign(Object.assign({}, metadata), (attachPinInteraction ? { interaction: attachPinInteraction } : {})));
40140
+ yield device.unlockDevice(hdTransport.DeviceSessionPinType.AttachToPin, {
40141
+ emitUiEvent: false,
40142
+ interaction: attachPinInteraction,
40143
+ });
40127
40144
  return getDeviceSession(device, {});
40128
40145
  }
40129
40146
  if (hasHostPassphrase) {
@@ -40133,12 +40150,12 @@ const selectDeviceSession = (device, expectedPassphraseState) => __awaiter(void
40133
40150
  });
40134
40151
  return getDeviceSession(device, {});
40135
40152
  }
40136
- device.emit(DEVICE.PASSPHRASE_ON_DEVICE, device, metadata);
40153
+ device.emit(DEVICE.PASSPHRASE_ON_DEVICE, device, Object.assign(Object.assign({}, metadata), (passphraseInteraction ? { interaction: passphraseInteraction } : {})));
40137
40154
  yield askDevicePassphrase(device, { on_device: true });
40138
40155
  return getDeviceSession(device, {});
40139
40156
  });
40140
40157
  function getProtocolV2WalletSession(device, options) {
40141
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
40158
+ var _a, _b, _c, _d, _e, _f, _g;
40142
40159
  return __awaiter(this, void 0, void 0, function* () {
40143
40160
  const forceWalletSelection = (options === null || options === void 0 ? void 0 : options.forceWalletSelection) === true || (options === null || options === void 0 ? void 0 : options.initSession) === true;
40144
40161
  if (forceWalletSelection) {
@@ -40165,12 +40182,45 @@ function getProtocolV2WalletSession(device, options) {
40165
40182
  : undefined;
40166
40183
  let response;
40167
40184
  let resumed = false;
40185
+ let mainWalletSelected = false;
40186
+ const clearCurrentWalletSession = () => {
40187
+ var _a;
40188
+ if (options === null || options === void 0 ? void 0 : options.onlyMainPin) {
40189
+ (_a = device.clearStandardInternalState) === null || _a === void 0 ? void 0 : _a.call(device);
40190
+ }
40191
+ else {
40192
+ device.clearInternalState();
40193
+ }
40194
+ };
40195
+ const rejectMismatchedAttachPinWallet = () => __awaiter(this, void 0, void 0, function* () {
40196
+ const features = yield refreshProtocolV2DeviceStatus(device);
40197
+ if (features.unlockedAttachPin !== true) {
40198
+ return;
40199
+ }
40200
+ try {
40201
+ yield device.lockDevice();
40202
+ }
40203
+ catch (_h) {
40204
+ }
40205
+ clearCurrentWalletSession();
40206
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckUnlockTypeError);
40207
+ });
40208
+ const selectMainWallet = (force = false) => __awaiter(this, void 0, void 0, function* () {
40209
+ if (force || !mainWalletSelected) {
40210
+ yield device.unlockDevice(hdTransport.DeviceSessionPinType.Main, {
40211
+ source: 'wallet-session-coordinator',
40212
+ reason: expectedPassphraseState ? 'session-recovery' : 'open-wallet',
40213
+ deviceOnly: true,
40214
+ });
40215
+ mainWalletSelected = true;
40216
+ }
40217
+ });
40168
40218
  if (options === null || options === void 0 ? void 0 : options.onlyMainPin) {
40169
40219
  expectedPassphraseState = cachedStandardSession === null || cachedStandardSession === void 0 ? void 0 : cachedStandardSession.passphraseState;
40170
40220
  if (cachedStandardSession) {
40171
40221
  try {
40172
- if (((_d = device.features) === null || _d === void 0 ? void 0 : _d.unlockedAttachPin) === true) {
40173
- yield device.unlockDevice(hdTransport.DeviceSessionPinType.Main);
40222
+ if (options === null || options === void 0 ? void 0 : options.selectMainWalletBeforeRestore) {
40223
+ yield selectMainWallet();
40174
40224
  }
40175
40225
  response = yield getDeviceSession(device, {
40176
40226
  session_id: cachedStandardSession.sessionId,
@@ -40178,7 +40228,7 @@ function getProtocolV2WalletSession(device, options) {
40178
40228
  resumed = true;
40179
40229
  }
40180
40230
  catch (error) {
40181
- (_e = device.clearStandardInternalState) === null || _e === void 0 ? void 0 : _e.call(device);
40231
+ (_d = device.clearStandardInternalState) === null || _d === void 0 ? void 0 : _d.call(device);
40182
40232
  if (!isWalletSessionInvalidError(error)) {
40183
40233
  throw error;
40184
40234
  }
@@ -40186,13 +40236,15 @@ function getProtocolV2WalletSession(device, options) {
40186
40236
  }
40187
40237
  }
40188
40238
  if (!response) {
40189
- yield device.unlockDevice(hdTransport.DeviceSessionPinType.Main);
40239
+ yield selectMainWallet();
40190
40240
  response = yield getDeviceSession(device, {});
40191
40241
  }
40192
40242
  }
40193
40243
  else if (cachedSessionId && expectedPassphraseState) {
40194
40244
  try {
40195
- response = yield getDeviceSession(device, { session_id: cachedSessionId });
40245
+ response = yield getDeviceSession(device, {
40246
+ session_id: cachedSessionId,
40247
+ });
40196
40248
  resumed = true;
40197
40249
  }
40198
40250
  catch (error) {
@@ -40203,6 +40255,16 @@ function getProtocolV2WalletSession(device, options) {
40203
40255
  resumed = false;
40204
40256
  }
40205
40257
  }
40258
+ else if (expectedPassphraseState) {
40259
+ try {
40260
+ response = yield getDeviceSession(device, {});
40261
+ }
40262
+ catch (error) {
40263
+ if ((options === null || options === void 0 ? void 0 : options.resumeOnly) || !isWalletSessionInvalidError(error)) {
40264
+ throw error;
40265
+ }
40266
+ }
40267
+ }
40206
40268
  if (!response) {
40207
40269
  if (options === null || options === void 0 ? void 0 : options.resumeOnly) {
40208
40270
  device.clearInternalState();
@@ -40216,7 +40278,7 @@ function getProtocolV2WalletSession(device, options) {
40216
40278
  }
40217
40279
  catch (error) {
40218
40280
  if (options === null || options === void 0 ? void 0 : options.onlyMainPin) {
40219
- (_f = device.clearStandardInternalState) === null || _f === void 0 ? void 0 : _f.call(device);
40281
+ (_e = device.clearStandardInternalState) === null || _e === void 0 ? void 0 : _e.call(device);
40220
40282
  }
40221
40283
  else {
40222
40284
  device.clearInternalState();
@@ -40225,13 +40287,14 @@ function getProtocolV2WalletSession(device, options) {
40225
40287
  }
40226
40288
  if (expectedPassphraseState && expectedPassphraseState !== message.btc_test_address) {
40227
40289
  resumed = false;
40290
+ yield rejectMismatchedAttachPinWallet();
40228
40291
  if (options === null || options === void 0 ? void 0 : options.resumeOnly) {
40229
40292
  device.clearInternalState();
40230
40293
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.WalletSessionInvalid);
40231
40294
  }
40232
40295
  if (options === null || options === void 0 ? void 0 : options.onlyMainPin) {
40233
- (_g = device.clearStandardInternalState) === null || _g === void 0 ? void 0 : _g.call(device);
40234
- yield device.unlockDevice(hdTransport.DeviceSessionPinType.Main);
40296
+ (_f = device.clearStandardInternalState) === null || _f === void 0 ? void 0 : _f.call(device);
40297
+ yield selectMainWallet(true);
40235
40298
  response = yield getDeviceSession(device, {});
40236
40299
  }
40237
40300
  else {
@@ -40244,7 +40307,7 @@ function getProtocolV2WalletSession(device, options) {
40244
40307
  }
40245
40308
  catch (error) {
40246
40309
  if (options === null || options === void 0 ? void 0 : options.onlyMainPin) {
40247
- (_h = device.clearStandardInternalState) === null || _h === void 0 ? void 0 : _h.call(device);
40310
+ (_g = device.clearStandardInternalState) === null || _g === void 0 ? void 0 : _g.call(device);
40248
40311
  }
40249
40312
  else {
40250
40313
  device.clearInternalState();
@@ -40252,12 +40315,8 @@ function getProtocolV2WalletSession(device, options) {
40252
40315
  throw error;
40253
40316
  }
40254
40317
  if (expectedPassphraseState !== message.btc_test_address) {
40255
- if (options === null || options === void 0 ? void 0 : options.onlyMainPin) {
40256
- (_j = device.clearStandardInternalState) === null || _j === void 0 ? void 0 : _j.call(device);
40257
- }
40258
- else {
40259
- device.clearInternalState();
40260
- }
40318
+ yield rejectMismatchedAttachPinWallet();
40319
+ clearCurrentWalletSession();
40261
40320
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckPassphraseStateError);
40262
40321
  }
40263
40322
  }
@@ -40277,19 +40336,11 @@ function getProtocolV2WalletSession(device, options) {
40277
40336
  return {
40278
40337
  passphraseState: message.btc_test_address,
40279
40338
  newSession: message.session_id,
40280
- unlockedAttachPin: (_l = (_k = device.features) === null || _k === void 0 ? void 0 : _k.unlockedAttachPin) !== null && _l !== void 0 ? _l : undefined,
40339
+ unlockedAttachPin: mainWalletSelected ? false : undefined,
40281
40340
  resumed,
40282
40341
  };
40283
40342
  });
40284
40343
  }
40285
- function restoreProtocolV2WalletSession(device, expectedPassphraseState) {
40286
- return __awaiter(this, void 0, void 0, function* () {
40287
- return getProtocolV2WalletSession(device, {
40288
- expectedPassphraseState,
40289
- resumeOnly: true,
40290
- });
40291
- });
40292
- }
40293
40344
 
40294
40345
  const getSupportProtocolV1MessageSchema = (features) => {
40295
40346
  var _a;
@@ -40351,6 +40402,7 @@ const getPassphraseStateWithRefreshDeviceInfo = (device, options) => __awaiter(v
40351
40402
  initSession: options === null || options === void 0 ? void 0 : options.initSession,
40352
40403
  expectedPassphraseState: options === null || options === void 0 ? void 0 : options.expectPassphraseState,
40353
40404
  onlyMainPin: options === null || options === void 0 ? void 0 : options.onlyMainPin,
40405
+ deriveCardano: options === null || options === void 0 ? void 0 : options.deriveCardano,
40354
40406
  });
40355
40407
  }
40356
40408
  const { features } = device;
@@ -40393,6 +40445,7 @@ const getPassphraseState = (device, options) => __awaiter(void 0, void 0, void 0
40393
40445
  initSession: options === null || options === void 0 ? void 0 : options.initSession,
40394
40446
  expectedPassphraseState: options === null || options === void 0 ? void 0 : options.expectPassphraseState,
40395
40447
  onlyMainPin: options === null || options === void 0 ? void 0 : options.onlyMainPin,
40448
+ deriveCardano: options === null || options === void 0 ? void 0 : options.deriveCardano,
40396
40449
  });
40397
40450
  }
40398
40451
  const supportAttachPinCapability = existCapability(features, hdTransport.Enum_Capability.Capability_AttachToPin);
@@ -40887,7 +40940,8 @@ function asBytes(rgba) {
40887
40940
  function align(value, boundary) {
40888
40941
  return Math.ceil(value / boundary) * boundary;
40889
40942
  }
40890
- function encodePro2Wallpaper(options) {
40943
+ function encodePro2Image(options) {
40944
+ var _a;
40891
40945
  const { width, height } = options;
40892
40946
  if (!Number.isInteger(width) || width <= 0 || width > 0xffff) {
40893
40947
  throw invalidParameter$2('Wallpaper width must be an integer between 1 and 65535.');
@@ -40900,11 +40954,14 @@ function encodePro2Wallpaper(options) {
40900
40954
  if (rgba.byteLength !== expectedLength) {
40901
40955
  throw invalidParameter$2(`Wallpaper RGBA data length must be ${expectedLength} bytes, received ${rgba.byteLength}.`);
40902
40956
  }
40957
+ const alphaMode = (_a = options.alphaMode) !== null && _a !== void 0 ? _a : 'preserve';
40903
40958
  let hasTransparency = false;
40904
- for (let index = 3; index < rgba.length; index += 4) {
40905
- if (rgba[index] !== 0xff) {
40906
- hasTransparency = true;
40907
- break;
40959
+ if (alphaMode === 'preserve') {
40960
+ for (let index = 3; index < rgba.length; index += 4) {
40961
+ if (rgba[index] !== 0xff) {
40962
+ hasTransparency = true;
40963
+ break;
40964
+ }
40908
40965
  }
40909
40966
  }
40910
40967
  const colorFormat = hasTransparency ? 'RGB565A8' : 'RGB565';
@@ -40925,9 +40982,19 @@ function encodePro2Wallpaper(options) {
40925
40982
  for (let x = 0; x < width; x += 1) {
40926
40983
  const sourceOffset = (y * width + x) * 4;
40927
40984
  const thresholdIndex = ((y & 7) << 3) + (x & 7);
40928
- const red = Math.min(rgba[sourceOffset] + RED_THRESHOLD[thresholdIndex], 0xff) & 0xf8;
40929
- const green = Math.min(rgba[sourceOffset + 1] + GREEN_THRESHOLD[thresholdIndex], 0xff) & 0xfc;
40930
- const blue = Math.min(rgba[sourceOffset + 2] + BLUE_THRESHOLD[thresholdIndex], 0xff) & 0xf8;
40985
+ const alpha = rgba[sourceOffset + 3];
40986
+ const redChannel = alphaMode === 'black-background'
40987
+ ? Math.round((rgba[sourceOffset] * alpha) / 0xff)
40988
+ : rgba[sourceOffset];
40989
+ const greenChannel = alphaMode === 'black-background'
40990
+ ? Math.round((rgba[sourceOffset + 1] * alpha) / 0xff)
40991
+ : rgba[sourceOffset + 1];
40992
+ const blueChannel = alphaMode === 'black-background'
40993
+ ? Math.round((rgba[sourceOffset + 2] * alpha) / 0xff)
40994
+ : rgba[sourceOffset + 2];
40995
+ const red = Math.min(redChannel + RED_THRESHOLD[thresholdIndex], 0xff) & 0xf8;
40996
+ const green = Math.min(greenChannel + GREEN_THRESHOLD[thresholdIndex], 0xff) & 0xfc;
40997
+ const blue = Math.min(blueChannel + BLUE_THRESHOLD[thresholdIndex], 0xff) & 0xf8;
40931
40998
  const rgb565 = ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);
40932
40999
  const rgbOffset = 12 + y * stride + x * 2;
40933
41000
  data[rgbOffset] = rgb565 & 0xff;
@@ -40939,6 +41006,148 @@ function encodePro2Wallpaper(options) {
40939
41006
  }
40940
41007
  return { data, colorFormat };
40941
41008
  }
41009
+ function encodePro2Wallpaper(options) {
41010
+ return encodePro2Image(options);
41011
+ }
41012
+
41013
+ const invalidParameter$1 = (message) => hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, message);
41014
+ function validateNonEmptyString(value, name) {
41015
+ if (typeof value !== 'string' || value.trim().length === 0) {
41016
+ throw invalidParameter$1(`Parameter [${name}] is required and must be a non-empty string.`);
41017
+ }
41018
+ return value;
41019
+ }
41020
+ const PROTOCOL_V2_FILESYSTEM_VOLUMES = new Set(['vol0', 'vol1']);
41021
+ const MAX_PROTOCOL_V2_FILESYSTEM_PATH_BYTES = 127;
41022
+ function getUtf8ByteLength$1(value) {
41023
+ return Array.from(value).reduce((length, character) => {
41024
+ var _a;
41025
+ const codePoint = (_a = character.codePointAt(0)) !== null && _a !== void 0 ? _a : 0;
41026
+ if (codePoint <= 0x7f)
41027
+ return length + 1;
41028
+ if (codePoint <= 0x7ff)
41029
+ return length + 2;
41030
+ if (codePoint <= 0xffff)
41031
+ return length + 3;
41032
+ return length + 4;
41033
+ }, 0);
41034
+ }
41035
+ function validateProtocolV2FilesystemPath(value, name, options = {}) {
41036
+ const rawPath = validateNonEmptyString(value, name).trim();
41037
+ const containsUnsupportedCharacter = Array.from(rawPath).some(character => {
41038
+ const codePoint = character.charCodeAt(0);
41039
+ return codePoint <= 0x1f || codePoint === 0x7f || character === '\\';
41040
+ });
41041
+ if (containsUnsupportedCharacter) {
41042
+ throw invalidParameter$1(`Parameter [${name}] contains unsupported path characters.`);
41043
+ }
41044
+ const match = /^([a-zA-Z0-9]+):(.*)$/.exec(rawPath);
41045
+ if (!match) {
41046
+ throw invalidParameter$1(`Parameter [${name}] must use a supported Protocol V2 filesystem volume.`);
41047
+ }
41048
+ const volume = match[1].toLowerCase();
41049
+ if (!PROTOCOL_V2_FILESYSTEM_VOLUMES.has(volume)) {
41050
+ throw invalidParameter$1(`Parameter [${name}] uses an unsupported filesystem volume.`);
41051
+ }
41052
+ const rawSuffix = match[2];
41053
+ if (rawSuffix.length === 0) {
41054
+ if (options.allowVolumeRoot)
41055
+ return `${volume}:`;
41056
+ throw invalidParameter$1(`Parameter [${name}] must identify a filesystem entry.`);
41057
+ }
41058
+ const suffix = rawSuffix.startsWith('/') ? rawSuffix : `/${rawSuffix}`;
41059
+ const segments = suffix.slice(1).split('/');
41060
+ if (segments.some(segment => segment.length === 0 || segment === '.' || segment === '..')) {
41061
+ throw invalidParameter$1(`Parameter [${name}] contains an invalid path segment.`);
41062
+ }
41063
+ const canonicalPath = `${volume}:${rawSuffix.startsWith('/') ? '/' : ''}${segments.join('/')}`;
41064
+ if (getUtf8ByteLength$1(canonicalPath) > MAX_PROTOCOL_V2_FILESYSTEM_PATH_BYTES) {
41065
+ throw invalidParameter$1(`Parameter [${name}] exceeds the maximum filesystem path length.`);
41066
+ }
41067
+ return canonicalPath;
41068
+ }
41069
+ function validateNonNegativeInteger(value, name, defaultValue) {
41070
+ if (value === undefined || value === null) {
41071
+ if (defaultValue !== undefined)
41072
+ return defaultValue;
41073
+ throw invalidParameter$1(`Missing required parameter: ${name}`);
41074
+ }
41075
+ const numeric = typeof value === 'string' && value.trim() !== '' ? Number(value) : value;
41076
+ if (typeof numeric !== 'number' || !Number.isSafeInteger(numeric) || numeric < 0) {
41077
+ throw invalidParameter$1(`Parameter [${name}] must be a non-negative integer.`);
41078
+ }
41079
+ return numeric;
41080
+ }
41081
+ function validateOptionalNonNegativeInteger(value, name) {
41082
+ if (value === undefined || value === null)
41083
+ return undefined;
41084
+ return validateNonNegativeInteger(value, name);
41085
+ }
41086
+ function validateOptionalPercentage(value, name) {
41087
+ const numeric = validateOptionalNonNegativeInteger(value, name);
41088
+ if (numeric === undefined)
41089
+ return undefined;
41090
+ if (numeric > 100) {
41091
+ throw invalidParameter$1(`Parameter [${name}] must be between 0 and 100.`);
41092
+ }
41093
+ return numeric;
41094
+ }
41095
+ function validateRequiredData(value, name) {
41096
+ if (value === undefined || value === null) {
41097
+ throw invalidParameter$1(`Missing required parameter: ${name}`);
41098
+ }
41099
+ }
41100
+
41101
+ const PRO2_NFT_IMAGE_WIDTH = 540;
41102
+ const PRO2_NFT_IMAGE_HEIGHT = 540;
41103
+ const PRO2_NFT_THUMBNAIL_WIDTH = 263;
41104
+ const PRO2_NFT_THUMBNAIL_HEIGHT = 263;
41105
+ const PRO2_NFT_DIRECTORY = 'vol1:/nft';
41106
+ const PRO2_NFT_DEFAULT_CHUNK_SIZE = 512;
41107
+ const PRO2_NFT_DEFAULT_PACE_MS = 20;
41108
+ const PRO2_NFT_DEFAULT_TIMEOUT_MS = 15000;
41109
+ const PRO2_NFT_MIN_CHUNK_SIZE = 64;
41110
+ const PRO2_NFT_MAX_CHUNK_SIZE = 2048;
41111
+ function utf8Length(value) {
41112
+ return new TextEncoder().encode(value).byteLength;
41113
+ }
41114
+ function assertImage(name, image, expectedWidth, expectedHeight) {
41115
+ if (image.width !== expectedWidth || image.height !== expectedHeight) {
41116
+ throw invalidParameter$1(`Pro2 NFT ${name} dimensions must be ${expectedWidth}x${expectedHeight}.`);
41117
+ }
41118
+ if (!(image.rgba instanceof ArrayBuffer) && !ArrayBuffer.isView(image.rgba)) {
41119
+ throw invalidParameter$1(`Parameter [${name}.rgba] must be an ArrayBuffer or Uint8Array.`);
41120
+ }
41121
+ }
41122
+ function buildPro2NftBundle(options) {
41123
+ const { image, thumbnail, title, subtitle, timestampMs } = options;
41124
+ assertImage('image', image, PRO2_NFT_IMAGE_WIDTH, PRO2_NFT_IMAGE_HEIGHT);
41125
+ assertImage('thumbnail', thumbnail, PRO2_NFT_THUMBNAIL_WIDTH, PRO2_NFT_THUMBNAIL_HEIGHT);
41126
+ const titleLength = typeof title === 'string' ? utf8Length(title) : 0;
41127
+ const subtitleLength = typeof subtitle === 'string' ? utf8Length(subtitle) : Number.POSITIVE_INFINITY;
41128
+ if (titleLength < 1 || titleLength > 63) {
41129
+ throw invalidParameter$1('Pro2 NFT title must contain 1 to 63 UTF-8 bytes.');
41130
+ }
41131
+ if (subtitleLength > 95) {
41132
+ throw invalidParameter$1('Pro2 NFT subtitle must contain at most 95 UTF-8 bytes.');
41133
+ }
41134
+ if (!Number.isSafeInteger(timestampMs) || timestampMs <= 0) {
41135
+ throw invalidParameter$1('Parameter [timestampMs] must be a positive safe integer.');
41136
+ }
41137
+ const encodedImage = encodePro2Image(Object.assign(Object.assign({}, image), { alphaMode: 'black-background' })).data;
41138
+ const encodedThumbnail = encodePro2Image(Object.assign(Object.assign({}, thumbnail), { alphaMode: 'black-background' })).data;
41139
+ const metadata = new TextEncoder().encode(JSON.stringify({ title, subtitle }));
41140
+ if (metadata.byteLength === 0 || metadata.byteLength > 512) {
41141
+ throw invalidParameter$1('Pro2 NFT metadata must contain 1 to 512 UTF-8 bytes.');
41142
+ }
41143
+ const hash8 = utils.bytesToHex(blake2s.blake2s(encodedImage)).slice(0, 8);
41144
+ return {
41145
+ basename: `nft-${hash8}-${timestampMs}`,
41146
+ image: encodedImage,
41147
+ thumbnail: encodedThumbnail,
41148
+ metadata,
41149
+ };
41150
+ }
40942
41151
 
40943
41152
  const getT1Data = () => ({
40944
41153
  default: {
@@ -41222,14 +41431,27 @@ const getHomeScreenDefaultList = (features) => {
41222
41431
  }
41223
41432
  return Object.keys(data);
41224
41433
  };
41434
+ const getNftSize = ({ deviceType, thumbnail, }) => {
41435
+ var _a;
41436
+ const sizes = {
41437
+ touch: {
41438
+ full: { width: 480, height: 800 },
41439
+ thumbnail: { width: 238, height: 238 },
41440
+ },
41441
+ pro: {
41442
+ full: { width: 480, height: 800 },
41443
+ thumbnail: { width: 226, height: 226, radius: 40 },
41444
+ },
41445
+ pro2: {
41446
+ full: { width: PRO2_NFT_IMAGE_WIDTH, height: PRO2_NFT_IMAGE_HEIGHT },
41447
+ thumbnail: { width: PRO2_NFT_THUMBNAIL_WIDTH, height: PRO2_NFT_THUMBNAIL_HEIGHT },
41448
+ },
41449
+ };
41450
+ return (_a = sizes[deviceType]) === null || _a === void 0 ? void 0 : _a[thumbnail ? 'thumbnail' : 'full'];
41451
+ };
41225
41452
  const getHomeScreenSize = ({ deviceType, homeScreenType, thumbnail, }) => {
41226
41453
  if (deviceType === hdShared.EDeviceType.Pro2) {
41227
- return thumbnail
41228
- ? undefined
41229
- : {
41230
- width: PRO2_WALLPAPER_WIDTH,
41231
- height: PRO2_WALLPAPER_HEIGHT,
41232
- };
41454
+ return thumbnail ? undefined : { width: PRO2_WALLPAPER_WIDTH, height: PRO2_WALLPAPER_HEIGHT };
41233
41455
  }
41234
41456
  const sizes = {
41235
41457
  touch: {
@@ -43025,8 +43247,10 @@ const PROTOCOL_V2_DEVICE_INFO_TIMEOUT_MS = 10 * 1000;
43025
43247
  function requestProtocolV2ProtocolInfo({ commands, timeoutMs, }) {
43026
43248
  return __awaiter(this, void 0, void 0, function* () {
43027
43249
  const response = timeoutMs === undefined
43028
- ? yield commands.typedCall('ProtocolInfoRequest', 'ProtocolInfo', {})
43029
- : yield commands.typedCall('ProtocolInfoRequest', 'ProtocolInfo', {}, { timeoutMs });
43250
+ ? yield commands.typedCall('ProtocolInfoRequest', 'ProtocolInfo', {
43251
+ eventless_wallet_session: true,
43252
+ })
43253
+ : yield commands.typedCall('ProtocolInfoRequest', 'ProtocolInfo', { eventless_wallet_session: true }, { timeoutMs });
43030
43254
  return response.message;
43031
43255
  });
43032
43256
  }
@@ -43054,6 +43278,22 @@ const parseRunOptions = (options) => {
43054
43278
  return options;
43055
43279
  };
43056
43280
  const Log$e = getLogger(exports.LoggerNames.Device);
43281
+ const isProtocolV2DeviceStatusUnsupportedError = (error) => {
43282
+ var _a, _b, _c;
43283
+ if (error instanceof hdShared.HardwareError) {
43284
+ if (error.errorCode === hdShared.HardwareErrorCode.DeviceNotSupportMethod) {
43285
+ return true;
43286
+ }
43287
+ if (((_a = error.params) === null || _a === void 0 ? void 0 : _a.failureCode) === 'Failure_UnexpectedMessage') {
43288
+ return true;
43289
+ }
43290
+ }
43291
+ const message = error instanceof Error
43292
+ ? error.message
43293
+ : String((_c = (_b = error === null || error === void 0 ? void 0 : error.message) !== null && _b !== void 0 ? _b : error) !== null && _c !== void 0 ? _c : '');
43294
+ return (/^Failure_UnexpectedMessage(?:,|\b)/i.test(message) ||
43295
+ /\b(?:unsupported message|handler not registered|message handler not found)\b/i.test(message));
43296
+ };
43057
43297
  function preloadSessionCache(deviceId, passphraseState, sessionId) {
43058
43298
  deviceWalletSessionStore.set(deviceId, passphraseState, sessionId);
43059
43299
  }
@@ -43086,6 +43326,7 @@ class Device extends events.exports {
43086
43326
  this.deviceAcquired = false;
43087
43327
  this.stateStore = new DeviceStateStore();
43088
43328
  this.protocolV2StateNeedsReload = false;
43329
+ this.protocolV2UiInteractionCounter = 0;
43089
43330
  this.externalState = [];
43090
43331
  this.unavailableCapabilities = {};
43091
43332
  this.instance = 0;
@@ -43644,11 +43885,7 @@ class Device extends events.exports {
43644
43885
  }
43645
43886
  }
43646
43887
  if (refresh.has('status') && !initializedWithDeviceInfo) {
43647
- const deviceInfo = refreshedDeviceInfo !== null && refreshedDeviceInfo !== void 0 ? refreshedDeviceInfo : (yield requestProtocolV2DeviceInfo({
43648
- commands: this.commands,
43649
- request: getProtocolV2DeviceInfoRequest(),
43650
- }));
43651
- yield this.probeProtocolV2RuntimeState(deviceInfo);
43888
+ yield this.probeProtocolV2RuntimeState(refreshedDeviceInfo);
43652
43889
  }
43653
43890
  if (refresh.has('settings') && ((_c = this.state) === null || _c === void 0 ? void 0 : _c.status.mode) === 'normal') {
43654
43891
  const { message } = yield this.commands.typedCall('DeviceSettingsGet', 'DeviceSettings', {});
@@ -43708,15 +43945,55 @@ class Device extends events.exports {
43708
43945
  this.updateState(mapFeaturesToState(normalized), source);
43709
43946
  return this.features;
43710
43947
  }
43948
+ ensureProtocolV2RuntimeContext(timeoutMs) {
43949
+ var _a, _b, _c, _d;
43950
+ return __awaiter(this, void 0, void 0, function* () {
43951
+ const cachedProtocolInfo = (_a = this.protocolV2RuntimeContext) !== null && _a !== void 0 ? _a : (!this.protocolV2StateNeedsReload
43952
+ ? (_d = (_c = (_b = this.state) === null || _b === void 0 ? void 0 : _b.raw) === null || _c === void 0 ? void 0 : _c.protocolV2ProtocolInfo) !== null && _d !== void 0 ? _d : undefined
43953
+ : undefined);
43954
+ if (cachedProtocolInfo) {
43955
+ this.protocolV2RuntimeContext = cachedProtocolInfo;
43956
+ return cachedProtocolInfo;
43957
+ }
43958
+ if (this.protocolV2RuntimeContextPromise) {
43959
+ return this.protocolV2RuntimeContextPromise;
43960
+ }
43961
+ const requestToken = {};
43962
+ const pendingRequest = (() => __awaiter(this, void 0, void 0, function* () {
43963
+ const protocolInfo = yield requestProtocolV2ProtocolInfo({
43964
+ commands: this.commands,
43965
+ timeoutMs,
43966
+ });
43967
+ if (this.protocolV2RuntimeContextRequestToken !== requestToken) {
43968
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInitializeFailed, 'Protocol V2 runtime context was invalidated while loading.');
43969
+ }
43970
+ this.protocolV2RuntimeContext = protocolInfo;
43971
+ return protocolInfo;
43972
+ }))();
43973
+ this.protocolV2RuntimeContextRequestToken = requestToken;
43974
+ this.protocolV2RuntimeContextPromise = pendingRequest;
43975
+ try {
43976
+ return yield pendingRequest;
43977
+ }
43978
+ finally {
43979
+ if (this.protocolV2RuntimeContextPromise === pendingRequest) {
43980
+ this.protocolV2RuntimeContextPromise = undefined;
43981
+ }
43982
+ if (this.protocolV2RuntimeContextRequestToken === requestToken) {
43983
+ this.protocolV2RuntimeContextRequestToken = undefined;
43984
+ }
43985
+ }
43986
+ });
43987
+ }
43711
43988
  probeProtocolV2RuntimeState(deviceInfo, timeoutMs) {
43712
- var _a;
43989
+ var _a, _b, _c;
43713
43990
  return __awaiter(this, void 0, void 0, function* () {
43714
- const protocolInfo = yield requestProtocolV2ProtocolInfo({
43715
- commands: this.commands,
43716
- timeoutMs,
43717
- });
43991
+ const protocolInfo = yield this.ensureProtocolV2RuntimeContext(timeoutMs);
43718
43992
  const runtimeMode = getProtocolV2RuntimeMode(protocolInfo);
43719
- const protocolV2DeviceType = resolveProtocolV2DeviceIdentity((_a = deviceInfo.hw) === null || _a === void 0 ? void 0 : _a.Device_type).deviceType;
43993
+ const runtimeDeviceInfo = deviceInfo !== null && deviceInfo !== void 0 ? deviceInfo : (_b = (_a = this.state) === null || _a === void 0 ? void 0 : _a.raw) === null || _b === void 0 ? void 0 : _b.protocolV2DeviceInfo;
43994
+ const protocolV2DeviceType = runtimeDeviceInfo
43995
+ ? resolveProtocolV2DeviceIdentity((_c = runtimeDeviceInfo.hw) === null || _c === void 0 ? void 0 : _c.Device_type).deviceType
43996
+ : this.getCurrentDeviceType();
43720
43997
  if (runtimeMode === 'romloader' && protocolV2DeviceType !== hdShared.EDeviceType.Pro2) {
43721
43998
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInitializeFailed, 'Protocol V2 romloader mode is only supported for Pro2.');
43722
43999
  }
@@ -43730,10 +44007,19 @@ class Device extends events.exports {
43730
44007
  }
43731
44008
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInitializeFailed, `Unknown Protocol V2 build fingerprint without DeviceStatusGet capability: ${protocolInfo.build_fingerprint}`);
43732
44009
  }
43733
- const deviceStatus = yield requestProtocolV2DeviceStatus({
43734
- commands: this.commands,
43735
- timeoutMs,
43736
- });
44010
+ let deviceStatus;
44011
+ try {
44012
+ deviceStatus = yield requestProtocolV2DeviceStatus({
44013
+ commands: this.commands,
44014
+ timeoutMs,
44015
+ });
44016
+ }
44017
+ catch (error) {
44018
+ if (runtimeMode === undefined && isProtocolV2DeviceStatusUnsupportedError(error)) {
44019
+ return this.updateProtocolV2Features(deviceInfo, null, 'bootloader', protocolInfo);
44020
+ }
44021
+ throw error;
44022
+ }
43737
44023
  return this.updateProtocolV2Features(deviceInfo, deviceStatus, 'normal', protocolInfo);
43738
44024
  });
43739
44025
  }
@@ -43764,6 +44050,9 @@ class Device extends events.exports {
43764
44050
  if (!this.isProtocolV2())
43765
44051
  return;
43766
44052
  this.protocolV2StateNeedsReload = true;
44053
+ this.protocolV2RuntimeContext = undefined;
44054
+ this.protocolV2RuntimeContextPromise = undefined;
44055
+ this.protocolV2RuntimeContextRequestToken = undefined;
43767
44056
  this.clearPreInitialized();
43768
44057
  }
43769
44058
  invalidateAfterWipe() {
@@ -43771,9 +44060,14 @@ class Device extends events.exports {
43771
44060
  if (deviceId) {
43772
44061
  deviceWalletSessionStore.deleteDevice(deviceId);
43773
44062
  }
43774
- if (this.isProtocolV2() && this.originalDescriptor.path !== deviceId) {
43775
- deviceWalletSessionStore.deleteDevice(this.originalDescriptor.path);
44063
+ if (this.isProtocolV2()) {
44064
+ if (this.originalDescriptor.path !== deviceId) {
44065
+ deviceWalletSessionStore.deleteDevice(this.originalDescriptor.path);
44066
+ }
43776
44067
  this.protocolV2StateNeedsReload = true;
44068
+ this.protocolV2RuntimeContext = undefined;
44069
+ this.protocolV2RuntimeContextPromise = undefined;
44070
+ this.protocolV2RuntimeContextRequestToken = undefined;
43777
44071
  }
43778
44072
  this.passphraseState = undefined;
43779
44073
  this.stateStore = new DeviceStateStore();
@@ -43784,6 +44078,9 @@ class Device extends events.exports {
43784
44078
  if (!this.isProtocolV2())
43785
44079
  return;
43786
44080
  this.protocolV2StateNeedsReload = true;
44081
+ this.protocolV2RuntimeContext = undefined;
44082
+ this.protocolV2RuntimeContextPromise = undefined;
44083
+ this.protocolV2RuntimeContextRequestToken = undefined;
43787
44084
  this.clearPreInitialized();
43788
44085
  let loaderMode;
43789
44086
  if (rebootType === hdTransport.DeviceRebootType.Bootloader) {
@@ -44082,6 +44379,55 @@ class Device extends events.exports {
44082
44379
  return res.message;
44083
44380
  });
44084
44381
  }
44382
+ beginProtocolV2UiInteraction() {
44383
+ if (!this.isProtocolV2())
44384
+ return;
44385
+ this.protocolV2UiInteraction = {
44386
+ interactionId: `${this.instanceId}:${Date.now()}:${++this.protocolV2UiInteractionCounter}`,
44387
+ phaseCounter: 0,
44388
+ sequence: 0,
44389
+ opened: false,
44390
+ };
44391
+ }
44392
+ createProtocolV2UiPhaseMetadata(phase, transition, options) {
44393
+ var _a;
44394
+ if (!this.isProtocolV2())
44395
+ return undefined;
44396
+ if (!this.protocolV2UiInteraction)
44397
+ this.beginProtocolV2UiInteraction();
44398
+ const interaction = this.protocolV2UiInteraction;
44399
+ if (!interaction)
44400
+ return undefined;
44401
+ const phaseId = (_a = options === null || options === void 0 ? void 0 : options.phaseId) !== null && _a !== void 0 ? _a : `${interaction.interactionId}:phase-${++interaction.phaseCounter}`;
44402
+ interaction.opened = true;
44403
+ interaction.sequence += 1;
44404
+ return Object.assign(Object.assign({ interactionId: interaction.interactionId, phaseId, sequence: interaction.sequence, phase,
44405
+ transition }, ((options === null || options === void 0 ? void 0 : options.outcome) ? { outcome: options.outcome } : {})), { protocol: 'V2' });
44406
+ }
44407
+ completeProtocolV2UiPhase(phase, outcome = 'succeeded') {
44408
+ return this.createProtocolV2UiPhaseMetadata(phase.phase, 'complete', {
44409
+ phaseId: phase.phaseId,
44410
+ outcome,
44411
+ });
44412
+ }
44413
+ finishProtocolV2UiInteraction(outcome = 'succeeded') {
44414
+ const interaction = this.protocolV2UiInteraction;
44415
+ if (!(interaction === null || interaction === void 0 ? void 0 : interaction.opened)) {
44416
+ this.protocolV2UiInteraction = undefined;
44417
+ return undefined;
44418
+ }
44419
+ const phaseId = `${interaction.interactionId}:phase-${Math.max(interaction.phaseCounter, 1)}`;
44420
+ const metadata = this.createProtocolV2UiPhaseMetadata('processing', 'finish', {
44421
+ phaseId,
44422
+ outcome,
44423
+ });
44424
+ this.protocolV2UiInteraction = undefined;
44425
+ return metadata;
44426
+ }
44427
+ hasOpenProtocolV2UiInteraction() {
44428
+ var _a;
44429
+ return ((_a = this.protocolV2UiInteraction) === null || _a === void 0 ? void 0 : _a.opened) === true;
44430
+ }
44085
44431
  supportUnlockVersionRange() {
44086
44432
  return {
44087
44433
  pro: {
@@ -44089,28 +44435,50 @@ class Device extends events.exports {
44089
44435
  },
44090
44436
  };
44091
44437
  }
44092
- unlockDevice(pinType = hdTransport.DeviceSessionPinType.Main) {
44093
- var _a, _b, _c, _d;
44438
+ unlockDevice(pinType, options) {
44439
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
44094
44440
  return __awaiter(this, void 0, void 0, function* () {
44095
44441
  if (this.isProtocolV2()) {
44442
+ const requestedPinType = pinType !== null && pinType !== void 0 ? pinType : hdTransport.DeviceSessionPinType.Main;
44443
+ const interaction = (_a = options === null || options === void 0 ? void 0 : options.interaction) !== null && _a !== void 0 ? _a : ((options === null || options === void 0 ? void 0 : options.emitUiEvent) === false
44444
+ ? undefined
44445
+ : this.createProtocolV2UiPhaseMetadata('pin', 'start'));
44446
+ if ((options === null || options === void 0 ? void 0 : options.emitUiEvent) !== false) {
44447
+ this.emit(DEVICE.PIN_ON_DEVICE, this, requestedPinType, {
44448
+ source: (_b = options === null || options === void 0 ? void 0 : options.source) !== null && _b !== void 0 ? _b : 'unlock-coordinator',
44449
+ reason: (_c = options === null || options === void 0 ? void 0 : options.reason) !== null && _c !== void 0 ? _c : 'device-unlock',
44450
+ deviceOnly: (_d = options === null || options === void 0 ? void 0 : options.deviceOnly) !== null && _d !== void 0 ? _d : true,
44451
+ completion: options === null || options === void 0 ? void 0 : options.completion,
44452
+ method: options === null || options === void 0 ? void 0 : options.method,
44453
+ page: options === null || options === void 0 ? void 0 : options.page,
44454
+ operation: options === null || options === void 0 ? void 0 : options.operation,
44455
+ interaction: (_e = options === null || options === void 0 ? void 0 : options.interaction) !== null && _e !== void 0 ? _e : interaction,
44456
+ });
44457
+ }
44096
44458
  try {
44097
- yield this.commands.typedCall('DeviceSessionAskPin', 'Success', { type: pinType });
44459
+ yield this.commands.typedCall('DeviceSessionAskPin', 'Success', {
44460
+ type: requestedPinType,
44461
+ });
44098
44462
  }
44099
44463
  catch (error) {
44100
44464
  const errorText = error instanceof Error
44101
44465
  ? `${error.name} ${error.message}`
44102
- : String((_b = (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : error) !== null && _b !== void 0 ? _b : '');
44466
+ : String((_g = (_f = error === null || error === void 0 ? void 0 : error.message) !== null && _f !== void 0 ? _f : error) !== null && _g !== void 0 ? _g : '');
44103
44467
  if (errorText.includes('Failure_UnexpectedMessage')) {
44104
44468
  throw hdShared.createDeviceNotSupportMethodError('deviceUnlock', this.getCurrentFirmwareType());
44105
44469
  }
44106
44470
  throw error;
44107
44471
  }
44472
+ const completion = interaction ? this.completeProtocolV2UiPhase(interaction) : undefined;
44473
+ if (completion) {
44474
+ this.emit(DEVICE.PIN_ON_DEVICE_COMPLETE, this, completion);
44475
+ }
44108
44476
  const status = yield requestProtocolV2DeviceStatus({ commands: this.commands });
44109
44477
  return this.updateProtocolV2Status(status);
44110
44478
  }
44111
- const firmwareVersion = (_c = this.getCurrentFirmwareVersionString()) !== null && _c !== void 0 ? _c : '0.0.0';
44479
+ const firmwareVersion = (_h = this.getCurrentFirmwareVersionString()) !== null && _h !== void 0 ? _h : '0.0.0';
44112
44480
  const versionRange = this.getCurrentMethodVersionRange(type => this.supportUnlockVersionRange()[type]);
44113
- const supportAttachPinCapability = (_d = this.state) === null || _d === void 0 ? void 0 : _d.capabilities.includes(hdTransport.Enum_Capability.Capability_AttachToPin);
44481
+ const supportAttachPinCapability = (_j = this.state) === null || _j === void 0 ? void 0 : _j.capabilities.includes(hdTransport.Enum_Capability.Capability_AttachToPin);
44114
44482
  const supportUnlock = supportAttachPinCapability ||
44115
44483
  (versionRange &&
44116
44484
  semver__default["default"].valid(firmwareVersion) &&
@@ -44145,7 +44513,7 @@ class Device extends events.exports {
44145
44513
  return Promise.resolve(features);
44146
44514
  });
44147
44515
  }
44148
- checkPassphraseStateSafety(passphraseState, useEmptyPassphrase, skipPassphraseCheck) {
44516
+ checkPassphraseStateSafety(passphraseState, useEmptyPassphrase, skipPassphraseCheck, deriveCardano) {
44149
44517
  return __awaiter(this, void 0, void 0, function* () {
44150
44518
  if (this.isUnacquired())
44151
44519
  return false;
@@ -44153,6 +44521,7 @@ class Device extends events.exports {
44153
44521
  const { passphraseState: newPassphraseState, unlockedAttachPin } = yield getPassphraseStateWithRefreshDeviceInfo(this, {
44154
44522
  expectPassphraseState: expectedPassphraseState,
44155
44523
  onlyMainPin: useEmptyPassphrase,
44524
+ deriveCardano,
44156
44525
  });
44157
44526
  const mainWalletUseAttachPin = unlockedAttachPin && useEmptyPassphrase;
44158
44527
  const useErrorAttachPin = unlockedAttachPin &&
@@ -44297,101 +44666,6 @@ const getBootloaderReleaseInfo = ({ features, willUpdateFirmwareVersion, firmwar
44297
44666
  };
44298
44667
  };
44299
44668
 
44300
- const PROTOCOL_V2_RETRY_ON_LOCKED_METHODS = [
44301
- 'cipherKeyValue',
44302
- 'allNetworkGetAddress',
44303
- 'allNetworkGetAddressByLoop',
44304
- 'btcGetAddress',
44305
- 'btcGetPublicKey',
44306
- 'btcSignMessage',
44307
- 'btcSignPsbt',
44308
- 'btcSignTransaction',
44309
- 'btcVerifyMessage',
44310
- 'confluxGetAddress',
44311
- 'confluxSignMessage',
44312
- 'confluxSignTransaction',
44313
- 'evmGetAddress',
44314
- 'evmGetPublicKey',
44315
- 'evmSignMessage',
44316
- 'evmSignTransaction',
44317
- 'evmSignTypedData',
44318
- 'evmVerifyMessage',
44319
- 'starcoinGetAddress',
44320
- 'starcoinGetPublicKey',
44321
- 'starcoinSignMessage',
44322
- 'starcoinSignTransaction',
44323
- 'starcoinVerifyMessage',
44324
- 'nemGetAddress',
44325
- 'nemSignTransaction',
44326
- 'solGetAddress',
44327
- 'solSignTransaction',
44328
- 'solSignOffchainMessage',
44329
- 'solSignMessage',
44330
- 'stellarGetAddress',
44331
- 'stellarSignTransaction',
44332
- 'tronGetAddress',
44333
- 'tronSignMessage',
44334
- 'tronSignTransaction',
44335
- 'nearGetAddress',
44336
- 'nearSignTransaction',
44337
- 'aptosGetAddress',
44338
- 'aptosGetPublicKey',
44339
- 'aptosSignTransaction',
44340
- 'aptosSignMessage',
44341
- 'aptosSignInMessage',
44342
- 'algoGetAddress',
44343
- 'algoSignTransaction',
44344
- 'cosmosGetAddress',
44345
- 'cosmosGetPublicKey',
44346
- 'cosmosSignTransaction',
44347
- 'xrpGetAddress',
44348
- 'xrpSignTransaction',
44349
- 'suiGetAddress',
44350
- 'suiGetPublicKey',
44351
- 'suiSignMessage',
44352
- 'suiSignTransaction',
44353
- 'cardanoGetAddress',
44354
- 'cardanoGetPublicKey',
44355
- 'cardanoSignTransaction',
44356
- 'cardanoSignMessage',
44357
- 'filecoinGetAddress',
44358
- 'filecoinSignTransaction',
44359
- 'polkadotGetAddress',
44360
- 'polkadotSignTransaction',
44361
- 'kaspaGetAddress',
44362
- 'kaspaSignTransaction',
44363
- 'nexaGetAddress',
44364
- 'nexaSignTransaction',
44365
- 'nostrGetPublicKey',
44366
- 'nostrSignEvent',
44367
- 'nostrEncryptMessage',
44368
- 'nostrDecryptMessage',
44369
- 'nostrSignSchnorr',
44370
- 'lnurlAuth',
44371
- 'nervosGetAddress',
44372
- 'nervosSignTransaction',
44373
- 'dnxGetAddress',
44374
- 'dnxSignTransaction',
44375
- 'tonGetAddress',
44376
- 'tonSignMessage',
44377
- 'tonSignProof',
44378
- 'tonSignData',
44379
- 'scdoGetAddress',
44380
- 'scdoSignTransaction',
44381
- 'scdoSignMessage',
44382
- 'alephiumGetAddress',
44383
- 'alephiumSignTransaction',
44384
- 'alephiumSignMessage',
44385
- 'benfenGetAddress',
44386
- 'benfenGetPublicKey',
44387
- 'benfenSignMessage',
44388
- 'benfenSignTransaction',
44389
- 'neoGetAddress',
44390
- 'neoSignTransaction',
44391
- ];
44392
- const retryOnLockedMethods = new Set(PROTOCOL_V2_RETRY_ON_LOCKED_METHODS);
44393
- const getProtocolV2UnlockPolicy = (methodName) => retryOnLockedMethods.has(methodName) ? 'retry-on-locked' : 'none';
44394
-
44395
44669
  const Log$d = getLogger(exports.LoggerNames.Method);
44396
44670
  const isEvmLedgerLegacyPathWithHighIndex = (path) => {
44397
44671
  let addressN;
@@ -44469,7 +44743,6 @@ class BaseMethod {
44469
44743
  this.useDevice = true;
44470
44744
  this.allowDeviceMode = [UI_REQUEST.NOT_INITIALIZE];
44471
44745
  this.requireDeviceMode = [];
44472
- this.unlockPolicy = getProtocolV2UnlockPolicy(this.name);
44473
44746
  }
44474
44747
  getVersionRange() {
44475
44748
  return {};
@@ -44607,7 +44880,7 @@ class TestInitializeDeviceDuration extends BaseMethod {
44607
44880
  }
44608
44881
 
44609
44882
  const PROTOCOL_V2_PING_MAX_MESSAGE_BYTES = 63;
44610
- const getUtf8ByteLength$1 = (value) => Array.from(value).reduce((length, character) => {
44883
+ const getUtf8ByteLength = (value) => Array.from(value).reduce((length, character) => {
44611
44884
  var _a;
44612
44885
  const codePoint = (_a = character.codePointAt(0)) !== null && _a !== void 0 ? _a : 0;
44613
44886
  if (codePoint <= 0x7f)
@@ -44623,7 +44896,7 @@ function validateProtocolV2PingMessage(value) {
44623
44896
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, 'Protocol V2 Ping message must be a string.');
44624
44897
  }
44625
44898
  const message = value !== null && value !== void 0 ? value : '';
44626
- if (getUtf8ByteLength$1(message) > PROTOCOL_V2_PING_MAX_MESSAGE_BYTES) {
44899
+ if (getUtf8ByteLength(message) > PROTOCOL_V2_PING_MAX_MESSAGE_BYTES) {
44627
44900
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, `Protocol V2 Ping message must not exceed ${PROTOCOL_V2_PING_MAX_MESSAGE_BYTES} UTF-8 bytes.`);
44628
44901
  }
44629
44902
  return message;
@@ -44837,7 +45110,12 @@ class GetPassphraseState extends BaseMethod {
44837
45110
  if (isProtocolV2 && this.payload.useEmptyPassphrase !== true) {
44838
45111
  const features = yield refreshProtocolV2DeviceStatus(this.device);
44839
45112
  if (features.unlocked === false) {
44840
- yield this.device.unlockDevice();
45113
+ yield this.device.unlockDevice(hdTransport.DeviceSessionPinType.Main, {
45114
+ source: 'unlock-coordinator',
45115
+ reason: 'device-locked',
45116
+ deviceOnly: true,
45117
+ method: 'getPassphraseState',
45118
+ });
44841
45119
  }
44842
45120
  }
44843
45121
  const { passphraseState } = yield getPassphraseStateWithRefreshDeviceInfo(this.device, isProtocolV2
@@ -44938,37 +45216,37 @@ function parseChainId(chainId) {
44938
45216
  throw new Error(`Invalid chainId ${chainId}`);
44939
45217
  }
44940
45218
 
44941
- const invalidParameter$1 = (message) => hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, message);
45219
+ const invalidParameter = (message) => hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, message);
44942
45220
  const invalidResponse = (message) => hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodError, message);
44943
45221
  const validateParams = (values, fields) => {
44944
45222
  fields.forEach(field => {
44945
45223
  const existsProp = Object.prototype.hasOwnProperty.call(values, field.name);
44946
45224
  if (!existsProp && field.required) {
44947
- throw invalidParameter$1(`Missing required parameter: ${field.name}`);
45225
+ throw invalidParameter(`Missing required parameter: ${field.name}`);
44948
45226
  }
44949
45227
  const value = values[field.name];
44950
45228
  if (value && field.type) {
44951
45229
  switch (field.type) {
44952
45230
  case 'array':
44953
45231
  if (!Array.isArray(value)) {
44954
- throw invalidParameter$1(`Parameter [${field.name}] is of type invalid and should be [${field.type}].`);
45232
+ throw invalidParameter(`Parameter [${field.name}] is of type invalid and should be [${field.type}].`);
44955
45233
  }
44956
45234
  else if (!field.allowEmpty && value.length < 1) {
44957
- throw invalidParameter$1(`Parameter "${field.name}" is empty.`);
45235
+ throw invalidParameter(`Parameter "${field.name}" is empty.`);
44958
45236
  }
44959
45237
  break;
44960
45238
  case 'uint':
44961
45239
  if (typeof value !== 'string' && typeof value !== 'number') {
44962
- throw invalidParameter$1(`Parameter [${field.name}] has invalid type. "string|number" expected.`);
45240
+ throw invalidParameter(`Parameter [${field.name}] has invalid type. "string|number" expected.`);
44963
45241
  }
44964
45242
  if ((typeof value === 'number' && !Number.isSafeInteger(value)) ||
44965
45243
  !/^(?:[1-9]\d*|\d)$/.test(value.toString().replace(/^-/, field.allowNegative ? '' : '-'))) {
44966
- throw invalidParameter$1(`Parameter [${field.name}] has invalid value "${value}". Integer representation expected.`);
45244
+ throw invalidParameter(`Parameter [${field.name}] has invalid value "${value}". Integer representation expected.`);
44967
45245
  }
44968
45246
  break;
44969
45247
  case 'bigNumber':
44970
45248
  if (typeof value !== 'string') {
44971
- throw invalidParameter$1(`Parameter [${field.name}] is of type invalid and should be [string].`);
45249
+ throw invalidParameter(`Parameter [${field.name}] is of type invalid and should be [string].`);
44972
45250
  }
44973
45251
  try {
44974
45252
  const bn = new BigNumber__default["default"](value);
@@ -44977,12 +45255,12 @@ const validateParams = (values, fields) => {
44977
45255
  }
44978
45256
  }
44979
45257
  catch (error) {
44980
- throw invalidParameter$1(`Parameter [${field.name}] is of type invalid and should be [${field.type}].`);
45258
+ throw invalidParameter(`Parameter [${field.name}] is of type invalid and should be [${field.type}].`);
44981
45259
  }
44982
45260
  break;
44983
45261
  case 'buffer': {
44984
45262
  if (typeof value === 'undefined' || value === null) {
44985
- throw invalidParameter$1(`Parameter [${field.name}] is of type invalid and should be [buffer].`);
45263
+ throw invalidParameter(`Parameter [${field.name}] is of type invalid and should be [buffer].`);
44986
45264
  }
44987
45265
  const isNodeBuffer = typeof Buffer !== 'undefined' &&
44988
45266
  typeof Buffer.isBuffer === 'function' &&
@@ -44995,18 +45273,18 @@ const validateParams = (values, fields) => {
44995
45273
  typeof ArrayBuffer.isView === 'function' &&
44996
45274
  ArrayBuffer.isView(value);
44997
45275
  if (!isNodeBuffer && !isCustomBuffer && !isArrayBuffer && !isArrayBufferView) {
44998
- throw invalidParameter$1(`Parameter [${field.name}] is of type invalid and should be [buffer].`);
45276
+ throw invalidParameter(`Parameter [${field.name}] is of type invalid and should be [buffer].`);
44999
45277
  }
45000
45278
  break;
45001
45279
  }
45002
45280
  case 'hexString':
45003
45281
  if (typeof value !== 'string' || !isHexString(addHexPrefix(value))) {
45004
- throw invalidParameter$1(`Parameter [${field.name}] is of type invalid and should be [${field.type}].`);
45282
+ throw invalidParameter(`Parameter [${field.name}] is of type invalid and should be [${field.type}].`);
45005
45283
  }
45006
45284
  break;
45007
45285
  default:
45008
45286
  if (typeof value !== field.type) {
45009
- throw invalidParameter$1(`Parameter [${field.name}] is of type invalid and should be [${field.type}].`);
45287
+ throw invalidParameter(`Parameter [${field.name}] is of type invalid and should be [${field.type}].`);
45010
45288
  }
45011
45289
  break;
45012
45290
  }
@@ -45040,10 +45318,10 @@ function validateResult(result, nonNullableFields, options) {
45040
45318
 
45041
45319
  const requiredString = (value, name) => {
45042
45320
  if (value === undefined || value === null) {
45043
- throw invalidParameter$1(`Missing required parameter: ${name}`);
45321
+ throw invalidParameter(`Missing required parameter: ${name}`);
45044
45322
  }
45045
45323
  if (typeof value !== 'string' || !value.trim()) {
45046
- throw invalidParameter$1(`Parameter [${name}] must be a non-empty string.`);
45324
+ throw invalidParameter(`Parameter [${name}] must be a non-empty string.`);
45047
45325
  }
45048
45326
  return value.trim();
45049
45327
  };
@@ -45061,20 +45339,20 @@ const requireHiddenWalletResponse = (session) => {
45061
45339
  };
45062
45340
  const normalizeParams = (payload) => {
45063
45341
  if (payload.mode === undefined) {
45064
- throw invalidParameter$1('Parameter [mode] is required.');
45342
+ throw invalidParameter('Parameter [mode] is required.');
45065
45343
  }
45066
45344
  if (payload.mode !== OpenWalletSessionMode.Standard &&
45067
45345
  payload.mode !== OpenWalletSessionMode.SelectHidden &&
45068
45346
  payload.mode !== OpenWalletSessionMode.ResumeHidden) {
45069
- throw invalidParameter$1('Parameter [mode] must be one of standard, select-hidden, or resume-hidden.');
45347
+ throw invalidParameter('Parameter [mode] must be one of standard, select-hidden, or resume-hidden.');
45070
45348
  }
45071
45349
  if (payload.useEmptyPassphrase !== undefined || payload.initSession !== undefined) {
45072
- throw invalidParameter$1('Legacy parameters [useEmptyPassphrase] and [initSession] are not supported by openWalletSession.');
45350
+ throw invalidParameter('Legacy parameters [useEmptyPassphrase] and [initSession] are not supported by openWalletSession.');
45073
45351
  }
45074
45352
  if (payload.mode === OpenWalletSessionMode.Standard ||
45075
45353
  payload.mode === OpenWalletSessionMode.SelectHidden) {
45076
45354
  if (payload.deviceId !== undefined || payload.passphraseState !== undefined) {
45077
- throw invalidParameter$1('Parameters [deviceId] and [passphraseState] are only allowed with mode [resume-hidden].');
45355
+ throw invalidParameter('Parameters [deviceId] and [passphraseState] are only allowed with mode [resume-hidden].');
45078
45356
  }
45079
45357
  return { mode: payload.mode };
45080
45358
  }
@@ -45097,35 +45375,60 @@ class OpenWalletSession extends BaseMethod {
45097
45375
  run() {
45098
45376
  return __awaiter(this, void 0, void 0, function* () {
45099
45377
  const isProtocolV2 = this.device.isProtocolV2();
45100
- const state = yield this.device.getDeviceState({ refreshSections: ['status'] });
45378
+ let state = yield this.device.getDeviceState({ refreshSections: ['status'] });
45101
45379
  let currentDeviceId = state.identity.deviceId;
45380
+ const hasAuthoritativeProtocolV2WalletStatus = (candidate) => candidate.status.unlocked === true &&
45381
+ typeof candidate.status.passphraseProtection === 'boolean' &&
45382
+ typeof candidate.status.unlockedAttachPin === 'boolean';
45383
+ const requireAuthoritativeProtocolV2WalletStatus = (candidate) => {
45384
+ if (!hasAuthoritativeProtocolV2WalletStatus(candidate)) {
45385
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInitializeFailed);
45386
+ }
45387
+ return candidate;
45388
+ };
45102
45389
  const requireDeviceId = () => {
45103
45390
  if (!currentDeviceId) {
45104
45391
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInitializeFailed);
45105
45392
  }
45106
45393
  return currentDeviceId;
45107
45394
  };
45108
- const refreshProtocolV2DeviceId = () => __awaiter(this, void 0, void 0, function* () {
45109
- const refreshedState = yield this.device.getDeviceState({ refreshSections: ['status'] });
45110
- currentDeviceId = refreshedState.identity.deviceId;
45111
- return requireDeviceId();
45395
+ const refreshProtocolV2DeviceState = () => __awaiter(this, void 0, void 0, function* () {
45396
+ state = yield this.device.getDeviceState({ refreshSections: ['status'] });
45397
+ currentDeviceId = state.identity.deviceId;
45398
+ return state;
45112
45399
  });
45113
- const unlockProtocolV2IfLocked = () => __awaiter(this, void 0, void 0, function* () {
45114
- if (isProtocolV2 && state.status.unlocked === false) {
45115
- yield this.device.unlockDevice();
45400
+ const ensureProtocolV2WalletStatus = () => __awaiter(this, void 0, void 0, function* () {
45401
+ if (isProtocolV2 && !hasAuthoritativeProtocolV2WalletStatus(state)) {
45402
+ yield this.device.unlockDevice(hdTransport.DeviceSessionPinType.Main, {
45403
+ source: 'unlock-coordinator',
45404
+ reason: 'device-locked',
45405
+ deviceOnly: true,
45406
+ method: 'openWalletSession',
45407
+ });
45408
+ requireAuthoritativeProtocolV2WalletStatus(yield refreshProtocolV2DeviceState());
45116
45409
  }
45410
+ return state;
45117
45411
  });
45118
45412
  const protocol = isProtocolV2 ? 'V2' : 'V1';
45119
45413
  if (this.params.mode === OpenWalletSessionMode.Standard) {
45120
45414
  this.device.passphraseState = undefined;
45121
45415
  const session = isProtocolV2
45122
- ? yield getProtocolV2WalletSession(this.device, { onlyMainPin: true })
45416
+ ? yield getProtocolV2WalletSession(this.device, {
45417
+ onlyMainPin: true,
45418
+ deriveCardano: this.payload.deriveCardano,
45419
+ selectMainWalletBeforeRestore: !hasAuthoritativeProtocolV2WalletStatus(state) ||
45420
+ state.status.unlockedAttachPin === true,
45421
+ })
45123
45422
  : yield getPassphraseStateWithRefreshDeviceInfo(this.device, {
45124
45423
  onlyMainPin: true,
45125
45424
  initSession: this.payload.initSession,
45126
45425
  });
45127
- const deviceId = isProtocolV2 ? yield refreshProtocolV2DeviceId() : requireDeviceId();
45128
- if (session.unlockedAttachPin) {
45426
+ const refreshedState = isProtocolV2
45427
+ ? requireAuthoritativeProtocolV2WalletStatus(yield refreshProtocolV2DeviceState())
45428
+ : state;
45429
+ const deviceId = requireDeviceId();
45430
+ if (session.unlockedAttachPin ||
45431
+ (isProtocolV2 && refreshedState.status.unlockedAttachPin === true)) {
45129
45432
  try {
45130
45433
  yield this.device.lockDevice();
45131
45434
  }
@@ -45144,8 +45447,8 @@ class OpenWalletSession extends BaseMethod {
45144
45447
  }
45145
45448
  if (this.params.mode === OpenWalletSessionMode.ResumeHidden) {
45146
45449
  if (isProtocolV2) {
45147
- yield unlockProtocolV2IfLocked();
45148
- const refreshedDeviceId = yield refreshProtocolV2DeviceId();
45450
+ yield ensureProtocolV2WalletStatus();
45451
+ const refreshedDeviceId = requireDeviceId();
45149
45452
  if (refreshedDeviceId !== this.params.deviceId) {
45150
45453
  deviceWalletSessionStore.delete(this.params.deviceId, this.params.passphraseState);
45151
45454
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckDeviceIdError);
@@ -45168,6 +45471,7 @@ class OpenWalletSession extends BaseMethod {
45168
45471
  const session = isProtocolV2
45169
45472
  ? yield getProtocolV2WalletSession(this.device, {
45170
45473
  expectedPassphraseState: this.params.passphraseState,
45474
+ deriveCardano: this.payload.deriveCardano,
45171
45475
  })
45172
45476
  : yield getPassphraseStateWithRefreshDeviceInfo(this.device, {
45173
45477
  expectPassphraseState: this.params.passphraseState,
@@ -45180,12 +45484,18 @@ class OpenWalletSession extends BaseMethod {
45180
45484
  return Object.assign(Object.assign({ protocol, walletType: 'hidden', deviceId }, requireHiddenWalletResponse(session)), { resumed: wasResumed(session) || (!isProtocolV2 && session.newSession === cachedSessionId) });
45181
45485
  }
45182
45486
  this.device.passphraseState = undefined;
45183
- yield unlockProtocolV2IfLocked();
45487
+ yield ensureProtocolV2WalletStatus();
45184
45488
  const session = isProtocolV2
45185
- ? yield getProtocolV2WalletSession(this.device, { forceWalletSelection: true })
45489
+ ? yield getProtocolV2WalletSession(this.device, {
45490
+ forceWalletSelection: true,
45491
+ deriveCardano: this.payload.deriveCardano,
45492
+ })
45186
45493
  : yield getPassphraseStateWithRefreshDeviceInfo(this.device, { initSession: true });
45187
- const deviceId = isProtocolV2 ? yield refreshProtocolV2DeviceId() : requireDeviceId();
45188
- if (isProtocolV2 && this.device.getCurrentPassphraseProtection() !== true) {
45494
+ const refreshedState = isProtocolV2
45495
+ ? requireAuthoritativeProtocolV2WalletStatus(yield refreshProtocolV2DeviceState())
45496
+ : state;
45497
+ const deviceId = requireDeviceId();
45498
+ if (isProtocolV2 && refreshedState.status.passphraseProtection !== true) {
45189
45499
  this.device.clearInternalState();
45190
45500
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceNotOpenedPassphrase);
45191
45501
  }
@@ -45229,7 +45539,7 @@ class GetLogs extends BaseMethod {
45229
45539
  class ClearSessionCache extends BaseMethod {
45230
45540
  init() {
45231
45541
  if (this.payload.passphraseState !== undefined && !this.payload.deviceId) {
45232
- throw invalidParameter$1('Parameter [deviceId] is required with [passphraseState].');
45542
+ throw invalidParameter('Parameter [deviceId] is required with [passphraseState].');
45233
45543
  }
45234
45544
  this.useDevice = false;
45235
45545
  this.useDevicePassphraseState = false;
@@ -45719,94 +46029,6 @@ class DeviceBackup extends BaseMethod {
45719
46029
  }
45720
46030
  }
45721
46031
 
45722
- const invalidParameter = (message) => hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, message);
45723
- function validateNonEmptyString(value, name) {
45724
- if (typeof value !== 'string' || value.trim().length === 0) {
45725
- throw invalidParameter(`Parameter [${name}] is required and must be a non-empty string.`);
45726
- }
45727
- return value;
45728
- }
45729
- const PROTOCOL_V2_FILESYSTEM_VOLUMES = new Set(['vol0', 'vol1']);
45730
- const MAX_PROTOCOL_V2_FILESYSTEM_PATH_BYTES = 127;
45731
- function getUtf8ByteLength(value) {
45732
- return Array.from(value).reduce((length, character) => {
45733
- var _a;
45734
- const codePoint = (_a = character.codePointAt(0)) !== null && _a !== void 0 ? _a : 0;
45735
- if (codePoint <= 0x7f)
45736
- return length + 1;
45737
- if (codePoint <= 0x7ff)
45738
- return length + 2;
45739
- if (codePoint <= 0xffff)
45740
- return length + 3;
45741
- return length + 4;
45742
- }, 0);
45743
- }
45744
- function validateProtocolV2FilesystemPath(value, name, options = {}) {
45745
- const rawPath = validateNonEmptyString(value, name).trim();
45746
- const containsUnsupportedCharacter = Array.from(rawPath).some(character => {
45747
- const codePoint = character.charCodeAt(0);
45748
- return codePoint <= 0x1f || codePoint === 0x7f || character === '\\';
45749
- });
45750
- if (containsUnsupportedCharacter) {
45751
- throw invalidParameter(`Parameter [${name}] contains unsupported path characters.`);
45752
- }
45753
- const match = /^([a-zA-Z0-9]+):(.*)$/.exec(rawPath);
45754
- if (!match) {
45755
- throw invalidParameter(`Parameter [${name}] must use a supported Protocol V2 filesystem volume.`);
45756
- }
45757
- const volume = match[1].toLowerCase();
45758
- if (!PROTOCOL_V2_FILESYSTEM_VOLUMES.has(volume)) {
45759
- throw invalidParameter(`Parameter [${name}] uses an unsupported filesystem volume.`);
45760
- }
45761
- const rawSuffix = match[2];
45762
- if (rawSuffix.length === 0) {
45763
- if (options.allowVolumeRoot)
45764
- return `${volume}:`;
45765
- throw invalidParameter(`Parameter [${name}] must identify a filesystem entry.`);
45766
- }
45767
- const suffix = rawSuffix.startsWith('/') ? rawSuffix : `/${rawSuffix}`;
45768
- const segments = suffix.slice(1).split('/');
45769
- if (segments.some(segment => segment.length === 0 || segment === '.' || segment === '..')) {
45770
- throw invalidParameter(`Parameter [${name}] contains an invalid path segment.`);
45771
- }
45772
- const canonicalPath = `${volume}:${rawSuffix.startsWith('/') ? '/' : ''}${segments.join('/')}`;
45773
- if (getUtf8ByteLength(canonicalPath) > MAX_PROTOCOL_V2_FILESYSTEM_PATH_BYTES) {
45774
- throw invalidParameter(`Parameter [${name}] exceeds the maximum filesystem path length.`);
45775
- }
45776
- return canonicalPath;
45777
- }
45778
- function validateNonNegativeInteger(value, name, defaultValue) {
45779
- if (value === undefined || value === null) {
45780
- if (defaultValue !== undefined)
45781
- return defaultValue;
45782
- throw invalidParameter(`Missing required parameter: ${name}`);
45783
- }
45784
- const numeric = typeof value === 'string' && value.trim() !== '' ? Number(value) : value;
45785
- if (typeof numeric !== 'number' || !Number.isSafeInteger(numeric) || numeric < 0) {
45786
- throw invalidParameter(`Parameter [${name}] must be a non-negative integer.`);
45787
- }
45788
- return numeric;
45789
- }
45790
- function validateOptionalNonNegativeInteger(value, name) {
45791
- if (value === undefined || value === null)
45792
- return undefined;
45793
- return validateNonNegativeInteger(value, name);
45794
- }
45795
- function validateOptionalPercentage(value, name) {
45796
- const numeric = validateOptionalNonNegativeInteger(value, name);
45797
- if (numeric === undefined)
45798
- return undefined;
45799
- if (numeric > 100) {
45800
- throw invalidParameter(`Parameter [${name}] must be between 0 and 100.`);
45801
- }
45802
- return numeric;
45803
- }
45804
- function validateRequiredData(value, name) {
45805
- if (value === undefined || value === null) {
45806
- throw invalidParameter(`Missing required parameter: ${name}`);
45807
- }
45808
- }
45809
-
45810
46032
  class DeviceChangePin extends BaseMethod {
45811
46033
  getSupportedProtocols() {
45812
46034
  return ['V1', 'V2'];
@@ -45831,7 +46053,7 @@ class DeviceChangePin extends BaseMethod {
45831
46053
  return __awaiter(this, void 0, void 0, function* () {
45832
46054
  if (this.device.isProtocolV2()) {
45833
46055
  if (this.params.remove) {
45834
- throw invalidParameter('Parameter [remove=true] is not supported by the Pro2 device PIN page.');
46056
+ throw invalidParameter$1('Parameter [remove=true] is not supported by the Pro2 device PIN page.');
45835
46057
  }
45836
46058
  const res = yield this.device.commands.typedCall('DeviceSettingsPageShow', 'Success', {
45837
46059
  page: hdTransport.DeviceSettingsPage.DevicePinChange,
@@ -46040,7 +46262,7 @@ const getProtocolV2SettingsBehavior = (operation) => {
46040
46262
  const assertSettingsSupported = (payload, unsupported, protocol) => {
46041
46263
  const provided = unsupported.filter(key => payload[key] !== undefined);
46042
46264
  if (provided.length > 0) {
46043
- throw invalidParameter(`${protocol} does not support settings: ${provided.join(', ')}.`);
46265
+ throw invalidParameter$1(`${protocol} does not support settings: ${provided.join(', ')}.`);
46044
46266
  }
46045
46267
  };
46046
46268
  const assertProtocolV2SettingValues = (payload, capabilities) => {
@@ -46048,7 +46270,7 @@ const assertProtocolV2SettingValues = (payload, capabilities) => {
46048
46270
  if (payload.brightness !== undefined &&
46049
46271
  brightnessRange &&
46050
46272
  (payload.brightness < brightnessRange.min || payload.brightness > brightnessRange.max)) {
46051
- throw invalidParameter(`Protocol V2 brightness must be between ${brightnessRange.min} and ${brightnessRange.max}.`);
46273
+ throw invalidParameter$1(`Protocol V2 brightness must be between ${brightnessRange.min} and ${brightnessRange.max}.`);
46052
46274
  }
46053
46275
  const delayFields = [
46054
46276
  ['autoLockDelayMs', capabilities.autoLockDelayOptions],
@@ -46057,7 +46279,7 @@ const assertProtocolV2SettingValues = (payload, capabilities) => {
46057
46279
  delayFields.forEach(([field, options]) => {
46058
46280
  const value = payload[field];
46059
46281
  if (value !== undefined && !options.some(option => option.valueMs === value)) {
46060
- throw invalidParameter(`Protocol V2 ${field} must be one of: ${options.map(option => option.valueMs).join(', ')}.`);
46282
+ throw invalidParameter$1(`Protocol V2 ${field} must be one of: ${options.map(option => option.valueMs).join(', ')}.`);
46061
46283
  }
46062
46284
  });
46063
46285
  };
@@ -46145,10 +46367,10 @@ class DeviceSettings extends BaseMethod {
46145
46367
  const hasPassphrasePage = requestedPassphrase !== undefined;
46146
46368
  const hasAirgapPage = requestedAirgap !== undefined;
46147
46369
  if (hasPassphrasePage && hasAirgapPage) {
46148
- throw invalidParameter('Protocol V2 passphrase and air-gap settings must be changed in separate calls.');
46370
+ throw invalidParameter$1('Protocol V2 passphrase and air-gap settings must be changed in separate calls.');
46149
46371
  }
46150
46372
  if ((hasPassphrasePage || hasAirgapPage) && Object.keys(settings).length > 0) {
46151
- throw invalidParameter('Protocol V2 on-device settings must not be combined with direct settings.');
46373
+ throw invalidParameter$1('Protocol V2 on-device settings must not be combined with direct settings.');
46152
46374
  }
46153
46375
  if (requestedPassphrase !== undefined) {
46154
46376
  const current = yield this.device.getDeviceState({ refreshSections: ['status'] });
@@ -46183,7 +46405,7 @@ class DeviceSettings extends BaseMethod {
46183
46405
  return res.message;
46184
46406
  }
46185
46407
  if (Object.keys(settings).length === 0) {
46186
- throw invalidParameter('No Protocol V2 compatible setting provided.');
46408
+ throw invalidParameter$1('No Protocol V2 compatible setting provided.');
46187
46409
  }
46188
46410
  const res = yield this.device.commands.typedCall('DeviceSettingsSet', 'Success', {
46189
46411
  settings,
@@ -46195,7 +46417,7 @@ class DeviceSettings extends BaseMethod {
46195
46417
  const capabilities = getDeviceSettingsCapabilities(this.device.getCurrentDeviceType(), 'V1');
46196
46418
  if (this.payload.safetyChecks !== undefined &&
46197
46419
  !capabilities.safetyCheckOptions.some(option => option.value === this.payload.safetyChecks)) {
46198
- throw invalidParameter(`Protocol V1 safetyChecks must be one of: ${capabilities.safetyCheckOptions
46420
+ throw invalidParameter$1(`Protocol V1 safetyChecks must be one of: ${capabilities.safetyCheckOptions
46199
46421
  .map(option => option.value)
46200
46422
  .join(', ')}.`);
46201
46423
  }
@@ -47455,7 +47677,7 @@ class DeviceUnlock extends BaseMethod {
47455
47677
  }
47456
47678
  run() {
47457
47679
  return __awaiter(this, void 0, void 0, function* () {
47458
- return this.device.unlockDevice();
47680
+ return this.device.unlockDevice(undefined, { emitUiEvent: false });
47459
47681
  });
47460
47682
  }
47461
47683
  }
@@ -49143,7 +49365,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
49143
49365
  if (binary.byteLength === 0) {
49144
49366
  throw new Error(`Protocol V2 RESC bundle is empty: ${bundle.name}`);
49145
49367
  }
49146
- if (downloadedFromRemote && (bundle.version || bundle.payloadHash || bundle.headerHash)) {
49368
+ if (downloadedFromRemote) {
49147
49369
  const header = parseProtocolV2OkppHeader(toProtocolV2Bytes(binary));
49148
49370
  if (!header || header.type !== 'RESC') {
49149
49371
  throw new Error(`Invalid Protocol V2 RESC bundle header: ${bundle.name}`);
@@ -49435,14 +49657,22 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
49435
49657
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareError, `Protocol V2 firmware target failed: target=${failedTarget.target_id} status=${(_a = failedTarget.status) !== null && _a !== void 0 ? _a : 'unknown'} payloadVersion=${(_b = failedTarget.payload_version) !== null && _b !== void 0 ? _b : 'unknown'} path=${(_c = failedTarget.path) !== null && _c !== void 0 ? _c : 'unknown'}`);
49436
49658
  }
49437
49659
  const matchingTargets = statusTargets.filter(target => { var _a; return expectedTargetIds.has((_a = normalizeProtocolV2TargetId(target.target_id)) !== null && _a !== void 0 ? _a : -1); });
49438
- const completedTargets = matchingTargets.filter(target => isProtocolV2TargetStatusFinished(target.status));
49439
- if (completedTargets.length === expectedTargetIds.size && expectedTargetIds.size > 0) {
49660
+ const completedTargetIds = new Set();
49661
+ matchingTargets.forEach(target => {
49662
+ const targetId = normalizeProtocolV2TargetId(target.target_id);
49663
+ if (targetId !== undefined && isProtocolV2TargetStatusFinished(target.status)) {
49664
+ completedTargetIds.add(targetId);
49665
+ }
49666
+ });
49667
+ const allExpectedTargetsCompleted = expectedTargetIds.size > 0 &&
49668
+ Array.from(expectedTargetIds).every(targetId => completedTargetIds.has(targetId));
49669
+ if (allExpectedTargetsCompleted) {
49440
49670
  this.postProgressMessage(100, 'installingFirmware');
49441
49671
  return true;
49442
49672
  }
49443
49673
  if (expectedTargetIds.size > 0 && matchingTargets.length > 0) {
49444
49674
  const hasInProgressTarget = matchingTargets.some(target => isProtocolV2TargetStatusInProgress(target.status));
49445
- const completedProgress = Math.floor((completedTargets.length / expectedTargetIds.size) * 100);
49675
+ const completedProgress = Math.floor((completedTargetIds.size / expectedTargetIds.size) * 100);
49446
49676
  const progress = Math.min(99, Math.max(completedProgress, hasInProgressTarget ? 1 : 0));
49447
49677
  this.postProgressMessage(progress, 'installingFirmware');
49448
49678
  }
@@ -49852,14 +50082,15 @@ class DeviceGetOnboardingStatus extends BaseMethod {
49852
50082
  }
49853
50083
 
49854
50084
  const MIN_FILE_CHUNK_SIZE = 64;
49855
- function isRetryableFileWriteTimeout(error) {
50085
+ function isProtocolV2ResponseTimeout(error) {
49856
50086
  var _a, _b;
49857
50087
  if (!error || typeof error !== 'object')
49858
50088
  return false;
49859
50089
  const candidate = error;
49860
50090
  const code = (_a = candidate.errorCode) !== null && _a !== void 0 ? _a : candidate.code;
49861
50091
  return (code === hdShared.HardwareErrorCode.BleTimeoutError ||
49862
- /Lowlevel response timeout/i.test((_b = candidate.message) !== null && _b !== void 0 ? _b : ''));
50092
+ code === 'response-timeout' ||
50093
+ /(?:BLE|Lowlevel|Protocol V2) response timeout/i.test((_b = candidate.message) !== null && _b !== void 0 ? _b : ''));
49863
50094
  }
49864
50095
  function getProtocolV2FileChunkLimit() {
49865
50096
  const env = DataManager.getSettings('env');
@@ -49946,7 +50177,7 @@ function writeProtocolV2File(options) {
49946
50177
  isWritePending = false;
49947
50178
  }
49948
50179
  catch (error) {
49949
- if (retryCount >= maxChunkRetries || !isRetryableFileWriteTimeout(error))
50180
+ if (retryCount >= maxChunkRetries || !isProtocolV2ResponseTimeout(error))
49950
50181
  throw error;
49951
50182
  retryCount += 1;
49952
50183
  (_h = options.throwIfAborted) === null || _h === void 0 ? void 0 : _h.call(options);
@@ -49977,6 +50208,11 @@ function writeProtocolV2File(options) {
49977
50208
  rateBytesPerSecond: elapsedMs > 0 ? Math.round((transferredBytes / elapsedMs) * 1000) : undefined,
49978
50209
  elapsedMs,
49979
50210
  });
50211
+ if (options.paceMs && options.paceMs > 0) {
50212
+ yield new Promise(resolve => {
50213
+ setTimeout(resolve, options.paceMs);
50214
+ });
50215
+ }
49980
50216
  }
49981
50217
  return Object.assign(Object.assign({}, lastMessage), { path: options.path, offset: startOffset, total_size: totalSize, processed_byte: startOffset + written, chunks });
49982
50218
  });
@@ -49986,7 +50222,7 @@ const WALLPAPER_DIRECTORY = 'vol1:/wallpapers';
49986
50222
  const SAFE_FILE_NAME = /^[A-Za-z0-9_-]+(?:\.bin)?$/;
49987
50223
  function normalizeFileName(fileName, data) {
49988
50224
  if (fileName !== undefined && (!fileName || !SAFE_FILE_NAME.test(fileName))) {
49989
- throw invalidParameter('Parameter [fileName] may only contain letters, numbers, underscores, hyphens and an optional .bin suffix.');
50225
+ throw invalidParameter$1('Parameter [fileName] may only contain letters, numbers, underscores, hyphens and an optional .bin suffix.');
49990
50226
  }
49991
50227
  const baseName = fileName !== null && fileName !== void 0 ? fileName : `wallpaper-${utils.bytesToHex(blake2s.blake2s(data)).slice(0, 12)}`;
49992
50228
  return baseName.endsWith('.bin') ? baseName : `${baseName}.bin`;
@@ -50004,13 +50240,13 @@ class DeviceUploadWallpaper extends BaseMethod {
50004
50240
  init() {
50005
50241
  const { width, height, rgba, fileName, chunkSize } = this.payload;
50006
50242
  if (width !== PRO2_WALLPAPER_WIDTH || height !== PRO2_WALLPAPER_HEIGHT) {
50007
- throw invalidParameter(`Pro2 wallpaper dimensions must be ${PRO2_WALLPAPER_WIDTH}x${PRO2_WALLPAPER_HEIGHT}.`);
50243
+ throw invalidParameter$1(`Pro2 wallpaper dimensions must be ${PRO2_WALLPAPER_WIDTH}x${PRO2_WALLPAPER_HEIGHT}.`);
50008
50244
  }
50009
50245
  if (!(rgba instanceof ArrayBuffer) && !ArrayBuffer.isView(rgba)) {
50010
- throw invalidParameter('Parameter [rgba] must be an ArrayBuffer or Uint8Array.');
50246
+ throw invalidParameter$1('Parameter [rgba] must be an ArrayBuffer or Uint8Array.');
50011
50247
  }
50012
50248
  if (chunkSize !== undefined && (!Number.isInteger(chunkSize) || chunkSize <= 0)) {
50013
- throw invalidParameter('Parameter [chunkSize] must be a positive integer.');
50249
+ throw invalidParameter$1('Parameter [chunkSize] must be a positive integer.');
50014
50250
  }
50015
50251
  const rgbaBytes = rgba instanceof ArrayBuffer
50016
50252
  ? rgba
@@ -50045,7 +50281,7 @@ class DeviceUploadWallpaper extends BaseMethod {
50045
50281
  return;
50046
50282
  const { encoded } = this;
50047
50283
  if (!encoded)
50048
- throw invalidParameter('Wallpaper data has not been initialized.');
50284
+ throw invalidParameter$1('Wallpaper data has not been initialized.');
50049
50285
  yield writeProtocolV2File({
50050
50286
  commands: this.device.commands,
50051
50287
  path: this.path,
@@ -50070,7 +50306,7 @@ class DeviceUploadWallpaper extends BaseMethod {
50070
50306
  return __awaiter(this, void 0, void 0, function* () {
50071
50307
  const { encoded } = this;
50072
50308
  if (!encoded)
50073
- throw invalidParameter('Wallpaper data has not been initialized.');
50309
+ throw invalidParameter$1('Wallpaper data has not been initialized.');
50074
50310
  yield this.ensureDirectory();
50075
50311
  yield this.upload();
50076
50312
  const response = yield this.device.commands.typedCall('DeviceSettingsSet', 'Success', {
@@ -50086,6 +50322,108 @@ class DeviceUploadWallpaper extends BaseMethod {
50086
50322
  }
50087
50323
  }
50088
50324
 
50325
+ const FILESYSTEM_FILE_WRITE_MESSAGE_TYPE = 60805;
50326
+ const NFT_UPDATE_MESSAGE_TYPE = 61500;
50327
+ class DeviceUploadNft extends BaseMethod {
50328
+ getSupportedProtocols() {
50329
+ return ['V2'];
50330
+ }
50331
+ init() {
50332
+ const { image, thumbnail, title, subtitle, timestampMs = Date.now(), chunkSize = PRO2_NFT_DEFAULT_CHUNK_SIZE, paceMs = PRO2_NFT_DEFAULT_PACE_MS, timeoutMs = PRO2_NFT_DEFAULT_TIMEOUT_MS, } = this.payload;
50333
+ if (!Number.isInteger(chunkSize) ||
50334
+ chunkSize < PRO2_NFT_MIN_CHUNK_SIZE ||
50335
+ chunkSize > PRO2_NFT_MAX_CHUNK_SIZE) {
50336
+ throw invalidParameter$1(`Parameter [chunkSize] must be an integer between ${PRO2_NFT_MIN_CHUNK_SIZE} and ${PRO2_NFT_MAX_CHUNK_SIZE}.`);
50337
+ }
50338
+ if (!Number.isInteger(paceMs) || paceMs < 0) {
50339
+ throw invalidParameter$1('Parameter [paceMs] must be a non-negative integer.');
50340
+ }
50341
+ if (!Number.isInteger(timeoutMs) || timeoutMs <= 0) {
50342
+ throw invalidParameter$1('Parameter [timeoutMs] must be a positive integer.');
50343
+ }
50344
+ this.bundle = buildPro2NftBundle({ image, thumbnail, title, subtitle, timestampMs });
50345
+ this.params = { image, thumbnail, title, subtitle, timestampMs, chunkSize, paceMs, timeoutMs };
50346
+ this.unlockPolicy = 'none';
50347
+ this.skipForceUpdateCheck = true;
50348
+ this.useDevicePassphraseState = false;
50349
+ }
50350
+ assertCapabilities() {
50351
+ return __awaiter(this, void 0, void 0, function* () {
50352
+ const protocolInfo = yield this.device.ensureProtocolV2RuntimeContext();
50353
+ const hasFileWrite = supportsProtocolV2Message(protocolInfo, FILESYSTEM_FILE_WRITE_MESSAGE_TYPE);
50354
+ const hasNftUpdate = supportsProtocolV2Message(protocolInfo, NFT_UPDATE_MESSAGE_TYPE);
50355
+ if (!hasFileWrite || !hasNftUpdate) {
50356
+ throw hdShared.createDeviceNotSupportMethodError(this.name, this.device.getCurrentFirmwareType());
50357
+ }
50358
+ });
50359
+ }
50360
+ updateNft(basename) {
50361
+ return __awaiter(this, void 0, void 0, function* () {
50362
+ const params = { file_name_no_ext: basename };
50363
+ const options = { timeoutMs: this.params.timeoutMs };
50364
+ try {
50365
+ return yield this.device.commands.typedCall('NftUpdate', 'Success', params, options);
50366
+ }
50367
+ catch (error) {
50368
+ if (!isProtocolV2ResponseTimeout(error)) {
50369
+ throw error;
50370
+ }
50371
+ this.throwIfAborted();
50372
+ return this.device.commands.typedCall('NftUpdate', 'Success', params, options);
50373
+ }
50374
+ });
50375
+ }
50376
+ run() {
50377
+ var _a;
50378
+ return __awaiter(this, void 0, void 0, function* () {
50379
+ const { bundle } = this;
50380
+ if (!bundle)
50381
+ throw invalidParameter$1('NFT data has not been initialized.');
50382
+ yield this.assertCapabilities();
50383
+ const files = [
50384
+ { path: `${PRO2_NFT_DIRECTORY}/${bundle.basename}.bin`, data: bundle.image },
50385
+ { path: `${PRO2_NFT_DIRECTORY}/${bundle.basename}_m.bin`, data: bundle.thumbnail },
50386
+ { path: `${PRO2_NFT_DIRECTORY}/${bundle.basename}.json`, data: bundle.metadata },
50387
+ ];
50388
+ const totalSize = files.reduce((sum, file) => sum + file.data.byteLength, 0);
50389
+ let transferredBeforeFile = 0;
50390
+ for (const file of files) {
50391
+ const transferredAtFileStart = transferredBeforeFile;
50392
+ yield writeProtocolV2File({
50393
+ commands: this.device.commands,
50394
+ path: file.path,
50395
+ data: file.data,
50396
+ totalSize: file.data.byteLength,
50397
+ chunkSize: this.params.chunkSize,
50398
+ timeoutMs: this.params.timeoutMs,
50399
+ paceMs: this.params.paceMs,
50400
+ overwrite: true,
50401
+ append: false,
50402
+ throwIfAborted: () => this.throwIfAborted(),
50403
+ onProgress: progress => {
50404
+ if (typeof this.postMessage !== 'function')
50405
+ return;
50406
+ const transferredBytes = transferredAtFileStart + progress.transferredBytes;
50407
+ this.postMessage(createUiMessage(UI_REQUEST.DEVICE_PROGRESS, Object.assign(Object.assign({}, progress), { progress: Math.floor((transferredBytes / totalSize) * 100), transferredBytes, totalBytes: totalSize })));
50408
+ },
50409
+ });
50410
+ transferredBeforeFile += file.data.byteLength;
50411
+ }
50412
+ this.throwIfAborted();
50413
+ const response = yield this.updateNft(bundle.basename);
50414
+ return {
50415
+ basename: bundle.basename,
50416
+ imagePath: files[0].path,
50417
+ thumbnailPath: files[1].path,
50418
+ metadataPath: files[2].path,
50419
+ totalSize,
50420
+ nftUpdated: true,
50421
+ message: (_a = response.message) === null || _a === void 0 ? void 0 : _a.message,
50422
+ };
50423
+ });
50424
+ }
50425
+ }
50426
+
50089
50427
  class FileWrite extends BaseMethod {
50090
50428
  getSupportedProtocols() {
50091
50429
  return ['V2'];
@@ -50210,6 +50548,178 @@ class CipherKeyValue extends BaseMethod {
50210
50548
  }
50211
50549
  }
50212
50550
 
50551
+ const isProtocolV2UiEnabled = (method) => method.protocolV2UiMode !== 'none';
50552
+ const getDisplayState = (value) => {
50553
+ const visited = new Set();
50554
+ let seen = false;
50555
+ let enabled = false;
50556
+ const visit = (current) => {
50557
+ if (current == null || typeof current !== 'object')
50558
+ return;
50559
+ if (visited.has(current))
50560
+ return;
50561
+ visited.add(current);
50562
+ if (Array.isArray(current)) {
50563
+ current.forEach(visit);
50564
+ return;
50565
+ }
50566
+ Object.entries(current).forEach(([key, item]) => {
50567
+ if ((key === 'show_display' || key === 'showOnOneKey') && typeof item === 'boolean') {
50568
+ seen = true;
50569
+ enabled || (enabled = item);
50570
+ return;
50571
+ }
50572
+ visit(item);
50573
+ });
50574
+ };
50575
+ visit(value);
50576
+ return { seen, enabled };
50577
+ };
50578
+ const createMethodInteraction = (reason, operation) => ({
50579
+ request: 'button',
50580
+ source: 'method-lifecycle',
50581
+ reason,
50582
+ completion: 'operation-completed',
50583
+ deviceOnly: true,
50584
+ operation,
50585
+ });
50586
+ const hasCipherConfirmation = (value) => {
50587
+ if (Array.isArray(value))
50588
+ return value.some(hasCipherConfirmation);
50589
+ if (value == null || typeof value !== 'object')
50590
+ return false;
50591
+ const params = value;
50592
+ return params.encrypt === true ? params.ask_on_encrypt === true : params.ask_on_decrypt === true;
50593
+ };
50594
+ const resolveProtocolV2UiInteraction = (method) => {
50595
+ if (method.protocolV2UiInteraction)
50596
+ return method.protocolV2UiInteraction;
50597
+ const operation = method.name;
50598
+ if (!operation)
50599
+ return undefined;
50600
+ const isAddress = /getAddress(?:ByLoop)?$/i.test(operation);
50601
+ const isPublicKey = /getPublicKey$/i.test(operation);
50602
+ if (isAddress || isPublicKey) {
50603
+ const paramsDisplay = getDisplayState(method.params);
50604
+ const payloadDisplay = getDisplayState(method.payload);
50605
+ const display = paramsDisplay.seen ? paramsDisplay : payloadDisplay;
50606
+ const shouldDisplay = display.seen ? display.enabled : isAddress;
50607
+ if (!shouldDisplay)
50608
+ return undefined;
50609
+ return createMethodInteraction(isAddress ? 'address-confirmation' : 'public-key-confirmation', operation);
50610
+ }
50611
+ if (/sign/i.test(operation) || /verifyMessage$/i.test(operation) || operation === 'lnurlAuth') {
50612
+ return createMethodInteraction('signing-confirmation', operation);
50613
+ }
50614
+ if (operation === 'nostrEncryptMessage' || operation === 'nostrDecryptMessage') {
50615
+ const display = getDisplayState(method.params);
50616
+ if (!display.enabled)
50617
+ return undefined;
50618
+ return createMethodInteraction('signing-confirmation', operation);
50619
+ }
50620
+ if (operation === 'cipherKeyValue' && hasCipherConfirmation(method.params)) {
50621
+ return createMethodInteraction('signing-confirmation', operation);
50622
+ }
50623
+ return undefined;
50624
+ };
50625
+ class ProtocolV2UiInteractionCoordinator {
50626
+ constructor(device, postMessage) {
50627
+ this.opened = false;
50628
+ this.closed = false;
50629
+ this.device = device;
50630
+ this.postMessage = postMessage;
50631
+ }
50632
+ enterMethodInteraction(interaction) {
50633
+ var _a, _b, _c, _d;
50634
+ this.methodInteraction = interaction;
50635
+ if (!interaction)
50636
+ return;
50637
+ const { request } = interaction, metadata = __rest(interaction, ["request"]);
50638
+ const interactionMeta = (_b = (_a = this.device).createProtocolV2UiPhaseMetadata) === null || _b === void 0 ? void 0 : _b.call(_a, request === 'pin' ? 'pin' : 'button', 'start');
50639
+ this.emit(request === 'pin' ? UI_REQUEST.REQUEST_PIN : UI_REQUEST.REQUEST_BUTTON, Object.assign(Object.assign({ device: this.device.toMessageObject() }, metadata), (interactionMeta ? { interaction: interactionMeta } : {})), `method:${request}:${interaction.reason}:${(_c = interaction.page) !== null && _c !== void 0 ? _c : ''}:${(_d = interaction.operation) !== null && _d !== void 0 ? _d : ''}`);
50640
+ }
50641
+ enterUnlockInteraction(method) {
50642
+ var _a, _b;
50643
+ const interaction = (_b = (_a = this.device).createProtocolV2UiPhaseMetadata) === null || _b === void 0 ? void 0 : _b.call(_a, 'pin', 'start');
50644
+ this.emit(UI_REQUEST.REQUEST_PIN, Object.assign({ device: this.device.toMessageObject(), source: 'unlock-coordinator', reason: 'device-locked', deviceOnly: true, method }, (interaction ? { interaction } : {})), `unlock:${method !== null && method !== void 0 ? method : ''}`);
50645
+ return interaction;
50646
+ }
50647
+ resumeMethodInteraction() {
50648
+ this.enterMethodInteraction(this.methodInteraction);
50649
+ }
50650
+ close() {
50651
+ var _a, _b, _c, _d;
50652
+ if (!this.device.isProtocolV2() ||
50653
+ (!this.opened && !((_b = (_a = this.device).hasOpenProtocolV2UiInteraction) === null || _b === void 0 ? void 0 : _b.call(_a))) ||
50654
+ this.closed)
50655
+ return;
50656
+ this.closed = true;
50657
+ const interaction = (_d = (_c = this.device).finishProtocolV2UiInteraction) === null || _d === void 0 ? void 0 : _d.call(_c);
50658
+ this.postMessage(interaction
50659
+ ? createUiMessage(UI_REQUEST.CLOSE_UI_WINDOW, interaction)
50660
+ : createUiMessage(UI_REQUEST.CLOSE_UI_WINDOW));
50661
+ }
50662
+ emit(type, payload, phase) {
50663
+ if (!this.device.isProtocolV2() || this.closed || this.currentPhase === phase)
50664
+ return;
50665
+ this.currentPhase = phase;
50666
+ this.opened = true;
50667
+ const message = type === UI_REQUEST.REQUEST_BUTTON
50668
+ ? createUiMessage(UI_REQUEST.REQUEST_BUTTON, payload)
50669
+ : createUiMessage(UI_REQUEST.REQUEST_PIN, payload);
50670
+ this.postMessage(message);
50671
+ }
50672
+ }
50673
+
50674
+ const Log$3 = getLogger(exports.LoggerNames.Core);
50675
+ const createProtocolV2UnlockContext = () => ({
50676
+ preflightCompleted: false,
50677
+ });
50678
+ function runMethodWithUnlockPolicy(method, device, options = {}) {
50679
+ var _a, _b;
50680
+ return __awaiter(this, void 0, void 0, function* () {
50681
+ const { context = createProtocolV2UnlockContext(), uiCoordinator, afterStatusBeforeUnlock, prepare, run: configuredRun, } = options;
50682
+ const run = configuredRun !== null && configuredRun !== void 0 ? configuredRun : (() => method.run());
50683
+ method.protocolV2UnlockContext = context;
50684
+ const shouldEmitUi = isProtocolV2UiEnabled(method);
50685
+ const shouldCoordinateUi = shouldEmitUi && uiCoordinator !== undefined;
50686
+ const requiresPreUnlock = device.isProtocolV2() &&
50687
+ (method.useDevicePassphraseState || method.unlockPolicy === 'unlock-before-run') &&
50688
+ !((_a = device.isBootloader) === null || _a === void 0 ? void 0 : _a.call(device)) &&
50689
+ !((_b = device.isRomloader) === null || _b === void 0 ? void 0 : _b.call(device));
50690
+ if (requiresPreUnlock && !context.preflightCompleted) {
50691
+ const status = yield refreshProtocolV2DeviceStatus(device);
50692
+ if (typeof (status === null || status === void 0 ? void 0 : status.unlocked) !== 'boolean') {
50693
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 DeviceStatus did not report an explicit unlock state.');
50694
+ }
50695
+ yield (afterStatusBeforeUnlock === null || afterStatusBeforeUnlock === void 0 ? void 0 : afterStatusBeforeUnlock());
50696
+ if (!status.unlocked) {
50697
+ const unlockInteraction = shouldCoordinateUi
50698
+ ? uiCoordinator.enterUnlockInteraction(method.name)
50699
+ : undefined;
50700
+ const unlockedStatus = yield device.unlockDevice(undefined, shouldCoordinateUi
50701
+ ? { emitUiEvent: false, interaction: unlockInteraction }
50702
+ : {
50703
+ source: 'unlock-coordinator',
50704
+ reason: 'device-locked',
50705
+ deviceOnly: true,
50706
+ method: method.name,
50707
+ });
50708
+ if ((unlockedStatus === null || unlockedStatus === void 0 ? void 0 : unlockedStatus.unlocked) !== true) {
50709
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 device remained locked after the unlock flow.');
50710
+ }
50711
+ Log$3.debug('Protocol V2 pre-unlock completed', { method: method.name });
50712
+ }
50713
+ context.preflightCompleted = true;
50714
+ }
50715
+ yield (prepare === null || prepare === void 0 ? void 0 : prepare());
50716
+ if (shouldCoordinateUi) {
50717
+ uiCoordinator.enterMethodInteraction(resolveProtocolV2UiInteraction(method));
50718
+ }
50719
+ return run();
50720
+ });
50721
+ }
50722
+
50213
50723
  const Mainnet = 'mainnet';
50214
50724
  const networkAliases = {
50215
50725
  tbtc: { name: 'btc', coin: 'Testnet' },
@@ -50485,16 +50995,26 @@ class AllNetworkGetAddressBase extends BaseMethod {
50485
50995
  this.device.on(DEVICE.PIN, onSignalAbort);
50486
50996
  this.device.on(DEVICE.PASSPHRASE, onSignalAbort);
50487
50997
  preCheckDeviceSupport(this.device, method);
50488
- if (this.temporarySafetyCheckPrompted) {
50489
- method.temporarySafetyCheckPrompted = true;
50490
- }
50491
- else {
50492
- const appliedTemporarySafetyCheck = yield method.checkSafetyLevelOnTestNet();
50493
- if (appliedTemporarySafetyCheck) {
50494
- this.temporarySafetyCheckPrompted = true;
50495
- }
50496
- }
50497
- const response = yield method.run();
50998
+ const response = yield runMethodWithUnlockPolicy(method, this.device, {
50999
+ context: this.protocolV2UnlockContext,
51000
+ prepare: () => __awaiter(this, void 0, void 0, function* () {
51001
+ if (this.temporarySafetyCheckPrompted) {
51002
+ method.temporarySafetyCheckPrompted = true;
51003
+ }
51004
+ else {
51005
+ const appliedTemporarySafetyCheck = yield method.checkSafetyLevelOnTestNet();
51006
+ if (appliedTemporarySafetyCheck) {
51007
+ this.temporarySafetyCheckPrompted = true;
51008
+ }
51009
+ }
51010
+ if (this.device.isProtocolV2() && this.payload.passphraseState) {
51011
+ const passphraseStateSafety = yield this.device.checkPassphraseStateSafety(this.payload.passphraseState, false, this.payload.skipPassphraseCheck);
51012
+ if (!passphraseStateSafety) {
51013
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckPassphraseStateError);
51014
+ }
51015
+ }
51016
+ }),
51017
+ });
50498
51018
  if (!Array.isArray(response) || response.length === 0) {
50499
51019
  throw new Error('No response');
50500
51020
  }
@@ -50535,7 +51055,9 @@ class AllNetworkGetAddressBase extends BaseMethod {
50535
51055
  script_type: 'SPENDADDRESS',
50536
51056
  show_display: false,
50537
51057
  });
50538
- this.postMessage(createUiMessage(UI_REQUEST.CLOSE_UI_PIN_WINDOW));
51058
+ if (!this.device.isProtocolV2()) {
51059
+ this.postMessage(createUiMessage(UI_REQUEST.CLOSE_UI_PIN_WINDOW));
51060
+ }
50539
51061
  if (res.message.root_fingerprint == null) {
50540
51062
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter);
50541
51063
  }
@@ -59737,6 +60259,7 @@ var ApiMethods = /*#__PURE__*/Object.freeze({
59737
60259
  deviceReboot: DeviceReboot,
59738
60260
  deviceGetOnboardingStatus: DeviceGetOnboardingStatus,
59739
60261
  deviceUploadWallpaper: DeviceUploadWallpaper,
60262
+ deviceUploadNft: DeviceUploadNft,
59740
60263
  uploadPortfolio: UploadPortfolio,
59741
60264
  cipherKeyValue: CipherKeyValue,
59742
60265
  allNetworkGetAddress: AllNetworkGetAddress,
@@ -59849,7 +60372,7 @@ const resolveAfter = (msec, value) => new Promise(resolve => {
59849
60372
  setTimeout(resolve, msec, value);
59850
60373
  });
59851
60374
 
59852
- const Log$3 = getLogger(exports.LoggerNames.DeviceConnector);
60375
+ const Log$2 = getLogger(exports.LoggerNames.DeviceConnector);
59853
60376
  class DeviceConnector {
59854
60377
  constructor() {
59855
60378
  this.listenTimestamp = 0;
@@ -59880,7 +60403,7 @@ class DeviceConnector {
59880
60403
  this.listening = true;
59881
60404
  let descriptors;
59882
60405
  try {
59883
- Log$3.debug('Start listening', current);
60406
+ Log$2.debug('Start listening', current);
59884
60407
  this.listenTimestamp = new Date().getTime();
59885
60408
  descriptors = waitForEvent
59886
60409
  ? yield this.transport.listen(current)
@@ -59888,21 +60411,21 @@ class DeviceConnector {
59888
60411
  if (!this.listening)
59889
60412
  return;
59890
60413
  this.upcoming = descriptors;
59891
- Log$3.debug('Listen result', descriptors);
60414
+ Log$2.debug('Listen result', descriptors);
59892
60415
  this._reportDevicesChange();
59893
60416
  if (this.listening)
59894
60417
  this.listen();
59895
60418
  }
59896
60419
  catch (error) {
59897
60420
  const time = new Date().getTime() - this.listenTimestamp;
59898
- Log$3.debug('Listen error', 'timestamp', time, typeof error);
60421
+ Log$2.debug('Listen error', 'timestamp', time, typeof error);
59899
60422
  if (time > 1100) {
59900
60423
  yield resolveAfter(1000, null);
59901
60424
  if (this.listening)
59902
60425
  this.listen();
59903
60426
  }
59904
60427
  else {
59905
- Log$3.warn('Transport error');
60428
+ Log$2.warn('Transport error');
59906
60429
  }
59907
60430
  }
59908
60431
  });
@@ -59912,7 +60435,7 @@ class DeviceConnector {
59912
60435
  }
59913
60436
  acquire(path, session, forceCleanRunPromise, expectedProtocol, protocolHint) {
59914
60437
  return __awaiter(this, void 0, void 0, function* () {
59915
- Log$3.debug('acquire', path, session, expectedProtocol, protocolHint);
60438
+ Log$2.debug('acquire', path, session, expectedProtocol, protocolHint);
59916
60439
  const env = DataManager.getSettings('env');
59917
60440
  try {
59918
60441
  let res;
@@ -59941,7 +60464,7 @@ class DeviceConnector {
59941
60464
  return res;
59942
60465
  }
59943
60466
  catch (error) {
59944
- Log$3.error('acquire error: ', error.message);
60467
+ Log$2.error('acquire error: ', error.message);
59945
60468
  safeThrowError(error);
59946
60469
  }
59947
60470
  });
@@ -59980,7 +60503,7 @@ class DeviceConnector {
59980
60503
  }
59981
60504
  }
59982
60505
 
59983
- const Log$2 = getLogger(exports.LoggerNames.Core);
60506
+ const Log$1 = getLogger(exports.LoggerNames.Core);
59984
60507
  class RequestQueue {
59985
60508
  constructor() {
59986
60509
  this.requestQueue = new Map();
@@ -60013,7 +60536,7 @@ class RequestQueue {
60013
60536
  abortRequest(requestId) {
60014
60537
  const request = this.requestQueue.get(requestId);
60015
60538
  if (request === null || request === void 0 ? void 0 : request.abortController) {
60016
- Log$2.debug(`Aborting request ${requestId}`);
60539
+ Log$1.debug(`Aborting request ${requestId}`);
60017
60540
  request.abortController.abort();
60018
60541
  return true;
60019
60542
  }
@@ -60065,7 +60588,7 @@ class RequestQueue {
60065
60588
  registerPendingCallbackTask(connectId, callbackPromise) {
60066
60589
  this.pendingCallbackTasks.set(connectId, callbackPromise);
60067
60590
  callbackPromise.promise.finally(() => {
60068
- Log$2.debug(`Callback task completed for connectId: ${connectId}`);
60591
+ Log$1.debug(`Callback task completed for connectId: ${connectId}`);
60069
60592
  if (this.pendingCallbackTasks.get(connectId) === callbackPromise) {
60070
60593
  this.pendingCallbackTasks.delete(connectId);
60071
60594
  }
@@ -60075,7 +60598,7 @@ class RequestQueue {
60075
60598
  return __awaiter(this, void 0, void 0, function* () {
60076
60599
  const pendingTask = this.pendingCallbackTasks.get(connectId);
60077
60600
  if (pendingTask && pendingTask !== exceptTask) {
60078
- Log$2.debug(`Waiting for pending callback task to complete for connectId: ${connectId}`);
60601
+ Log$1.debug(`Waiting for pending callback task to complete for connectId: ${connectId}`);
60079
60602
  yield pendingTask.promise;
60080
60603
  }
60081
60604
  });
@@ -60090,6 +60613,8 @@ class RequestQueue {
60090
60613
 
60091
60614
  function registerHardwareUiEventListeners(device, handlers) {
60092
60615
  device.on(DEVICE.PIN, handlers.pin);
60616
+ device.on(DEVICE.PIN_ON_DEVICE, handlers.pinOnDevice);
60617
+ device.on(DEVICE.PIN_ON_DEVICE_COMPLETE, handlers.pinOnDeviceComplete);
60093
60618
  device.on(DEVICE.BUTTON, handlers.button);
60094
60619
  device.on(DEVICE.PASSPHRASE, handlers.passphrase);
60095
60620
  device.on(DEVICE.PASSPHRASE_ON_DEVICE, handlers.passphraseOnDevice);
@@ -60119,208 +60644,6 @@ const getSynchronize = (mutex) => {
60119
60644
  return (action, lockId) => lock(lockId).then(unlock => Promise.resolve().then(action).finally(unlock));
60120
60645
  };
60121
60646
 
60122
- function isDeviceLockedError(error) {
60123
- return (typeof error === 'object' &&
60124
- error !== null &&
60125
- 'errorCode' in error &&
60126
- error.errorCode === hdShared.HardwareErrorCode.DeviceLocked);
60127
- }
60128
-
60129
- const isProtocolV2UiEnabled = (method) => method.protocolV2UiMode !== 'none';
60130
- const getDisplayState = (value) => {
60131
- const visited = new Set();
60132
- let seen = false;
60133
- let enabled = false;
60134
- const visit = (current) => {
60135
- if (current == null || typeof current !== 'object')
60136
- return;
60137
- if (visited.has(current))
60138
- return;
60139
- visited.add(current);
60140
- if (Array.isArray(current)) {
60141
- current.forEach(visit);
60142
- return;
60143
- }
60144
- Object.entries(current).forEach(([key, item]) => {
60145
- if ((key === 'show_display' || key === 'showOnOneKey') && typeof item === 'boolean') {
60146
- seen = true;
60147
- enabled || (enabled = item);
60148
- return;
60149
- }
60150
- visit(item);
60151
- });
60152
- };
60153
- visit(value);
60154
- return { seen, enabled };
60155
- };
60156
- const createMethodInteraction = (reason, operation) => ({
60157
- request: 'button',
60158
- source: 'method-lifecycle',
60159
- reason,
60160
- completion: 'operation-completed',
60161
- deviceOnly: true,
60162
- operation,
60163
- });
60164
- const hasCipherConfirmation = (value) => {
60165
- if (Array.isArray(value))
60166
- return value.some(hasCipherConfirmation);
60167
- if (value == null || typeof value !== 'object')
60168
- return false;
60169
- const params = value;
60170
- return params.encrypt === true ? params.ask_on_encrypt === true : params.ask_on_decrypt === true;
60171
- };
60172
- const resolveProtocolV2UiInteraction = (method) => {
60173
- if (method.protocolV2UiInteraction)
60174
- return method.protocolV2UiInteraction;
60175
- const operation = method.name;
60176
- if (!operation)
60177
- return undefined;
60178
- const isAddress = /getAddress(?:ByLoop)?$/i.test(operation);
60179
- const isPublicKey = /getPublicKey$/i.test(operation);
60180
- if (isAddress || isPublicKey) {
60181
- const paramsDisplay = getDisplayState(method.params);
60182
- const payloadDisplay = getDisplayState(method.payload);
60183
- const display = paramsDisplay.seen ? paramsDisplay : payloadDisplay;
60184
- const shouldDisplay = display.seen ? display.enabled : isAddress;
60185
- if (!shouldDisplay)
60186
- return undefined;
60187
- return createMethodInteraction(isAddress ? 'address-confirmation' : 'public-key-confirmation', operation);
60188
- }
60189
- if (/sign/i.test(operation) || /verifyMessage$/i.test(operation) || operation === 'lnurlAuth') {
60190
- return createMethodInteraction('signing-confirmation', operation);
60191
- }
60192
- if (operation === 'nostrEncryptMessage' || operation === 'nostrDecryptMessage') {
60193
- const display = getDisplayState(method.params);
60194
- if (!display.enabled)
60195
- return undefined;
60196
- return createMethodInteraction('signing-confirmation', operation);
60197
- }
60198
- if (operation === 'cipherKeyValue' && hasCipherConfirmation(method.params)) {
60199
- return createMethodInteraction('signing-confirmation', operation);
60200
- }
60201
- return undefined;
60202
- };
60203
- class ProtocolV2UiInteractionCoordinator {
60204
- constructor(device, postMessage) {
60205
- this.opened = false;
60206
- this.closed = false;
60207
- this.device = device;
60208
- this.postMessage = postMessage;
60209
- }
60210
- enterMethodInteraction(interaction) {
60211
- var _a, _b;
60212
- this.methodInteraction = interaction;
60213
- if (!interaction)
60214
- return;
60215
- const { request } = interaction, metadata = __rest(interaction, ["request"]);
60216
- this.emit(request === 'pin' ? UI_REQUEST.REQUEST_PIN : UI_REQUEST.REQUEST_BUTTON, Object.assign({ device: this.device.toMessageObject() }, metadata), `method:${request}:${interaction.reason}:${(_a = interaction.page) !== null && _a !== void 0 ? _a : ''}:${(_b = interaction.operation) !== null && _b !== void 0 ? _b : ''}`);
60217
- }
60218
- enterUnlockInteraction(method) {
60219
- this.emit(UI_REQUEST.REQUEST_PIN, {
60220
- device: this.device.toMessageObject(),
60221
- source: 'unlock-coordinator',
60222
- reason: 'device-locked',
60223
- deviceOnly: true,
60224
- method,
60225
- }, `unlock:${method !== null && method !== void 0 ? method : ''}`);
60226
- }
60227
- resumeMethodInteraction() {
60228
- this.enterMethodInteraction(this.methodInteraction);
60229
- }
60230
- close() {
60231
- if (!this.device.isProtocolV2() || !this.opened || this.closed)
60232
- return;
60233
- this.closed = true;
60234
- this.postMessage(createUiMessage(UI_REQUEST.CLOSE_UI_WINDOW));
60235
- }
60236
- emit(type, payload, phase) {
60237
- if (!this.device.isProtocolV2() || this.closed || this.currentPhase === phase)
60238
- return;
60239
- this.currentPhase = phase;
60240
- this.opened = true;
60241
- const message = type === UI_REQUEST.REQUEST_BUTTON
60242
- ? createUiMessage(UI_REQUEST.REQUEST_BUTTON, payload)
60243
- : createUiMessage(UI_REQUEST.REQUEST_PIN, payload);
60244
- this.postMessage(message);
60245
- }
60246
- }
60247
-
60248
- const Log$1 = getLogger(exports.LoggerNames.Core);
60249
- const restoreExpectedWalletSessionAfterUnlock = (method, device) => __awaiter(void 0, void 0, void 0, function* () {
60250
- var _a, _b, _c;
60251
- const expectedPassphraseState = ((_a = method.payload) === null || _a === void 0 ? void 0 : _a.useEmptyPassphrase)
60252
- ? undefined
60253
- : (_c = (_b = method.payload) === null || _b === void 0 ? void 0 : _b.passphraseState) !== null && _c !== void 0 ? _c : device.passphraseState;
60254
- if (!method.useDevicePassphraseState ||
60255
- typeof expectedPassphraseState !== 'string' ||
60256
- expectedPassphraseState.length === 0) {
60257
- return;
60258
- }
60259
- yield restoreProtocolV2WalletSession(device, expectedPassphraseState);
60260
- Log$1.debug('Protocol V2 wallet session restored after unlock', { method: method.name });
60261
- });
60262
- function runMethodWithUnlockRetry(method, device, uiCoordinator) {
60263
- var _a, _b, _c, _d, _e;
60264
- return __awaiter(this, void 0, void 0, function* () {
60265
- const shouldEmitUi = isProtocolV2UiEnabled(method);
60266
- const isProtocolV2 = device.isProtocolV2();
60267
- const requiresFreshStatus = isProtocolV2 &&
60268
- method.unlockPolicy === 'unlock-before-run' &&
60269
- !((_a = device.isBootloader) === null || _a === void 0 ? void 0 : _a.call(device)) &&
60270
- !((_b = device.isRomloader) === null || _b === void 0 ? void 0 : _b.call(device));
60271
- if (requiresFreshStatus) {
60272
- yield refreshProtocolV2DeviceStatus(device);
60273
- }
60274
- const shouldUnlockBeforeRun = isProtocolV2 &&
60275
- method.unlockPolicy !== 'none' &&
60276
- !((_c = device.isBootloader) === null || _c === void 0 ? void 0 : _c.call(device)) &&
60277
- !((_d = device.isRomloader) === null || _d === void 0 ? void 0 : _d.call(device)) &&
60278
- ((_e = device.features) === null || _e === void 0 ? void 0 : _e.unlocked) === false;
60279
- if (shouldUnlockBeforeRun) {
60280
- if (shouldEmitUi) {
60281
- uiCoordinator === null || uiCoordinator === void 0 ? void 0 : uiCoordinator.enterUnlockInteraction(method.name);
60282
- }
60283
- yield device.unlockDevice();
60284
- Log$1.debug('Protocol V2 pre-unlock completed', { method: method.name });
60285
- yield restoreExpectedWalletSessionAfterUnlock(method, device);
60286
- if (shouldEmitUi) {
60287
- uiCoordinator === null || uiCoordinator === void 0 ? void 0 : uiCoordinator.enterMethodInteraction(resolveProtocolV2UiInteraction(method));
60288
- }
60289
- return method.run();
60290
- }
60291
- if (shouldEmitUi) {
60292
- uiCoordinator === null || uiCoordinator === void 0 ? void 0 : uiCoordinator.enterMethodInteraction(resolveProtocolV2UiInteraction(method));
60293
- }
60294
- try {
60295
- return yield method.run();
60296
- }
60297
- catch (error) {
60298
- if (!isProtocolV2 || method.unlockPolicy !== 'retry-on-locked' || !isDeviceLockedError(error)) {
60299
- throw error;
60300
- }
60301
- Log$1.debug('Protocol V2 unlock retry triggered', { method: method.name });
60302
- if (shouldEmitUi) {
60303
- uiCoordinator === null || uiCoordinator === void 0 ? void 0 : uiCoordinator.enterUnlockInteraction(method.name);
60304
- }
60305
- yield device.unlockDevice();
60306
- Log$1.debug('Protocol V2 unlock completed', { method: method.name });
60307
- yield restoreExpectedWalletSessionAfterUnlock(method, device);
60308
- if (shouldEmitUi) {
60309
- uiCoordinator === null || uiCoordinator === void 0 ? void 0 : uiCoordinator.resumeMethodInteraction();
60310
- }
60311
- try {
60312
- const response = yield method.run();
60313
- Log$1.debug('Protocol V2 method retry completed', { method: method.name, success: true });
60314
- return response;
60315
- }
60316
- catch (retryError) {
60317
- Log$1.debug('Protocol V2 method retry completed', { method: method.name, success: false });
60318
- throw retryError;
60319
- }
60320
- }
60321
- });
60322
- }
60323
-
60324
60647
  const Log = getLogger(exports.LoggerNames.Core);
60325
60648
  const PRE_INITIALIZE_TTL_MS = 60 * 1000;
60326
60649
  const preWarmInflight = new Map();
@@ -60552,6 +60875,8 @@ const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, voi
60552
60875
  }
60553
60876
  registerHardwareUiEventListeners(device, {
60554
60877
  pin: onDevicePinHandler,
60878
+ pinOnDevice: onEnterPinOnDeviceHandler,
60879
+ pinOnDeviceComplete: onPinOnDeviceCompleteHandler,
60555
60880
  button: onDeviceButtonHandler,
60556
60881
  passphrase: message.payload.useEmptyPassphrase
60557
60882
  ? onEmptyPassphraseHandler
@@ -60563,6 +60888,7 @@ const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, voi
60563
60888
  device.on(DEVICE.STATE, onDeviceStateHandler);
60564
60889
  device.on(DEVICE.SELECT_DEVICE_IN_BOOTLOADER_FOR_WEB_DEVICE, onSelectDeviceInBootloaderForWebDeviceHandler);
60565
60890
  const protocolV2UiCoordinator = new ProtocolV2UiInteractionCoordinator(device, postMessage);
60891
+ device.beginProtocolV2UiInteraction();
60566
60892
  device.on(DEVICE.SELECT_DEVICE_FOR_SWITCH_FIRMWARE_WEB_DEVICE, onSelectDeviceForSwitchFirmwareWebDeviceHandler);
60567
60893
  try {
60568
60894
  if (method.connectId) {
@@ -60570,7 +60896,7 @@ const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, voi
60570
60896
  }
60571
60897
  yield waitForPendingPromise(getPrePendingCallPromise, setPrePendingCallPromise);
60572
60898
  const inner = () => __awaiter(void 0, void 0, void 0, function* () {
60573
- var _j, _k, _l, _m, _o, _p, _q;
60899
+ var _j, _k;
60574
60900
  method.assertProtocolSupported(device.getProtocol(), device.getCurrentFirmwareType());
60575
60901
  const versionRange = device.getCurrentMethodVersionRange(type => method.getVersionRange()[type]);
60576
60902
  const currentFirmwareVersion = (_j = device.getCurrentFirmwareVersionString()) !== null && _j !== void 0 ? _j : '0.0.0';
@@ -60639,45 +60965,60 @@ const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, voi
60639
60965
  }
60640
60966
  return Promise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceUnexpectedMode, unexpectedMode));
60641
60967
  }
60642
- if (method.deviceId && method.checkDeviceId) {
60643
- const isSameDeviceID = yield checkLiveDeviceId(device, method.deviceId);
60644
- if (!isSameDeviceID) {
60645
- return Promise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckDeviceIdError));
60646
- }
60647
- }
60648
- method.checkFirmwareRelease();
60649
- method.checkDeviceSupportFeature();
60650
- if (_deviceList && device.features && !device.isProtocolV2()) {
60651
- yield TransportManager.reconfigure(device.features);
60652
- }
60653
- checkPassphraseEnableState(method, device.features);
60654
- if (shouldCheckPassphraseState(method, device)) {
60655
- const support = device.supportNewPassphrase();
60656
- if (!support.support) {
60657
- return Promise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceNotSupportPassphrase, `Device not support passphrase, please update to ${support.require}`, {
60658
- require: support.require,
60659
- }));
60660
- }
60661
- const passphraseStateSafety = yield device.checkPassphraseStateSafety((_l = method.payload) === null || _l === void 0 ? void 0 : _l.passphraseState, (_m = method.payload) === null || _m === void 0 ? void 0 : _m.useEmptyPassphrase, (_o = method.payload) === null || _o === void 0 ? void 0 : _o.skipPassphraseCheck);
60662
- checkPassphraseEnableState(method, device.features);
60663
- if (!passphraseStateSafety) {
60664
- DevicePool.clearDeviceCache(method.payload.connectId);
60665
- return Promise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckPassphraseStateError));
60666
- }
60667
- postMessage(createUiMessage(UI_REQUEST.CLOSE_UI_PIN_WINDOW));
60668
- }
60669
- try {
60670
- yield method.checkSafetyLevelOnTestNet();
60671
- }
60672
- catch (e) {
60673
- const error = e instanceof hdShared.HardwareError
60674
- ? e
60675
- : hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'open safety check failed.');
60676
- throw error;
60677
- }
60678
- (_q = (_p = method.device) === null || _p === void 0 ? void 0 : _p.commands) === null || _q === void 0 ? void 0 : _q.checkDisposed();
60679
60968
  try {
60680
- const response = yield runMethodWithUnlockRetry(method, device, protocolV2UiCoordinator);
60969
+ let deviceIdCheckedDuringUnlockPreflight = false;
60970
+ const response = yield runMethodWithUnlockPolicy(method, device, {
60971
+ uiCoordinator: protocolV2UiCoordinator,
60972
+ afterStatusBeforeUnlock: () => {
60973
+ if (method.deviceId && method.checkDeviceId) {
60974
+ if (!device.checkDeviceId(method.deviceId)) {
60975
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckDeviceIdError);
60976
+ }
60977
+ deviceIdCheckedDuringUnlockPreflight = true;
60978
+ }
60979
+ },
60980
+ prepare: () => __awaiter(void 0, void 0, void 0, function* () {
60981
+ var _l, _m, _o, _p, _q;
60982
+ if (method.deviceId && method.checkDeviceId && !deviceIdCheckedDuringUnlockPreflight) {
60983
+ const isSameDeviceID = yield checkLiveDeviceId(device, method.deviceId);
60984
+ if (!isSameDeviceID) {
60985
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckDeviceIdError);
60986
+ }
60987
+ }
60988
+ method.checkFirmwareRelease();
60989
+ method.checkDeviceSupportFeature();
60990
+ if (_deviceList && device.features && !device.isProtocolV2()) {
60991
+ yield TransportManager.reconfigure(device.features);
60992
+ }
60993
+ checkPassphraseEnableState(method, device.features);
60994
+ if (shouldCheckPassphraseState(method, device)) {
60995
+ const support = device.supportNewPassphrase();
60996
+ if (!support.support) {
60997
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceNotSupportPassphrase, `Device not support passphrase, please update to ${support.require}`, {
60998
+ require: support.require,
60999
+ });
61000
+ }
61001
+ const passphraseStateSafety = yield device.checkPassphraseStateSafety((_l = method.payload) === null || _l === void 0 ? void 0 : _l.passphraseState, (_m = method.payload) === null || _m === void 0 ? void 0 : _m.useEmptyPassphrase, (_o = method.payload) === null || _o === void 0 ? void 0 : _o.skipPassphraseCheck, hasDeriveCardano(method));
61002
+ checkPassphraseEnableState(method, device.features);
61003
+ if (!passphraseStateSafety) {
61004
+ DevicePool.clearDeviceCache(method.payload.connectId);
61005
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckPassphraseStateError);
61006
+ }
61007
+ if (!device.isProtocolV2()) {
61008
+ postMessage(createUiMessage(UI_REQUEST.CLOSE_UI_PIN_WINDOW));
61009
+ }
61010
+ }
61011
+ try {
61012
+ yield method.checkSafetyLevelOnTestNet();
61013
+ }
61014
+ catch (e) {
61015
+ throw e instanceof hdShared.HardwareError
61016
+ ? e
61017
+ : hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'open safety check failed.');
61018
+ }
61019
+ (_q = (_p = method.device) === null || _p === void 0 ? void 0 : _p.commands) === null || _q === void 0 ? void 0 : _q.checkDisposed();
61020
+ }),
61021
+ });
60681
61022
  messageResponse = createResponseMessage(method.responseID, true, response);
60682
61023
  requestQueue.resolveRequest(method.responseID, messageResponse);
60683
61024
  completeMethodRequestContext(method);
@@ -61173,15 +61514,7 @@ const onDeviceStateHandler = (...[_, stateEvent]) => {
61173
61514
  const onDevicePassphraseHandler = (...[device, requestPayload, callback]) => __awaiter(void 0, void 0, void 0, function* () {
61174
61515
  Log.debug('onDevicePassphraseHandler');
61175
61516
  const uiPromise = createUiPromise(UI_RESPONSE.RECEIVE_PASSPHRASE, device);
61176
- postMessage(createUiMessage(UI_REQUEST.REQUEST_PASSPHRASE, {
61177
- device: device.toMessageObject(),
61178
- passphraseState: device.passphraseState,
61179
- existsAttachPinUser: requestPayload.existsAttachPinUser,
61180
- deviceOnly: requestPayload.deviceOnly,
61181
- source: requestPayload.source,
61182
- reason: requestPayload.reason,
61183
- expectedPassphraseState: requestPayload.expectedPassphraseState,
61184
- }));
61517
+ postMessage(createUiMessage(UI_REQUEST.REQUEST_PASSPHRASE, Object.assign({ device: device.toMessageObject(), passphraseState: device.passphraseState, existsAttachPinUser: requestPayload.existsAttachPinUser, deviceOnly: requestPayload.deviceOnly, source: requestPayload.source, reason: requestPayload.reason, expectedPassphraseState: requestPayload.expectedPassphraseState }, (requestPayload.interaction ? { interaction: requestPayload.interaction } : {}))));
61185
61518
  const uiResp = yield uiPromise.promise;
61186
61519
  const { value, passphraseOnDevice, save, attachPinOnDevice } = uiResp.payload;
61187
61520
  callback({
@@ -61196,20 +61529,19 @@ const onEmptyPassphraseHandler = (...[_, , callback]) => {
61196
61529
  callback({ passphrase: '' });
61197
61530
  };
61198
61531
  const onEnterPassphraseOnDeviceHandler = (...[device, requestPayload]) => {
61199
- postMessage(createUiMessage(UI_REQUEST.REQUEST_PASSPHRASE_ON_DEVICE, {
61200
- device: device.toMessageObject(),
61201
- passphraseState: device.passphraseState,
61202
- source: requestPayload === null || requestPayload === void 0 ? void 0 : requestPayload.source,
61203
- reason: requestPayload === null || requestPayload === void 0 ? void 0 : requestPayload.reason,
61204
- }));
61532
+ postMessage(createUiMessage(UI_REQUEST.REQUEST_PASSPHRASE_ON_DEVICE, Object.assign({ device: device.toMessageObject(), passphraseState: device.passphraseState, source: requestPayload === null || requestPayload === void 0 ? void 0 : requestPayload.source, reason: requestPayload === null || requestPayload === void 0 ? void 0 : requestPayload.reason }, ((requestPayload === null || requestPayload === void 0 ? void 0 : requestPayload.interaction) ? { interaction: requestPayload.interaction } : {}))));
61205
61533
  };
61206
61534
  const onEnterAttachPinOnDeviceHandler = (...[device, requestPayload]) => {
61207
- postMessage(createUiMessage(UI_REQUEST.REQUEST_PIN, {
61208
- device: device.toMessageObject(),
61209
- type: 'ButtonRequest_AttachPin',
61210
- source: requestPayload === null || requestPayload === void 0 ? void 0 : requestPayload.source,
61211
- reason: requestPayload === null || requestPayload === void 0 ? void 0 : requestPayload.reason,
61212
- }));
61535
+ postMessage(createUiMessage(UI_REQUEST.REQUEST_PIN, Object.assign({ device: device.toMessageObject(), type: 'ButtonRequest_AttachPin', source: requestPayload === null || requestPayload === void 0 ? void 0 : requestPayload.source, reason: requestPayload === null || requestPayload === void 0 ? void 0 : requestPayload.reason }, ((requestPayload === null || requestPayload === void 0 ? void 0 : requestPayload.interaction) ? { interaction: requestPayload.interaction } : {}))));
61536
+ };
61537
+ const onEnterPinOnDeviceHandler = (...[device, pinType, metadata]) => {
61538
+ var _a;
61539
+ postMessage(createUiMessage(UI_REQUEST.REQUEST_PIN, Object.assign({ device: device.toMessageObject(), type: pinType === hdTransport.DeviceSessionPinType.AttachToPin
61540
+ ? 'ButtonRequest_AttachPin'
61541
+ : 'ButtonRequest_PinEntry', source: metadata === null || metadata === void 0 ? void 0 : metadata.source, reason: metadata === null || metadata === void 0 ? void 0 : metadata.reason, deviceOnly: (_a = metadata === null || metadata === void 0 ? void 0 : metadata.deviceOnly) !== null && _a !== void 0 ? _a : true, completion: metadata === null || metadata === void 0 ? void 0 : metadata.completion, method: metadata === null || metadata === void 0 ? void 0 : metadata.method, page: metadata === null || metadata === void 0 ? void 0 : metadata.page, operation: metadata === null || metadata === void 0 ? void 0 : metadata.operation }, ((metadata === null || metadata === void 0 ? void 0 : metadata.interaction) ? { interaction: metadata.interaction } : {}))));
61542
+ };
61543
+ const onPinOnDeviceCompleteHandler = (...[_, metadata]) => {
61544
+ postMessage(createUiMessage(UI_REQUEST.CLOSE_UI_PIN_WINDOW, metadata));
61213
61545
  };
61214
61546
  const onSelectDeviceInBootloaderForWebDeviceHandler = (...[device, callback]) => __awaiter(void 0, void 0, void 0, function* () {
61215
61547
  Log.debug('onSelectDeviceInBootloaderForWebDeviceHandler');
@@ -61525,6 +61857,7 @@ exports.getLog = getLog;
61525
61857
  exports.getLogBlockLabel = getLogBlockLabel;
61526
61858
  exports.getLogger = getLogger;
61527
61859
  exports.getMethodVersionRange = getMethodVersionRange;
61860
+ exports.getNftSize = getNftSize;
61528
61861
  exports.getOutputScriptType = getOutputScriptType;
61529
61862
  exports.getSDKVersion = getSDKVersion;
61530
61863
  exports.getSafeLogPayload = getSafeLogPayload;