@onekeyfe/hd-core 1.2.0-alpha.13 → 1.2.0-alpha.14
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.
- package/__tests__/DeviceCommands.test.ts +47 -0
- package/__tests__/protocol-v2.test.ts +20 -6
- package/dist/api/FileWrite.d.ts +1 -0
- package/dist/api/FileWrite.d.ts.map +1 -1
- package/dist/api/UploadPortfolio.d.ts.map +1 -1
- package/dist/device/DeviceCommands.d.ts.map +1 -1
- package/dist/index.js +43 -23
- package/dist/protocols/protocol-v2/lockedError.d.ts +2 -0
- package/dist/protocols/protocol-v2/lockedError.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/api/FileWrite.ts +3 -1
- package/src/api/UploadPortfolio.ts +3 -1
- package/src/device/DeviceCommands.ts +3 -1
- package/src/protocols/protocol-v2/lockedError.ts +10 -0
- package/src/protocols/protocol-v2/unlockRetry.ts +1 -11
- package/src/protocols/protocol-v2/walletSession.ts +25 -10
|
@@ -11,6 +11,7 @@ const createCommands = () => {
|
|
|
11
11
|
const commands = Object.create(DeviceCommands.prototype) as DeviceCommands;
|
|
12
12
|
commands.device = {
|
|
13
13
|
clearCancelableAction: jest.fn(),
|
|
14
|
+
isProtocolV2: jest.fn(() => true),
|
|
14
15
|
} as any;
|
|
15
16
|
return commands;
|
|
16
17
|
};
|
|
@@ -41,6 +42,52 @@ describe('DeviceCommands failure mapping', () => {
|
|
|
41
42
|
});
|
|
42
43
|
});
|
|
43
44
|
|
|
45
|
+
it.each(['Device locked', 'Device is locked'])(
|
|
46
|
+
'maps legacy Protocol V2 locked message "%s" without a subcode',
|
|
47
|
+
async message => {
|
|
48
|
+
const commands = createCommands();
|
|
49
|
+
|
|
50
|
+
await expect(
|
|
51
|
+
commands._filterCommonTypes(
|
|
52
|
+
{
|
|
53
|
+
type: 'Failure',
|
|
54
|
+
message: {
|
|
55
|
+
code: 'Failure_ProcessError',
|
|
56
|
+
message,
|
|
57
|
+
},
|
|
58
|
+
} as any,
|
|
59
|
+
'PortfolioUpdate'
|
|
60
|
+
)
|
|
61
|
+
).rejects.toMatchObject({
|
|
62
|
+
errorCode: HardwareErrorCode.DeviceLocked,
|
|
63
|
+
params: {
|
|
64
|
+
failureCode: 'Failure_ProcessError',
|
|
65
|
+
firmwareMessage: message,
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
it('does not use the legacy locked-message fallback for Protocol V1', async () => {
|
|
72
|
+
const commands = createCommands();
|
|
73
|
+
(commands.device.isProtocolV2 as jest.Mock).mockReturnValue(false);
|
|
74
|
+
|
|
75
|
+
await expect(
|
|
76
|
+
commands._filterCommonTypes(
|
|
77
|
+
{
|
|
78
|
+
type: 'Failure',
|
|
79
|
+
message: {
|
|
80
|
+
code: 'Failure_ProcessError',
|
|
81
|
+
message: 'Device is locked',
|
|
82
|
+
},
|
|
83
|
+
} as any,
|
|
84
|
+
'ApplySettings'
|
|
85
|
+
)
|
|
86
|
+
).rejects.toMatchObject({
|
|
87
|
+
errorCode: HardwareErrorCode.RuntimeError,
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
44
91
|
it.each([
|
|
45
92
|
['ButtonAck', 'Not in Ethereum signing mode'],
|
|
46
93
|
['PinMatrixAck', 'Not in Conflux signing mode'],
|
|
@@ -205,13 +205,14 @@ describe('UploadPortfolio', () => {
|
|
|
205
205
|
method.init();
|
|
206
206
|
const result = await method.run();
|
|
207
207
|
|
|
208
|
+
expect(method.unlockPolicy).toBe('retry-on-locked');
|
|
208
209
|
expect(typedCall).toHaveBeenNthCalledWith(
|
|
209
210
|
1,
|
|
210
211
|
'FilesystemFileWrite',
|
|
211
212
|
'FilesystemFile',
|
|
212
213
|
{
|
|
213
214
|
file: {
|
|
214
|
-
path: 'vol1:/portfolio/portfolio.
|
|
215
|
+
path: 'vol1:/portfolio/portfolio.okpkg.pending',
|
|
215
216
|
offset: 0,
|
|
216
217
|
total_size: 3,
|
|
217
218
|
data: packageBytes,
|
|
@@ -223,8 +224,9 @@ describe('UploadPortfolio', () => {
|
|
|
223
224
|
{ timeoutMs: undefined }
|
|
224
225
|
);
|
|
225
226
|
expect(typedCall).toHaveBeenNthCalledWith(2, 'PortfolioUpdate', 'Success', {});
|
|
227
|
+
expect(method.postMessage).not.toHaveBeenCalled();
|
|
226
228
|
expect(result).toMatchObject({
|
|
227
|
-
path: 'vol1:/portfolio/portfolio.
|
|
229
|
+
path: 'vol1:/portfolio/portfolio.okpkg.pending',
|
|
228
230
|
processed_byte: 3,
|
|
229
231
|
portfolioUpdated: true,
|
|
230
232
|
});
|
|
@@ -802,7 +804,7 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
802
804
|
expect(device.getInternalState()).toBeUndefined();
|
|
803
805
|
});
|
|
804
806
|
|
|
805
|
-
test('
|
|
807
|
+
test('unlocks and retries DeviceSessionGet when the Pro2 wallet session is locked', async () => {
|
|
806
808
|
const device = Device.fromDescriptor({
|
|
807
809
|
id: 'cache-device-4',
|
|
808
810
|
path: 'cache-path-4',
|
|
@@ -812,11 +814,23 @@ describe('Protocol V2 feature adapter', () => {
|
|
|
812
814
|
{ ...descriptor, protocolType: 'V2' } as any,
|
|
813
815
|
{ status: { device_id: 'stable-device-4', unlocked: false } }
|
|
814
816
|
);
|
|
815
|
-
const
|
|
817
|
+
const lockedError = Object.assign(new Error('Device is locked'), {
|
|
818
|
+
errorCode: HardwareErrorCode.DeviceLocked,
|
|
819
|
+
});
|
|
820
|
+
const typedCall = jest
|
|
821
|
+
.fn()
|
|
822
|
+
.mockRejectedValueOnce(lockedError)
|
|
823
|
+
.mockResolvedValueOnce({
|
|
824
|
+
message: { session_id: 'session-after-unlock', btc_test_address: '' },
|
|
825
|
+
});
|
|
816
826
|
(device as any).commands = { typedCall };
|
|
827
|
+
const unlockDevice = jest.spyOn(device, 'unlockDevice').mockResolvedValue(undefined as any);
|
|
817
828
|
|
|
818
|
-
await expect(getProtocolV2WalletSession(device)).
|
|
819
|
-
|
|
829
|
+
await expect(getProtocolV2WalletSession(device)).resolves.toMatchObject({
|
|
830
|
+
newSession: 'session-after-unlock',
|
|
831
|
+
});
|
|
832
|
+
expect(unlockDevice).toHaveBeenCalledTimes(1);
|
|
833
|
+
expect(typedCall).toHaveBeenCalledTimes(2);
|
|
820
834
|
});
|
|
821
835
|
|
|
822
836
|
test('does not request a Pro2 wallet session before features are initialized', async () => {
|
package/dist/api/FileWrite.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileWrite.d.ts","sourceRoot":"","sources":["../../src/api/FileWrite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAW1C,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,WAAW,GAAG,UAAU,GAAG,IAAI,GAAG,MAAM,CAAC;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC7B,CAAC;AAEF,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,UAAU,CAAC,eAAe,CAAC;IAChE,IAAI;
|
|
1
|
+
{"version":3,"file":"FileWrite.d.ts","sourceRoot":"","sources":["../../src/api/FileWrite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAW1C,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,WAAW,GAAG,UAAU,GAAG,IAAI,GAAG,MAAM,CAAC;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC7B,CAAC;AAEF,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,UAAU,CAAC,eAAe,CAAC;IAChE,IAAI;IAuBE,GAAG;;;;;;;CAqBV"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UploadPortfolio.d.ts","sourceRoot":"","sources":["../../src/api/UploadPortfolio.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,aAAa,CAAC;AAEpC,MAAM,MAAM,qBAAqB,GAAG;IAClC,YAAY,EAAE,WAAW,GAAG,UAAU,GAAG,IAAI,CAAC;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC7B,CAAC;AAKF,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,SAAS;IACpD,IAAI;
|
|
1
|
+
{"version":3,"file":"UploadPortfolio.d.ts","sourceRoot":"","sources":["../../src/api/UploadPortfolio.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,aAAa,CAAC;AAEpC,MAAM,MAAM,qBAAqB,GAAG;IAClC,YAAY,EAAE,WAAW,GAAG,UAAU,GAAG,IAAI,CAAC;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC7B,CAAC;AAKF,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,SAAS;IACpD,IAAI;IAiBE,GAAG;;;;;;;;CASV"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeviceCommands.d.ts","sourceRoot":"","sources":["../../src/device/DeviceCommands.ts"],"names":[],"mappings":"AAKA,OAAO,EAAU,KAAK,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAQlE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,KAAK,EAEV,QAAQ,EACR,SAAS,EACT,oBAAoB,EACrB,MAAM,wBAAwB,CAAC;AAEhC,MAAM,MAAM,wBAAwB,GAAG;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,KAAK,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAC;AACxC,KAAK,UAAU,GAAG,OAAO,CAAC,MAAM,WAAW,EAAE,MAAM,CAAC,CAAC;AACrD,MAAM,MAAM,oBAAoB,CAAC,CAAC,SAAS,UAAU,IAAI;IACvD,IAAI,EAAE,CAAC,CAAC;IACR,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;CACzB,CAAC;AACF,KAAK,oBAAoB,GAAG;KACzB,CAAC,IAAI,UAAU,GAAG,oBAAoB,CAAC,CAAC,CAAC;CAC3C,CAAC;AACF,MAAM,MAAM,sBAAsB,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;AAiItE,eAAO,MAAM,oBAAoB,WAAY,MAAM;;;;;;;;;;;;;;;;;;EA0ClD,CAAC;AAEF,eAAO,MAAM,0BAA0B,WAAY,MAAM;;;;;;;;;;;;;;;;;;EAgCxD,CAAC;AASF,qBAAa,cAAc;IACzB,UAAU,EAAE,MAAM,CAAC;IAEnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,MAAM,EAAE,MAAM,CAAC;IAEf,SAAS,EAAE,SAAS,CAAC;IAErB,MAAM,EAAE,MAAM,CAAC;IAEf,QAAQ,EAAE,OAAO,CAAC;IAElB,WAAW,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAC;gBAElC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAUpC,OAAO,CAAC,cAAc,EAAE,OAAO;IAKrC,aAAa;IAOP,0BAA0B;;;;;;;;;;;;;;;;;;;IAkB1B,YAAY;;;;;;;;;;;;;;;;;;;IAkBZ,MAAM;IAsBN,IAAI,CACR,IAAI,EAAE,UAAU,EAChB,GAAG,CAAC,EAAE,sBAAsB,CAAC,SAAS,CAAC,EACvC,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,sBAAsB,CAAC;IA0DlC,SAAS,CAAC,CAAC,SAAS,UAAU,EAAE,CAAC,SAAS,UAAU,EAAE,EACpD,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,CAAC,EACV,GAAG,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,EACpB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAE3C,SAAS,CAAC,CAAC,SAAS,UAAU,EAAE,CAAC,SAAS,UAAU,EAClD,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,CAAC,EACV,GAAG,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,EACpB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC;IAsF7B,WAAW,CACf,IAAI,EAAE,UAAU,EAChB,GAAG,CAAC,EAAE,sBAAsB,CAAC,SAAS,CAAC,EACvC,OAAO,CAAC,EAAE,oBAAoB;IAMhC,kBAAkB,CAChB,GAAG,EAAE,sBAAsB,EAC3B,QAAQ,EAAE,UAAU,EACpB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"DeviceCommands.d.ts","sourceRoot":"","sources":["../../src/device/DeviceCommands.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -39250,6 +39250,13 @@ const PROTOBUF_MESSAGE_CONFIG = {
|
|
|
39250
39250
|
],
|
|
39251
39251
|
};
|
|
39252
39252
|
|
|
39253
|
+
function isDeviceLockedError(error) {
|
|
39254
|
+
return (typeof error === 'object' &&
|
|
39255
|
+
error !== null &&
|
|
39256
|
+
'errorCode' in error &&
|
|
39257
|
+
error.errorCode === hdShared.HardwareErrorCode.DeviceLocked);
|
|
39258
|
+
}
|
|
39259
|
+
|
|
39253
39260
|
const getErrorText = (error) => {
|
|
39254
39261
|
if (error instanceof Error)
|
|
39255
39262
|
return `${error.name} ${error.message}`;
|
|
@@ -39277,24 +39284,39 @@ function refreshProtocolV2DeviceStatus(device) {
|
|
|
39277
39284
|
});
|
|
39278
39285
|
}
|
|
39279
39286
|
function getProtocolV2WalletSession(device, options) {
|
|
39280
|
-
var _a, _b, _c, _d
|
|
39287
|
+
var _a, _b, _c, _d;
|
|
39281
39288
|
return __awaiter(this, void 0, void 0, function* () {
|
|
39282
|
-
if (((_a = device.features) === null || _a === void 0 ? void 0 : _a.unlocked) === false) {
|
|
39283
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Device is locked');
|
|
39284
|
-
}
|
|
39285
39289
|
if (options === null || options === void 0 ? void 0 : options.initSession) {
|
|
39286
39290
|
device.clearInternalState();
|
|
39287
39291
|
}
|
|
39288
|
-
|
|
39292
|
+
let sessionId = typeof device.getInternalState === 'function' ? device.getInternalState() : undefined;
|
|
39289
39293
|
try {
|
|
39290
39294
|
const requestDeviceSession = (sessionId) => device.commands.typedCall('DeviceSessionGet', 'DeviceSession', sessionId ? { session_id: sessionId } : {});
|
|
39291
|
-
const
|
|
39292
|
-
|
|
39295
|
+
const requestWalletSession = () => __awaiter(this, void 0, void 0, function* () {
|
|
39296
|
+
try {
|
|
39297
|
+
return yield requestDeviceSession(sessionId);
|
|
39298
|
+
}
|
|
39299
|
+
catch (error) {
|
|
39300
|
+
if (!sessionId || !isProtocolV2InvalidSessionError(error)) {
|
|
39301
|
+
throw error;
|
|
39302
|
+
}
|
|
39303
|
+
device.clearInternalState();
|
|
39304
|
+
sessionId = undefined;
|
|
39305
|
+
return requestDeviceSession();
|
|
39306
|
+
}
|
|
39307
|
+
});
|
|
39308
|
+
let response;
|
|
39309
|
+
try {
|
|
39310
|
+
response = yield requestWalletSession();
|
|
39311
|
+
}
|
|
39312
|
+
catch (error) {
|
|
39313
|
+
if (!isDeviceLockedError(error)) {
|
|
39293
39314
|
throw error;
|
|
39294
39315
|
}
|
|
39295
|
-
device.
|
|
39296
|
-
|
|
39297
|
-
}
|
|
39316
|
+
yield device.unlockDevice();
|
|
39317
|
+
response = yield requestWalletSession();
|
|
39318
|
+
}
|
|
39319
|
+
const { message } = response;
|
|
39298
39320
|
if ((options === null || options === void 0 ? void 0 : options.expectedPassphraseState) &&
|
|
39299
39321
|
options.expectedPassphraseState !== message.btc_test_address) {
|
|
39300
39322
|
device.clearInternalState();
|
|
@@ -39303,11 +39325,11 @@ function getProtocolV2WalletSession(device, options) {
|
|
|
39303
39325
|
if (message.btc_test_address && device.getCurrentPassphraseProtection() !== true) {
|
|
39304
39326
|
yield refreshProtocolV2DeviceStatus(device);
|
|
39305
39327
|
}
|
|
39306
|
-
device.updateInternalState(((
|
|
39328
|
+
device.updateInternalState(((_a = device.getCurrentPassphraseProtection()) !== null && _a !== void 0 ? _a : false) || Boolean(message.btc_test_address), message.btc_test_address, device.getCurrentDeviceId(), message.session_id, (options === null || options === void 0 ? void 0 : options.initSession) ? null : (_b = device.features) === null || _b === void 0 ? void 0 : _b.sessionId);
|
|
39307
39329
|
return {
|
|
39308
39330
|
passphraseState: message.btc_test_address,
|
|
39309
39331
|
newSession: message.session_id,
|
|
39310
|
-
unlockedAttachPin: (
|
|
39332
|
+
unlockedAttachPin: (_d = (_c = device.features) === null || _c === void 0 ? void 0 : _c.unlockedAttachPin) !== null && _d !== void 0 ? _d : undefined,
|
|
39311
39333
|
};
|
|
39312
39334
|
}
|
|
39313
39335
|
catch (error) {
|
|
@@ -41112,6 +41134,7 @@ class DeviceCommands {
|
|
|
41112
41134
|
});
|
|
41113
41135
|
}
|
|
41114
41136
|
_filterCommonTypes(res, callType, options) {
|
|
41137
|
+
var _a;
|
|
41115
41138
|
try {
|
|
41116
41139
|
if (shouldReduceDebugForCall(callType)) {
|
|
41117
41140
|
}
|
|
@@ -41161,7 +41184,8 @@ class DeviceCommands {
|
|
|
41161
41184
|
}
|
|
41162
41185
|
}
|
|
41163
41186
|
if (code === 'Failure_ProcessError') {
|
|
41164
|
-
|
|
41187
|
+
const isLegacyProtocolV2LockedFailure = this.device.isProtocolV2() && /^device (?:is )?locked$/i.test((_a = message === null || message === void 0 ? void 0 : message.trim()) !== null && _a !== void 0 ? _a : '');
|
|
41188
|
+
if (subcode === 9 || isLegacyProtocolV2LockedFailure) {
|
|
41165
41189
|
error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceLocked, message, {
|
|
41166
41190
|
failureCode: code,
|
|
41167
41191
|
subcode,
|
|
@@ -48375,7 +48399,7 @@ class FileRead extends BaseMethod {
|
|
|
48375
48399
|
|
|
48376
48400
|
class FileWrite extends BaseMethod {
|
|
48377
48401
|
init() {
|
|
48378
|
-
var _a, _b;
|
|
48402
|
+
var _a, _b, _c;
|
|
48379
48403
|
this.requireProtocolV2 = true;
|
|
48380
48404
|
this.skipForceUpdateCheck = true;
|
|
48381
48405
|
this.useDevicePassphraseState = false;
|
|
@@ -48391,6 +48415,7 @@ class FileWrite extends BaseMethod {
|
|
|
48391
48415
|
chunkLen: validateOptionalNonNegativeInteger(this.payload.chunkLen, 'chunkLen'),
|
|
48392
48416
|
overwrite: (_a = this.payload.overwrite) !== null && _a !== void 0 ? _a : offset === 0,
|
|
48393
48417
|
append: (_b = this.payload.append) !== null && _b !== void 0 ? _b : false,
|
|
48418
|
+
emitProgress: (_c = this.payload.emitProgress) !== null && _c !== void 0 ? _c : true,
|
|
48394
48419
|
uiPercentage: validateOptionalPercentage(this.payload.uiPercentage, 'uiPercentage'),
|
|
48395
48420
|
timeoutMs: validateOptionalNonNegativeInteger(this.payload.timeoutMs, 'timeoutMs'),
|
|
48396
48421
|
};
|
|
@@ -48411,7 +48436,7 @@ class FileWrite extends BaseMethod {
|
|
|
48411
48436
|
timeoutMs: this.params.timeoutMs === undefined ? undefined : Number(this.params.timeoutMs),
|
|
48412
48437
|
throwIfAborted: () => this.throwIfAborted(),
|
|
48413
48438
|
onProgress: payload => {
|
|
48414
|
-
if (typeof this.postMessage === 'function') {
|
|
48439
|
+
if (this.params.emitProgress && typeof this.postMessage === 'function') {
|
|
48415
48440
|
this.postMessage(createUiMessage(UI_REQUEST.DEVICE_PROGRESS, payload));
|
|
48416
48441
|
}
|
|
48417
48442
|
},
|
|
@@ -48515,13 +48540,14 @@ class PathInfo extends BaseMethod {
|
|
|
48515
48540
|
}
|
|
48516
48541
|
}
|
|
48517
48542
|
|
|
48518
|
-
const PORTFOLIO_PENDING_PATH = 'vol1:/portfolio/portfolio.
|
|
48543
|
+
const PORTFOLIO_PENDING_PATH = 'vol1:/portfolio/portfolio.okpkg.pending';
|
|
48519
48544
|
const PORTFOLIO_CHUNK_SIZE = 2048;
|
|
48520
48545
|
class UploadPortfolio extends FileWrite {
|
|
48521
48546
|
init() {
|
|
48522
48547
|
const { packageBytes, timeoutMs } = this.payload;
|
|
48523
|
-
this.payload = Object.assign(Object.assign({}, this.payload), { path: PORTFOLIO_PENDING_PATH, offset: 0, data: packageBytes, chunkSize: PORTFOLIO_CHUNK_SIZE, overwrite: true, append: false, timeoutMs });
|
|
48548
|
+
this.payload = Object.assign(Object.assign({}, this.payload), { path: PORTFOLIO_PENDING_PATH, offset: 0, data: packageBytes, chunkSize: PORTFOLIO_CHUNK_SIZE, overwrite: true, append: false, emitProgress: false, timeoutMs });
|
|
48524
48549
|
super.init();
|
|
48550
|
+
this.unlockPolicy = 'retry-on-locked';
|
|
48525
48551
|
}
|
|
48526
48552
|
run() {
|
|
48527
48553
|
const _super = Object.create(null, {
|
|
@@ -58166,12 +58192,6 @@ const getSynchronize = (mutex) => {
|
|
|
58166
58192
|
};
|
|
58167
58193
|
|
|
58168
58194
|
const Log$1 = getLogger(exports.LoggerNames.Core);
|
|
58169
|
-
function isDeviceLockedError(error) {
|
|
58170
|
-
return (typeof error === 'object' &&
|
|
58171
|
-
error !== null &&
|
|
58172
|
-
'errorCode' in error &&
|
|
58173
|
-
error.errorCode === hdShared.HardwareErrorCode.DeviceLocked);
|
|
58174
|
-
}
|
|
58175
58195
|
function runMethodWithUnlockRetry(method, device) {
|
|
58176
58196
|
return __awaiter(this, void 0, void 0, function* () {
|
|
58177
58197
|
try {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lockedError.d.ts","sourceRoot":"","sources":["../../../src/protocols/protocol-v2/lockedError.ts"],"names":[],"mappings":"AAEA,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAO3D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unlockRetry.d.ts","sourceRoot":"","sources":["../../../src/protocols/protocol-v2/unlockRetry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"unlockRetry.d.ts","sourceRoot":"","sources":["../../../src/protocols/protocol-v2/unlockRetry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAIlD,KAAK,cAAc,GAAG,IAAI,CAAC,UAAU,EAAE,KAAK,GAAG,cAAc,CAAC,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AACnF,KAAK,gBAAgB,GAAG,IAAI,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CAAC,CAAC;AAEtE,wBAAsB,wBAAwB,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,gBAAgB,gBAwB9F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"walletSession.d.ts","sourceRoot":"","sources":["../../../src/protocols/protocol-v2/walletSession.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"walletSession.d.ts","sourceRoot":"","sources":["../../../src/protocols/protocol-v2/walletSession.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAclD,eAAO,MAAM,+BAA+B,UAAW,OAAO,YACQ,CAAC;AAEvE,wBAAsB,6BAA6B,CAAC,MAAM,EAAE,MAAM,8DAGjE;AAED,wBAAsB,6BAA6B,CAAC,MAAM,EAAE,MAAM,qCAGjE;AAED,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,uBAAuB,CAAC,EAAE,MAAM,CAAA;CAAE;;;;GAyEtE"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-core",
|
|
3
|
-
"version": "1.2.0-alpha.
|
|
3
|
+
"version": "1.2.0-alpha.14",
|
|
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.0-alpha.
|
|
29
|
-
"@onekeyfe/hd-transport": "1.2.0-alpha.
|
|
28
|
+
"@onekeyfe/hd-shared": "1.2.0-alpha.14",
|
|
29
|
+
"@onekeyfe/hd-transport": "1.2.0-alpha.14",
|
|
30
30
|
"axios": "1.15.2",
|
|
31
31
|
"bignumber.js": "^9.0.2",
|
|
32
32
|
"bytebuffer": "^5.0.1",
|
|
@@ -44,5 +44,5 @@
|
|
|
44
44
|
"@types/w3c-web-usb": "^1.0.10",
|
|
45
45
|
"@types/web-bluetooth": "^0.0.21"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "c1edaed6435fb6049c7516c64b298ee62519e797"
|
|
48
48
|
}
|
package/src/api/FileWrite.ts
CHANGED
|
@@ -18,6 +18,7 @@ export type FileWriteParams = {
|
|
|
18
18
|
chunkLen?: number;
|
|
19
19
|
overwrite?: boolean;
|
|
20
20
|
append?: boolean;
|
|
21
|
+
emitProgress?: boolean;
|
|
21
22
|
uiPercentage?: number;
|
|
22
23
|
timeoutMs?: number | string;
|
|
23
24
|
};
|
|
@@ -40,6 +41,7 @@ export default class FileWrite extends BaseMethod<FileWriteParams> {
|
|
|
40
41
|
chunkLen: validateOptionalNonNegativeInteger(this.payload.chunkLen, 'chunkLen'),
|
|
41
42
|
overwrite: this.payload.overwrite ?? offset === 0,
|
|
42
43
|
append: this.payload.append ?? false,
|
|
44
|
+
emitProgress: this.payload.emitProgress ?? true,
|
|
43
45
|
uiPercentage: validateOptionalPercentage(this.payload.uiPercentage, 'uiPercentage'),
|
|
44
46
|
timeoutMs: validateOptionalNonNegativeInteger(this.payload.timeoutMs, 'timeoutMs'),
|
|
45
47
|
};
|
|
@@ -60,7 +62,7 @@ export default class FileWrite extends BaseMethod<FileWriteParams> {
|
|
|
60
62
|
timeoutMs: this.params.timeoutMs === undefined ? undefined : Number(this.params.timeoutMs),
|
|
61
63
|
throwIfAborted: () => this.throwIfAborted(),
|
|
62
64
|
onProgress: payload => {
|
|
63
|
-
if (typeof this.postMessage === 'function') {
|
|
65
|
+
if (this.params.emitProgress && typeof this.postMessage === 'function') {
|
|
64
66
|
this.postMessage(createUiMessage(UI_REQUEST.DEVICE_PROGRESS, payload));
|
|
65
67
|
}
|
|
66
68
|
},
|
|
@@ -6,7 +6,7 @@ export type UploadPortfolioParams = {
|
|
|
6
6
|
timeoutMs?: number | string;
|
|
7
7
|
};
|
|
8
8
|
|
|
9
|
-
const PORTFOLIO_PENDING_PATH = 'vol1:/portfolio/portfolio.
|
|
9
|
+
const PORTFOLIO_PENDING_PATH = 'vol1:/portfolio/portfolio.okpkg.pending';
|
|
10
10
|
const PORTFOLIO_CHUNK_SIZE = 2048;
|
|
11
11
|
|
|
12
12
|
export default class UploadPortfolio extends FileWrite {
|
|
@@ -20,9 +20,11 @@ export default class UploadPortfolio extends FileWrite {
|
|
|
20
20
|
chunkSize: PORTFOLIO_CHUNK_SIZE,
|
|
21
21
|
overwrite: true,
|
|
22
22
|
append: false,
|
|
23
|
+
emitProgress: false,
|
|
23
24
|
timeoutMs,
|
|
24
25
|
};
|
|
25
26
|
super.init();
|
|
27
|
+
this.unlockPolicy = 'retry-on-locked';
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
async run() {
|
|
@@ -578,7 +578,9 @@ export class DeviceCommands {
|
|
|
578
578
|
}
|
|
579
579
|
|
|
580
580
|
if (code === 'Failure_ProcessError') {
|
|
581
|
-
|
|
581
|
+
const isLegacyProtocolV2LockedFailure =
|
|
582
|
+
this.device.isProtocolV2() && /^device (?:is )?locked$/i.test(message?.trim() ?? '');
|
|
583
|
+
if (subcode === 9 || isLegacyProtocolV2LockedFailure) {
|
|
582
584
|
error = ERRORS.TypedError(HardwareErrorCode.DeviceLocked, message, {
|
|
583
585
|
failureCode: code,
|
|
584
586
|
subcode,
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { HardwareErrorCode } from '@onekeyfe/hd-shared';
|
|
2
|
+
|
|
3
|
+
export function isDeviceLockedError(error: unknown): boolean {
|
|
4
|
+
return (
|
|
5
|
+
typeof error === 'object' &&
|
|
6
|
+
error !== null &&
|
|
7
|
+
'errorCode' in error &&
|
|
8
|
+
error.errorCode === HardwareErrorCode.DeviceLocked
|
|
9
|
+
);
|
|
10
|
+
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { HardwareErrorCode } from '@onekeyfe/hd-shared';
|
|
2
|
-
|
|
3
1
|
import { LoggerNames, getLogger } from '../../utils';
|
|
2
|
+
import { isDeviceLockedError } from './lockedError';
|
|
4
3
|
|
|
5
4
|
import type { BaseMethod } from '../../api/BaseMethod';
|
|
6
5
|
import type { Device } from '../../device/Device';
|
|
@@ -10,15 +9,6 @@ const Log = getLogger(LoggerNames.Core);
|
|
|
10
9
|
type RunnableMethod = Pick<BaseMethod, 'run' | 'unlockPolicy'> & { name?: string };
|
|
11
10
|
type UnlockableDevice = Pick<Device, 'isProtocolV2' | 'unlockDevice'>;
|
|
12
11
|
|
|
13
|
-
function isDeviceLockedError(error: unknown): boolean {
|
|
14
|
-
return (
|
|
15
|
-
typeof error === 'object' &&
|
|
16
|
-
error !== null &&
|
|
17
|
-
'errorCode' in error &&
|
|
18
|
-
error.errorCode === HardwareErrorCode.DeviceLocked
|
|
19
|
-
);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
12
|
export async function runMethodWithUnlockRetry(method: RunnableMethod, device: UnlockableDevice) {
|
|
23
13
|
try {
|
|
24
14
|
return await method.run();
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { ERRORS, HardwareErrorCode } from '@onekeyfe/hd-shared';
|
|
2
2
|
|
|
3
|
+
import { isDeviceLockedError } from './lockedError';
|
|
4
|
+
|
|
3
5
|
import type { Device } from '../../device/Device';
|
|
4
6
|
|
|
5
7
|
const getErrorText = (error: unknown) => {
|
|
@@ -31,15 +33,11 @@ export async function getProtocolV2WalletSession(
|
|
|
31
33
|
device: Device,
|
|
32
34
|
options?: { initSession?: boolean; expectedPassphraseState?: string }
|
|
33
35
|
) {
|
|
34
|
-
if (device.features?.unlocked === false) {
|
|
35
|
-
throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, 'Device is locked');
|
|
36
|
-
}
|
|
37
|
-
|
|
38
36
|
if (options?.initSession) {
|
|
39
37
|
device.clearInternalState();
|
|
40
38
|
}
|
|
41
39
|
|
|
42
|
-
|
|
40
|
+
let sessionId =
|
|
43
41
|
typeof device.getInternalState === 'function' ? device.getInternalState() : undefined;
|
|
44
42
|
|
|
45
43
|
try {
|
|
@@ -50,13 +48,30 @@ export async function getProtocolV2WalletSession(
|
|
|
50
48
|
sessionId ? { session_id: sessionId } : {}
|
|
51
49
|
);
|
|
52
50
|
|
|
53
|
-
const
|
|
54
|
-
|
|
51
|
+
const requestWalletSession = async () => {
|
|
52
|
+
try {
|
|
53
|
+
return await requestDeviceSession(sessionId);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
if (!sessionId || !isProtocolV2InvalidSessionError(error)) {
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
58
|
+
device.clearInternalState();
|
|
59
|
+
sessionId = undefined;
|
|
60
|
+
return requestDeviceSession();
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
let response;
|
|
65
|
+
try {
|
|
66
|
+
response = await requestWalletSession();
|
|
67
|
+
} catch (error) {
|
|
68
|
+
if (!isDeviceLockedError(error)) {
|
|
55
69
|
throw error;
|
|
56
70
|
}
|
|
57
|
-
device.
|
|
58
|
-
|
|
59
|
-
}
|
|
71
|
+
await device.unlockDevice();
|
|
72
|
+
response = await requestWalletSession();
|
|
73
|
+
}
|
|
74
|
+
const { message } = response;
|
|
60
75
|
|
|
61
76
|
if (
|
|
62
77
|
options?.expectedPassphraseState &&
|