@onekeyfe/hd-core 1.2.0-alpha.100 → 1.2.0-alpha.102

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 (56) hide show
  1. package/__tests__/bridgeBinaryPayload.test.ts +173 -0
  2. package/__tests__/check-all-firmware-release-protocol-v2.test.ts +2 -0
  3. package/__tests__/device-pool-state.test.ts +29 -0
  4. package/__tests__/firmware-update/firmware-update-plan.test.ts +59 -55
  5. package/__tests__/get-device-state.test.ts +102 -13
  6. package/__tests__/protocol-v2-legacy-recovery.test.ts +29 -0
  7. package/__tests__/protocol-v2.test.ts +234 -1
  8. package/__tests__/refresh-device-state.test.ts +4 -1
  9. package/__tests__/search-devices.test.ts +2 -0
  10. package/__tests__/ton-sign-message.test.ts +84 -0
  11. package/dist/api/FirmwareUpdateV4.d.ts +3 -0
  12. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  13. package/dist/api/GetDeviceState.d.ts.map +1 -1
  14. package/dist/api/SearchDevices.d.ts.map +1 -1
  15. package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +1 -1
  16. package/dist/api/firmware/protocolV2Release.d.ts.map +1 -1
  17. package/dist/api/ton/TonSignMessage.d.ts.map +1 -1
  18. package/dist/api/utils.d.ts.map +1 -1
  19. package/dist/core/index.d.ts.map +1 -1
  20. package/dist/core/protocolV2LegacyRecovery.d.ts +5 -0
  21. package/dist/core/protocolV2LegacyRecovery.d.ts.map +1 -0
  22. package/dist/device/Device.d.ts +9 -2
  23. package/dist/device/Device.d.ts.map +1 -1
  24. package/dist/device/DevicePool.d.ts +1 -1
  25. package/dist/device/DevicePool.d.ts.map +1 -1
  26. package/dist/index.d.ts +14 -4
  27. package/dist/index.js +263 -71
  28. package/dist/protocols/protocol-v2/features.d.ts +8 -0
  29. package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
  30. package/dist/protocols/protocol-v2/index.d.ts +2 -2
  31. package/dist/protocols/protocol-v2/index.d.ts.map +1 -1
  32. package/dist/topLevelInject.d.ts.map +1 -1
  33. package/dist/types/api/firmwareUpdatePlan.d.ts +2 -2
  34. package/dist/types/api/firmwareUpdatePlan.d.ts.map +1 -1
  35. package/dist/types/api/getDeviceState.d.ts +1 -0
  36. package/dist/types/api/getDeviceState.d.ts.map +1 -1
  37. package/dist/utils/bridgeBinaryPayload.d.ts +3 -0
  38. package/dist/utils/bridgeBinaryPayload.d.ts.map +1 -0
  39. package/package.json +4 -4
  40. package/src/api/FirmwareUpdateV4.ts +70 -23
  41. package/src/api/GetDeviceState.ts +1 -0
  42. package/src/api/SearchDevices.ts +2 -0
  43. package/src/api/firmware/FirmwareUpdatePlan.ts +37 -36
  44. package/src/api/firmware/protocolV2Release.ts +1 -0
  45. package/src/api/ton/TonSignMessage.ts +5 -3
  46. package/src/api/utils.ts +5 -2
  47. package/src/core/index.ts +4 -0
  48. package/src/core/protocolV2LegacyRecovery.ts +12 -0
  49. package/src/device/Device.ts +78 -20
  50. package/src/device/DevicePool.ts +17 -5
  51. package/src/protocols/protocol-v2/features.ts +10 -0
  52. package/src/protocols/protocol-v2/index.ts +2 -0
  53. package/src/topLevelInject.ts +4 -2
  54. package/src/types/api/firmwareUpdatePlan.ts +2 -2
  55. package/src/types/api/getDeviceState.ts +2 -0
  56. package/src/utils/bridgeBinaryPayload.ts +137 -0
package/dist/index.js CHANGED
@@ -7,6 +7,7 @@ var sha256 = require('@noble/hashes/sha256');
7
7
  var utils = require('@noble/hashes/utils');
8
8
  var semver = require('semver');
9
9
  var hdTransport = require('@onekeyfe/hd-transport');
10
+ var buffer = require('buffer');
10
11
  var axios = require('axios');
11
12
  var lodash = require('lodash');
12
13
  var ByteBuffer = require('bytebuffer');
@@ -15,7 +16,6 @@ var BigNumber = require('bignumber.js');
15
16
  var JSZip = require('jszip');
16
17
  var sha3 = require('@noble/hashes/sha3');
17
18
  var blake2b = require('@noble/hashes/blake2b');
18
- var buffer = require('buffer');
19
19
 
20
20
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
21
21
 
@@ -734,7 +734,7 @@ const assertFirmwareUpdatePlan = (value) => {
734
734
  if (!artifact) {
735
735
  return planError('Firmware update plan artifact is invalid');
736
736
  }
737
- assertExactKeys(artifact, ['artifactId', 'role', 'target', 'url', 'container', 'expectedSize', 'expectedSha256'], ['logicalName', 'targetVersion']);
737
+ assertExactKeys(artifact, ['artifactId', 'role', 'target', 'url', 'container'], ['logicalName', 'expectedSize', 'expectedSha256', 'targetVersion']);
738
738
  const artifactId = assertBoundedString(artifact.artifactId, 'artifact id', 160);
739
739
  if (artifactIds.has(artifactId)) {
740
740
  return planError('Firmware update plan contains duplicate artifact ids');
@@ -750,13 +750,19 @@ const assertFirmwareUpdatePlan = (value) => {
750
750
  if (artifact.logicalName !== undefined) {
751
751
  assertBoundedString(artifact.logicalName, 'logical name', 256);
752
752
  }
753
- if (!Number.isSafeInteger(artifact.expectedSize) || artifact.expectedSize <= 0) {
753
+ if (artifact.expectedSize !== undefined &&
754
+ (!Number.isSafeInteger(artifact.expectedSize) || artifact.expectedSize <= 0)) {
754
755
  return planError('Firmware update plan artifact size is invalid');
755
756
  }
756
- if (typeof artifact.expectedSha256 !== 'string' ||
757
- !/^[a-f0-9]{64}$/u.test(artifact.expectedSha256)) {
757
+ if (artifact.expectedSha256 !== undefined &&
758
+ (typeof artifact.expectedSha256 !== 'string' ||
759
+ !/^[a-f0-9]{64}$/u.test(artifact.expectedSha256))) {
758
760
  return planError('Firmware update plan artifact digest is invalid');
759
761
  }
762
+ if (plan.executor === 'v4' &&
763
+ (artifact.expectedSize === undefined || artifact.expectedSha256 === undefined)) {
764
+ return planError('Protocol V2 firmware artifact integrity metadata is invalid');
765
+ }
760
766
  if (artifact.targetVersion !== undefined) {
761
767
  assertBoundedString(artifact.targetVersion, 'target version', 64);
762
768
  }
@@ -1007,10 +1013,10 @@ const buildFirmwareUpdatePlan = ({ features, firmwareType, platform, firmware, b
1007
1013
  else {
1008
1014
  if (isUpgrade(bootloader) || forcedTargets.has('bootloader')) {
1009
1015
  const bootloaderRelease = asRelease(bootloader);
1010
- const integrity = requireArtifactIntegrity({
1016
+ const integrity = asIntegrity({
1011
1017
  size: bootloaderRelease === null || bootloaderRelease === void 0 ? void 0 : bootloaderRelease.bootloaderExpectedSize,
1012
1018
  sha256: bootloaderRelease === null || bootloaderRelease === void 0 ? void 0 : bootloaderRelease.bootloaderFingerprint,
1013
- }, 'Bootloader release');
1019
+ });
1014
1020
  artifacts.push(Object.assign(Object.assign({ artifactId: 'bootloader', role: 'bootloader', target: 'bootloader', url: assertArtifactUrl(bootloaderRelease === null || bootloaderRelease === void 0 ? void 0 : bootloaderRelease.bootloaderResource, 'Bootloader release'), container: 'raw' }, integrity), (asVersion(bootloaderRelease === null || bootloaderRelease === void 0 ? void 0 : bootloaderRelease.bootloaderVersion)
1015
1021
  ? {
1016
1022
  targetVersion: asVersion(bootloaderRelease === null || bootloaderRelease === void 0 ? void 0 : bootloaderRelease.bootloaderVersion),
@@ -1024,7 +1030,10 @@ const buildFirmwareUpdatePlan = ({ features, firmwareType, platform, firmware, b
1024
1030
  });
1025
1031
  }
1026
1032
  if (shouldUpdateFirmware) {
1027
- const integrity = requireArtifactIntegrity({ size: firmwareRelease.expectedSize, sha256: firmwareRelease.fingerprint }, 'Firmware release');
1033
+ const integrity = asIntegrity({
1034
+ size: firmwareRelease.expectedSize,
1035
+ sha256: firmwareRelease.fingerprint,
1036
+ });
1028
1037
  artifacts.push(Object.assign(Object.assign({ artifactId: 'firmware', role: 'firmware', target: 'firmware', url: assertArtifactUrl(firmwareRelease.url, 'Firmware release'), container: 'raw' }, integrity), (asVersion(firmwareRelease.version)
1029
1038
  ? { targetVersion: asVersion(firmwareRelease.version) }
1030
1039
  : {})));
@@ -1036,24 +1045,24 @@ const buildFirmwareUpdatePlan = ({ features, firmwareType, platform, firmware, b
1036
1045
  platform,
1037
1046
  });
1038
1047
  if (resourceUrl) {
1039
- const integrity = requireArtifactIntegrity({
1048
+ const integrity = asIntegrity({
1040
1049
  size: resourceUrl === asString(firmwareRelease.fullResource)
1041
1050
  ? firmwareRelease.fullResourceExpectedSize
1042
1051
  : firmwareRelease.resourceExpectedSize,
1043
1052
  sha256: resourceUrl === asString(firmwareRelease.fullResource)
1044
1053
  ? firmwareRelease.fullResourceFingerprint
1045
1054
  : firmwareRelease.resourceFingerprint,
1046
- }, 'Legacy resource archive');
1055
+ });
1047
1056
  artifacts.push(Object.assign({ artifactId: 'resource', role: 'resource', target: 'resource', url: assertArtifactUrl(resourceUrl, 'Firmware resource release'), container: 'zip' }, integrity));
1048
1057
  }
1049
1058
  }
1050
1059
  }
1051
1060
  if (isUpgrade(ble) || isRecoveryInstall(ble) || forcedTargets.has('ble')) {
1052
1061
  const bleRelease = asRelease(ble);
1053
- const integrity = requireArtifactIntegrity({
1062
+ const integrity = asIntegrity({
1054
1063
  size: bleRelease === null || bleRelease === void 0 ? void 0 : bleRelease.expectedSize,
1055
1064
  sha256: (_a = bleRelease === null || bleRelease === void 0 ? void 0 : bleRelease.fingerprintWeb) !== null && _a !== void 0 ? _a : bleRelease === null || bleRelease === void 0 ? void 0 : bleRelease.fingerprint,
1056
- }, 'BLE release');
1065
+ });
1057
1066
  artifacts.push(Object.assign(Object.assign({ artifactId: 'ble', role: 'ble', target: 'ble', url: assertArtifactUrl((_b = bleRelease === null || bleRelease === void 0 ? void 0 : bleRelease.webUpdate) !== null && _b !== void 0 ? _b : bleRelease === null || bleRelease === void 0 ? void 0 : bleRelease.url, 'BLE release'), container: 'raw' }, integrity), (asVersion(bleRelease === null || bleRelease === void 0 ? void 0 : bleRelease.version)
1058
1067
  ? { targetVersion: asVersion(bleRelease === null || bleRelease === void 0 ? void 0 : bleRelease.version) }
1059
1068
  : {})));
@@ -2210,14 +2219,132 @@ function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
2210
2219
  }
2211
2220
  }
2212
2221
 
2222
+ const BRIDGE_BINARY_PAYLOAD_MARKER = '__onekey_hd_bridge_binary_payload__';
2223
+ const BASE64_PATTERN = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
2224
+ const invalidBinaryPayload = (message) => hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, message);
2225
+ function isPlainObject(value) {
2226
+ if (!value || typeof value !== 'object' || Array.isArray(value))
2227
+ return false;
2228
+ const prototype = Object.getPrototypeOf(value);
2229
+ return prototype === Object.prototype || prototype === null;
2230
+ }
2231
+ function isArrayBufferValue(value) {
2232
+ return Boolean(typeof ArrayBuffer !== 'undefined' &&
2233
+ (value instanceof ArrayBuffer ||
2234
+ Object.prototype.toString.call(value) === '[object ArrayBuffer]'));
2235
+ }
2236
+ function isBlobValue(value) {
2237
+ return Boolean(typeof Blob !== 'undefined' &&
2238
+ (value instanceof Blob || Object.prototype.toString.call(value) === '[object Blob]') &&
2239
+ typeof value.arrayBuffer === 'function');
2240
+ }
2241
+ function readBinaryPayload(value) {
2242
+ if (!isPlainObject(value) || !(BRIDGE_BINARY_PAYLOAD_MARKER in value))
2243
+ return undefined;
2244
+ const payload = value;
2245
+ if (payload[BRIDGE_BINARY_PAYLOAD_MARKER] !== 1 ||
2246
+ (payload.type !== 'array-buffer' && payload.type !== 'uint8-array') ||
2247
+ typeof payload.data !== 'string') {
2248
+ throw invalidBinaryPayload('Invalid bridge binary payload');
2249
+ }
2250
+ return payload;
2251
+ }
2252
+ function bytesToPayload(bytes, type) {
2253
+ return {
2254
+ [BRIDGE_BINARY_PAYLOAD_MARKER]: 1,
2255
+ data: buffer.Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString('base64'),
2256
+ type,
2257
+ };
2258
+ }
2259
+ function payloadToBytes(payload) {
2260
+ if (payload.data.length % 4 !== 0 || !BASE64_PATTERN.test(payload.data)) {
2261
+ throw invalidBinaryPayload('Invalid bridge binary payload data');
2262
+ }
2263
+ const decoded = buffer.Buffer.from(payload.data, 'base64');
2264
+ if (decoded.toString('base64') !== payload.data) {
2265
+ throw invalidBinaryPayload('Invalid bridge binary payload data');
2266
+ }
2267
+ return Uint8Array.from(decoded);
2268
+ }
2269
+ function encodeValue(value, seen) {
2270
+ return __awaiter(this, void 0, void 0, function* () {
2271
+ if (isArrayBufferValue(value)) {
2272
+ return bytesToPayload(new Uint8Array(value), 'array-buffer');
2273
+ }
2274
+ if (typeof ArrayBuffer !== 'undefined' && ArrayBuffer.isView(value)) {
2275
+ return bytesToPayload(new Uint8Array(value.buffer, value.byteOffset, value.byteLength), 'uint8-array');
2276
+ }
2277
+ if (isBlobValue(value)) {
2278
+ return bytesToPayload(new Uint8Array(yield value.arrayBuffer()), 'uint8-array');
2279
+ }
2280
+ const encodedPayload = readBinaryPayload(value);
2281
+ if (encodedPayload)
2282
+ return encodedPayload;
2283
+ if (Array.isArray(value)) {
2284
+ if (seen.has(value))
2285
+ throw invalidBinaryPayload('Circular bridge payload');
2286
+ seen.add(value);
2287
+ try {
2288
+ const encoded = [];
2289
+ for (const item of value) {
2290
+ encoded.push(yield encodeValue(item, seen));
2291
+ }
2292
+ return encoded.some((item, index) => item !== value[index]) ? encoded : value;
2293
+ }
2294
+ finally {
2295
+ seen.delete(value);
2296
+ }
2297
+ }
2298
+ if (!isPlainObject(value))
2299
+ return value;
2300
+ if (seen.has(value))
2301
+ throw invalidBinaryPayload('Circular bridge payload');
2302
+ seen.add(value);
2303
+ try {
2304
+ const entries = [];
2305
+ for (const [key, item] of Object.entries(value)) {
2306
+ entries.push([key, yield encodeValue(item, seen)]);
2307
+ }
2308
+ return entries.some(([key, item]) => item !== value[key]) ? Object.fromEntries(entries) : value;
2309
+ }
2310
+ finally {
2311
+ seen.delete(value);
2312
+ }
2313
+ });
2314
+ }
2315
+ function decodeValue(value) {
2316
+ const payload = readBinaryPayload(value);
2317
+ if (payload) {
2318
+ const bytes = payloadToBytes(payload);
2319
+ return payload.type === 'array-buffer' ? bytes.buffer : bytes;
2320
+ }
2321
+ if (Array.isArray(value)) {
2322
+ const decoded = value.map(decodeValue);
2323
+ return decoded.some((item, index) => item !== value[index]) ? decoded : value;
2324
+ }
2325
+ if (!isPlainObject(value))
2326
+ return value;
2327
+ const entries = Object.entries(value).map(([key, item]) => [key, decodeValue(item)]);
2328
+ return entries.some(([key, item]) => item !== value[key]) ? Object.fromEntries(entries) : value;
2329
+ }
2330
+ function encodeBridgeBinaryPayload(value) {
2331
+ return __awaiter(this, void 0, void 0, function* () {
2332
+ return encodeValue(value, new WeakSet());
2333
+ });
2334
+ }
2335
+ function decodeBridgeBinaryPayload(value) {
2336
+ return decodeValue(value);
2337
+ }
2338
+
2213
2339
  const eventEmitter = new events.exports();
2214
2340
  const topLevelInject = () => {
2215
2341
  let lowLevelApi;
2216
- const call = (params) => {
2342
+ const call = (params) => __awaiter(void 0, void 0, void 0, function* () {
2217
2343
  if (!lowLevelApi)
2218
2344
  return Promise.resolve(undefined);
2219
- return lowLevelApi.call(params);
2220
- };
2345
+ const encodedParams = yield encodeBridgeBinaryPayload(params);
2346
+ return lowLevelApi.call(encodedParams);
2347
+ });
2221
2348
  const protocolAwareCall = createProtocolAwareCall(call);
2222
2349
  const api = Object.assign(Object.assign({ on: (type, fn) => {
2223
2350
  eventEmitter.on(type, fn);
@@ -43233,7 +43360,7 @@ class DevicePool extends events.exports {
43233
43360
  try {
43234
43361
  yield device.initialize(initOptions);
43235
43362
  if ((initOptions === null || initOptions === void 0 ? void 0 : initOptions.refreshRuntimeState) && device.isProtocolV2()) {
43236
- yield this._refreshProtocolV2DiscoveryState(device);
43363
+ yield this._refreshProtocolV2DiscoveryState(device, initOptions);
43237
43364
  }
43238
43365
  }
43239
43366
  finally {
@@ -43250,26 +43377,28 @@ class DevicePool extends events.exports {
43250
43377
  let refreshError;
43251
43378
  yield device.run(() => __awaiter(this, void 0, void 0, function* () {
43252
43379
  try {
43253
- yield this._refreshProtocolV2DiscoveryState(device);
43380
+ yield this._refreshProtocolV2DiscoveryState(device, initOptions);
43254
43381
  }
43255
43382
  catch (error) {
43256
43383
  refreshError = error;
43257
43384
  }
43258
- }), {
43259
- connectProtocol: initOptions.connectProtocol,
43260
- forceProtocolDetection: initOptions.forceProtocolDetection,
43261
- });
43385
+ }), Object.assign({ connectProtocol: initOptions.connectProtocol, forceProtocolDetection: initOptions.forceProtocolDetection }, (initOptions.allowLegacyProtocolV2ProtocolInfo
43386
+ ? { allowLegacyProtocolV2ProtocolInfo: true }
43387
+ : {})));
43262
43388
  if (refreshError instanceof Error)
43263
43389
  throw refreshError;
43264
43390
  if (refreshError)
43265
43391
  throw new Error(String(refreshError));
43266
43392
  });
43267
43393
  }
43268
- static _refreshProtocolV2DiscoveryState(device) {
43394
+ static _refreshProtocolV2DiscoveryState(device, initOptions) {
43269
43395
  return __awaiter(this, void 0, void 0, function* () {
43270
- yield device.getDeviceState({ refreshSections: ['status'] });
43396
+ const stateReadOptions = (initOptions === null || initOptions === void 0 ? void 0 : initOptions.allowLegacyProtocolV2ProtocolInfo)
43397
+ ? { allowLegacyProtocolV2ProtocolInfo: true }
43398
+ : {};
43399
+ yield device.getDeviceState(Object.assign({ refreshSections: ['status'] }, stateReadOptions));
43271
43400
  try {
43272
- yield device.getDeviceState({ refreshSections: ['settings'] });
43401
+ yield device.getDeviceState(Object.assign({ refreshSections: ['settings'] }, stateReadOptions));
43273
43402
  }
43274
43403
  catch (error) {
43275
43404
  Log$j.debug('Unable to refresh Protocol V2 device label during discovery', error);
@@ -44217,6 +44346,7 @@ const getProtocolV2SeState = (se) => {
44217
44346
  }
44218
44347
  };
44219
44348
  const getProtocolV2SeType = (se) => normalizeEnumValue(hdTransport.DeviceSeType, se === null || se === void 0 ? void 0 : se.type);
44349
+ const isLegacyProtocolV2ProtocolInfo = (protocolInfo) => Object.prototype.hasOwnProperty.call(protocolInfo, 'protobuf_definition');
44220
44350
  const parseProtocolV2BuildFingerprint = (buildFingerprint) => {
44221
44351
  if (!buildFingerprint)
44222
44352
  return null;
@@ -45632,7 +45762,9 @@ class Device extends events.exports {
45632
45762
  commands: this.commands,
45633
45763
  timeoutMs: options === null || options === void 0 ? void 0 : options.protocolV2DeviceInfoTimeoutMs,
45634
45764
  });
45635
- const features = yield this.probeProtocolV2RuntimeState(deviceInfo, options === null || options === void 0 ? void 0 : options.protocolV2DeviceInfoTimeoutMs);
45765
+ const features = (options === null || options === void 0 ? void 0 : options.allowLegacyProtocolV2ProtocolInfo)
45766
+ ? yield this.probeProtocolV2RuntimeState(deviceInfo, options.protocolV2DeviceInfoTimeoutMs, { allowLegacyProtocolV2ProtocolInfo: true })
45767
+ : yield this.probeProtocolV2RuntimeState(deviceInfo, options === null || options === void 0 ? void 0 : options.protocolV2DeviceInfoTimeoutMs);
45636
45768
  Log$g.debug('Protocol V2 features:', features);
45637
45769
  }
45638
45770
  catch (error) {
@@ -45655,7 +45787,7 @@ class Device extends events.exports {
45655
45787
  });
45656
45788
  }
45657
45789
  getDeviceState(params = {}) {
45658
- var _a, _b, _c;
45790
+ var _a, _b, _c, _d;
45659
45791
  return __awaiter(this, void 0, void 0, function* () {
45660
45792
  const refresh = new Set((_a = params.refreshSections) !== null && _a !== void 0 ? _a : []);
45661
45793
  const getProtocolV2DeviceInfoRequest = () => {
@@ -45673,7 +45805,14 @@ class Device extends events.exports {
45673
45805
  commands: this.commands,
45674
45806
  request: getProtocolV2DeviceInfoRequest(),
45675
45807
  });
45676
- yield this.probeProtocolV2RuntimeState(deviceInfo);
45808
+ if (params.allowLegacyProtocolV2ProtocolInfo) {
45809
+ yield this.probeProtocolV2RuntimeState(deviceInfo, undefined, {
45810
+ allowLegacyProtocolV2ProtocolInfo: true,
45811
+ });
45812
+ }
45813
+ else {
45814
+ yield this.probeProtocolV2RuntimeState(deviceInfo);
45815
+ }
45677
45816
  refreshedDeviceInfo = deviceInfo;
45678
45817
  initializedWithDeviceInfo = true;
45679
45818
  }
@@ -45703,9 +45842,12 @@ class Device extends events.exports {
45703
45842
  }
45704
45843
  }
45705
45844
  if (refresh.has('status') && !initializedWithDeviceInfo) {
45706
- yield this.probeProtocolV2RuntimeState(refreshedDeviceInfo);
45845
+ const cachedMode = (_c = this.state) === null || _c === void 0 ? void 0 : _c.status.mode;
45846
+ yield this.probeProtocolV2RuntimeState(refreshedDeviceInfo, undefined, Object.assign({ forceRuntimeContextRefresh: cachedMode === 'bootloader' || cachedMode === 'romloader' }, (params.allowLegacyProtocolV2ProtocolInfo
45847
+ ? { allowLegacyProtocolV2ProtocolInfo: true }
45848
+ : {})));
45707
45849
  }
45708
- if (refresh.has('settings') && ((_c = this.state) === null || _c === void 0 ? void 0 : _c.status.mode) === 'normal') {
45850
+ if (refresh.has('settings') && ((_d = this.state) === null || _d === void 0 ? void 0 : _d.status.mode) === 'normal') {
45709
45851
  const { message } = yield this.commands.typedCall('DeviceSettingsGet', 'DeviceSettings', {});
45710
45852
  this.updateState(mapDeviceSettingsToState(message), 'settings-read');
45711
45853
  }
@@ -45763,18 +45905,27 @@ class Device extends events.exports {
45763
45905
  this.updateState(mapFeaturesToState(normalized), source);
45764
45906
  return this.features;
45765
45907
  }
45766
- ensureProtocolV2RuntimeContext(timeoutMs) {
45908
+ ensureProtocolV2RuntimeContext(timeoutMs, options) {
45767
45909
  var _a, _b, _c, _d;
45768
45910
  return __awaiter(this, void 0, void 0, function* () {
45769
- const cachedProtocolInfo = (_a = this.protocolV2RuntimeContext) !== null && _a !== void 0 ? _a : (!this.protocolV2StateNeedsReload
45770
- ? (_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
45771
- : undefined);
45911
+ const assertProtocolInfoAllowed = (protocolInfo) => {
45912
+ if (isLegacyProtocolV2ProtocolInfo(protocolInfo) &&
45913
+ (options === null || options === void 0 ? void 0 : options.allowLegacyProtocolV2ProtocolInfo) !== true) {
45914
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInitializeFailed, 'Legacy Protocol V2 ProtocolInfo is supported only during device discovery and firmware update.');
45915
+ }
45916
+ return protocolInfo;
45917
+ };
45918
+ const cachedProtocolInfo = (options === null || options === void 0 ? void 0 : options.forceRefresh) === true
45919
+ ? undefined
45920
+ : (_a = this.protocolV2RuntimeContext) !== null && _a !== void 0 ? _a : (!this.protocolV2StateNeedsReload
45921
+ ? (_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
45922
+ : undefined);
45772
45923
  if (cachedProtocolInfo) {
45773
45924
  this.protocolV2RuntimeContext = cachedProtocolInfo;
45774
- return cachedProtocolInfo;
45925
+ return assertProtocolInfoAllowed(cachedProtocolInfo);
45775
45926
  }
45776
45927
  if (this.protocolV2RuntimeContextPromise) {
45777
- return this.protocolV2RuntimeContextPromise;
45928
+ return assertProtocolInfoAllowed(yield this.protocolV2RuntimeContextPromise);
45778
45929
  }
45779
45930
  const requestToken = {};
45780
45931
  const pendingRequest = (() => __awaiter(this, void 0, void 0, function* () {
@@ -45791,7 +45942,7 @@ class Device extends events.exports {
45791
45942
  this.protocolV2RuntimeContextRequestToken = requestToken;
45792
45943
  this.protocolV2RuntimeContextPromise = pendingRequest;
45793
45944
  try {
45794
- return yield pendingRequest;
45945
+ return assertProtocolInfoAllowed(yield pendingRequest);
45795
45946
  }
45796
45947
  finally {
45797
45948
  if (this.protocolV2RuntimeContextPromise === pendingRequest) {
@@ -45803,11 +45954,15 @@ class Device extends events.exports {
45803
45954
  }
45804
45955
  });
45805
45956
  }
45806
- probeProtocolV2RuntimeState(deviceInfo, timeoutMs) {
45957
+ probeProtocolV2RuntimeState(deviceInfo, timeoutMs, options) {
45807
45958
  var _a, _b, _c;
45808
45959
  return __awaiter(this, void 0, void 0, function* () {
45809
- const protocolInfo = yield this.ensureProtocolV2RuntimeContext(timeoutMs);
45960
+ const protocolInfo = yield this.ensureProtocolV2RuntimeContext(timeoutMs, {
45961
+ forceRefresh: options === null || options === void 0 ? void 0 : options.forceRuntimeContextRefresh,
45962
+ allowLegacyProtocolV2ProtocolInfo: options === null || options === void 0 ? void 0 : options.allowLegacyProtocolV2ProtocolInfo,
45963
+ });
45810
45964
  const runtimeMode = getProtocolV2RuntimeMode(protocolInfo);
45965
+ const legacyProtocolInfo = isLegacyProtocolV2ProtocolInfo(protocolInfo);
45811
45966
  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;
45812
45967
  const protocolV2DeviceType = runtimeDeviceInfo
45813
45968
  ? resolveProtocolV2DeviceIdentity((_c = runtimeDeviceInfo.hw) === null || _c === void 0 ? void 0 : _c.Device_type).deviceType
@@ -45817,7 +45972,8 @@ class Device extends events.exports {
45817
45972
  protocolV2DeviceType !== hdShared.EDeviceType.Neo) {
45818
45973
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInitializeFailed, 'Protocol V2 romloader mode is only supported for Pro2 and Neo.');
45819
45974
  }
45820
- const deviceStatusSupported = supportsProtocolV2Message(protocolInfo, PROTOCOL_V2_DEVICE_STATUS_GET_MESSAGE_TYPE);
45975
+ const deviceStatusSupported = legacyProtocolInfo ||
45976
+ supportsProtocolV2Message(protocolInfo, PROTOCOL_V2_DEVICE_STATUS_GET_MESSAGE_TYPE);
45821
45977
  if (runtimeMode === 'bootloader' || runtimeMode === 'romloader') {
45822
45978
  return this.updateProtocolV2Features(deviceInfo, null, runtimeMode, protocolInfo);
45823
45979
  }
@@ -46069,6 +46225,7 @@ class Device extends events.exports {
46069
46225
  var _a, _b;
46070
46226
  return __awaiter(this, void 0, void 0, function* () {
46071
46227
  const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInterruptedFromUser);
46228
+ this.markTransportDisconnected();
46072
46229
  yield ((_a = this.cancelableAction) === null || _a === void 0 ? void 0 : _a.call(this, error));
46073
46230
  yield ((_b = this.commands) === null || _b === void 0 ? void 0 : _b.cancel());
46074
46231
  if (this.runPromise) {
@@ -46823,6 +46980,7 @@ class SearchDevices extends BaseMethod {
46823
46980
  connectProtocol: undefined,
46824
46981
  forceProtocolDetection: true,
46825
46982
  refreshRuntimeState: true,
46983
+ allowLegacyProtocolV2ProtocolInfo: true,
46826
46984
  });
46827
46985
  deviceList.push(...result.deviceList);
46828
46986
  }
@@ -46906,9 +47064,7 @@ class GetDeviceState extends BaseMethod {
46906
47064
  }
46907
47065
  run() {
46908
47066
  return __awaiter(this, void 0, void 0, function* () {
46909
- const state = yield this.device.getDeviceState({
46910
- refreshSections: SCOPE_SECTIONS[this.params.scope],
46911
- });
47067
+ const state = yield this.device.getDeviceState(Object.assign({ refreshSections: SCOPE_SECTIONS[this.params.scope] }, (this.params.scope === 'firmware' ? { allowLegacyProtocolV2ProtocolInfo: true } : {})));
46912
47068
  if (this.params.scope === 'settings' &&
46913
47069
  this.device.isProtocolV2() &&
46914
47070
  isLoaderMode(state.status.mode)) {
@@ -47447,6 +47603,7 @@ function loadProtocolV2FirmwareReleaseContext({ device, firmwareType: firmwareTy
47447
47603
  refreshSections: checkFirmwareHash
47448
47604
  ? ['identity', 'versions', 'verification']
47449
47605
  : ['identity', 'versions'],
47606
+ allowLegacyProtocolV2ProtocolInfo: true,
47450
47607
  });
47451
47608
  if (state.identity.deviceType !== 'pro2' && state.identity.deviceType !== 'neo') {
47452
47609
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceNotSupportMethod, `${methodName} requires a Pro2 or Neo device for Protocol V2`);
@@ -51810,6 +51967,10 @@ const isProtocolV2FirmwareStatusEndpointUnavailable = (error) => {
51810
51967
  message.includes('message handler not found') ||
51811
51968
  message.includes('unsupported message'));
51812
51969
  };
51970
+ const isProtocolV2FirmwareUpdateEndpointUnavailable = (error) => {
51971
+ const message = getProtocolV2UnknownErrorText(error).toLowerCase();
51972
+ return (message.includes('handler not registered') || message.includes('message handler not found'));
51973
+ };
51813
51974
  const isProtocolV2TerminalInstallStatusError = (error) => {
51814
51975
  var _a;
51815
51976
  return error instanceof hdShared.HardwareError &&
@@ -51942,6 +52103,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
51942
52103
  this.protocolV2HasExplicitTargetSelection = false;
51943
52104
  this.protocolV2PreparedSources = [];
51944
52105
  this.protocolV2ExecutionInLoader = false;
52106
+ this.protocolV2LegacyDirectUpdate = false;
51945
52107
  this.protocolV2BootResourceStagingSafe = false;
51946
52108
  this.protocolV2CompletedTargetVersions = new Map();
51947
52109
  this.protocolV2FinalStatusVerified = false;
@@ -53047,19 +53209,13 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53047
53209
  }
53048
53210
  return ((_a = this.device.features) === null || _a === void 0 ? void 0 : _a.mode) === 'romloader';
53049
53211
  }
53050
- enterProtocolV2BootloaderMode() {
53212
+ isLegacyProtocolV2Runtime() {
53213
+ var _a, _b;
53214
+ const protocolInfo = (_b = (_a = this.device.state) === null || _a === void 0 ? void 0 : _a.raw) === null || _b === void 0 ? void 0 : _b.protocolV2ProtocolInfo;
53215
+ return protocolInfo ? isLegacyProtocolV2ProtocolInfo(protocolInfo) : false;
53216
+ }
53217
+ rebootProtocolV2ToBootloader() {
53051
53218
  return __awaiter(this, void 0, void 0, function* () {
53052
- if (this.isProtocolV2RomloaderMode()) {
53053
- Log$6.debug('Protocol V2 device is in romloader mode; start firmware update directly');
53054
- this.protocolV2ExecutionInLoader = true;
53055
- return false;
53056
- }
53057
- if (this.isProtocolV2BootloaderMode()) {
53058
- Log$6.debug('Protocol V2 device is already in bootloader mode, skip reboot');
53059
- this.protocolV2ExecutionInLoader = true;
53060
- this.postTipMessage(exports.FirmwareUpdateTipMessage.GoToBootloaderSuccess);
53061
- return false;
53062
- }
53063
53219
  try {
53064
53220
  this.postTipMessage(exports.FirmwareUpdateTipMessage.AutoRebootToBootloader);
53065
53221
  yield this.protocolV2Reboot(hdTransport.DeviceRebootType.Bootloader);
@@ -53078,6 +53234,25 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53078
53234
  }
53079
53235
  });
53080
53236
  }
53237
+ enterProtocolV2BootloaderMode() {
53238
+ return __awaiter(this, void 0, void 0, function* () {
53239
+ this.protocolV2LegacyDirectUpdate = false;
53240
+ if (this.isProtocolV2RomloaderMode()) {
53241
+ Log$6.debug('Protocol V2 device is in romloader mode; start firmware update directly');
53242
+ this.protocolV2LegacyDirectUpdate = this.isLegacyProtocolV2Runtime();
53243
+ this.protocolV2ExecutionInLoader = true;
53244
+ return false;
53245
+ }
53246
+ if (this.isProtocolV2BootloaderMode()) {
53247
+ Log$6.debug('Protocol V2 device is already in bootloader mode, skip reboot');
53248
+ this.protocolV2LegacyDirectUpdate = this.isLegacyProtocolV2Runtime();
53249
+ this.protocolV2ExecutionInLoader = true;
53250
+ this.postTipMessage(exports.FirmwareUpdateTipMessage.GoToBootloaderSuccess);
53251
+ return false;
53252
+ }
53253
+ return this.rebootProtocolV2ToBootloader();
53254
+ });
53255
+ }
53081
53256
  waitForProtocolV2BootloaderMode(timeout = PROTOCOL_V2_BOOTLOADER_RECONNECT_TIMEOUT, retryInterval = 1000) {
53082
53257
  return __awaiter(this, void 0, void 0, function* () {
53083
53258
  const startTime = Date.now();
@@ -53094,7 +53269,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53094
53269
  timeoutMs: this.getProtocolV2DeviceInfoTimeout(),
53095
53270
  });
53096
53271
  this.assertProtocolV2DeviceInfoIdentity(deviceInfo);
53097
- const features = yield this.device.probeProtocolV2RuntimeState(deviceInfo, PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT);
53272
+ const features = yield this.device.probeProtocolV2RuntimeState(deviceInfo, PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT, { allowLegacyProtocolV2ProtocolInfo: true });
53098
53273
  if ((features === null || features === void 0 ? void 0 : features.mode) === 'bootloader') {
53099
53274
  return features;
53100
53275
  }
@@ -53588,7 +53763,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53588
53763
  }
53589
53764
  probeProtocolV2NormalMode(deviceInfo) {
53590
53765
  return __awaiter(this, void 0, void 0, function* () {
53591
- const features = yield this.device.probeProtocolV2RuntimeState(deviceInfo, PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT);
53766
+ const features = yield this.device.probeProtocolV2RuntimeState(deviceInfo, PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT, { allowLegacyProtocolV2ProtocolInfo: true });
53592
53767
  return features.mode === 'normal' && !features.bootloaderMode;
53593
53768
  });
53594
53769
  }
@@ -53641,7 +53816,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53641
53816
  request: PROTOCOL_V2_VERSIONS_DEVICE_INFO_REQUEST,
53642
53817
  });
53643
53818
  this.assertProtocolV2DeviceInfoIdentity(deviceInfo);
53644
- const features = yield this.device.probeProtocolV2RuntimeState(deviceInfo, PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT);
53819
+ const features = yield this.device.probeProtocolV2RuntimeState(deviceInfo, PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT, { allowLegacyProtocolV2ProtocolInfo: true });
53645
53820
  if (features.mode === 'normal' && !features.bootloaderMode) {
53646
53821
  return features;
53647
53822
  }
@@ -53768,7 +53943,22 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53768
53943
  protocolV2StartFirmwareUpdate({ targets, }) {
53769
53944
  return __awaiter(this, void 0, void 0, function* () {
53770
53945
  const commands = this.device.getCommands();
53771
- const response = yield commands.typedCall('DeviceFirmwareUpdateRequest', 'Success', { targets }, { timeoutMs: PROTOCOL_V2_START_UPDATE_TIMEOUT });
53946
+ const startUpdate = () => commands.typedCall('DeviceFirmwareUpdateRequest', 'Success', { targets }, { timeoutMs: PROTOCOL_V2_START_UPDATE_TIMEOUT });
53947
+ let response;
53948
+ try {
53949
+ response = yield startUpdate();
53950
+ }
53951
+ catch (error) {
53952
+ if (!this.protocolV2LegacyDirectUpdate ||
53953
+ !isProtocolV2FirmwareUpdateEndpointUnavailable(error)) {
53954
+ throw error;
53955
+ }
53956
+ this.protocolV2LegacyDirectUpdate = false;
53957
+ Log$6.debug('[FirmwareUpdateV4] legacy App does not expose DeviceFirmwareUpdateRequest; rebooting to bootloader');
53958
+ yield this.rebootProtocolV2ToBootloader();
53959
+ response = yield startUpdate();
53960
+ }
53961
+ this.protocolV2LegacyDirectUpdate = false;
53772
53962
  this.postTipMessage(exports.FirmwareUpdateTipMessage.FirmwareUpdating);
53773
53963
  this.postProgressMessage(0, 'installingFirmware');
53774
53964
  return response;
@@ -63221,11 +63411,13 @@ class TonSignMessage extends BaseMethod {
63221
63411
  super(...arguments);
63222
63412
  this.initState = null;
63223
63413
  this.processTxRequest = (request, data) => __awaiter(this, void 0, void 0, function* () {
63414
+ var _a;
63224
63415
  if (!request.init_data_length) {
63225
63416
  const deviceType = this.device.getCurrentDeviceType();
63226
63417
  const hasClassic = DeviceModelToTypes.model_classic1s.includes(deviceType);
63227
- const hasSigningMessageRepr = request.signning_message == null;
63228
- return Promise.resolve(Object.assign(Object.assign({}, request), { skip_validate: hasClassic || hasSigningMessageRepr }));
63418
+ const signingMessage = (_a = request.signing_message) !== null && _a !== void 0 ? _a : request.signning_message;
63419
+ const shouldSkipValidation = signingMessage == null;
63420
+ return Promise.resolve(Object.assign(Object.assign({}, request), { signing_message: signingMessage, skip_validate: hasClassic || shouldSkipValidation }));
63229
63421
  }
63230
63422
  const [first, rest] = cutString(data, request.init_data_length * 2);
63231
63423
  const response = yield this.device.commands.typedCall('TonTxAck', 'TonSignedMessage', {
@@ -64349,13 +64541,15 @@ var ApiMethods = /*#__PURE__*/Object.freeze({
64349
64541
 
64350
64542
  const publicMethodRegistry = ApiMethods;
64351
64543
  function findMethod(message) {
64352
- const { method } = message.payload;
64544
+ const payload = decodeBridgeBinaryPayload(message.payload);
64545
+ const normalizedMessage = payload === message.payload ? message : Object.assign(Object.assign({}, message), { payload });
64546
+ const { method } = payload;
64353
64547
  if (typeof method !== 'string') {
64354
64548
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, 'Method is not set');
64355
64549
  }
64356
64550
  const MethodConstructor = publicMethodRegistry[method];
64357
64551
  if (MethodConstructor) {
64358
- return new MethodConstructor(message);
64552
+ return new MethodConstructor(normalizedMessage);
64359
64553
  }
64360
64554
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, `Method ${method} is not set`);
64361
64555
  }
@@ -64730,6 +64924,10 @@ const createUiProgressMessageFilter = (intervalMs = DEFAULT_UI_PROGRESS_INTERVAL
64730
64924
  };
64731
64925
  };
64732
64926
 
64927
+ const isLegacyProtocolV2FirmwareRecoveryMethod = (method) => (method === null || method === void 0 ? void 0 : method.name) === 'firmwareUpdateV4' ||
64928
+ (method === null || method === void 0 ? void 0 : method.name) === 'checkAllFirmwareRelease' ||
64929
+ ((method === null || method === void 0 ? void 0 : method.name) === 'getDeviceState' && method.payload.scope === 'firmware');
64930
+
64733
64931
  const Log = getLogger(exports.LoggerNames.Core);
64734
64932
  const PRE_INITIALIZE_TTL_MS = 60 * 1000;
64735
64933
  const preWarmInflight = new Map();
@@ -64744,15 +64942,9 @@ function hasDeriveCardano(method) {
64744
64942
  }
64745
64943
  return method.name.startsWith('cardano') || ((_a = method.payload) === null || _a === void 0 ? void 0 : _a.deriveCardano);
64746
64944
  }
64747
- const parseInitOptions = (method) => ({
64748
- initSession: method === null || method === void 0 ? void 0 : method.payload.initSession,
64749
- passphraseState: (method === null || method === void 0 ? void 0 : method.payload.useEmptyPassphrase) ? undefined : method === null || method === void 0 ? void 0 : method.payload.passphraseState,
64750
- deviceId: method === null || method === void 0 ? void 0 : method.payload.deviceId,
64751
- deriveCardano: method && hasDeriveCardano(method),
64752
- connectProtocol: method === null || method === void 0 ? void 0 : method.payload.connectProtocol,
64753
- forceProtocolDetection: method === null || method === void 0 ? void 0 : method.payload.forceProtocolDetection,
64754
- protocolV2DeviceInfoTimeoutMs: method === null || method === void 0 ? void 0 : method.payload.protocolV2DeviceInfoTimeoutMs,
64755
- });
64945
+ const parseInitOptions = (method) => (Object.assign({ initSession: method === null || method === void 0 ? void 0 : method.payload.initSession, passphraseState: (method === null || method === void 0 ? void 0 : method.payload.useEmptyPassphrase) ? undefined : method === null || method === void 0 ? void 0 : method.payload.passphraseState, deviceId: method === null || method === void 0 ? void 0 : method.payload.deviceId, deriveCardano: method && hasDeriveCardano(method), connectProtocol: method === null || method === void 0 ? void 0 : method.payload.connectProtocol, forceProtocolDetection: method === null || method === void 0 ? void 0 : method.payload.forceProtocolDetection, protocolV2DeviceInfoTimeoutMs: method === null || method === void 0 ? void 0 : method.payload.protocolV2DeviceInfoTimeoutMs }, (isLegacyProtocolV2FirmwareRecoveryMethod(method)
64946
+ ? { allowLegacyProtocolV2ProtocolInfo: true }
64947
+ : {})));
64756
64948
  let _core;
64757
64949
  let _deviceList;
64758
64950
  let _connector;
@@ -7,6 +7,14 @@ export type ProtocolV2SeStateLabel = 'BOOT' | 'APP_FACTORY' | 'APP';
7
7
  export declare const getProtocolV2SeState: (se?: DeviceSEInfo) => ProtocolV2SeStateLabel | null;
8
8
  export declare const getProtocolV2SeType: (se?: DeviceSEInfo) => string | null;
9
9
  export type ProtocolV2RuntimeMode = 'normal' | 'bootloader' | 'romloader';
10
+ export type ProtocolV2ProtocolInfo = ProtocolInfo & {
11
+ protobuf_definition?: string | null;
12
+ };
13
+ export declare const isLegacyProtocolV2ProtocolInfo: (protocolInfo: ProtocolInfo) => protocolInfo is ProtocolInfo & {
14
+ protobuf_definition?: string | null | undefined;
15
+ } & {
16
+ protobuf_definition: string | null;
17
+ };
10
18
  export type ProtocolV2BuildFingerprint = {
11
19
  binary: 'application' | 'bootloader' | 'romloader';
12
20
  version: string;