@onekeyfe/hd-core 1.2.6 → 1.2.8-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -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
|
+
});
|
|
@@ -54,6 +54,14 @@ describe('SolSignOffchainMessage', () => {
|
|
|
54
54
|
});
|
|
55
55
|
});
|
|
56
56
|
|
|
57
|
+
test('maps omitted required signers to an empty repeated field', () => {
|
|
58
|
+
const method = createMethod({ requiredSigners: undefined });
|
|
59
|
+
|
|
60
|
+
method.init();
|
|
61
|
+
|
|
62
|
+
expect(method.params.required_signers).toEqual([]);
|
|
63
|
+
});
|
|
64
|
+
|
|
57
65
|
test.each([
|
|
58
66
|
{ requiredSigners: ['11'], error: '32-byte hex public key' },
|
|
59
67
|
{ requiredSigners: [signerB, signerA], error: 'strictly sorted and unique' },
|
|
@@ -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
|
@@ -55555,6 +55555,9 @@ const PORTFOLIO_PACKAGE_MAX_BYTES = 128 * 1024;
|
|
|
55555
55555
|
const FILESYSTEM_FILE_WRITE_MESSAGE_TYPE = 60805;
|
|
55556
55556
|
const PORTFOLIO_UPDATE_MESSAGE_TYPE = 61400;
|
|
55557
55557
|
class UploadPortfolio extends FileWrite {
|
|
55558
|
+
getVersionRange() {
|
|
55559
|
+
return { model_pro2: { min: '1.0.3' } };
|
|
55560
|
+
}
|
|
55558
55561
|
init() {
|
|
55559
55562
|
const { packageBase64, timeoutMs, uiMode = 'silent' } = this.payload;
|
|
55560
55563
|
const packageBytes = decodeCanonicalBase64({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-core",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.8-alpha.1",
|
|
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.
|
|
29
|
-
"@onekeyfe/hd-transport": "1.2.
|
|
28
|
+
"@onekeyfe/hd-shared": "1.2.8-alpha.1",
|
|
29
|
+
"@onekeyfe/hd-transport": "1.2.8-alpha.1",
|
|
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": "
|
|
49
|
+
"gitHead": "df614dc773e3e1075e5fbcdaee62d10a7a641eed"
|
|
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({
|