@onekeyfe/hd-core 1.2.0-alpha.13 → 1.2.0-alpha.15
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__/DeviceEventRegistration.test.ts +35 -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/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
- package/dist/core/deviceEventRegistration.d.ts +11 -0
- package/dist/core/deviceEventRegistration.d.ts.map +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/device/DeviceCommands.d.ts.map +1 -1
- package/dist/index.js +73 -33
- 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/api/allnetwork/AllNetworkGetAddressBase.ts +13 -8
- package/src/core/deviceEventRegistration.ts +28 -0
- package/src/core/index.ts +9 -7
- 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'],
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { DEVICE } from '../src/events';
|
|
2
|
+
import { registerHardwareUiEventListeners } from '../src/core/deviceEventRegistration';
|
|
3
|
+
|
|
4
|
+
const handlers = {
|
|
5
|
+
pin: jest.fn(),
|
|
6
|
+
button: jest.fn(),
|
|
7
|
+
passphrase: jest.fn(),
|
|
8
|
+
passphraseOnDevice: jest.fn(),
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const createDevice = (protocolV2: boolean) => ({
|
|
12
|
+
isProtocolV2: jest.fn(() => protocolV2),
|
|
13
|
+
on: jest.fn(),
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
describe('hardware UI event registration', () => {
|
|
17
|
+
test('does not register hardware-originated UI events for Protocol V2 devices', () => {
|
|
18
|
+
const device = createDevice(true);
|
|
19
|
+
|
|
20
|
+
expect(registerHardwareUiEventListeners(device as any, handlers)).toBe(false);
|
|
21
|
+
expect(device.on).not.toHaveBeenCalled();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('keeps the existing interactive event listeners for Protocol V1 devices', () => {
|
|
25
|
+
const device = createDevice(false);
|
|
26
|
+
|
|
27
|
+
expect(registerHardwareUiEventListeners(device as any, handlers)).toBe(true);
|
|
28
|
+
expect(device.on.mock.calls.map(([type]) => type)).toEqual([
|
|
29
|
+
DEVICE.PIN,
|
|
30
|
+
DEVICE.BUTTON,
|
|
31
|
+
DEVICE.PASSPHRASE,
|
|
32
|
+
DEVICE.PASSPHRASE_ON_DEVICE,
|
|
33
|
+
]);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
@@ -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":"AllNetworkGetAddressBase.d.ts","sourceRoot":"","sources":["../../../src/api/allnetwork/AllNetworkGetAddressBase.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"AllNetworkGetAddressBase.d.ts","sourceRoot":"","sources":["../../../src/api/allnetwork/AllNetworkGetAddressBase.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAgB3C,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,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;IAwHzB,QAAQ,CAAC,oBAAoB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAE9E,GAAG;CAuBV"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { DEVICE } from '../events';
|
|
2
|
+
import type { Device, DeviceEvents } from '../device/Device';
|
|
3
|
+
export type HardwareUiEventHandlers = {
|
|
4
|
+
pin: (...event: DeviceEvents[typeof DEVICE.PIN]) => void;
|
|
5
|
+
button: (...event: DeviceEvents[typeof DEVICE.BUTTON]) => void;
|
|
6
|
+
passphrase: (...event: DeviceEvents[typeof DEVICE.PASSPHRASE]) => void;
|
|
7
|
+
passphraseOnDevice: (...event: DeviceEvents[typeof DEVICE.PASSPHRASE_ON_DEVICE]) => void;
|
|
8
|
+
};
|
|
9
|
+
export declare const shouldRegisterHardwareUiEvents: (device: Pick<Device, 'isProtocolV2'>) => boolean;
|
|
10
|
+
export declare function registerHardwareUiEventListeners(device: Pick<Device, 'isProtocolV2' | 'on'>, handlers: HardwareUiEventHandlers): boolean;
|
|
11
|
+
//# sourceMappingURL=deviceEventRegistration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deviceEventRegistration.d.ts","sourceRoot":"","sources":["../../src/core/deviceEventRegistration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnC,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAE7D,MAAM,MAAM,uBAAuB,GAAG;IACpC,GAAG,EAAE,CAAC,GAAG,KAAK,EAAE,YAAY,CAAC,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;IACzD,MAAM,EAAE,CAAC,GAAG,KAAK,EAAE,YAAY,CAAC,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;IAC/D,UAAU,EAAE,CAAC,GAAG,KAAK,EAAE,YAAY,CAAC,OAAO,MAAM,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;IACvE,kBAAkB,EAAE,CAAC,GAAG,KAAK,EAAE,YAAY,CAAC,OAAO,MAAM,CAAC,oBAAoB,CAAC,KAAK,IAAI,CAAC;CAC1F,CAAC;AAEF,eAAO,MAAM,8BAA8B,WAAY,KAAK,MAAM,EAAE,cAAc,CAAC,YAC3D,CAAC;AAEzB,wBAAgB,gCAAgC,CAC9C,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC,EAC3C,QAAQ,EAAE,uBAAuB,WAWlC"}
|
package/dist/core/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":";AACA,OAAO,YAAY,MAAM,QAAQ,CAAC;AAoClC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAkB1C,OAAO,eAAe,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":";AACA,OAAO,YAAY,MAAM,QAAQ,CAAC;AAoClC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAkB1C,OAAO,eAAe,MAAM,2BAA2B,CAAC;AAMxD,OAAO,KAAK,EAAE,eAAe,EAAyB,MAAM,UAAU,CAAC;AACvE,OAAO,KAAK,EAAE,WAAW,EAAmD,MAAM,WAAW,CAAC;AAI9F,OAAO,KAAK,EAAE,6BAA6B,EAAoB,MAAM,wBAAwB,CAAC;AAW9F,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;AA+D7D,eAAO,MAAM,OAAO,YAAmB,WAAW,WAAW,WAAW,iBA6EvE,CAAC;AA0zBF,eAAO,MAAM,MAAM,YAAa,WAAW,cAAc,MAAM,SAkF9D,CAAC;AAiFF,eAAO,MAAM,qBAAqB,gFAejC,CAAC;AA0GF,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,YAAY;IAC5C,OAAO,CAAC,cAAc,CAAoB;IAE1C,SAAgB,aAAa,EAAE,MAAM,CAAC;IAEtC,OAAO,CAAC,YAAY,CAAsB;IAG1C,OAAO,CAAC,qBAAqB,CAA4B;IAEzD,OAAO,CAAC,iBAAiB,CAAoB;;IAS7C,eAAe,CAAC,WAAW,EAAE,MAAM;IAInC,OAAO,CAAC,cAAc;IAoBhB,aAAa,CAAC,OAAO,EAAE,WAAW;IA+DxC,OAAO;CASR;AAED,eAAO,MAAM,QAAQ,YAGpB,CAAC;AAEF,eAAO,MAAM,aAAa,uBAIzB,CAAC;AAMF,eAAO,MAAM,IAAI,aACL,eAAe,aACd,GAAG,WACL,6BAA6B,8BAoBvC,CAAC;AAEF,eAAO,MAAM,eAAe;SAKrB,eAAe,CAAC,KAAK,CAAC;eAChB,GAAG;;UASf,CAAC"}
|
|
@@ -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, {
|
|
@@ -48584,6 +48610,18 @@ class CipherKeyValue extends BaseMethod {
|
|
|
48584
48610
|
}
|
|
48585
48611
|
}
|
|
48586
48612
|
|
|
48613
|
+
const shouldRegisterHardwareUiEvents = (device) => !device.isProtocolV2();
|
|
48614
|
+
function registerHardwareUiEventListeners(device, handlers) {
|
|
48615
|
+
if (!shouldRegisterHardwareUiEvents(device)) {
|
|
48616
|
+
return false;
|
|
48617
|
+
}
|
|
48618
|
+
device.on(DEVICE.PIN, handlers.pin);
|
|
48619
|
+
device.on(DEVICE.BUTTON, handlers.button);
|
|
48620
|
+
device.on(DEVICE.PASSPHRASE, handlers.passphrase);
|
|
48621
|
+
device.on(DEVICE.PASSPHRASE_ON_DEVICE, handlers.passphraseOnDevice);
|
|
48622
|
+
return true;
|
|
48623
|
+
}
|
|
48624
|
+
|
|
48587
48625
|
const Mainnet = 'mainnet';
|
|
48588
48626
|
const networkAliases = {
|
|
48589
48627
|
tbtc: { name: 'btc', coin: 'Testnet' },
|
|
@@ -48851,9 +48889,11 @@ class AllNetworkGetAddressBase extends BaseMethod {
|
|
|
48851
48889
|
commandsInstanceId: (_c = this.device.commands) === null || _c === void 0 ? void 0 : _c.instanceId,
|
|
48852
48890
|
});
|
|
48853
48891
|
}
|
|
48854
|
-
this.device
|
|
48855
|
-
|
|
48856
|
-
|
|
48892
|
+
if (shouldRegisterHardwareUiEvents(this.device)) {
|
|
48893
|
+
this.device.on(DEVICE.BUTTON, buttonListener);
|
|
48894
|
+
this.device.on(DEVICE.PIN, onSignalAbort);
|
|
48895
|
+
this.device.on(DEVICE.PASSPHRASE, onSignalAbort);
|
|
48896
|
+
}
|
|
48857
48897
|
preCheckDeviceSupport(this.device, method);
|
|
48858
48898
|
if (this.temporarySafetyCheckPrompted) {
|
|
48859
48899
|
method.temporarySafetyCheckPrompted = true;
|
|
@@ -48892,9 +48932,11 @@ class AllNetworkGetAddressBase extends BaseMethod {
|
|
|
48892
48932
|
}
|
|
48893
48933
|
}
|
|
48894
48934
|
finally {
|
|
48895
|
-
this.device
|
|
48896
|
-
|
|
48897
|
-
|
|
48935
|
+
if (shouldRegisterHardwareUiEvents(this.device)) {
|
|
48936
|
+
this.device.off(DEVICE.BUTTON, buttonListener);
|
|
48937
|
+
this.device.off(DEVICE.PIN, onSignalAbort);
|
|
48938
|
+
this.device.off(DEVICE.PASSPHRASE, onSignalAbort);
|
|
48939
|
+
}
|
|
48898
48940
|
}
|
|
48899
48941
|
return result;
|
|
48900
48942
|
});
|
|
@@ -58166,12 +58208,6 @@ const getSynchronize = (mutex) => {
|
|
|
58166
58208
|
};
|
|
58167
58209
|
|
|
58168
58210
|
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
58211
|
function runMethodWithUnlockRetry(method, device) {
|
|
58176
58212
|
return __awaiter(this, void 0, void 0, function* () {
|
|
58177
58213
|
try {
|
|
@@ -58425,10 +58461,14 @@ const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, voi
|
|
|
58425
58461
|
if (activeRequests.length > 0) {
|
|
58426
58462
|
Log.warn(`[${method.instanceId}] Device ${device.instanceId} has ${activeRequests.length} active requests:`, activeRequests.map(formatRequestContext));
|
|
58427
58463
|
}
|
|
58428
|
-
device
|
|
58429
|
-
|
|
58430
|
-
|
|
58431
|
-
|
|
58464
|
+
registerHardwareUiEventListeners(device, {
|
|
58465
|
+
pin: onDevicePinHandler,
|
|
58466
|
+
button: onDeviceButtonHandler,
|
|
58467
|
+
passphrase: message.payload.useEmptyPassphrase
|
|
58468
|
+
? onEmptyPassphraseHandler
|
|
58469
|
+
: onDevicePassphraseHandler,
|
|
58470
|
+
passphraseOnDevice: onEnterPassphraseOnDeviceHandler,
|
|
58471
|
+
});
|
|
58432
58472
|
device.on(DEVICE.FEATURES, onDeviceFeaturesHandler);
|
|
58433
58473
|
device.on(DEVICE.SELECT_DEVICE_IN_BOOTLOADER_FOR_WEB_DEVICE, onSelectDeviceInBootloaderForWebDeviceHandler);
|
|
58434
58474
|
device.on(DEVICE.SELECT_DEVICE_FOR_SWITCH_FIRMWARE_WEB_DEVICE, onSelectDeviceForSwitchFirmwareWebDeviceHandler);
|
|
@@ -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.15",
|
|
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.15",
|
|
29
|
+
"@onekeyfe/hd-transport": "1.2.0-alpha.15",
|
|
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": "06dd8f9cba892bb66242e5a51038a7103fb05f09"
|
|
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() {
|
|
@@ -15,6 +15,7 @@ import { DEVICE, IFRAME, createUiMessage } from '../../events';
|
|
|
15
15
|
import { isMethodVersionRangeUnsupported } from '../../utils';
|
|
16
16
|
import { UI_REQUEST } from '../../constants/ui-request';
|
|
17
17
|
import { onDeviceButtonHandler } from '../../core';
|
|
18
|
+
import { shouldRegisterHardwareUiEvents } from '../../core/deviceEventRegistration';
|
|
18
19
|
import {
|
|
19
20
|
completeRequestContext,
|
|
20
21
|
createRequestContext,
|
|
@@ -364,11 +365,13 @@ export default abstract class AllNetworkGetAddressBase extends BaseMethod<
|
|
|
364
365
|
});
|
|
365
366
|
}
|
|
366
367
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
368
|
+
if (shouldRegisterHardwareUiEvents(this.device)) {
|
|
369
|
+
// pro pin event
|
|
370
|
+
this.device.on(DEVICE.BUTTON, buttonListener);
|
|
371
|
+
// classic pin event
|
|
372
|
+
this.device.on(DEVICE.PIN, onSignalAbort);
|
|
373
|
+
this.device.on(DEVICE.PASSPHRASE, onSignalAbort);
|
|
374
|
+
}
|
|
372
375
|
|
|
373
376
|
preCheckDeviceSupport(this.device, method);
|
|
374
377
|
if (this.temporarySafetyCheckPrompted) {
|
|
@@ -422,9 +425,11 @@ export default abstract class AllNetworkGetAddressBase extends BaseMethod<
|
|
|
422
425
|
);
|
|
423
426
|
}
|
|
424
427
|
} finally {
|
|
425
|
-
this.device
|
|
426
|
-
|
|
427
|
-
|
|
428
|
+
if (shouldRegisterHardwareUiEvents(this.device)) {
|
|
429
|
+
this.device.off(DEVICE.BUTTON, buttonListener);
|
|
430
|
+
this.device.off(DEVICE.PIN, onSignalAbort);
|
|
431
|
+
this.device.off(DEVICE.PASSPHRASE, onSignalAbort);
|
|
432
|
+
}
|
|
428
433
|
}
|
|
429
434
|
|
|
430
435
|
return result;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { DEVICE } from '../events';
|
|
2
|
+
|
|
3
|
+
import type { Device, DeviceEvents } from '../device/Device';
|
|
4
|
+
|
|
5
|
+
export type HardwareUiEventHandlers = {
|
|
6
|
+
pin: (...event: DeviceEvents[typeof DEVICE.PIN]) => void;
|
|
7
|
+
button: (...event: DeviceEvents[typeof DEVICE.BUTTON]) => void;
|
|
8
|
+
passphrase: (...event: DeviceEvents[typeof DEVICE.PASSPHRASE]) => void;
|
|
9
|
+
passphraseOnDevice: (...event: DeviceEvents[typeof DEVICE.PASSPHRASE_ON_DEVICE]) => void;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const shouldRegisterHardwareUiEvents = (device: Pick<Device, 'isProtocolV2'>) =>
|
|
13
|
+
!device.isProtocolV2();
|
|
14
|
+
|
|
15
|
+
export function registerHardwareUiEventListeners(
|
|
16
|
+
device: Pick<Device, 'isProtocolV2' | 'on'>,
|
|
17
|
+
handlers: HardwareUiEventHandlers
|
|
18
|
+
) {
|
|
19
|
+
if (!shouldRegisterHardwareUiEvents(device)) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
device.on(DEVICE.PIN, handlers.pin);
|
|
24
|
+
device.on(DEVICE.BUTTON, handlers.button);
|
|
25
|
+
device.on(DEVICE.PASSPHRASE, handlers.passphrase);
|
|
26
|
+
device.on(DEVICE.PASSPHRASE_ON_DEVICE, handlers.passphraseOnDevice);
|
|
27
|
+
return true;
|
|
28
|
+
}
|
package/src/core/index.ts
CHANGED
|
@@ -55,6 +55,7 @@ import {
|
|
|
55
55
|
import TransportManager from '../data-manager/TransportManager';
|
|
56
56
|
import DeviceConnector from '../device/DeviceConnector';
|
|
57
57
|
import RequestQueue from './RequestQueue';
|
|
58
|
+
import { registerHardwareUiEventListeners } from './deviceEventRegistration';
|
|
58
59
|
import { getSynchronize } from '../utils/getSynchronize';
|
|
59
60
|
import { runMethodWithUnlockRetry } from '../protocols/protocol-v2/unlockRetry';
|
|
60
61
|
|
|
@@ -395,13 +396,14 @@ const onCallDevice = async (
|
|
|
395
396
|
);
|
|
396
397
|
}
|
|
397
398
|
|
|
398
|
-
device
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
399
|
+
registerHardwareUiEventListeners(device, {
|
|
400
|
+
pin: onDevicePinHandler,
|
|
401
|
+
button: onDeviceButtonHandler,
|
|
402
|
+
passphrase: message.payload.useEmptyPassphrase
|
|
403
|
+
? onEmptyPassphraseHandler
|
|
404
|
+
: onDevicePassphraseHandler,
|
|
405
|
+
passphraseOnDevice: onEnterPassphraseOnDeviceHandler,
|
|
406
|
+
});
|
|
405
407
|
device.on(DEVICE.FEATURES, onDeviceFeaturesHandler);
|
|
406
408
|
device.on(
|
|
407
409
|
DEVICE.SELECT_DEVICE_IN_BOOTLOADER_FOR_WEB_DEVICE,
|
|
@@ -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 &&
|