@onekeyfe/hd-core 1.2.0-alpha.23 → 1.2.0-alpha.24
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 +35 -0
- package/__tests__/connectSettings.test.ts +5 -47
- package/__tests__/device-lifecycle-events.test.ts +59 -0
- package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +30 -39
- package/__tests__/open-wallet-session.test.ts +192 -129
- package/__tests__/protocol-v2-ping.test.ts +28 -0
- package/__tests__/protocol-v2.test.ts +338 -376
- package/__tests__/public-pro2-api-boundary.test.ts +22 -0
- package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV2.d.ts +0 -11
- package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV3.d.ts +3 -7
- package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV4.d.ts +5 -21
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/OpenWalletSession.d.ts +1 -8
- package/dist/api/OpenWalletSession.d.ts.map +1 -1
- package/dist/api/device/DeviceUpdateBootloader.d.ts +1 -5
- package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +0 -7
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
- package/dist/api/firmware/getBinary.d.ts +0 -7
- package/dist/api/firmware/getBinary.d.ts.map +1 -1
- package/dist/api/firmware/updateBootloader.d.ts +0 -2
- package/dist/api/firmware/updateBootloader.d.ts.map +1 -1
- package/dist/api/firmware/uploadFirmware.d.ts +1 -9
- package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/protocol-v2/Ping.d.ts +2 -0
- package/dist/api/protocol-v2/Ping.d.ts.map +1 -1
- package/dist/api/stellar/StellarSignTransaction.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/data-manager/DataManager.d.ts +0 -1
- package/dist/data-manager/DataManager.d.ts.map +1 -1
- package/dist/data-manager/connectSettings.d.ts.map +1 -1
- package/dist/device/Device.d.ts.map +1 -1
- package/dist/device/DeviceCommands.d.ts.map +1 -1
- package/dist/index.d.ts +89 -273
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +783 -2443
- package/dist/inject.d.ts.map +1 -1
- package/dist/lowLevelInject.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/unlockRetry.d.ts +2 -3
- package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/walletSession.d.ts +12 -0
- package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
- package/dist/topLevelInject.d.ts.map +1 -1
- package/dist/types/api/checkAllFirmwareRelease.d.ts +0 -3
- package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
- package/dist/types/api/deviceUpdateBootloader.d.ts +0 -6
- package/dist/types/api/deviceUpdateBootloader.d.ts.map +1 -1
- package/dist/types/api/export.d.ts +1 -4
- package/dist/types/api/export.d.ts.map +1 -1
- package/dist/types/api/firmwareUpdate.d.ts +0 -69
- package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
- package/dist/types/api/index.d.ts +4 -10
- package/dist/types/api/index.d.ts.map +1 -1
- package/dist/types/api/openWalletSession.d.ts +0 -12
- package/dist/types/api/openWalletSession.d.ts.map +1 -1
- package/dist/types/api/protocolV2.d.ts +4 -0
- package/dist/types/api/protocolV2.d.ts.map +1 -1
- package/dist/types/settings.d.ts +0 -13
- package/dist/types/settings.d.ts.map +1 -1
- package/dist/utils/deviceInfoUtils.d.ts.map +1 -1
- package/dist/utils/patch.d.ts +1 -1
- package/dist/utils/patch.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/api/CheckAllFirmwareRelease.ts +3 -23
- package/src/api/FirmwareUpdateV2.ts +120 -292
- package/src/api/FirmwareUpdateV3.ts +55 -256
- package/src/api/FirmwareUpdateV4.ts +297 -757
- package/src/api/OpenWalletSession.ts +23 -86
- package/src/api/device/DeviceUpdateBootloader.ts +6 -122
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +0 -50
- package/src/api/firmware/updateBootloader.ts +4 -19
- package/src/api/firmware/uploadFirmware.ts +22 -140
- package/src/api/index.ts +1 -0
- package/src/api/protocol-v2/Ping.ts +32 -1
- package/src/core/index.ts +39 -7
- package/src/data/messages/messages-protocol-v2.json +33 -1
- package/src/data-manager/DataManager.ts +33 -33
- package/src/data-manager/connectSettings.ts +0 -11
- package/src/device/Device.ts +7 -9
- package/src/device/DeviceCommands.ts +19 -0
- package/src/index.ts +0 -5
- package/src/inject.ts +4 -22
- package/src/lowLevelInject.ts +1 -5
- package/src/protocols/protocol-v2/unlockRetry.ts +20 -3
- package/src/protocols/protocol-v2/walletSession.ts +26 -8
- package/src/topLevelInject.ts +1 -5
- package/src/types/api/checkAllFirmwareRelease.ts +0 -3
- package/src/types/api/deviceUpdateBootloader.ts +0 -6
- package/src/types/api/export.ts +0 -18
- package/src/types/api/firmwareUpdate.ts +0 -76
- package/src/types/api/index.ts +3 -14
- package/src/types/api/openWalletSession.ts +0 -19
- package/src/types/api/protocolV2.ts +10 -0
- package/src/types/settings.ts +0 -13
- package/src/utils/deviceInfoUtils.ts +15 -3
- package/__tests__/firmware-update/check-all-firmware-release.test.ts +0 -86
- package/__tests__/firmware-update/firmware-artifact-source.test.ts +0 -119
- package/__tests__/firmware-update/firmware-host-binding.test.ts +0 -70
- package/__tests__/firmware-update/firmware-update-capabilities.test.ts +0 -13
- package/__tests__/firmware-update/firmware-update-plan.test.ts +0 -326
- package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +0 -213
- package/__tests__/firmware-update/firmware-upload-source.test.ts +0 -70
- package/dist/api/firmware/FirmwareArtifactSource.d.ts +0 -25
- package/dist/api/firmware/FirmwareArtifactSource.d.ts.map +0 -1
- package/dist/api/firmware/FirmwareHostBinding.d.ts +0 -6
- package/dist/api/firmware/FirmwareHostBinding.d.ts.map +0 -1
- package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts +0 -3
- package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts.map +0 -1
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts +0 -23
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +0 -1
- package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts +0 -30
- package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +0 -1
- package/dist/types/api/firmwareUpdateCapabilities.d.ts +0 -9
- package/dist/types/api/firmwareUpdateCapabilities.d.ts.map +0 -1
- package/dist/types/api/firmwareUpdatePlan.d.ts +0 -27
- package/dist/types/api/firmwareUpdatePlan.d.ts.map +0 -1
- package/dist/types/api/firmwareUpdatePreparedPlan.d.ts +0 -42
- package/dist/types/api/firmwareUpdatePreparedPlan.d.ts.map +0 -1
- package/src/api/firmware/FirmwareArtifactSource.ts +0 -278
- package/src/api/firmware/FirmwareHostBinding.ts +0 -100
- package/src/api/firmware/FirmwareUpdateCapabilities.ts +0 -9
- package/src/api/firmware/FirmwareUpdatePlan.ts +0 -621
- package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +0 -392
- package/src/types/api/firmwareUpdateCapabilities.ts +0 -9
- package/src/types/api/firmwareUpdatePlan.ts +0 -36
- package/src/types/api/firmwareUpdatePreparedPlan.ts +0 -53
package/src/inject.ts
CHANGED
|
@@ -1,17 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
prepareFirmwareUpdatePlan,
|
|
4
|
-
validateFirmwareUpdatePreparedPlan,
|
|
5
|
-
} from './api/firmware/FirmwareUpdatePreparedPlan';
|
|
6
|
-
import {
|
|
7
|
-
getFirmwareUpdateHostBindingGeneration,
|
|
8
|
-
registerFirmwareUpdateHostBinding,
|
|
9
|
-
unregisterFirmwareUpdateHostBinding,
|
|
10
|
-
} from './api/firmware/FirmwareHostBinding';
|
|
11
|
-
|
|
1
|
+
import type { Unsuccessful } from './types';
|
|
12
2
|
import type { EventEmitter } from 'events';
|
|
13
3
|
import type { CallMethod } from './events';
|
|
14
|
-
import type { Unsuccessful } from './types';
|
|
15
4
|
import type { CoreApi } from './types/api';
|
|
16
5
|
import type { AllNetworkAddress } from './types/api/allNetworkGetAddress';
|
|
17
6
|
|
|
@@ -79,10 +68,7 @@ export const inject = ({
|
|
|
79
68
|
|
|
80
69
|
call,
|
|
81
70
|
|
|
82
|
-
dispose
|
|
83
|
-
unregisterFirmwareUpdateHostBinding();
|
|
84
|
-
await dispose();
|
|
85
|
-
},
|
|
71
|
+
dispose,
|
|
86
72
|
|
|
87
73
|
uiResponse,
|
|
88
74
|
|
|
@@ -113,12 +99,6 @@ export const createCoreApi = (
|
|
|
113
99
|
| 'updateSettings'
|
|
114
100
|
| 'switchTransport'
|
|
115
101
|
> => ({
|
|
116
|
-
getFirmwareUpdateCapabilities,
|
|
117
|
-
registerFirmwareUpdateHostBinding,
|
|
118
|
-
unregisterFirmwareUpdateHostBinding,
|
|
119
|
-
getFirmwareUpdateHostBindingGeneration,
|
|
120
|
-
prepareFirmwareUpdatePlan,
|
|
121
|
-
validateFirmwareUpdatePreparedPlan,
|
|
122
102
|
getLogs: () => call({ method: 'getLogs' }),
|
|
123
103
|
clearSessionCache: params => call({ ...params, method: 'clearSessionCache' }),
|
|
124
104
|
/**
|
|
@@ -167,6 +147,8 @@ export const createCoreApi = (
|
|
|
167
147
|
|
|
168
148
|
testInitializeDeviceDuration: (connectId, params) =>
|
|
169
149
|
call({ ...params, connectId, method: 'testInitializeDeviceDuration' }),
|
|
150
|
+
testProtocolV2Ping: (connectId, params) =>
|
|
151
|
+
call({ ...params, connectId, method: 'testProtocolV2Ping' }),
|
|
170
152
|
preInitialize: (connectId, params) => call({ ...params, connectId, method: 'preInitialize' }),
|
|
171
153
|
deviceBackup: connectId => call({ connectId, method: 'deviceBackup' }),
|
|
172
154
|
deviceChangePin: (connectId, params) => call({ ...params, connectId, method: 'deviceChangePin' }),
|
package/src/lowLevelInject.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { createCoreApi } from './inject';
|
|
2
|
-
import { unregisterFirmwareUpdateHostBinding } from './api/firmware/FirmwareHostBinding';
|
|
3
2
|
|
|
4
3
|
import type { EventEmitter } from 'events';
|
|
5
4
|
import type { CallMethod, CoreMessage } from './events';
|
|
@@ -44,10 +43,7 @@ export const lowLevelInject = ({
|
|
|
44
43
|
|
|
45
44
|
call,
|
|
46
45
|
|
|
47
|
-
dispose
|
|
48
|
-
unregisterFirmwareUpdateHostBinding();
|
|
49
|
-
await dispose();
|
|
50
|
-
},
|
|
46
|
+
dispose,
|
|
51
47
|
|
|
52
48
|
uiResponse,
|
|
53
49
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { LoggerNames, getLogger } from '../../utils';
|
|
2
2
|
import { isDeviceLockedError } from './lockedError';
|
|
3
3
|
import { isProtocolV2UiEnabled, resolveProtocolV2UiInteraction } from './uiInteraction';
|
|
4
|
+
import { restoreProtocolV2WalletSession } from './walletSession';
|
|
4
5
|
|
|
5
6
|
import type { BaseMethod } from '../../api/BaseMethod';
|
|
6
7
|
import type { Device } from '../../device/Device';
|
|
@@ -10,9 +11,14 @@ const Log = getLogger(LoggerNames.Core);
|
|
|
10
11
|
|
|
11
12
|
type RunnableMethod = Pick<
|
|
12
13
|
BaseMethod,
|
|
13
|
-
|
|
14
|
+
| 'run'
|
|
15
|
+
| 'unlockPolicy'
|
|
16
|
+
| 'protocolV2UiInteraction'
|
|
17
|
+
| 'protocolV2UiMode'
|
|
18
|
+
| 'params'
|
|
19
|
+
| 'payload'
|
|
20
|
+
| 'useDevicePassphraseState'
|
|
14
21
|
> & { name?: string };
|
|
15
|
-
type UnlockableDevice = Pick<Device, 'isProtocolV2' | 'unlockDevice' | 'features'>;
|
|
16
22
|
type UiInteractionCoordinator = Pick<
|
|
17
23
|
ProtocolV2UiInteractionCoordinator,
|
|
18
24
|
'enterMethodInteraction' | 'enterUnlockInteraction' | 'resumeMethodInteraction'
|
|
@@ -20,7 +26,7 @@ type UiInteractionCoordinator = Pick<
|
|
|
20
26
|
|
|
21
27
|
export async function runMethodWithUnlockRetry(
|
|
22
28
|
method: RunnableMethod,
|
|
23
|
-
device:
|
|
29
|
+
device: Device,
|
|
24
30
|
uiCoordinator?: UiInteractionCoordinator
|
|
25
31
|
) {
|
|
26
32
|
const shouldEmitUi = isProtocolV2UiEnabled(method);
|
|
@@ -59,6 +65,17 @@ export async function runMethodWithUnlockRetry(
|
|
|
59
65
|
}
|
|
60
66
|
await device.unlockDevice();
|
|
61
67
|
Log.debug('Protocol V2 unlock completed', { method: method.name });
|
|
68
|
+
const expectedPassphraseState = method.payload?.useEmptyPassphrase
|
|
69
|
+
? undefined
|
|
70
|
+
: method.payload?.passphraseState ?? device.passphraseState;
|
|
71
|
+
if (
|
|
72
|
+
method.useDevicePassphraseState &&
|
|
73
|
+
typeof expectedPassphraseState === 'string' &&
|
|
74
|
+
expectedPassphraseState.length > 0
|
|
75
|
+
) {
|
|
76
|
+
await restoreProtocolV2WalletSession(device, expectedPassphraseState);
|
|
77
|
+
Log.debug('Protocol V2 wallet session restored after unlock', { method: method.name });
|
|
78
|
+
}
|
|
62
79
|
if (shouldEmitUi) {
|
|
63
80
|
uiCoordinator?.resumeMethodInteraction();
|
|
64
81
|
}
|
|
@@ -36,15 +36,12 @@ const getDeviceSession = async (device: Device, request: DeviceSessionGet) => {
|
|
|
36
36
|
}
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
-
const askDevicePassphrase = async (device: Device) => {
|
|
39
|
+
const askDevicePassphrase = async (device: Device, passphrase?: string) => {
|
|
40
40
|
const request = () =>
|
|
41
41
|
device.commands.typedCall(
|
|
42
42
|
'DeviceSessionAskPassphrase',
|
|
43
43
|
'Success',
|
|
44
|
-
{}
|
|
45
|
-
{
|
|
46
|
-
timeoutMs: 120_000,
|
|
47
|
-
}
|
|
44
|
+
passphrase ? { passphrase } : {}
|
|
48
45
|
);
|
|
49
46
|
try {
|
|
50
47
|
return await request();
|
|
@@ -64,7 +61,10 @@ const selectDeviceSession = async (device: Device) => {
|
|
|
64
61
|
reason: 'open-wallet' as const,
|
|
65
62
|
};
|
|
66
63
|
const response = await device.commands.promptPassphrase(
|
|
67
|
-
{
|
|
64
|
+
{
|
|
65
|
+
existsAttachPinUser,
|
|
66
|
+
...metadata,
|
|
67
|
+
},
|
|
68
68
|
{ cancelDeviceOnReject: false }
|
|
69
69
|
);
|
|
70
70
|
const hasHostPassphrase =
|
|
@@ -94,8 +94,11 @@ const selectDeviceSession = async (device: Device) => {
|
|
|
94
94
|
return getDeviceSession(device, {});
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
|
|
97
|
+
if (hasHostPassphrase) {
|
|
98
|
+
await askDevicePassphrase(device, response.passphrase);
|
|
99
|
+
return getDeviceSession(device, {});
|
|
100
|
+
}
|
|
101
|
+
|
|
99
102
|
device.emit(DEVICE.PASSPHRASE_ON_DEVICE, device, metadata);
|
|
100
103
|
await askDevicePassphrase(device);
|
|
101
104
|
return getDeviceSession(device, {});
|
|
@@ -107,6 +110,7 @@ export async function getProtocolV2WalletSession(
|
|
|
107
110
|
initSession?: boolean;
|
|
108
111
|
expectedPassphraseState?: string;
|
|
109
112
|
onlyMainPin?: boolean;
|
|
113
|
+
resumeOnly?: boolean;
|
|
110
114
|
}
|
|
111
115
|
) {
|
|
112
116
|
if (options?.initSession) {
|
|
@@ -152,6 +156,10 @@ export async function getProtocolV2WalletSession(
|
|
|
152
156
|
}
|
|
153
157
|
|
|
154
158
|
if (!response) {
|
|
159
|
+
if (options?.resumeOnly) {
|
|
160
|
+
device.clearInternalState();
|
|
161
|
+
throw ERRORS.TypedError(HardwareErrorCode.WalletSessionInvalid);
|
|
162
|
+
}
|
|
155
163
|
response = await selectDeviceSession(device);
|
|
156
164
|
}
|
|
157
165
|
|
|
@@ -182,3 +190,13 @@ export async function getProtocolV2WalletSession(
|
|
|
182
190
|
resumed,
|
|
183
191
|
};
|
|
184
192
|
}
|
|
193
|
+
|
|
194
|
+
export async function restoreProtocolV2WalletSession(
|
|
195
|
+
device: Device,
|
|
196
|
+
expectedPassphraseState: string
|
|
197
|
+
) {
|
|
198
|
+
return getProtocolV2WalletSession(device, {
|
|
199
|
+
expectedPassphraseState,
|
|
200
|
+
resumeOnly: true,
|
|
201
|
+
});
|
|
202
|
+
}
|
package/src/topLevelInject.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import EventEmitter from 'events';
|
|
2
2
|
|
|
3
3
|
import { createCoreApi } from './inject';
|
|
4
|
-
import { unregisterFirmwareUpdateHostBinding } from './api/firmware/FirmwareHostBinding';
|
|
5
4
|
|
|
6
5
|
import type { ConnectSettings } from './types/settings';
|
|
7
6
|
import type { CoreApi } from './types/api';
|
|
@@ -47,10 +46,7 @@ export const topLevelInject = () => {
|
|
|
47
46
|
lowLevelApi?.removeAllListeners(type);
|
|
48
47
|
},
|
|
49
48
|
|
|
50
|
-
dispose:
|
|
51
|
-
unregisterFirmwareUpdateHostBinding();
|
|
52
|
-
await lowLevelApi?.dispose();
|
|
53
|
-
},
|
|
49
|
+
dispose: () => lowLevelApi?.dispose(),
|
|
54
50
|
|
|
55
51
|
uiResponse: response => lowLevelApi?.uiResponse(response),
|
|
56
52
|
|
|
@@ -2,7 +2,6 @@ import type { IBLEFirmwareReleaseInfo } from '../settings';
|
|
|
2
2
|
import type { EFirmwareType } from '@onekeyfe/hd-shared';
|
|
3
3
|
import type { CommonParams, Response } from '../params';
|
|
4
4
|
import type { Features, IDeviceBLEFirmwareStatus, IDeviceFirmwareStatus } from '../device';
|
|
5
|
-
import type { FirmwareUpdatePlan } from './firmwareUpdatePlan';
|
|
6
5
|
|
|
7
6
|
export type FirmwareRelease = {
|
|
8
7
|
shouldUpdate?: boolean;
|
|
@@ -21,13 +20,11 @@ export type AllFirmwareRelease = {
|
|
|
21
20
|
bootloader?: FirmwareRelease;
|
|
22
21
|
bridge?: FirmwareRelease;
|
|
23
22
|
features?: Features;
|
|
24
|
-
firmwareUpdatePlan?: FirmwareUpdatePlan;
|
|
25
23
|
};
|
|
26
24
|
|
|
27
25
|
export type CheckAllFirmwareReleaseParams = {
|
|
28
26
|
checkBridgeRelease?: boolean;
|
|
29
27
|
firmwareType?: EFirmwareType;
|
|
30
|
-
platform?: 'native' | 'desktop' | 'ext' | 'web' | 'web-embed';
|
|
31
28
|
};
|
|
32
29
|
|
|
33
30
|
export declare function checkAllFirmwareRelease(
|
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
import type { Success } from '@onekeyfe/hd-transport';
|
|
2
2
|
import type { EFirmwareType } from '@onekeyfe/hd-shared';
|
|
3
|
-
import type { FirmwareArtifactReader, FirmwareArtifactReference } from './firmwareUpdate';
|
|
4
|
-
import type { FirmwareUpdatePreparedPlan } from './firmwareUpdatePreparedPlan';
|
|
5
3
|
import type { Response } from '../params';
|
|
6
4
|
|
|
7
5
|
export type DeviceUpdateBootloaderParams = {
|
|
8
|
-
preparedPlan?: FirmwareUpdatePreparedPlan;
|
|
9
|
-
hostBindingGeneration?: number;
|
|
10
6
|
binary?: ArrayBuffer;
|
|
11
|
-
artifact?: FirmwareArtifactReference;
|
|
12
|
-
artifactReader?: FirmwareArtifactReader;
|
|
13
7
|
firmwareType?: EFirmwareType;
|
|
14
8
|
};
|
|
15
9
|
|
package/src/types/api/export.ts
CHANGED
|
@@ -25,29 +25,11 @@ export type {
|
|
|
25
25
|
DeviceUploadResourceResponse,
|
|
26
26
|
} from './deviceUploadResource';
|
|
27
27
|
export type {
|
|
28
|
-
FirmwareArtifactReader,
|
|
29
|
-
FirmwareArtifactReference,
|
|
30
|
-
FirmwareUpdateHostBinding,
|
|
31
|
-
FirmwareUpdateArtifactParams,
|
|
32
28
|
FirmwareUpdateParams,
|
|
33
29
|
FirmwareUpdateBinaryParams,
|
|
34
30
|
FirmwareUpdateV3Params,
|
|
35
31
|
FirmwareUpdateV4Params,
|
|
36
|
-
FirmwareUpdateV4Target,
|
|
37
32
|
} from './firmwareUpdate';
|
|
38
|
-
export type {
|
|
39
|
-
FirmwareUpdatePlan,
|
|
40
|
-
FirmwareUpdatePlanArtifact,
|
|
41
|
-
FirmwareUpdatePlanArtifactRole,
|
|
42
|
-
FirmwareUpdatePlanTarget,
|
|
43
|
-
} from './firmwareUpdatePlan';
|
|
44
|
-
export type {
|
|
45
|
-
FirmwareUpdatePreparedArtifact,
|
|
46
|
-
FirmwareUpdatePreparedArtifactInput,
|
|
47
|
-
FirmwareUpdatePreparedEntry,
|
|
48
|
-
FirmwareUpdatePreparedPlan,
|
|
49
|
-
} from './firmwareUpdatePreparedPlan';
|
|
50
|
-
export type { FirmwareUpdateCapabilities } from './firmwareUpdateCapabilities';
|
|
51
33
|
export type { AllFirmwareRelease } from './checkAllFirmwareRelease';
|
|
52
34
|
|
|
53
35
|
export type { AllNetworkAddressParams, AllNetworkGetAddressParams } from './allNetworkGetAddress';
|
|
@@ -1,53 +1,14 @@
|
|
|
1
1
|
import type { EFirmwareType } from '@onekeyfe/hd-shared';
|
|
2
2
|
import type { PROTO } from '../../constants';
|
|
3
3
|
import type { Params, Response } from '../params';
|
|
4
|
-
import type { FirmwareUpdatePreparedPlan } from './firmwareUpdatePreparedPlan';
|
|
5
4
|
|
|
6
5
|
type IUpdateType = 'firmware' | 'ble';
|
|
7
6
|
|
|
8
|
-
export interface FirmwareArtifactReference {
|
|
9
|
-
artifactRef: string;
|
|
10
|
-
size: number;
|
|
11
|
-
sha256: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface FirmwareArtifactReader {
|
|
15
|
-
open(input: { artifactRef: string }): Promise<{
|
|
16
|
-
readerId: string;
|
|
17
|
-
size: number;
|
|
18
|
-
}>;
|
|
19
|
-
read(input: { readerId: string; offset: number; length: number }): Promise<{
|
|
20
|
-
data: ArrayBuffer;
|
|
21
|
-
bytesRead: number;
|
|
22
|
-
eof: boolean;
|
|
23
|
-
}>;
|
|
24
|
-
close(input: { readerId: string }): Promise<void>;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface FirmwareUpdateHostBinding {
|
|
28
|
-
artifactReader: FirmwareArtifactReader;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
7
|
export interface FirmwareUpdateBinaryParams {
|
|
32
8
|
binary: ArrayBuffer;
|
|
33
9
|
updateType: IUpdateType;
|
|
34
10
|
}
|
|
35
11
|
|
|
36
|
-
export interface FirmwareUpdateArtifactParams {
|
|
37
|
-
preparedPlan: FirmwareUpdatePreparedPlan;
|
|
38
|
-
hostBindingGeneration: number;
|
|
39
|
-
artifact: FirmwareArtifactReference;
|
|
40
|
-
resourceArtifact?: FirmwareArtifactReference;
|
|
41
|
-
resourceEntries?: Array<{
|
|
42
|
-
entryName: string;
|
|
43
|
-
artifact: FirmwareArtifactReference;
|
|
44
|
-
}>;
|
|
45
|
-
updateType: IUpdateType;
|
|
46
|
-
forcedUpdateRes?: boolean;
|
|
47
|
-
isUpdateBootloader?: boolean;
|
|
48
|
-
firmwareType?: EFirmwareType;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
12
|
export interface FirmwareUpdateParams {
|
|
52
13
|
version?: number[];
|
|
53
14
|
updateType: IUpdateType;
|
|
@@ -76,14 +37,8 @@ export declare function firmwareUpdateV2(
|
|
|
76
37
|
connectId: string | undefined,
|
|
77
38
|
params: Params<FirmwareUpdateBinaryParams & Platform>
|
|
78
39
|
): Response<PROTO.Success>;
|
|
79
|
-
export declare function firmwareUpdateV2(
|
|
80
|
-
connectId: string | undefined,
|
|
81
|
-
params: Params<FirmwareUpdateArtifactParams & Platform>
|
|
82
|
-
): Response<PROTO.Success>;
|
|
83
40
|
|
|
84
41
|
export interface FirmwareUpdateV3Params {
|
|
85
|
-
preparedPlan?: FirmwareUpdatePreparedPlan;
|
|
86
|
-
hostBindingGeneration?: number;
|
|
87
42
|
bleVersion?: number[];
|
|
88
43
|
bleBinary?: ArrayBuffer;
|
|
89
44
|
chunkSize?: number;
|
|
@@ -100,17 +55,6 @@ export interface FirmwareUpdateV3Params {
|
|
|
100
55
|
firmwareType?: EFirmwareType;
|
|
101
56
|
|
|
102
57
|
platform: IPlatform;
|
|
103
|
-
|
|
104
|
-
artifactReader?: FirmwareArtifactReader;
|
|
105
|
-
artifacts?: {
|
|
106
|
-
ble?: FirmwareArtifactReference;
|
|
107
|
-
firmware?: FirmwareArtifactReference;
|
|
108
|
-
bootloader?: FirmwareArtifactReference;
|
|
109
|
-
resourceEntries?: Array<{
|
|
110
|
-
entryName: string;
|
|
111
|
-
artifact: FirmwareArtifactReference;
|
|
112
|
-
}>;
|
|
113
|
-
};
|
|
114
58
|
}
|
|
115
59
|
|
|
116
60
|
/**
|
|
@@ -129,14 +73,10 @@ export type FirmwareUpdateV4Target =
|
|
|
129
73
|
| 'se04';
|
|
130
74
|
|
|
131
75
|
export interface FirmwareUpdateV4Params {
|
|
132
|
-
preparedPlan?: FirmwareUpdatePreparedPlan;
|
|
133
|
-
hostBindingGeneration?: number;
|
|
134
76
|
platform: IPlatform;
|
|
135
|
-
expectedDeviceId?: string;
|
|
136
77
|
chunkSize?: number;
|
|
137
78
|
firmwareType?: EFirmwareType;
|
|
138
79
|
targetsToUpdate?: FirmwareUpdateV4Target[];
|
|
139
|
-
expectedTargetVersions?: Partial<Record<FirmwareUpdateV4Target, string>>;
|
|
140
80
|
|
|
141
81
|
/** FW_MGMT_TARGET_ROMLOADER = 2; Pro2 cannot install it through firmwareUpdateV4. */
|
|
142
82
|
romloaderBinary?: ArrayBuffer;
|
|
@@ -162,24 +102,8 @@ export interface FirmwareUpdateV4Params {
|
|
|
162
102
|
binary: ArrayBuffer;
|
|
163
103
|
devicePath: string;
|
|
164
104
|
}>;
|
|
165
|
-
artifactReader?: FirmwareArtifactReader;
|
|
166
|
-
componentArtifacts?: Partial<
|
|
167
|
-
Record<Exclude<FirmwareUpdateV4Target, 'resource'>, FirmwareArtifactReference>
|
|
168
|
-
>;
|
|
169
|
-
resourceBundleArtifacts?: Array<{
|
|
170
|
-
name: string;
|
|
171
|
-
artifact: FirmwareArtifactReference;
|
|
172
|
-
}>;
|
|
173
105
|
}
|
|
174
106
|
|
|
175
|
-
export declare function registerFirmwareUpdateHostBinding(
|
|
176
|
-
binding: FirmwareUpdateHostBinding
|
|
177
|
-
): number;
|
|
178
|
-
|
|
179
|
-
export declare function unregisterFirmwareUpdateHostBinding(generation?: number): boolean;
|
|
180
|
-
|
|
181
|
-
export declare function getFirmwareUpdateHostBindingGeneration(): number;
|
|
182
|
-
|
|
183
107
|
export declare function firmwareUpdateV3(
|
|
184
108
|
connectId: string | undefined,
|
|
185
109
|
params: Params<FirmwareUpdateV3Params>
|
package/src/types/api/index.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type {
|
|
|
2
2
|
deviceGetOnboardingStatus,
|
|
3
3
|
deviceReboot,
|
|
4
4
|
deviceUploadWallpaper,
|
|
5
|
+
testProtocolV2Ping,
|
|
5
6
|
uploadPortfolio,
|
|
6
7
|
} from './protocolV2';
|
|
7
8
|
import type { off, on, removeAllListeners } from './event';
|
|
@@ -29,15 +30,7 @@ import type {
|
|
|
29
30
|
firmwareUpdateV2,
|
|
30
31
|
firmwareUpdateV3,
|
|
31
32
|
firmwareUpdateV4,
|
|
32
|
-
getFirmwareUpdateHostBindingGeneration,
|
|
33
|
-
registerFirmwareUpdateHostBinding,
|
|
34
|
-
unregisterFirmwareUpdateHostBinding,
|
|
35
33
|
} from './firmwareUpdate';
|
|
36
|
-
import type { getFirmwareUpdateCapabilities } from './firmwareUpdateCapabilities';
|
|
37
|
-
import type {
|
|
38
|
-
prepareFirmwareUpdatePlan,
|
|
39
|
-
validateFirmwareUpdatePreparedPlan,
|
|
40
|
-
} from './firmwareUpdatePreparedPlan';
|
|
41
34
|
import type { promptWebDeviceAccess } from './promptWebDeviceAccess';
|
|
42
35
|
import type { deviceReset } from './deviceReset';
|
|
43
36
|
import type { deviceRecovery } from './deviceRecovery';
|
|
@@ -157,6 +150,7 @@ export type { DeviceStateScope, GetDeviceStateParams } from './getDeviceState';
|
|
|
157
150
|
export type { GetPassphraseStateParams } from './getPassphraseState';
|
|
158
151
|
export type { OpenWalletSessionParams, OpenWalletSessionPayload } from './openWalletSession';
|
|
159
152
|
export type { ClearSessionCacheParams, ClearSessionCachePayload } from './sessionCache';
|
|
153
|
+
export type { TestProtocolV2PingParams } from './protocolV2';
|
|
160
154
|
|
|
161
155
|
export type CoreApi = {
|
|
162
156
|
/**
|
|
@@ -180,6 +174,7 @@ export type CoreApi = {
|
|
|
180
174
|
* Test function
|
|
181
175
|
*/
|
|
182
176
|
testInitializeDeviceDuration: typeof testInitializeDeviceDuration;
|
|
177
|
+
testProtocolV2Ping: typeof testProtocolV2Ping;
|
|
183
178
|
preInitialize: typeof preInitialize;
|
|
184
179
|
|
|
185
180
|
/**
|
|
@@ -227,12 +222,6 @@ export type CoreApi = {
|
|
|
227
222
|
firmwareUpdateV2: typeof firmwareUpdateV2;
|
|
228
223
|
firmwareUpdateV3: typeof firmwareUpdateV3;
|
|
229
224
|
firmwareUpdateV4: typeof firmwareUpdateV4;
|
|
230
|
-
registerFirmwareUpdateHostBinding: typeof registerFirmwareUpdateHostBinding;
|
|
231
|
-
unregisterFirmwareUpdateHostBinding: typeof unregisterFirmwareUpdateHostBinding;
|
|
232
|
-
getFirmwareUpdateHostBindingGeneration: typeof getFirmwareUpdateHostBindingGeneration;
|
|
233
|
-
getFirmwareUpdateCapabilities: typeof getFirmwareUpdateCapabilities;
|
|
234
|
-
prepareFirmwareUpdatePlan: typeof prepareFirmwareUpdatePlan;
|
|
235
|
-
validateFirmwareUpdatePreparedPlan: typeof validateFirmwareUpdatePreparedPlan;
|
|
236
225
|
cipherKeyValue: typeof cipherKeyValue;
|
|
237
226
|
|
|
238
227
|
/**
|
|
@@ -5,35 +5,16 @@ export type OpenWalletSessionParams =
|
|
|
5
5
|
mode: 'standard';
|
|
6
6
|
deviceId?: never;
|
|
7
7
|
passphraseState?: never;
|
|
8
|
-
useEmptyPassphrase?: never;
|
|
9
|
-
initSession?: never;
|
|
10
8
|
}
|
|
11
9
|
| {
|
|
12
10
|
mode: 'select-hidden';
|
|
13
11
|
deviceId?: never;
|
|
14
12
|
passphraseState?: never;
|
|
15
|
-
useEmptyPassphrase?: never;
|
|
16
|
-
initSession?: never;
|
|
17
13
|
}
|
|
18
14
|
| {
|
|
19
15
|
mode: 'resume-hidden';
|
|
20
16
|
deviceId: string;
|
|
21
17
|
passphraseState: string;
|
|
22
|
-
useEmptyPassphrase?: never;
|
|
23
|
-
initSession?: never;
|
|
24
|
-
}
|
|
25
|
-
| {
|
|
26
|
-
/**
|
|
27
|
-
* Compatibility form. `useEmptyPassphrase: true` opens the standard wallet;
|
|
28
|
-
* otherwise `initSession: true` starts a fresh hidden-wallet selection, a
|
|
29
|
-
* complete wallet binding resumes a hidden wallet, and no binding starts the
|
|
30
|
-
* hidden-wallet selection flow.
|
|
31
|
-
*/
|
|
32
|
-
mode?: undefined;
|
|
33
|
-
useEmptyPassphrase?: boolean;
|
|
34
|
-
initSession?: boolean;
|
|
35
|
-
deviceId?: string;
|
|
36
|
-
passphraseState?: string;
|
|
37
18
|
};
|
|
38
19
|
|
|
39
20
|
type OpenWalletSessionPayloadBase = {
|
|
@@ -27,6 +27,16 @@ export type FileInfo = {
|
|
|
27
27
|
|
|
28
28
|
// ── Method signatures ─────────────────────────────────────────────────────
|
|
29
29
|
|
|
30
|
+
export type TestProtocolV2PingParams = CommonParams & {
|
|
31
|
+
/** Firmware diagnostic echo payload, limited to 63 UTF-8 bytes. */
|
|
32
|
+
message?: string;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export declare function testProtocolV2Ping(
|
|
36
|
+
connectId: string,
|
|
37
|
+
params?: TestProtocolV2PingParams
|
|
38
|
+
): Response<Success>;
|
|
39
|
+
|
|
30
40
|
export declare function deviceReboot(
|
|
31
41
|
connectId: string,
|
|
32
42
|
params: CommonParams & DeviceRebootParams
|
package/src/types/settings.ts
CHANGED
|
@@ -31,8 +31,6 @@ export type ConnectSettings = {
|
|
|
31
31
|
timestamp: number;
|
|
32
32
|
isFrame?: boolean;
|
|
33
33
|
preRelease?: boolean;
|
|
34
|
-
firmwareManifestMode?: 'sdk-managed' | 'external-only';
|
|
35
|
-
preloadedConfig?: RemoteConfigResponse;
|
|
36
34
|
fetchConfig?: boolean;
|
|
37
35
|
extension?: string;
|
|
38
36
|
configFetcher?: (url: string) => Promise<RemoteConfigResponse | null>;
|
|
@@ -57,7 +55,6 @@ export type IProtocolV2FirmwareComponent = {
|
|
|
57
55
|
target: IProtocolV2FirmwareComponentTarget;
|
|
58
56
|
url: string;
|
|
59
57
|
fingerprint?: string;
|
|
60
|
-
expectedSize?: number;
|
|
61
58
|
version?: IVersionArray;
|
|
62
59
|
};
|
|
63
60
|
|
|
@@ -67,8 +64,6 @@ export type IProtocolV2ResourceBundle = {
|
|
|
67
64
|
name: string;
|
|
68
65
|
/** Download URL. */
|
|
69
66
|
url: string;
|
|
70
|
-
fingerprint?: string;
|
|
71
|
-
expectedSize?: number;
|
|
72
67
|
/** Device target path, such as vol0:/bundles/images/images.okpkg. */
|
|
73
68
|
devicePath: string;
|
|
74
69
|
/** okpkg payload_version used to skip matching content after FileRead. */
|
|
@@ -90,16 +85,10 @@ export type IFirmwareReleaseInfo = {
|
|
|
90
85
|
firmwareType?: EFirmwareType;
|
|
91
86
|
/** Firmware UI resource */
|
|
92
87
|
resource?: string;
|
|
93
|
-
resourceFingerprint?: string;
|
|
94
|
-
resourceExpectedSize?: number;
|
|
95
88
|
/** Firmware full UI resource */
|
|
96
89
|
fullResource?: string;
|
|
97
|
-
fullResourceFingerprint?: string;
|
|
98
|
-
fullResourceExpectedSize?: number;
|
|
99
90
|
fullResourceRange?: string[];
|
|
100
91
|
bootloaderResource?: string;
|
|
101
|
-
bootloaderFingerprint?: string;
|
|
102
|
-
bootloaderExpectedSize?: number;
|
|
103
92
|
bootloaderVersion?: IVersionArray;
|
|
104
93
|
displayBootloaderVersion?: IVersionArray;
|
|
105
94
|
bootloaderRelatedFirmwareVersion?: IVersionArray;
|
|
@@ -112,7 +101,6 @@ export type IFirmwareReleaseInfo = {
|
|
|
112
101
|
[k in ILocale]: string;
|
|
113
102
|
};
|
|
114
103
|
fingerprint: string;
|
|
115
|
-
expectedSize?: number;
|
|
116
104
|
version: IVersionArray;
|
|
117
105
|
changelog: {
|
|
118
106
|
[k in ILocale]: string;
|
|
@@ -128,7 +116,6 @@ export type IBLEFirmwareReleaseInfo = {
|
|
|
128
116
|
webUpdate: string;
|
|
129
117
|
fingerprint: string;
|
|
130
118
|
fingerprintWeb: string;
|
|
131
|
-
expectedSize?: number;
|
|
132
119
|
version: IVersionArray;
|
|
133
120
|
changelog: {
|
|
134
121
|
[k in ILocale]: string;
|
|
@@ -60,9 +60,21 @@ export const getDeviceUUID = getDeviceSerialNo;
|
|
|
60
60
|
export const getDeviceLabel = (features?: DeviceFeaturesInput) => {
|
|
61
61
|
if (!features) return null;
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
const deviceType = getDeviceType(features);
|
|
64
|
+
if (deviceType == null) return null;
|
|
65
|
+
|
|
66
|
+
if ('label' in features && typeof features.label === 'string' && features.label.length > 0) {
|
|
67
|
+
return features.label;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const bleName = getDeviceBleName(features);
|
|
71
|
+
if (bleName) return bleName;
|
|
72
|
+
|
|
73
|
+
if (deviceType === EDeviceType.ClassicPure) {
|
|
74
|
+
return 'OneKey Classic 1S';
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return `OneKey ${deviceType.charAt(0).toUpperCase() + deviceType.slice(1)}`;
|
|
66
78
|
};
|
|
67
79
|
|
|
68
80
|
/**
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { EDeviceType, EFirmwareType } from '@onekeyfe/hd-shared';
|
|
2
|
-
|
|
3
|
-
import CheckAllFirmwareRelease from '../../src/api/CheckAllFirmwareRelease';
|
|
4
|
-
import { buildFirmwareUpdatePlan } from '../../src/api/firmware/FirmwareUpdatePlan';
|
|
5
|
-
import {
|
|
6
|
-
getBleFirmwareReleaseInfo,
|
|
7
|
-
getBootloaderReleaseInfo,
|
|
8
|
-
getFirmwareReleaseInfo,
|
|
9
|
-
} from '../../src/api/firmware/releaseHelper';
|
|
10
|
-
|
|
11
|
-
jest.mock('../../src/data/config', () => ({
|
|
12
|
-
getSDKVersion: jest.fn(() => '1.0.0'),
|
|
13
|
-
DEFAULT_DOMAIN: 'https://jssdk.onekey.so/1.0.0/',
|
|
14
|
-
}));
|
|
15
|
-
|
|
16
|
-
jest.mock('../../src/api/firmware/FirmwareUpdatePlan', () => ({
|
|
17
|
-
buildFirmwareUpdatePlan: jest.fn(),
|
|
18
|
-
}));
|
|
19
|
-
|
|
20
|
-
jest.mock('../../src/api/firmware/releaseHelper', () => ({
|
|
21
|
-
getBleFirmwareReleaseInfo: jest.fn(),
|
|
22
|
-
getBootloaderReleaseInfo: jest.fn(),
|
|
23
|
-
getFirmwareReleaseInfo: jest.fn(),
|
|
24
|
-
}));
|
|
25
|
-
|
|
26
|
-
const mockBuildFirmwareUpdatePlan = buildFirmwareUpdatePlan as jest.MockedFunction<
|
|
27
|
-
typeof buildFirmwareUpdatePlan
|
|
28
|
-
>;
|
|
29
|
-
const mockGetBleFirmwareReleaseInfo = getBleFirmwareReleaseInfo as jest.MockedFunction<
|
|
30
|
-
typeof getBleFirmwareReleaseInfo
|
|
31
|
-
>;
|
|
32
|
-
const mockGetBootloaderReleaseInfo = getBootloaderReleaseInfo as jest.MockedFunction<
|
|
33
|
-
typeof getBootloaderReleaseInfo
|
|
34
|
-
>;
|
|
35
|
-
const mockGetFirmwareReleaseInfo = getFirmwareReleaseInfo as jest.MockedFunction<
|
|
36
|
-
typeof getFirmwareReleaseInfo
|
|
37
|
-
>;
|
|
38
|
-
|
|
39
|
-
describe('CheckAllFirmwareRelease', () => {
|
|
40
|
-
test('keeps release information available when an optional Plan cannot be built', async () => {
|
|
41
|
-
const firmware = {
|
|
42
|
-
status: 'outdated' as const,
|
|
43
|
-
release: {
|
|
44
|
-
url: 'https://firmware.onekey.so/classic/firmware.bin',
|
|
45
|
-
version: [3, 0, 0],
|
|
46
|
-
},
|
|
47
|
-
};
|
|
48
|
-
const noUpdate = {
|
|
49
|
-
status: 'valid' as const,
|
|
50
|
-
release: undefined,
|
|
51
|
-
};
|
|
52
|
-
mockGetFirmwareReleaseInfo.mockReturnValue(firmware);
|
|
53
|
-
mockGetBootloaderReleaseInfo.mockReturnValue(noUpdate);
|
|
54
|
-
mockGetBleFirmwareReleaseInfo.mockReturnValue(noUpdate);
|
|
55
|
-
mockBuildFirmwareUpdatePlan.mockImplementation(() => {
|
|
56
|
-
throw new Error('FirmwarePlanInvalid');
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
const method = new CheckAllFirmwareRelease({
|
|
60
|
-
id: 1,
|
|
61
|
-
payload: {
|
|
62
|
-
method: 'checkAllFirmwareRelease',
|
|
63
|
-
platform: 'native',
|
|
64
|
-
},
|
|
65
|
-
});
|
|
66
|
-
method.init();
|
|
67
|
-
method.device = {
|
|
68
|
-
features: {
|
|
69
|
-
deviceType: EDeviceType.Classic1s,
|
|
70
|
-
serialNo: '',
|
|
71
|
-
firmwareType: EFirmwareType.Universal,
|
|
72
|
-
firmwareVersion: '1.0.0',
|
|
73
|
-
bootloaderVersion: '1.0.0',
|
|
74
|
-
},
|
|
75
|
-
} as typeof method.device;
|
|
76
|
-
|
|
77
|
-
await expect(method.run()).resolves.toEqual(
|
|
78
|
-
expect.objectContaining({
|
|
79
|
-
firmware,
|
|
80
|
-
bootloader: noUpdate,
|
|
81
|
-
ble: noUpdate,
|
|
82
|
-
firmwareUpdatePlan: undefined,
|
|
83
|
-
})
|
|
84
|
-
);
|
|
85
|
-
});
|
|
86
|
-
});
|