@onekeyfe/hd-core 1.2.6-alpha.2 → 1.2.6-alpha.3

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.
@@ -6,6 +6,8 @@ import TransportManager from '../src/data-manager/TransportManager';
6
6
  import { IFRAME } from '../src/events';
7
7
  import SearchDevices from '../src/api/SearchDevices';
8
8
  import { DeviceList } from '../src/device/DeviceList';
9
+ import { Device } from '../src/device/Device';
10
+ import { DevicePool } from '../src/device/DevicePool';
9
11
 
10
12
  jest.mock('../src/data/config', () => ({
11
13
  getSDKVersion: jest.fn(() => '1.0.0-test'),
@@ -205,3 +207,112 @@ describe('Core 错误输出边界', () => {
205
207
  await core.dispose();
206
208
  });
207
209
  });
210
+
211
+ describe('Portfolio firmware compatibility through Core', () => {
212
+ afterEach(() => {
213
+ jest.restoreAllMocks();
214
+ });
215
+
216
+ test.each(
217
+ (['pro2', 'neo'] as const).flatMap(deviceType =>
218
+ (['silent', 'progress'] as const).map(uiMode => ({ deviceType, uiMode }))
219
+ )
220
+ )(
221
+ 'checks the current $deviceType firmware before a $uiMode upload',
222
+ async ({ deviceType, uiMode }) => {
223
+ DevicePool.resetState();
224
+ jest.spyOn(DataManager, 'getSettings').mockReturnValue('react-native' as never);
225
+ const device = Device.fromDescriptor({
226
+ id: 'portfolio-device',
227
+ path: 'portfolio-device',
228
+ commType: 'ble',
229
+ protocolType: 'V2',
230
+ } as never);
231
+ jest.spyOn(Device, 'fromDescriptor').mockReturnValue(device);
232
+ jest.spyOn(device, 'acquire').mockResolvedValue(undefined);
233
+ jest.spyOn(device, 'initialize').mockResolvedValue(undefined);
234
+ jest.spyOn(device, 'release').mockResolvedValue(undefined);
235
+ jest.spyOn(device, 'ensureProtocolV2RuntimeContext').mockResolvedValue({
236
+ version: 2,
237
+ supported_messages: [60805, 61400],
238
+ });
239
+ const typedCall = jest.fn();
240
+ device.commands = {
241
+ typedCall,
242
+ disposed: false,
243
+ dispose: jest.fn(),
244
+ checkDisposed: jest.fn(),
245
+ } as never;
246
+ const core = initCore();
247
+ let id = 0;
248
+ const upload = () =>
249
+ core.handleMessage({
250
+ id: ++id,
251
+ type: IFRAME.CALL,
252
+ payload: {
253
+ method: 'uploadPortfolio',
254
+ connectId: 'portfolio-device',
255
+ connectProtocol: 'V2',
256
+ packageBase64: 'AQID',
257
+ uiMode,
258
+ },
259
+ } as never);
260
+
261
+ try {
262
+ // Reuse one device across version changes to cover a retry after upgrading.
263
+ for (const firmwareVersion of ['1.0.1', '1.0.2', '1.0.3', '1.0.10']) {
264
+ device.features = {
265
+ protocol: 'V2',
266
+ deviceType,
267
+ firmwareType: 'universal',
268
+ firmwareVersion,
269
+ mode: 'normal',
270
+ initialized: true,
271
+ bootloaderMode: false,
272
+ capabilities: [],
273
+ } as never;
274
+ typedCall.mockReset();
275
+ typedCall
276
+ .mockResolvedValueOnce({ message: { processed_byte: 3 } })
277
+ .mockResolvedValueOnce({ message: { message: 'Portfolio updated' } });
278
+
279
+ const response = await upload();
280
+ if (firmwareVersion === '1.0.1' || firmwareVersion === '1.0.2') {
281
+ expect(response).toMatchObject({
282
+ success: false,
283
+ payload: {
284
+ code: HardwareErrorCode.CallMethodNeedUpgradeFirmware,
285
+ params: { current: firmwareVersion, require: '1.0.3', method: 'uploadPortfolio' },
286
+ },
287
+ });
288
+ expect(typedCall).not.toHaveBeenCalled();
289
+ } else {
290
+ expect(response).toMatchObject({ success: true, payload: { portfolioUpdated: true } });
291
+ expect(typedCall).toHaveBeenCalledTimes(2);
292
+ expect(typedCall).toHaveBeenLastCalledWith('PortfolioUpdate', 'Success', {});
293
+ }
294
+ }
295
+
296
+ typedCall.mockReset();
297
+ typedCall
298
+ .mockResolvedValueOnce({ message: { processed_byte: 3 } })
299
+ .mockRejectedValueOnce(
300
+ ERRORS.TypedError(
301
+ HardwareErrorCode.RuntimeError,
302
+ 'Failure_DataError,Invalid portfolio package'
303
+ )
304
+ );
305
+ await expect(upload()).resolves.toMatchObject({
306
+ success: false,
307
+ payload: {
308
+ code: HardwareErrorCode.RuntimeError,
309
+ error: 'Failure_DataError,Invalid portfolio package',
310
+ },
311
+ });
312
+ } finally {
313
+ await core.dispose();
314
+ DevicePool.resetState();
315
+ }
316
+ }
317
+ );
318
+ });
@@ -5,6 +5,11 @@ export type UploadPortfolioParams = {
5
5
  uiMode?: 'silent' | 'progress';
6
6
  };
7
7
  export default class UploadPortfolio extends FileWrite {
8
+ getVersionRange(): {
9
+ model_pro2: {
10
+ min: string;
11
+ };
12
+ };
8
13
  init(): void;
9
14
  run(): Promise<{
10
15
  portfolioUpdated: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"UploadPortfolio.d.ts","sourceRoot":"","sources":["../../src/api/UploadPortfolio.ts"],"names":[],"mappings":"AAIA,OAAO,SAAS,MAAM,aAAa,CAAC;AAEpC,MAAM,MAAM,qBAAqB,GAAG;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAE5B,MAAM,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;CAChC,CAAC;AAQF,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,SAAS;IACpD,IAAI;IAuBE,GAAG;;;;;;;;CAsBV"}
1
+ {"version":3,"file":"UploadPortfolio.d.ts","sourceRoot":"","sources":["../../src/api/UploadPortfolio.ts"],"names":[],"mappings":"AAIA,OAAO,SAAS,MAAM,aAAa,CAAC;AAEpC,MAAM,MAAM,qBAAqB,GAAG;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAE5B,MAAM,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;CAChC,CAAC;AAQF,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,SAAS;IACpD,eAAe;;;;;IAKf,IAAI;IAuBE,GAAG;;;;;;;;CAsBV"}
package/dist/index.js CHANGED
@@ -55547,6 +55547,9 @@ const PORTFOLIO_PACKAGE_MAX_BYTES = 128 * 1024;
55547
55547
  const FILESYSTEM_FILE_WRITE_MESSAGE_TYPE = 60805;
55548
55548
  const PORTFOLIO_UPDATE_MESSAGE_TYPE = 61400;
55549
55549
  class UploadPortfolio extends FileWrite {
55550
+ getVersionRange() {
55551
+ return { model_pro2: { min: '1.0.3' } };
55552
+ }
55550
55553
  init() {
55551
55554
  const { packageBase64, timeoutMs, uiMode = 'silent' } = this.payload;
55552
55555
  const packageBytes = decodeCanonicalBase64({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/hd-core",
3
- "version": "1.2.6-alpha.2",
3
+ "version": "1.2.6-alpha.3",
4
4
  "description": "Core processes and APIs for communicating with OneKey hardware devices.",
5
5
  "author": "OneKey",
6
6
  "homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
@@ -25,8 +25,8 @@
25
25
  "url": "https://github.com/OneKeyHQ/hardware-js-sdk/issues"
26
26
  },
27
27
  "dependencies": {
28
- "@onekeyfe/hd-shared": "1.2.6-alpha.2",
29
- "@onekeyfe/hd-transport": "1.2.6-alpha.2",
28
+ "@onekeyfe/hd-shared": "1.2.6-alpha.3",
29
+ "@onekeyfe/hd-transport": "1.2.6-alpha.3",
30
30
  "axios": "1.15.2",
31
31
  "bignumber.js": "^9.0.2",
32
32
  "buffer": "^6.0.3",
@@ -46,5 +46,5 @@
46
46
  "@types/w3c-web-usb": "^1.0.10",
47
47
  "@types/web-bluetooth": "^0.0.21"
48
48
  },
49
- "gitHead": "c01014c750c5c0bc4f6bff2e07b2fee985893f59"
49
+ "gitHead": "4ca9104edb5113a625070484628fe4b2a56478e5"
50
50
  }
@@ -18,6 +18,11 @@ const FILESYSTEM_FILE_WRITE_MESSAGE_TYPE = 60805;
18
18
  const PORTFOLIO_UPDATE_MESSAGE_TYPE = 61400;
19
19
 
20
20
  export default class UploadPortfolio extends FileWrite {
21
+ getVersionRange() {
22
+ // Pro2 and Neo rotated the Portfolio verification key in firmware 1.0.3.
23
+ return { model_pro2: { min: '1.0.3' } };
24
+ }
25
+
21
26
  init() {
22
27
  const { packageBase64, timeoutMs, uiMode = 'silent' } = this.payload as UploadPortfolioParams;
23
28
  const packageBytes = decodeCanonicalBase64({