@onekeyfe/hd-core 1.2.2-alpha.1 → 1.2.2-alpha.10

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 (34) hide show
  1. package/__tests__/AllNetworkGetAddressBase.tracing.test.ts +2 -2
  2. package/__tests__/device-lifecycle-events.test.ts +67 -0
  3. package/__tests__/open-wallet-session.test.ts +613 -80
  4. package/__tests__/pro2HostAssetPackage.test.ts +108 -1
  5. package/__tests__/protocol-v2.test.ts +194 -49
  6. package/__tests__/protocolV2FileWrite.test.ts +40 -0
  7. package/dist/api/FirmwareUpdateV4.d.ts +1 -0
  8. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  9. package/dist/api/OpenWalletSession.d.ts.map +1 -1
  10. package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
  11. package/dist/api/helpers/protocolV2FileWrite.d.ts +1 -0
  12. package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
  13. package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts.map +1 -1
  14. package/dist/core/RequestQueue.d.ts +2 -0
  15. package/dist/core/RequestQueue.d.ts.map +1 -1
  16. package/dist/core/index.d.ts +2 -1
  17. package/dist/core/index.d.ts.map +1 -1
  18. package/dist/index.d.ts +1 -1
  19. package/dist/index.js +1411 -1117
  20. package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
  21. package/dist/utils/patch.d.ts +1 -1
  22. package/dist/utils/patch.d.ts.map +1 -1
  23. package/dist/utils/pro2HostAssetPackage.d.ts.map +1 -1
  24. package/package.json +4 -4
  25. package/src/api/FirmwareUpdateV4.ts +42 -10
  26. package/src/api/OpenWalletSession.ts +0 -3
  27. package/src/api/allnetwork/AllNetworkGetAddressBase.ts +3 -1
  28. package/src/api/helpers/protocolV2FileWrite.ts +11 -5
  29. package/src/api/protocol-v2/DeviceUploadWallpaper.ts +8 -2
  30. package/src/core/RequestQueue.ts +16 -1
  31. package/src/core/index.ts +48 -21
  32. package/src/data/messages/messages-protocol-v2.json +1471 -1367
  33. package/src/protocols/protocol-v2/walletSession.ts +157 -38
  34. package/src/utils/pro2HostAssetPackage.ts +73 -27
@@ -1,3 +1,4 @@
1
+ /* eslint-disable no-bitwise -- LZ4 decoding and deterministic test data generation require bitwise operations. */
1
2
  import { sha3_512 } from '@noble/hashes/sha3';
2
3
 
3
4
  import {
@@ -5,6 +6,82 @@ import {
5
6
  supportsPro2HostAssetPackage,
6
7
  } from '../src/utils/pro2HostAssetPackage';
7
8
 
9
+ const decodeRawLz4Block = (compressed: Uint8Array, expectedLength: number) => {
10
+ const output = new Uint8Array(expectedLength);
11
+ let inputOffset = 0;
12
+ let outputOffset = 0;
13
+
14
+ const readLength = (initialLength: number) => {
15
+ let length = initialLength;
16
+ if (length === 15) {
17
+ let extension = 255;
18
+ while (extension === 255) {
19
+ extension = compressed[inputOffset];
20
+ inputOffset += 1;
21
+ length += extension;
22
+ }
23
+ }
24
+ return length;
25
+ };
26
+
27
+ while (inputOffset < compressed.byteLength) {
28
+ const token = compressed[inputOffset];
29
+ inputOffset += 1;
30
+ const literalLength = readLength(token >>> 4);
31
+ output.set(compressed.subarray(inputOffset, inputOffset + literalLength), outputOffset);
32
+ inputOffset += literalLength;
33
+ outputOffset += literalLength;
34
+ if (inputOffset >= compressed.byteLength) break;
35
+
36
+ const matchOffset = compressed[inputOffset] | (compressed[inputOffset + 1] << 8);
37
+ inputOffset += 2;
38
+ const matchLength = readLength(token & 0x0f) + 4;
39
+ for (let index = 0; index < matchLength; index += 1) {
40
+ output[outputOffset] = output[outputOffset - matchOffset];
41
+ outputOffset += 1;
42
+ }
43
+ }
44
+
45
+ expect(outputOffset).toBe(expectedLength);
46
+ return output;
47
+ };
48
+
49
+ const decodeFirstPackageEntry = (packageData: Uint8Array, rawLength: number) => {
50
+ const containerHeaderSize = 0x5f90;
51
+ const archive = packageData.subarray(containerHeaderSize);
52
+ const archiveView = new DataView(archive.buffer, archive.byteOffset, archive.byteLength);
53
+ const compressedOffset = archiveView.getUint32(42 + 0x100, true);
54
+ const compressed = archive.subarray(compressedOffset);
55
+ const compressedView = new DataView(
56
+ compressed.buffer,
57
+ compressed.byteOffset,
58
+ compressed.byteLength
59
+ );
60
+ const blockCount = compressedView.getUint16(0, true);
61
+ const blockSize = 1 << compressedView.getUint16(2, true);
62
+ let blockOffset = 8 + blockCount * 4;
63
+ const decodedBlocks: Uint8Array[] = [];
64
+
65
+ for (let index = 0; index < blockCount; index += 1) {
66
+ const compressedLength = compressedView.getUint32(8 + index * 4, true);
67
+ const expectedLength = Math.min(blockSize, rawLength - index * blockSize);
68
+ decodedBlocks.push(
69
+ decodeRawLz4Block(
70
+ compressed.subarray(blockOffset, blockOffset + compressedLength),
71
+ expectedLength
72
+ )
73
+ );
74
+ blockOffset += compressedLength;
75
+ }
76
+
77
+ const decoded = new Uint8Array(rawLength);
78
+ decodedBlocks.reduce((offset, block) => {
79
+ decoded.set(block, offset);
80
+ return offset + block.byteLength;
81
+ }, 0);
82
+ return decoded;
83
+ };
84
+
8
85
  describe('Pro2 host asset package', () => {
9
86
  test('builds the unsigned RESOURCE container and LZ4-blocked archive expected by firmware', () => {
10
87
  const raw = new TextEncoder().encode('123456789');
@@ -40,12 +117,42 @@ describe('Pro2 host asset package', () => {
40
117
 
41
118
  const compressedOffset = archiveView.getUint32(42 + 0x100, true);
42
119
  expect(archiveView.getUint16(compressedOffset, true)).toBe(1);
43
- expect(archiveView.getUint16(compressedOffset + 2, true)).toBe(12);
120
+ expect(archiveView.getUint16(compressedOffset + 2, true)).toBe(14);
44
121
  expect(archiveView.getUint32(compressedOffset + 4, true)).toBe(0);
45
122
  expect(archiveView.getUint32(compressedOffset + 8, true)).toBe(10);
46
123
  expect(payload.subarray(compressedOffset + 12)).toEqual(new Uint8Array([0x90, ...raw]));
47
124
  });
48
125
 
126
+ test('round-trips multi-block data byte-for-byte with best-match compression', () => {
127
+ const raw = Uint8Array.from({ length: 16_384 * 3 + 137 }, (_, index) => {
128
+ const column = index % 604;
129
+ const row = Math.floor(index / 604);
130
+ return (column * 31 + row * 17) & 0xff;
131
+ });
132
+
133
+ const packageData = buildPro2HostAssetPackage([{ name: 'wallpaper.bin', data: raw }]);
134
+
135
+ expect(decodeFirstPackageEntry(packageData, raw.byteLength)).toEqual(raw);
136
+ });
137
+
138
+ test('falls back to 8 KiB blocks when a compressed 16 KiB block exceeds firmware capacity', () => {
139
+ let state = 0x12345678;
140
+ const raw = Uint8Array.from({ length: 16_384 }, () => {
141
+ state ^= state << 13;
142
+ state ^= state >>> 17;
143
+ state ^= state << 5;
144
+ return state & 0xff;
145
+ });
146
+
147
+ const packageData = buildPro2HostAssetPackage([{ name: 'wallpaper.bin', data: raw }]);
148
+ const archive = packageData.subarray(0x5f90);
149
+ const archiveView = new DataView(archive.buffer, archive.byteOffset, archive.byteLength);
150
+ const compressedOffset = archiveView.getUint32(42 + 0x100, true);
151
+
152
+ expect(archiveView.getUint16(compressedOffset + 2, true)).toBe(13);
153
+ expect(decodeFirstPackageEntry(packageData, raw.byteLength)).toEqual(raw);
154
+ });
155
+
49
156
  test.each([
50
157
  ['1.0.0', false],
51
158
  ['1.0.1-beta.1', false],
@@ -7,6 +7,7 @@ import { encode as encodeJpeg } from 'jpeg-js';
7
7
  import {
8
8
  DeviceRebootType,
9
9
  DeviceSessionPinType,
10
+ DeviceSessionSeedDomain,
10
11
  DeviceSettingsPage,
11
12
  DeviceType,
12
13
  } from '@onekeyfe/hd-transport';
@@ -255,6 +256,9 @@ describe('DeviceUploadWallpaper', () => {
255
256
  });
256
257
 
257
258
  test('uploads and applies the fixed wallpaper package on firmware 1.0.1', async () => {
259
+ const getSettingsSpy = jest
260
+ .spyOn(DataManager, 'getSettings')
261
+ .mockReturnValue('react-native' as any);
258
262
  const typedCall = jest.fn().mockImplementation((request, _response, params) => {
259
263
  if (request === 'FilesystemDirMake') return { message: {} };
260
264
  if (request === 'FilesystemFileWrite') {
@@ -282,8 +286,13 @@ describe('DeviceUploadWallpaper', () => {
282
286
  (method as any).device = device;
283
287
  method.postMessage = jest.fn();
284
288
 
285
- method.init();
286
- const result = await method.run();
289
+ let result;
290
+ try {
291
+ method.init();
292
+ result = await method.run();
293
+ } finally {
294
+ getSettingsSpy.mockRestore();
295
+ }
287
296
 
288
297
  const fileWrites = typedCall.mock.calls.filter(call => call[0] === 'FilesystemFileWrite');
289
298
  expect(new Set(fileWrites.map(call => call[2].file.path))).toEqual(
@@ -292,6 +301,7 @@ describe('DeviceUploadWallpaper', () => {
292
301
  expect(fileWrites[0][2].file.data.subarray(0, 4)).toEqual(
293
302
  new Uint8Array([0x4f, 0x4b, 0x50, 0x50])
294
303
  );
304
+ expect(fileWrites[0][2].file.data).toHaveLength(1960);
295
305
  expect(typedCall).toHaveBeenLastCalledWith('DeviceSettingsSet', 'Success', {
296
306
  settings: { wallpaper_path: 'vol1:/wallpapers/wallpaper.okpkg' },
297
307
  });
@@ -1115,10 +1125,9 @@ describe('Protocol V2 feature adapter', () => {
1115
1125
  expect(typedCall).toHaveBeenCalledWith('DeviceSessionAskPassphrase', 'Success', {
1116
1126
  passphrase: '',
1117
1127
  on_device: false,
1128
+ seed_domains: [DeviceSessionSeedDomain.SeedDomain_Standard],
1118
1129
  });
1119
- expect(typedCall).toHaveBeenCalledWith('DeviceSessionGet', 'DeviceSession', {
1120
- seed_domains: [],
1121
- });
1130
+ expect(typedCall).toHaveBeenCalledWith('DeviceSessionGet', 'DeviceSession', {});
1122
1131
  device.passphraseState = 'state-1';
1123
1132
  expect(device.getInternalState()).toBe('session-1');
1124
1133
  });
@@ -1171,13 +1180,10 @@ describe('Protocol V2 feature adapter', () => {
1171
1180
  expect(
1172
1181
  typedCall.mock.calls.filter(call => call[0] === 'DeviceSessionAskPassphrase')
1173
1182
  ).toHaveLength(1);
1174
- expect(typedCall).toHaveBeenCalledWith('DeviceSessionGet', 'DeviceSession', {
1175
- seed_domains: [],
1176
- });
1183
+ expect(typedCall).toHaveBeenCalledWith('DeviceSessionGet', 'DeviceSession', {});
1177
1184
  expect(typedCall).toHaveBeenCalledWith('DeviceSessionGet', 'DeviceSession', {
1178
1185
  session_id: 'standard-session',
1179
1186
  btc_test_address: 'standard-state',
1180
- seed_domains: [],
1181
1187
  });
1182
1188
  expect(deviceWalletSessionStore.getStandard(deviceId)).toEqual({
1183
1189
  passphraseState: 'standard-state',
@@ -1542,10 +1548,9 @@ describe('Protocol V2 feature adapter', () => {
1542
1548
  expect(typedCall).toHaveBeenCalledWith('DeviceSessionAskPassphrase', 'Success', {
1543
1549
  passphrase: 'host hidden wallet',
1544
1550
  on_device: false,
1551
+ seed_domains: [DeviceSessionSeedDomain.SeedDomain_Standard],
1545
1552
  });
1546
- expect(typedCall).toHaveBeenCalledWith('DeviceSessionGet', 'DeviceSession', {
1547
- seed_domains: [],
1548
- });
1553
+ expect(typedCall).toHaveBeenCalledWith('DeviceSessionGet', 'DeviceSession', {});
1549
1554
  });
1550
1555
 
1551
1556
  test('deviceStatusGet returns raw DeviceStatus and updates dynamic features', async () => {
@@ -1654,7 +1659,6 @@ describe('Protocol V2 feature adapter', () => {
1654
1659
  expect(typedCall).toHaveBeenCalledWith('DeviceSessionGet', 'DeviceSession', {
1655
1660
  session_id: 'session-a',
1656
1661
  btc_test_address: 'state-a',
1657
- seed_domains: [],
1658
1662
  });
1659
1663
  expect(device.getInternalState()).toBe('session-b');
1660
1664
  });
@@ -1728,7 +1732,6 @@ describe('Protocol V2 feature adapter', () => {
1728
1732
  {
1729
1733
  session_id: 'session-a',
1730
1734
  btc_test_address: 'state-a',
1731
- seed_domains: [],
1732
1735
  },
1733
1736
  ],
1734
1737
  ]);
@@ -1775,10 +1778,14 @@ describe('Protocol V2 feature adapter', () => {
1775
1778
  [
1776
1779
  'DeviceSessionAskPassphrase',
1777
1780
  'Success',
1778
- { passphrase: 'host hidden wallet', on_device: false },
1781
+ {
1782
+ passphrase: 'host hidden wallet',
1783
+ on_device: false,
1784
+ seed_domains: [DeviceSessionSeedDomain.SeedDomain_Standard],
1785
+ },
1779
1786
  ],
1780
1787
  ['DeviceStatusGet', 'DeviceStatus', {}],
1781
- ['DeviceSessionGet', 'DeviceSession', { seed_domains: [] }],
1788
+ ['DeviceSessionGet', 'DeviceSession', {}],
1782
1789
  ]);
1783
1790
  });
1784
1791
 
@@ -1940,7 +1947,6 @@ describe('Protocol V2 feature adapter', () => {
1940
1947
  expect(promptPassphrase).not.toHaveBeenCalled();
1941
1948
  expect(typedCall).toHaveBeenCalledWith('DeviceSessionGet', 'DeviceSession', {
1942
1949
  btc_test_address: 'expected-state',
1943
- seed_domains: [],
1944
1950
  });
1945
1951
  expect(typedCall).toHaveBeenCalledWith('LockDevice', 'Success', {});
1946
1952
  expect(typedCall.mock.calls.filter(call => call[0] === 'DeviceSessionGet')).toHaveLength(1);
@@ -2238,7 +2244,7 @@ describe('Protocol V2 feature adapter', () => {
2238
2244
  firmwareVersion: '4.15.0',
2239
2245
  passphraseProtection: true,
2240
2246
  sessionId: 'feature-session',
2241
- unlockedAttachPin: true,
2247
+ unlockedAttachPin: false,
2242
2248
  };
2243
2249
  const typedCall = jest
2244
2250
  .fn()
@@ -2331,7 +2337,6 @@ describe('Protocol V2 feature adapter', () => {
2331
2337
  ).resolves.toMatchObject({ passphraseState: 'expected-state' });
2332
2338
  expect(typedCall).toHaveBeenCalledWith('DeviceSessionGet', 'DeviceSession', {
2333
2339
  btc_test_address: 'expected-state',
2334
- seed_domains: [],
2335
2340
  });
2336
2341
  expect(promptPassphrase).not.toHaveBeenCalled();
2337
2342
  });
@@ -2405,7 +2410,6 @@ describe('Protocol V2 feature adapter', () => {
2405
2410
  {
2406
2411
  session_id: 'session-pro2-app',
2407
2412
  btc_test_address: 'state-pro2-app',
2408
- seed_domains: [],
2409
2413
  },
2410
2414
  ],
2411
2415
  ]);
@@ -2595,10 +2599,9 @@ describe('Protocol V2 feature adapter', () => {
2595
2599
  expect(typedCall).toHaveBeenNthCalledWith(2, 'DeviceSessionAskPassphrase', 'Success', {
2596
2600
  passphrase: 'host hidden wallet',
2597
2601
  on_device: false,
2602
+ seed_domains: [DeviceSessionSeedDomain.SeedDomain_Standard],
2598
2603
  });
2599
- expect(typedCall).toHaveBeenLastCalledWith('DeviceSessionGet', 'DeviceSession', {
2600
- seed_domains: [],
2601
- });
2604
+ expect(typedCall).toHaveBeenLastCalledWith('DeviceSessionGet', 'DeviceSession', {});
2602
2605
  });
2603
2606
 
2604
2607
  test('does not mark Pro2 passphrase enabled from a main PIN session alone', async () => {
@@ -2678,16 +2681,14 @@ describe('Protocol V2 feature adapter', () => {
2678
2681
  expect(device.getInternalState()).toBeUndefined();
2679
2682
  expect(typedCall).toHaveBeenCalledWith('DeviceSessionGet', 'DeviceSession', {
2680
2683
  btc_test_address: 'expected-state',
2681
- seed_domains: [],
2682
2684
  });
2683
2685
  expect(typedCall).toHaveBeenCalledWith('DeviceSessionAskPassphrase', 'Success', {
2684
2686
  passphrase: 'host hidden wallet',
2685
2687
  on_device: false,
2688
+ seed_domains: [DeviceSessionSeedDomain.SeedDomain_Standard],
2686
2689
  });
2687
2690
  expect(typedCall).toHaveBeenCalledWith('DeviceStatusGet', 'DeviceStatus', {});
2688
- expect(typedCall).toHaveBeenCalledWith('DeviceSessionGet', 'DeviceSession', {
2689
- seed_domains: [],
2690
- });
2691
+ expect(typedCall).toHaveBeenCalledWith('DeviceSessionGet', 'DeviceSession', {});
2691
2692
  });
2692
2693
 
2693
2694
  test('fails closed instead of switching to Main PIN during a standard-wallet safety check', async () => {
@@ -2785,20 +2786,19 @@ describe('Protocol V2 feature adapter', () => {
2785
2786
  await expect(
2786
2787
  device.checkPassphraseStateSafety('stale-hidden-state', true, false)
2787
2788
  ).resolves.toBe(true);
2788
- expect(typedCall).toHaveBeenCalledTimes(5);
2789
+ expect(typedCall).toHaveBeenCalledTimes(6);
2789
2790
  expect(typedCall).toHaveBeenCalledWith('ProtocolInfoRequest', 'ProtocolInfo', {
2790
2791
  eventless_wallet_session: true,
2791
2792
  });
2792
- expect(typedCall).toHaveBeenCalledWith('DeviceSessionGet', 'DeviceSession', {
2793
- seed_domains: [],
2794
- });
2793
+ expect(typedCall).toHaveBeenCalledWith('DeviceSessionGet', 'DeviceSession', {});
2795
2794
  expect(typedCall).toHaveBeenCalledWith('DeviceSessionAskPassphrase', 'Success', {
2796
2795
  passphrase: '',
2797
2796
  on_device: false,
2797
+ seed_domains: [DeviceSessionSeedDomain.SeedDomain_Standard],
2798
2798
  });
2799
2799
  expect(typedCall).toHaveBeenCalledWith('DeviceStatusGet', 'DeviceStatus', {});
2800
2800
  expect(typedCall.mock.calls.filter(([request]) => request === 'DeviceStatusGet')).toHaveLength(
2801
- 2
2801
+ 3
2802
2802
  );
2803
2803
  expect(typedCall).not.toHaveBeenCalledWith('DeviceSessionAskPin', 'Success', expect.anything());
2804
2804
  });
@@ -5663,7 +5663,7 @@ describe('Protocol V2 firmware update targets', () => {
5663
5663
  expect(method.postTipMessage).not.toHaveBeenCalled();
5664
5664
  expect(method.postProgressMessage).not.toHaveBeenCalled();
5665
5665
  await cancelableAction?.();
5666
- expect(cancelDevice).toHaveBeenCalledTimes(1);
5666
+ expect(cancelDevice).not.toHaveBeenCalled();
5667
5667
  });
5668
5668
 
5669
5669
  test('does not send the install request when Protocol V2 staging fails', async () => {
@@ -7184,7 +7184,14 @@ describe('Protocol V2 firmware update targets', () => {
7184
7184
  true
7185
7185
  );
7186
7186
  expect((method as any).exitProtocolV2BootloaderToNormal).not.toHaveBeenCalled();
7187
- expect(method.postProgressMessage).toHaveBeenCalledWith(100, 'transferData');
7187
+ expect(method.postProgressMessage).toHaveBeenCalledWith(
7188
+ 100,
7189
+ 'transferData',
7190
+ expect.objectContaining({
7191
+ transferredBytes: 5,
7192
+ totalBytes: 5,
7193
+ })
7194
+ );
7188
7195
  expect((method as any).completeProtocolV2FinalVerification).toHaveBeenCalledTimes(1);
7189
7196
  });
7190
7197
 
@@ -7258,7 +7265,14 @@ describe('Protocol V2 firmware update targets', () => {
7258
7265
  expect.objectContaining({ processedSize: 2, totalSize: 3 })
7259
7266
  );
7260
7267
  expect(method.postProgressMessage).toHaveBeenCalledTimes(1);
7261
- expect(method.postProgressMessage).toHaveBeenCalledWith(100, 'transferData');
7268
+ expect(method.postProgressMessage).toHaveBeenCalledWith(
7269
+ 100,
7270
+ 'transferData',
7271
+ expect.objectContaining({
7272
+ transferredBytes: 3,
7273
+ totalBytes: 3,
7274
+ })
7275
+ );
7262
7276
  expect((method as any).protocolV2StartFirmwareUpdate).toHaveBeenCalledTimes(1);
7263
7277
  expect((method as any).protocolV2StartFirmwareUpdate).toHaveBeenCalledWith({
7264
7278
  targets: [{ target_id: 4, path: 'vol0:/application_p1.bin' }],
@@ -8578,26 +8592,43 @@ describe('Protocol V2 firmware update targets', () => {
8578
8592
  (method as any).verifyProtocolV2StagedFile = jest.fn().mockResolvedValue(undefined);
8579
8593
  (method as any).protocolV2StartFirmwareUpdate = jest.fn();
8580
8594
  (method as any).waitForProtocolV2FirmwareUpdateComplete = jest.fn();
8595
+ const dateNowSpy = jest
8596
+ .spyOn(Date, 'now')
8597
+ .mockReturnValueOnce(1_000)
8598
+ .mockReturnValueOnce(5_000);
8581
8599
 
8582
- await (method as any).executeProtocolV2SourceUpdate({
8583
- installSources: [],
8584
- resourceSources: [
8585
- {
8586
- name: 'images.okpkg',
8587
- source: {
8588
- size: 3,
8589
- readAt: jest.fn(),
8590
- close: jest.fn(),
8600
+ try {
8601
+ await (method as any).executeProtocolV2SourceUpdate({
8602
+ installSources: [],
8603
+ resourceSources: [
8604
+ {
8605
+ name: 'images.okpkg',
8606
+ source: {
8607
+ size: 3,
8608
+ readAt: jest.fn(),
8609
+ close: jest.fn(),
8610
+ },
8611
+ devicePath: 'vol0:/bundles/images/images.okpkg',
8591
8612
  },
8592
- devicePath: 'vol0:/bundles/images/images.okpkg',
8593
- },
8594
- ],
8595
- });
8613
+ ],
8614
+ });
8615
+ } finally {
8616
+ dateNowSpy.mockRestore();
8617
+ }
8596
8618
 
8597
8619
  expect((method as any).protocolV2SourceUpdateProcess).toHaveBeenCalledTimes(1);
8598
8620
  expect((method as any).protocolV2SourceUpdateProcess).toHaveBeenCalledWith(
8599
- expect.objectContaining({ filePath: 'vol0:/bundles/images/images.okpkg' })
8621
+ expect.objectContaining({
8622
+ filePath: 'vol0:/bundles/images/images.okpkg',
8623
+ transferStartedAt: 1_000,
8624
+ })
8600
8625
  );
8626
+ expect(method.postProgressMessage).toHaveBeenLastCalledWith(100, 'transferData', {
8627
+ transferredBytes: 3,
8628
+ totalBytes: 3,
8629
+ rateBytesPerSecond: 1,
8630
+ elapsedMs: 4_000,
8631
+ });
8601
8632
  expect((method as any).verifyProtocolV2StagedFile).toHaveBeenCalledWith(
8602
8633
  'vol0:/bundles/images/images.okpkg',
8603
8634
  3
@@ -8827,6 +8858,84 @@ describe('Protocol V2 firmware update targets', () => {
8827
8858
  expect(recoverProtocolV2FileTransfer).not.toHaveBeenCalled();
8828
8859
  });
8829
8860
 
8861
+ test('does not recover or wrap a cancelled V4 file transfer', async () => {
8862
+ const method = new FirmwareUpdateV4({
8863
+ id: 1,
8864
+ payload: {
8865
+ method: 'firmwareUpdateV4',
8866
+ },
8867
+ });
8868
+ const abortController = new AbortController();
8869
+ method.abortSignal = abortController.signal;
8870
+ (method as any).fileWriteChunk = jest.fn().mockImplementation(() => {
8871
+ abortController.abort();
8872
+ return Promise.reject(new Error('transport disposed'));
8873
+ });
8874
+ const recoverProtocolV2FileTransfer = jest.fn();
8875
+ (method as any).recoverProtocolV2FileTransfer = recoverProtocolV2FileTransfer;
8876
+ const source = await openFirmwareByteSource({
8877
+ binary: new Uint8Array([1]).buffer,
8878
+ });
8879
+
8880
+ try {
8881
+ await expect(
8882
+ (method as any).protocolV2SourceUpdateProcess({
8883
+ source,
8884
+ filePath: 'vol1:firmware.bin',
8885
+ processedSize: 0,
8886
+ totalSize: 1,
8887
+ })
8888
+ ).rejects.toMatchObject({ errorCode: HardwareErrorCode.CallQueueActionCancelled });
8889
+ } finally {
8890
+ await source?.close();
8891
+ }
8892
+ expect(recoverProtocolV2FileTransfer).not.toHaveBeenCalled();
8893
+ });
8894
+
8895
+ test('keeps public transfer bytes monotonic when a V4 file retry restarts at zero', async () => {
8896
+ const method = new FirmwareUpdateV4({
8897
+ id: 1,
8898
+ payload: {
8899
+ method: 'firmwareUpdateV4',
8900
+ },
8901
+ });
8902
+ let writeCount = 0;
8903
+ (method as any).fileWriteChunk = jest.fn(
8904
+ (_path: string, _size: number, offset: number, data: Uint8Array) => {
8905
+ writeCount += 1;
8906
+ if (writeCount === 3) {
8907
+ return Promise.reject(new Error('transport timeout'));
8908
+ }
8909
+ return Promise.resolve({
8910
+ message: { processed_byte: offset + data.byteLength },
8911
+ });
8912
+ }
8913
+ );
8914
+ (method as any).getProtocolV2FirmwareChunkSize = jest.fn().mockReturnValue(1000);
8915
+ (method as any).recoverProtocolV2FileTransfer = jest.fn().mockResolvedValue(undefined);
8916
+ method.postProgressMessage = jest.fn();
8917
+ const source = await openFirmwareByteSource({
8918
+ binary: new Uint8Array(3000).buffer,
8919
+ });
8920
+
8921
+ try {
8922
+ await (method as any).protocolV2SourceUpdateProcess({
8923
+ source,
8924
+ filePath: 'vol1:firmware.bin',
8925
+ processedSize: 0,
8926
+ totalSize: 3000,
8927
+ });
8928
+ } finally {
8929
+ await source?.close();
8930
+ }
8931
+
8932
+ const transferredBytes = (method.postProgressMessage as jest.Mock).mock.calls.map(
8933
+ ([, , metrics]) => metrics.transferredBytes
8934
+ );
8935
+ expect(transferredBytes).toEqual([1000, 2000, 3000]);
8936
+ expect((method as any).recoverProtocolV2FileTransfer).toHaveBeenCalledTimes(1);
8937
+ });
8938
+
8830
8939
  test('throttles repeated transfer progress while preserving file completion', async () => {
8831
8940
  const method = new FirmwareUpdateV4({
8832
8941
  id: 1,
@@ -9185,6 +9294,42 @@ describe('Protocol V2 firmware update targets', () => {
9185
9294
  expect(typedCall).toHaveBeenCalledTimes(6);
9186
9295
  });
9187
9296
 
9297
+ test('preserves the underlying transport error code after firmware transfer retries', async () => {
9298
+ const method = new FirmwareUpdateV4({
9299
+ id: 1,
9300
+ payload: {
9301
+ method: 'firmwareUpdateV4',
9302
+ },
9303
+ });
9304
+ const typedCall = jest
9305
+ .fn()
9306
+ .mockRejectedValue(ERRORS.TypedError(HardwareErrorCode.BleTimeoutError, 'response timeout'));
9307
+
9308
+ (method as any).device = stubDevice({
9309
+ getCommands: () => ({ typedCall }),
9310
+ });
9311
+ method.postProgressMessage = jest.fn();
9312
+ method.postTipMessage = jest.fn();
9313
+ (method as any).recoverProtocolV2FileTransfer = jest.fn().mockResolvedValue(undefined);
9314
+
9315
+ const source = await openFirmwareByteSource({
9316
+ binary: new Uint8Array([1, 2, 3]).buffer,
9317
+ });
9318
+ await expect(
9319
+ (method as any).protocolV2SourceUpdateProcess({
9320
+ source,
9321
+ filePath: 'vol0:/firmware.bin',
9322
+ processedSize: 0,
9323
+ totalSize: 3,
9324
+ })
9325
+ ).rejects.toMatchObject({
9326
+ errorCode: HardwareErrorCode.EmmcFileWriteFirmwareError,
9327
+ params: { causeCode: HardwareErrorCode.BleTimeoutError },
9328
+ });
9329
+ await source?.close();
9330
+ expect(typedCall).toHaveBeenCalledTimes(3);
9331
+ });
9332
+
9188
9333
  // TODO(#850/#855): PR #855 added resume-on-retry and per-chunk retry on the
9189
9334
  // writeProtocolV2File path. PR #850 replaced that path with FirmwareByteSource
9190
9335
  // streaming (protocolV2SourceUpdateProcess), which restarts a failed transfer from
@@ -10,6 +10,46 @@ jest.mock('../src/data/config', () => ({
10
10
  }));
11
11
 
12
12
  describe('writeProtocolV2File', () => {
13
+ test('allows a verified caller-specific BLE chunk limit', async () => {
14
+ const getSettingsSpy = jest
15
+ .spyOn(DataManager, 'getSettings')
16
+ .mockReturnValue('react-native' as any);
17
+ const isBleConnectSpy = jest.spyOn(DataManager, 'isBleConnect').mockReturnValue(true);
18
+ const data = new Uint8Array(1961);
19
+ const typedCall = jest.fn().mockResolvedValue({ message: {} });
20
+
21
+ try {
22
+ await writeProtocolV2File({
23
+ commands: { typedCall } as any,
24
+ path: 'vol1:/wallpapers/wallpaper.okpkg',
25
+ data,
26
+ bleChunkSizeLimit: 1960,
27
+ });
28
+ } finally {
29
+ getSettingsSpy.mockRestore();
30
+ isBleConnectSpy.mockRestore();
31
+ }
32
+
33
+ expect(typedCall).toHaveBeenCalledTimes(2);
34
+ expect(typedCall.mock.calls[0][2].file.data).toEqual(data.slice(0, 1960));
35
+ expect(typedCall.mock.calls[1][2].file.data).toEqual(data.slice(1960));
36
+ });
37
+
38
+ test('does not apply the BLE-only limit to WebUSB', async () => {
39
+ const data = new Uint8Array(1961);
40
+ const typedCall = jest.fn().mockResolvedValue({ message: {} });
41
+
42
+ await writeProtocolV2File({
43
+ commands: { typedCall } as any,
44
+ path: 'vol1:/wallpapers/wallpaper.okpkg',
45
+ data,
46
+ bleChunkSizeLimit: 1960,
47
+ });
48
+
49
+ expect(typedCall).toHaveBeenCalledTimes(1);
50
+ expect(typedCall.mock.calls[0][2].file.data).toEqual(data);
51
+ });
52
+
13
53
  test('按分片写入并只在首片设置 overwrite', async () => {
14
54
  const data = new Uint8Array(4097);
15
55
  const typedCall = jest.fn().mockResolvedValue({ message: {} });
@@ -23,6 +23,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
23
23
  private protocolV2LastRuntimeProbeFeatures?;
24
24
  private protocolV2LastTransferProgress?;
25
25
  private protocolV2LastTransferProgressAt;
26
+ private protocolV2LastTransferredBytes;
26
27
  init(): void;
27
28
  private getProtocolV2FirmwareChunkSize;
28
29
  run(): Promise<{
@@ -1 +1 @@
1
- {"version":3,"file":"FirmwareUpdateV4.d.ts","sourceRoot":"","sources":["../../src/api/FirmwareUpdateV4.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FirmwareUpdateV4.d.ts","sourceRoot":"","sources":["../../src/api/FirmwareUpdateV4.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EAMZ,MAAM,qBAAqB,CAAC;AA0B7B,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAiC/E,OAAO,KAAK,EAEV,sBAAsB,EAEvB,MAAM,6BAA6B,CAAC;AAqErC,wBAAgB,wCAAwC,CACtD,UAAU,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,EAC5C,MAAM,EAAE,sBAAsB,EAC9B,0BAA0B,UAAQ,QAiCnC;AA8UD,eAAO,MAAM,oCAAoC,WACvC,WAAW,GAAG,UAAU,eACnB,MAAM,GAAG,SAAS,YAKhC,CAAC;AAEF,eAAO,MAAM,iCAAiC,0BACrB,MAAM,uBACR,MAAM,iBACZ,MAAM,eACR,MAAM,SAsBpB,CAAC;AAUF,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,wBAAwB,CAAC,sBAAsB,CAAC;IAC5F,OAAO,CAAC,8BAA8B,CAAC,CAAS;IAEhD,OAAO,CAAC,sBAAsB,CAAC,CAAS;IAExC,OAAO,CAAC,oCAAoC,CAAS;IAErD,qBAAqB;IAIrB,OAAO,CAAC,yBAAyB,CAA4B;IAE7D,OAAO,CAAC,2BAA2B,CAAS;IAE5C,OAAO,CAAC,iCAAiC,CAAS;IAElD,OAAO,CAAC,iCAAiC,CAA6B;IAEtE,OAAO,CAAC,4BAA4B,CAAqB;IAEzD,OAAO,CAAC,6BAA6B,CAAC,CAAW;IAEjD,OAAO,CAAC,+BAA+B,CAAC,CAAuB;IAE/D,OAAO,CAAC,iCAAiC,CAA6B;IAEtE,OAAO,CAAC,+BAA+B,CAAS;IAEhD,OAAO,CAAC,mCAAmC,CAAS;IAEpD,OAAO,CAAC,wCAAwC,CAAS;IAEzD,OAAO,CAAC,kCAAkC,CAAC,CAAW;IAEtD,OAAO,CAAC,8BAA8B,CAAC,CAAS;IAEhD,OAAO,CAAC,gCAAgC,CAAK;IAE7C,OAAO,CAAC,8BAA8B,CAAK;IAE3C,IAAI;IA6LJ,OAAO,CAAC,8BAA8B;IAwBhC,GAAG;;;;;YAKK,aAAa;YA0Ib,4BAA4B;YAkB5B,0BAA0B;YAY1B,8BAA8B;YAK9B,+BAA+B;YAqG/B,4BAA4B;YA+C5B,0CAA0C;YAkB1C,qCAAqC;YAoFrC,gCAAgC;YAgBhC,uCAAuC;YAmDvC,8BAA8B;IA8B5C,OAAO,CAAC,8BAA8B;IA0BtC,OAAO,CAAC,kCAAkC;IAc1C,OAAO,CAAC,gCAAgC;YAuD1B,2BAA2B;IAmBzC,OAAO,CAAC,yBAAyB;IAKjC,OAAO,CAAC,oCAAoC;IAY5C,OAAO,CAAC,4BAA4B;IAUpC,OAAO,CAAC,kCAAkC;IAS1C,OAAO,CAAC,8BAA8B;YAMxB,iCAAiC;YAOjC,iCAAiC;YAmBjC,iCAAiC;IAM/C,OAAO,CAAC,uBAAuB;IAI/B,OAAO,CAAC,mCAAmC;IAe3C,OAAO,CAAC,iCAAiC;IAWzC,OAAO,CAAC,2BAA2B;IAsBnC,OAAO,CAAC,yBAAyB;IAiBjC,OAAO,CAAC,wBAAwB;YAkBlB,iCAAiC;YA6CjC,uCAAuC;YA0CvC,+BAA+B;IAmF7C,OAAO,CAAC,6BAA6B;IAMrC,OAAO,CAAC,gCAAgC;YAM1B,8BAA8B;YAmD9B,kCAAkC;IAkChD,OAAO,CAAC,0BAA0B;IAUlC,OAAO,CAAC,yBAAyB;YAcnB,4BAA4B;IAkBpC,6BAA6B;YAkBrB,+BAA+B;IAkD7C,OAAO,CAAC,6BAA6B;YAkCvB,6BAA6B;YA0B7B,0CAA0C;YA6B1C,uBAAuB;YAiCvB,8BAA8B;YAkF9B,6BAA6B;IA0F3C,OAAO,CAAC,mCAAmC;YAI7B,0BAA0B;IAaxC,OAAO,CAAC,8BAA8B;IAiBtC,OAAO,CAAC,4BAA4B;IAoLpC,OAAO,CAAC,6BAA6B;IAcrC,OAAO,CAAC,qCAAqC;IAyB7C,OAAO,CAAC,kCAAkC;IAgB1C,OAAO,CAAC,8CAA8C;YAIxC,uCAAuC;YAkVvC,gCAAgC;YAkBhC,yBAAyB;IASvC,OAAO,CAAC,2BAA2B;YAMrB,8BAA8B;IAQ5C,OAAO,CAAC,0BAA0B;YAkBpB,mCAAmC;YAWnC,qCAAqC;YAmDrC,yBAAyB;YAgGzB,8BAA8B;IAU5C,OAAO,CAAC,kCAAkC;YAQ5B,cAAc;YAuCd,6BAA6B;YAW7B,0BAA0B;YAoB1B,6BAA6B;YAwD7B,gBAAgB;IA0B9B,OAAO,CAAC,qBAAqB;CAM9B"}
@@ -1 +1 @@
1
- {"version":3,"file":"OpenWalletSession.d.ts","sourceRoot":"","sources":["../../src/api/OpenWalletSession.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAI1C,OAAO,KAAK,EACV,uBAAuB,EACvB,wBAAwB,EACzB,MAAM,gCAAgC,CAAC;AAwExC,MAAM,CAAC,OAAO,OAAO,iBAAkB,SAAQ,UAAU,CAAC,uBAAuB,CAAC;IAChF,qBAAqB;IAIrB,IAAI;IAYE,GAAG,IAAI,OAAO,CAAC,wBAAwB,CAAC;CAmM/C"}
1
+ {"version":3,"file":"OpenWalletSession.d.ts","sourceRoot":"","sources":["../../src/api/OpenWalletSession.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAI1C,OAAO,KAAK,EACV,uBAAuB,EACvB,wBAAwB,EACzB,MAAM,gCAAgC,CAAC;AAwExC,MAAM,CAAC,OAAO,OAAO,iBAAkB,SAAQ,UAAU,CAAC,uBAAuB,CAAC;IAChF,qBAAqB;IAIrB,IAAI;IAYE,GAAG,IAAI,OAAO,CAAC,wBAAwB,CAAC;CAgM/C"}
@@ -1 +1 @@
1
- {"version":3,"file":"AllNetworkGetAddressBase.d.ts","sourceRoot":"","sources":["../../../src/api/allnetwork/AllNetworkGetAddressBase.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAe3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EACV,iBAAiB,EACjB,uBAAuB,EACvB,oBAAoB,EACpB,QAAQ,EACT,MAAM,sCAAsC,CAAC;AAI9C,MAAM,MAAM,aAAa,GAAG;IAC1B,UAAU,EAAE,MAAM,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,uBAAuB,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,GAAG,CAAC;IAClG,kBAAkB,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,EAAE,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC,CAAC;AAEzF,MAAM,MAAM,gBAAgB,GAAG;KAC5B,CAAC,IAAI,YAAY,GAAG,aAAa;CACnC,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAOrD,CAAC;AAiMF,KAAK,YAAY,GAAG;IAClB,UAAU,EAAE,MAAM,OAAO,CAAC;IAC1B,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,oBAAoB,EAAE,uBAAuB,CAAC;IAC9C,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,wBAAyB,SAAQ,UAAU,CACvE;IACE,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,EAAE,CACJ;IACC,qBAAqB;IAIrB,eAAe,EAAE,eAAe,GAAG,IAAI,CAAQ;IAE/C,IAAI;IAkBJ,kBAAkB,CAAC,EACjB,OAAO,EACP,OAAO,EACP,aAAa,GACd,EAAE;QACD,OAAO,EAAE,QAAQ,CAAC;QAClB,OAAO,EAAE,uBAAuB,CAAC;QACjC,aAAa,EAAE,MAAM,CAAC;KACvB,GAAG,YAAY;IAqBV,UAAU,CACd,UAAU,EAAE,MAAM,OAAO,EACzB,MAAM,EAAE,GAAG,GAAG;QACZ,MAAM,EAAE,CAAC,GAAG,GAAG;YAAE,oBAAoB,EAAE,oBAAoB,CAAA;SAAE,CAAC,EAAE,CAAC;KAClE,EACD,eAAe,EAAE,MAAM;IAuIzB,QAAQ,CAAC,oBAAoB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAE9E,GAAG;CAyBV"}
1
+ {"version":3,"file":"AllNetworkGetAddressBase.d.ts","sourceRoot":"","sources":["../../../src/api/allnetwork/AllNetworkGetAddressBase.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAe3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EACV,iBAAiB,EACjB,uBAAuB,EACvB,oBAAoB,EACpB,QAAQ,EACT,MAAM,sCAAsC,CAAC;AAI9C,MAAM,MAAM,aAAa,GAAG;IAC1B,UAAU,EAAE,MAAM,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,uBAAuB,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,GAAG,CAAC;IAClG,kBAAkB,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,EAAE,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC,CAAC;AAEzF,MAAM,MAAM,gBAAgB,GAAG;KAC5B,CAAC,IAAI,YAAY,GAAG,aAAa;CACnC,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAOrD,CAAC;AAiMF,KAAK,YAAY,GAAG;IAClB,UAAU,EAAE,MAAM,OAAO,CAAC;IAC1B,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,oBAAoB,EAAE,uBAAuB,CAAC;IAC9C,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,wBAAyB,SAAQ,UAAU,CACvE;IACE,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,EAAE,CACJ;IACC,qBAAqB;IAIrB,eAAe,EAAE,eAAe,GAAG,IAAI,CAAQ;IAE/C,IAAI;IAkBJ,kBAAkB,CAAC,EACjB,OAAO,EACP,OAAO,EACP,aAAa,GACd,EAAE;QACD,OAAO,EAAE,QAAQ,CAAC;QAClB,OAAO,EAAE,uBAAuB,CAAC;QACjC,aAAa,EAAE,MAAM,CAAC;KACvB,GAAG,YAAY;IAqBV,UAAU,CACd,UAAU,EAAE,MAAM,OAAO,EACzB,MAAM,EAAE,GAAG,GAAG;QACZ,MAAM,EAAE,CAAC,GAAG,GAAG;YAAE,oBAAoB,EAAE,oBAAoB,CAAA;SAAE,CAAC,EAAE,CAAC;KAClE,EACD,eAAe,EAAE,MAAM;IAyIzB,QAAQ,CAAC,oBAAoB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAE9E,GAAG;CAyBV"}
@@ -21,6 +21,7 @@ export type ProtocolV2FileWriteOptions = {
21
21
  chunkSize?: number;
22
22
  chunkLen?: number;
23
23
  chunkSizeLimit?: number;
24
+ bleChunkSizeLimit?: number;
24
25
  overwrite?: boolean;
25
26
  append?: boolean;
26
27
  uiPercentage?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"protocolV2FileWrite.d.ts","sourceRoot":"","sources":["../../../src/api/helpers/protocolV2FileWrite.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAIlE,MAAM,MAAM,uBAAuB,GAAG,WAAW,GAAG,UAAU,GAAG,IAAI,GAAG,MAAM,CAAC;AAE/E,MAAM,MAAM,2BAA2B,GAAG;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,EAAE,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,uBAAuB,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,+BAA+B,KAAK,MAAM,GAAG,SAAS,CAAC;IACnF,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,2BAA2B,KAAK,IAAI,CAAC;CAC9D,CAAC;AAyDF,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,WASzD;AA8CD,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B;;;;;;GAuO5E"}
1
+ {"version":3,"file":"protocolV2FileWrite.d.ts","sourceRoot":"","sources":["../../../src/api/helpers/protocolV2FileWrite.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAIlE,MAAM,MAAM,uBAAuB,GAAG,WAAW,GAAG,UAAU,GAAG,IAAI,GAAG,MAAM,CAAC;AAE/E,MAAM,MAAM,2BAA2B,GAAG;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,EAAE,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,uBAAuB,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,+BAA+B,KAAK,MAAM,GAAG,SAAS,CAAC;IACnF,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,2BAA2B,KAAK,IAAI,CAAC;CAC9D,CAAC;AAyDF,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,WASzD;AAkDD,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B;;;;;;GAuO5E"}
@@ -1 +1 @@
1
- {"version":3,"file":"DeviceUploadWallpaper.d.ts","sourceRoot":"","sources":["../../../src/api/protocol-v2/DeviceUploadWallpaper.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAO3C,OAAO,EAGL,KAAK,wBAAwB,EAE9B,MAAM,2BAA2B,CAAC;AAMnC,MAAM,MAAM,2BAA2B,GAAG;IACxC,UAAU,EAAE,MAAM,CAAC;IAKnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAK1C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,wBAAwB,CAAC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAqBF,MAAM,CAAC,OAAO,OAAO,qBAAsB,SAAQ,UAAU,CAAC,2BAA2B,CAAC;IACxF,qBAAqB;IAIrB,OAAO,CAAC,OAAO,CAAC,CAA8D;IAE9E,OAAO,CAAC,cAAc,CAAS;IAE/B,OAAO,CAAC,QAAQ,CAAS;IAEzB,OAAO,CAAC,IAAI,CAAM;IAElB,IAAI;YA2BU,kBAAkB;YAgBlB,eAAe;YAaf,MAAM;IAsBd,GAAG,IAAI,OAAO,CAAC,6BAA6B,CAAC;CAgCpD"}
1
+ {"version":3,"file":"DeviceUploadWallpaper.d.ts","sourceRoot":"","sources":["../../../src/api/protocol-v2/DeviceUploadWallpaper.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAO3C,OAAO,EAGL,KAAK,wBAAwB,EAE9B,MAAM,2BAA2B,CAAC;AAMnC,MAAM,MAAM,2BAA2B,GAAG;IACxC,UAAU,EAAE,MAAM,CAAC;IAKnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAK1C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,wBAAwB,CAAC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAsBF,MAAM,CAAC,OAAO,OAAO,qBAAsB,SAAQ,UAAU,CAAC,2BAA2B,CAAC;IACxF,qBAAqB;IAIrB,OAAO,CAAC,OAAO,CAAC,CAA8D;IAE9E,OAAO,CAAC,cAAc,CAAS;IAE/B,OAAO,CAAC,QAAQ,CAAS;IAEzB,OAAO,CAAC,IAAI,CAAM;IAElB,IAAI;YA2BU,kBAAkB;YAgBlB,eAAe;YAaf,MAAM;IAuBd,GAAG,IAAI,OAAO,CAAC,6BAA6B,CAAC;CAoCpD"}