@onekeyfe/hd-core 1.2.0-alpha.56 → 1.2.0-alpha.62
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__/AllNetworkGetAddressBase.tracing.test.ts +0 -231
- package/__tests__/DeviceCommands.test.ts +0 -45
- package/__tests__/DeviceEventRegistration.test.ts +0 -6
- package/__tests__/check-all-firmware-release-protocol-v2.test.ts +3 -198
- package/__tests__/connectSettings.test.ts +47 -5
- package/__tests__/device-initialize-timeout.test.ts +56 -0
- package/__tests__/device-lifecycle-events.test.ts +3 -105
- package/__tests__/device-state-contract.test.ts +0 -1
- package/__tests__/device-state-mapper.test.ts +1 -1
- package/__tests__/deviceSettings.test.ts +1 -1
- package/__tests__/firmware-update/check-all-firmware-release.test.ts +175 -0
- package/__tests__/firmware-update/firmware-artifact-source.test.ts +119 -0
- package/__tests__/firmware-update/firmware-host-binding.test.ts +70 -0
- package/__tests__/firmware-update/firmware-preparation-error.test.ts +27 -0
- package/__tests__/firmware-update/firmware-update-bootloader-poll.test.ts +200 -0
- package/__tests__/firmware-update/firmware-update-capabilities.test.ts +13 -0
- package/__tests__/firmware-update/firmware-update-plan-bootloader-identity.test.ts +294 -0
- package/__tests__/firmware-update/firmware-update-plan.test.ts +593 -0
- package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +213 -0
- package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +59 -31
- package/__tests__/firmware-update/firmware-update-v3-reconnect.test.ts +58 -0
- package/__tests__/firmware-update/firmware-upload-source.test.ts +70 -0
- package/__tests__/get-device-state.test.ts +12 -132
- package/__tests__/homescreen.test.ts +1 -41
- package/__tests__/kaspaSignTransaction.test.ts +26 -3
- package/__tests__/logBlockEvent.test.ts +1 -1
- package/__tests__/method-protocol-support.test.ts +0 -19
- package/__tests__/open-wallet-session.test.ts +37 -568
- package/__tests__/protocol-v2-unlock-policy.test.ts +35 -201
- package/__tests__/protocol-v2.test.ts +1046 -1388
- package/__tests__/protocolV2FileWrite.test.ts +0 -39
- package/__tests__/protocolV2UiInteraction.test.ts +0 -63
- package/__tests__/public-pro2-api-boundary.test.ts +0 -1
- package/__tests__/search-devices.test.ts +3 -12
- package/dist/api/BaseMethod.d.ts +1 -3
- package/dist/api/BaseMethod.d.ts.map +1 -1
- package/dist/api/CheckAllFirmwareRelease.d.ts +1 -2
- package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
- package/dist/api/FirmwareUpdate.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV2.d.ts +11 -0
- package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV3.d.ts +7 -3
- package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV4.d.ts +25 -11
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/GetPassphraseState.d.ts.map +1 -1
- package/dist/api/OpenWalletSession.d.ts.map +1 -1
- package/dist/api/SearchDevices.d.ts.map +1 -1
- package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
- package/dist/api/device/DeviceUnlock.d.ts +2 -2
- package/dist/api/device/DeviceUnlock.d.ts.map +1 -1
- package/dist/api/device/DeviceUpdateBootloader.d.ts +5 -1
- package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareArtifactSource.d.ts +25 -0
- package/dist/api/firmware/FirmwareArtifactSource.d.ts.map +1 -0
- package/dist/api/firmware/FirmwareHostBinding.d.ts +6 -0
- package/dist/api/firmware/FirmwareHostBinding.d.ts.map +1 -0
- package/dist/api/firmware/FirmwarePreparationError.d.ts +3 -0
- package/dist/api/firmware/FirmwarePreparationError.d.ts.map +1 -0
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +9 -0
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts +3 -0
- package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts.map +1 -0
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts +25 -0
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +1 -0
- package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts +32 -0
- package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +1 -0
- package/dist/api/firmware/getBinary.d.ts +7 -0
- package/dist/api/firmware/getBinary.d.ts.map +1 -1
- package/dist/api/firmware/progressThrottle.d.ts +3 -0
- package/dist/api/firmware/progressThrottle.d.ts.map +1 -0
- package/dist/api/firmware/updateBootloader.d.ts +2 -0
- package/dist/api/firmware/updateBootloader.d.ts.map +1 -1
- package/dist/api/firmware/uploadFirmware.d.ts +9 -1
- package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
- package/dist/api/helpers/protocolV2FileWrite.d.ts +0 -2
- package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
- package/dist/api/index.d.ts +0 -2
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/kaspa/KaspaSignTransaction.d.ts.map +1 -1
- package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts.map +1 -1
- package/dist/api/protocol-v2/helpers.d.ts.map +1 -1
- package/dist/api/stellar/StellarSignTransaction.d.ts +1 -1
- package/dist/core/deviceEventRegistration.d.ts +0 -2
- package/dist/core/deviceEventRegistration.d.ts.map +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/data-manager/DataManager.d.ts +2 -4
- 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 +6 -29
- package/dist/device/Device.d.ts.map +1 -1
- package/dist/device/DeviceCommands.d.ts +4 -4
- package/dist/device/DeviceCommands.d.ts.map +1 -1
- package/dist/device/DevicePool.d.ts.map +1 -1
- package/dist/events/device.d.ts +0 -4
- package/dist/events/device.d.ts.map +1 -1
- package/dist/events/logBlockEvent.d.ts.map +1 -1
- package/dist/events/ui-promise.d.ts +2 -4
- package/dist/events/ui-promise.d.ts.map +1 -1
- package/dist/events/ui-request.d.ts +2 -31
- package/dist/events/ui-request.d.ts.map +1 -1
- package/dist/events/ui-response.d.ts +2 -10
- package/dist/events/ui-response.d.ts.map +1 -1
- package/dist/index.d.ts +231 -214
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3530 -2634
- package/dist/inject.d.ts +1 -6
- package/dist/inject.d.ts.map +1 -1
- package/dist/lowLevelInject.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/features.d.ts +4 -0
- package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/firmware.d.ts.map +1 -1
- 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/uiInteraction.d.ts +4 -7
- package/dist/protocols/protocol-v2/uiInteraction.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/unlockPolicy.d.ts +3 -1
- package/dist/protocols/protocol-v2/unlockPolicy.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/unlockRetry.d.ts +10 -0
- package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/walletSession.d.ts +1 -6
- 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 +4 -2
- package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
- package/dist/types/api/deviceUnlock.d.ts +1 -5
- package/dist/types/api/deviceUnlock.d.ts.map +1 -1
- package/dist/types/api/deviceUpdateBootloader.d.ts +6 -0
- package/dist/types/api/deviceUpdateBootloader.d.ts.map +1 -1
- package/dist/types/api/export.d.ts +4 -2
- package/dist/types/api/export.d.ts.map +1 -1
- package/dist/types/api/firmwareUpdate.d.ts +70 -2
- package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
- package/dist/types/api/firmwareUpdateCapabilities.d.ts +9 -0
- package/dist/types/api/firmwareUpdateCapabilities.d.ts.map +1 -0
- package/dist/types/api/firmwareUpdatePlan.d.ts +28 -0
- package/dist/types/api/firmwareUpdatePlan.d.ts.map +1 -0
- package/dist/types/api/firmwareUpdatePreparedPlan.d.ts +42 -0
- package/dist/types/api/firmwareUpdatePreparedPlan.d.ts.map +1 -0
- package/dist/types/api/index.d.ts +10 -7
- package/dist/types/api/index.d.ts.map +1 -1
- package/dist/types/api/protocolV2.d.ts +0 -3
- package/dist/types/api/protocolV2.d.ts.map +1 -1
- package/dist/types/device.d.ts.map +1 -1
- package/dist/types/params.d.ts +0 -1
- package/dist/types/params.d.ts.map +1 -1
- package/dist/types/settings.d.ts +13 -22
- package/dist/types/settings.d.ts.map +1 -1
- package/dist/utils/deviceFeaturesCompat.d.ts +1 -0
- package/dist/utils/deviceFeaturesCompat.d.ts.map +1 -1
- package/dist/utils/deviceFeaturesUtils.d.ts +0 -4
- package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
- package/dist/utils/homescreen.d.ts +0 -4
- package/dist/utils/homescreen.d.ts.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/patch.d.ts +1 -1
- package/dist/utils/patch.d.ts.map +1 -1
- package/dist/utils/pro2Wallpaper.d.ts +0 -10
- package/dist/utils/pro2Wallpaper.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/api/BaseMethod.ts +10 -8
- package/src/api/CheckAllFirmwareRelease.ts +57 -54
- package/src/api/FirmwareUpdate.ts +15 -7
- package/src/api/FirmwareUpdateV2.ts +316 -126
- package/src/api/FirmwareUpdateV3.ts +265 -63
- package/src/api/FirmwareUpdateV4.ts +975 -584
- package/src/api/GetPassphraseState.ts +1 -7
- package/src/api/OpenWalletSession.ts +17 -70
- package/src/api/SearchDevices.ts +1 -3
- package/src/api/allnetwork/AllNetworkGetAddress.ts +21 -21
- package/src/api/allnetwork/AllNetworkGetAddressBase.ts +11 -34
- package/src/api/device/DeviceUnlock.ts +3 -8
- package/src/api/device/DeviceUpdateBootloader.ts +122 -6
- package/src/api/firmware/FirmwareArtifactSource.ts +278 -0
- package/src/api/firmware/FirmwareHostBinding.ts +100 -0
- package/src/api/firmware/FirmwarePreparationError.ts +12 -0
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +83 -16
- package/src/api/firmware/FirmwareUpdateCapabilities.ts +9 -0
- package/src/api/firmware/FirmwareUpdatePlan.ts +772 -0
- package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +415 -0
- package/src/api/firmware/progressThrottle.ts +44 -0
- package/src/api/firmware/updateBootloader.ts +19 -4
- package/src/api/firmware/uploadFirmware.ts +144 -39
- package/src/api/helpers/protocolV2FileWrite.ts +7 -27
- package/src/api/index.ts +0 -2
- package/src/api/kaspa/KaspaSignTransaction.ts +12 -1
- package/src/api/protocol-v2/ProtocolInfoRequest.ts +1 -3
- package/src/api/protocol-v2/helpers.ts +0 -1
- package/src/core/deviceEventRegistration.ts +0 -4
- package/src/core/index.ts +83 -167
- package/src/data/messages/messages-protocol-v2.json +0 -25
- package/src/data-manager/DataManager.ts +39 -71
- package/src/data-manager/connectSettings.ts +11 -0
- package/src/device/Device.ts +43 -259
- package/src/device/DeviceCommands.ts +1 -7
- package/src/device/DevicePool.ts +2 -7
- package/src/events/device.ts +0 -4
- package/src/events/logBlockEvent.ts +0 -1
- package/src/events/ui-promise.ts +2 -4
- package/src/events/ui-request.ts +2 -36
- package/src/events/ui-response.ts +2 -12
- package/src/index.ts +5 -0
- package/src/inject.ts +24 -60
- package/src/lowLevelInject.ts +8 -7
- package/src/protocols/protocol-v2/features.ts +7 -10
- package/src/protocols/protocol-v2/firmware.ts +0 -2
- package/src/protocols/protocol-v2/lockedError.ts +10 -0
- package/src/protocols/protocol-v2/uiInteraction.ts +6 -46
- package/src/protocols/protocol-v2/unlockPolicy.ts +105 -1
- package/src/protocols/protocol-v2/unlockRetry.ts +109 -0
- package/src/protocols/protocol-v2/walletSession.ts +36 -214
- package/src/topLevelInject.ts +8 -7
- package/src/types/api/checkAllFirmwareRelease.ts +4 -2
- package/src/types/api/deviceUnlock.ts +1 -12
- package/src/types/api/deviceUpdateBootloader.ts +6 -0
- package/src/types/api/export.ts +18 -1
- package/src/types/api/firmwareUpdate.ts +76 -3
- package/src/types/api/firmwareUpdateCapabilities.ts +9 -0
- package/src/types/api/firmwareUpdatePlan.ts +38 -0
- package/src/types/api/firmwareUpdatePreparedPlan.ts +53 -0
- package/src/types/api/index.ts +14 -13
- package/src/types/api/protocolV2.ts +0 -13
- package/src/types/device.ts +0 -3
- package/src/types/params.ts +1 -7
- package/src/types/settings.ts +13 -42
- package/src/utils/deviceFeaturesCompat.ts +6 -0
- package/src/utils/deviceFeaturesUtils.ts +0 -8
- package/src/utils/homescreen.ts +6 -32
- package/src/utils/index.ts +1 -6
- package/src/utils/pro2Wallpaper.ts +8 -35
- package/__tests__/deviceUploadNft.test.ts +0 -293
- package/__tests__/pro2Nft.test.ts +0 -108
- package/__tests__/protocol-binding.test.ts +0 -89
- package/__tests__/protocol-v2-resources.test.ts +0 -286
- package/__tests__/protocol-v2-ui-lifecycle.test.ts +0 -91
- package/__tests__/uiProgressThrottle.test.ts +0 -74
- package/__tests__/uiPromiseRegistry.test.ts +0 -86
- package/dist/api/DetectDeviceConnectProtocol.d.ts +0 -7
- package/dist/api/DetectDeviceConnectProtocol.d.ts.map +0 -1
- package/dist/api/protocol-v2/DeviceUploadNft.d.ts +0 -31
- package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +0 -1
- package/dist/core/uiPromiseRegistry.d.ts +0 -4
- package/dist/core/uiPromiseRegistry.d.ts.map +0 -1
- package/dist/protocols/protocol-v2/resources.d.ts +0 -30
- package/dist/protocols/protocol-v2/resources.d.ts.map +0 -1
- package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts +0 -22
- package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts.map +0 -1
- package/dist/types/api/detectDeviceConnectProtocol.d.ts +0 -4
- package/dist/types/api/detectDeviceConnectProtocol.d.ts.map +0 -1
- package/dist/utils/pro2Nft.d.ts +0 -31
- package/dist/utils/pro2Nft.d.ts.map +0 -1
- package/dist/utils/uiProgressThrottle.d.ts +0 -3
- package/dist/utils/uiProgressThrottle.d.ts.map +0 -1
- package/src/api/DetectDeviceConnectProtocol.ts +0 -18
- package/src/api/protocol-v2/DeviceUploadNft.ts +0 -189
- package/src/core/uiPromiseRegistry.ts +0 -41
- package/src/protocols/protocol-v2/resources.ts +0 -359
- package/src/protocols/protocol-v2/unlockPolicyRunner.ts +0 -118
- package/src/types/api/detectDeviceConnectProtocol.ts +0 -6
- package/src/utils/pro2Nft.ts +0 -142
- package/src/utils/uiProgressThrottle.ts +0 -63
|
@@ -10,6 +10,7 @@ import { bytesToHex } from '../helpers/hexUtils';
|
|
|
10
10
|
import { DataManager } from '../../data-manager';
|
|
11
11
|
import { DevicePool } from '../../device/DevicePool';
|
|
12
12
|
import { buildProtocolV1FeaturesPayload } from '../../deviceProfile';
|
|
13
|
+
import { openFirmwareByteSource, readFirmwareByteSourceFully } from './FirmwareArtifactSource';
|
|
13
14
|
|
|
14
15
|
import type { KnownDevice } from '../../types';
|
|
15
16
|
import type { TypedCall, TypedResponseMessage } from '../../device/DeviceCommands';
|
|
@@ -17,6 +18,7 @@ import type { PROTO } from '../../constants';
|
|
|
17
18
|
import type { CoreMessage, IFirmwareUpdateProgressType } from '../../events';
|
|
18
19
|
import type { Success } from '@onekeyfe/hd-transport';
|
|
19
20
|
import type { Device } from '../../device/Device';
|
|
21
|
+
import type { FirmwareByteSource } from './FirmwareArtifactSource';
|
|
20
22
|
|
|
21
23
|
const NEW_BOOT_UPRATE_FIRMWARE_VERSION = '2.4.5';
|
|
22
24
|
const SESSION_ERROR = 'session not found';
|
|
@@ -88,17 +90,20 @@ export const waitBleInstall = async (updateType: string) => {
|
|
|
88
90
|
}
|
|
89
91
|
};
|
|
90
92
|
|
|
91
|
-
|
|
93
|
+
const toArrayBuffer = (payload: ArrayBuffer | Buffer): ArrayBuffer => {
|
|
94
|
+
if (payload instanceof ArrayBuffer) {
|
|
95
|
+
return payload;
|
|
96
|
+
}
|
|
97
|
+
return new Uint8Array(payload.buffer, payload.byteOffset, payload.byteLength).slice().buffer;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export const uploadFirmwareFromSource = async (
|
|
92
101
|
updateType: 'firmware' | 'ble',
|
|
93
102
|
typedCall: TypedCall,
|
|
94
103
|
postMessage: (message: CoreMessage) => void,
|
|
95
104
|
device: Device,
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
rebootOnSuccess,
|
|
99
|
-
}: PROTO.FirmwareUpload & {
|
|
100
|
-
rebootOnSuccess?: boolean;
|
|
101
|
-
},
|
|
105
|
+
source: FirmwareByteSource,
|
|
106
|
+
rebootOnSuccess?: boolean,
|
|
102
107
|
isUpdateBootloader?: boolean
|
|
103
108
|
) => {
|
|
104
109
|
const deviceType = device.getCurrentDeviceType();
|
|
@@ -119,20 +124,20 @@ export const uploadFirmware = async (
|
|
|
119
124
|
if (supportUpgradeFileHeader) {
|
|
120
125
|
// Extract and validate firmware header (first 1KB)
|
|
121
126
|
const HEADER_SIZE = 1024;
|
|
122
|
-
if (
|
|
127
|
+
if (source.size < HEADER_SIZE) {
|
|
123
128
|
throw ERRORS.TypedError(
|
|
124
129
|
HardwareErrorCode.RuntimeError,
|
|
125
|
-
`firmware payload too small: ${
|
|
130
|
+
`firmware payload too small: ${source.size} bytes, expected at least ${HEADER_SIZE} bytes`
|
|
126
131
|
);
|
|
127
132
|
}
|
|
128
133
|
|
|
129
134
|
Log.debug('Uploading firmware header:', {
|
|
130
135
|
size: HEADER_SIZE,
|
|
131
|
-
totalSize:
|
|
136
|
+
totalSize: source.size,
|
|
132
137
|
});
|
|
133
138
|
postProgressTip(device, 'UploadingFirmwareHeader', postMessage);
|
|
134
139
|
|
|
135
|
-
const header = new Uint8Array(
|
|
140
|
+
const header = new Uint8Array(await source.readAt(0, HEADER_SIZE));
|
|
136
141
|
|
|
137
142
|
try {
|
|
138
143
|
const headerRes = await typedCall('UpgradeFileHeader', 'Success', {
|
|
@@ -169,6 +174,9 @@ export const uploadFirmware = async (
|
|
|
169
174
|
postProgressMessage(device, 0, 'installingFirmware', postMessage);
|
|
170
175
|
let updateResponse: TypedResponseMessage<'Success'>;
|
|
171
176
|
try {
|
|
177
|
+
// Classic/Mini bootloaders accept one protobuf payload and do not expose
|
|
178
|
+
// a request-range protocol. Other device families remain fully streamed.
|
|
179
|
+
const payload = await readFirmwareByteSourceFully(source);
|
|
172
180
|
updateResponse = await typedCall('FirmwareUpload', 'Success', {
|
|
173
181
|
payload,
|
|
174
182
|
});
|
|
@@ -200,9 +208,7 @@ export const uploadFirmware = async (
|
|
|
200
208
|
updateType,
|
|
201
209
|
postMessage,
|
|
202
210
|
device,
|
|
203
|
-
|
|
204
|
-
payload,
|
|
205
|
-
},
|
|
211
|
+
source,
|
|
206
212
|
rebootOnSuccess
|
|
207
213
|
);
|
|
208
214
|
return response.message;
|
|
@@ -211,7 +217,7 @@ export const uploadFirmware = async (
|
|
|
211
217
|
|
|
212
218
|
postConfirmationMessage(device);
|
|
213
219
|
postProgressTip(device, 'ConfirmOnDevice', postMessage);
|
|
214
|
-
const length =
|
|
220
|
+
const length = source.size;
|
|
215
221
|
|
|
216
222
|
let response = await typedCall('FirmwareErase', ['FirmwareRequest', 'Success'], { length });
|
|
217
223
|
postProgressTip(device, 'FirmwareEraseSuccess', postMessage);
|
|
@@ -220,7 +226,7 @@ export const uploadFirmware = async (
|
|
|
220
226
|
const start = response.message.offset!;
|
|
221
227
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
222
228
|
const end = response.message.offset! + response.message.length!;
|
|
223
|
-
const chunk =
|
|
229
|
+
const chunk = await source.readAt(start, end - start);
|
|
224
230
|
|
|
225
231
|
if (start > 0) {
|
|
226
232
|
postProgressMessage(
|
|
@@ -249,11 +255,45 @@ export const uploadFirmware = async (
|
|
|
249
255
|
throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, 'uploadFirmware: unknown device model');
|
|
250
256
|
};
|
|
251
257
|
|
|
258
|
+
export const uploadFirmware = async (
|
|
259
|
+
updateType: 'firmware' | 'ble',
|
|
260
|
+
typedCall: TypedCall,
|
|
261
|
+
postMessage: (message: CoreMessage) => void,
|
|
262
|
+
device: Device,
|
|
263
|
+
{
|
|
264
|
+
payload,
|
|
265
|
+
rebootOnSuccess,
|
|
266
|
+
}: PROTO.FirmwareUpload & {
|
|
267
|
+
rebootOnSuccess?: boolean;
|
|
268
|
+
},
|
|
269
|
+
isUpdateBootloader?: boolean
|
|
270
|
+
) => {
|
|
271
|
+
const source = await openFirmwareByteSource({
|
|
272
|
+
binary: toArrayBuffer(payload),
|
|
273
|
+
});
|
|
274
|
+
if (!source) {
|
|
275
|
+
throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, 'firmware payload is empty');
|
|
276
|
+
}
|
|
277
|
+
try {
|
|
278
|
+
return await uploadFirmwareFromSource(
|
|
279
|
+
updateType,
|
|
280
|
+
typedCall,
|
|
281
|
+
postMessage,
|
|
282
|
+
device,
|
|
283
|
+
source,
|
|
284
|
+
rebootOnSuccess,
|
|
285
|
+
isUpdateBootloader
|
|
286
|
+
);
|
|
287
|
+
} finally {
|
|
288
|
+
await source.close();
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
|
|
252
292
|
const newTouchUpdateProcess = async (
|
|
253
293
|
updateType: 'firmware' | 'ble',
|
|
254
294
|
postMessage: (message: CoreMessage) => void,
|
|
255
295
|
device: Device,
|
|
256
|
-
|
|
296
|
+
source: FirmwareByteSource,
|
|
257
297
|
rebootOnSuccess = true
|
|
258
298
|
) => {
|
|
259
299
|
let typedCall = device.getCommands().typedCall.bind(device.getCommands());
|
|
@@ -263,13 +303,13 @@ const newTouchUpdateProcess = async (
|
|
|
263
303
|
const env = DataManager.getSettings('env');
|
|
264
304
|
const perPackageSize = DataManager.isBleConnect(env) ? 16 : 128;
|
|
265
305
|
const chunkSize = 1024 * perPackageSize;
|
|
266
|
-
const totalChunks = Math.ceil(
|
|
306
|
+
const totalChunks = Math.ceil(source.size / chunkSize);
|
|
267
307
|
let offset = 0;
|
|
268
308
|
for (let i = 0; i < totalChunks; i++) {
|
|
269
309
|
const chunkStart = i * chunkSize;
|
|
270
|
-
const chunkEnd = Math.min(chunkStart + chunkSize,
|
|
310
|
+
const chunkEnd = Math.min(chunkStart + chunkSize, source.size);
|
|
271
311
|
const chunkLength = chunkEnd - chunkStart;
|
|
272
|
-
const chunk =
|
|
312
|
+
const chunk = await source.readAt(chunkStart, chunkLength);
|
|
273
313
|
const overwrite = i === 0;
|
|
274
314
|
const progress = Math.round(((i + 1) / totalChunks) * 100);
|
|
275
315
|
const writeRes = await emmcFileWriteWithRetry(
|
|
@@ -322,12 +362,7 @@ const newTouchUpdateProcess = async (
|
|
|
322
362
|
try {
|
|
323
363
|
if (isBleReconnect) {
|
|
324
364
|
try {
|
|
325
|
-
await device.deviceConnector?.acquire(
|
|
326
|
-
device.originalDescriptor.id,
|
|
327
|
-
null,
|
|
328
|
-
true,
|
|
329
|
-
device.originalDescriptor.protocolType
|
|
330
|
-
);
|
|
365
|
+
await device.deviceConnector?.acquire(device.originalDescriptor.id, null, true);
|
|
331
366
|
const typedCall = device.getCommands().typedCall.bind(device.getCommands());
|
|
332
367
|
await Promise.race([
|
|
333
368
|
typedCall('Initialize', 'Features', {}),
|
|
@@ -346,8 +381,7 @@ const newTouchUpdateProcess = async (
|
|
|
346
381
|
const devicesDescriptor = deviceDiff?.descriptors ?? [];
|
|
347
382
|
const { deviceList } = await DevicePool.getDevices(
|
|
348
383
|
devicesDescriptor,
|
|
349
|
-
device.originalDescriptor.id
|
|
350
|
-
{ connectProtocol: device.originalDescriptor.protocolType }
|
|
384
|
+
device.originalDescriptor.id
|
|
351
385
|
);
|
|
352
386
|
if (deviceList.length === 1) {
|
|
353
387
|
device.updateFromCache(deviceList[0]);
|
|
@@ -422,12 +456,7 @@ const emmcFileWriteWithRetry = async (
|
|
|
422
456
|
const env = DataManager.getSettings('env');
|
|
423
457
|
if (DataManager.isBleConnect(env)) {
|
|
424
458
|
await wait(3000);
|
|
425
|
-
await device.deviceConnector?.acquire(
|
|
426
|
-
device.originalDescriptor.id,
|
|
427
|
-
null,
|
|
428
|
-
true,
|
|
429
|
-
device.originalDescriptor.protocolType
|
|
430
|
-
);
|
|
459
|
+
await device.deviceConnector?.acquire(device.originalDescriptor.id, null, true);
|
|
431
460
|
await device.initialize();
|
|
432
461
|
} else if (
|
|
433
462
|
error?.message?.indexOf(SESSION_ERROR) > -1 ||
|
|
@@ -435,9 +464,7 @@ const emmcFileWriteWithRetry = async (
|
|
|
435
464
|
) {
|
|
436
465
|
const deviceDiff = await device.deviceConnector?.enumerate();
|
|
437
466
|
const devicesDescriptor = deviceDiff?.descriptors ?? [];
|
|
438
|
-
const { deviceList } = await DevicePool.getDevices(devicesDescriptor, undefined
|
|
439
|
-
connectProtocol: device.originalDescriptor.protocolType,
|
|
440
|
-
});
|
|
467
|
+
const { deviceList } = await DevicePool.getDevices(devicesDescriptor, undefined);
|
|
441
468
|
if (deviceList.length === 1 && deviceList[0]?.isBootloader()) {
|
|
442
469
|
device.updateFromCache(deviceList[0]);
|
|
443
470
|
await device.acquire();
|
|
@@ -503,6 +530,67 @@ export const updateResource = async (
|
|
|
503
530
|
return processResourceRequest(typedCall, res, data);
|
|
504
531
|
};
|
|
505
532
|
|
|
533
|
+
export const updateResourceFromSource = async (
|
|
534
|
+
typedCall: TypedCall,
|
|
535
|
+
fileName: string,
|
|
536
|
+
source: FirmwareByteSource,
|
|
537
|
+
onConfirmAfter?: () => void
|
|
538
|
+
) => {
|
|
539
|
+
const initialLength = Math.min(INIT_DATA_CHUNK_SIZE, source.size);
|
|
540
|
+
const initialChunk = new Uint8Array(await source.readAt(0, initialLength));
|
|
541
|
+
let response = await typedCall('ResourceUpdate', ['ResourceRequest', 'Success'], {
|
|
542
|
+
file_name: fileName,
|
|
543
|
+
data_length: source.size,
|
|
544
|
+
initial_data_chunk: bytesToHex(initialChunk),
|
|
545
|
+
hash: bytesToHex(blake2s(initialChunk)),
|
|
546
|
+
});
|
|
547
|
+
onConfirmAfter?.();
|
|
548
|
+
|
|
549
|
+
while (response.type !== 'Success') {
|
|
550
|
+
const { offset, data_length: dataLength } = response.message;
|
|
551
|
+
if (
|
|
552
|
+
!Number.isSafeInteger(offset) ||
|
|
553
|
+
offset === undefined ||
|
|
554
|
+
offset < 0 ||
|
|
555
|
+
!Number.isSafeInteger(dataLength) ||
|
|
556
|
+
dataLength === undefined ||
|
|
557
|
+
dataLength <= 0 ||
|
|
558
|
+
offset + dataLength > source.size
|
|
559
|
+
) {
|
|
560
|
+
throw ERRORS.TypedError(
|
|
561
|
+
HardwareErrorCode.RuntimeError,
|
|
562
|
+
'Device requested an invalid firmware resource range'
|
|
563
|
+
);
|
|
564
|
+
}
|
|
565
|
+
const chunk = new Uint8Array(await source.readAt(offset, dataLength));
|
|
566
|
+
response = await typedCall('ResourceAck', ['ResourceRequest', 'Success'], {
|
|
567
|
+
data_chunk: bytesToHex(chunk),
|
|
568
|
+
hash: bytesToHex(blake2s(chunk)),
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
return response.message;
|
|
572
|
+
};
|
|
573
|
+
|
|
574
|
+
export const updateResourcesFromSources = async (
|
|
575
|
+
typedCall: TypedCall,
|
|
576
|
+
postMessage: (message: CoreMessage) => void,
|
|
577
|
+
device: Device,
|
|
578
|
+
entries: ReadonlyArray<{ entryName: string; source: FirmwareByteSource }>
|
|
579
|
+
) => {
|
|
580
|
+
postProgressTip(device, 'UpdateSysResource', postMessage);
|
|
581
|
+
for (const [index, entry] of entries.entries()) {
|
|
582
|
+
await updateResourceFromSource(typedCall, entry.entryName, entry.source);
|
|
583
|
+
postProgressMessage(
|
|
584
|
+
device,
|
|
585
|
+
Math.floor(((index + 1) / entries.length) * 100),
|
|
586
|
+
'installingFirmware',
|
|
587
|
+
postMessage
|
|
588
|
+
);
|
|
589
|
+
}
|
|
590
|
+
postProgressTip(device, 'UpdateSysResourceSuccess', postMessage);
|
|
591
|
+
return true;
|
|
592
|
+
};
|
|
593
|
+
|
|
506
594
|
export const updateResources = async (
|
|
507
595
|
typedCall: TypedCall,
|
|
508
596
|
postMessage: (message: CoreMessage) => void,
|
|
@@ -537,11 +625,28 @@ export const updateBootloader = async (
|
|
|
537
625
|
typedCall: TypedCall,
|
|
538
626
|
postMessage: (message: CoreMessage) => void,
|
|
539
627
|
device: Device,
|
|
540
|
-
|
|
628
|
+
data: ArrayBuffer
|
|
629
|
+
) => {
|
|
630
|
+
const source = await openFirmwareByteSource({ binary: data });
|
|
631
|
+
if (!source) {
|
|
632
|
+
throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, 'bootloader payload is empty');
|
|
633
|
+
}
|
|
634
|
+
try {
|
|
635
|
+
return await updateBootloaderFromSource(typedCall, postMessage, device, source);
|
|
636
|
+
} finally {
|
|
637
|
+
await source.close();
|
|
638
|
+
}
|
|
639
|
+
};
|
|
640
|
+
|
|
641
|
+
export const updateBootloaderFromSource = async (
|
|
642
|
+
typedCall: TypedCall,
|
|
643
|
+
postMessage: (message: CoreMessage) => void,
|
|
644
|
+
device: Device,
|
|
645
|
+
source: FirmwareByteSource
|
|
541
646
|
) => {
|
|
542
647
|
postProgressTip(device, 'UpdateBootloader', postMessage);
|
|
543
648
|
postProgressMessage(device, Math.floor(0), 'installingFirmware', postMessage);
|
|
544
|
-
await
|
|
649
|
+
await updateResourceFromSource(typedCall, 'bootloader.bin', source, () => {
|
|
545
650
|
postProcessingMessage('resource', postMessage);
|
|
546
651
|
});
|
|
547
652
|
postProgressMessage(device, Math.floor(100), 'installingFirmware', postMessage);
|
|
@@ -31,22 +31,19 @@ export type ProtocolV2FileWriteOptions = {
|
|
|
31
31
|
uiPercentage?: number;
|
|
32
32
|
timeoutMs?: number;
|
|
33
33
|
maxChunkRetries?: number;
|
|
34
|
-
paceMs?: number;
|
|
35
34
|
throwIfAborted?: () => void;
|
|
36
35
|
onProgress?: (progress: ProtocolV2FileWriteProgress) => void;
|
|
37
36
|
};
|
|
38
37
|
|
|
39
38
|
const MIN_FILE_CHUNK_SIZE = 64;
|
|
40
|
-
const FILE_TRANSFER_RATE_WINDOW_MS = 1000;
|
|
41
39
|
|
|
42
|
-
|
|
40
|
+
function isRetryableFileWriteTimeout(error: unknown) {
|
|
43
41
|
if (!error || typeof error !== 'object') return false;
|
|
44
|
-
const candidate = error as { errorCode?: number; code?: number
|
|
42
|
+
const candidate = error as { errorCode?: number; code?: number; message?: string };
|
|
45
43
|
const code = candidate.errorCode ?? candidate.code;
|
|
46
44
|
return (
|
|
47
45
|
code === HardwareErrorCode.BleTimeoutError ||
|
|
48
|
-
|
|
49
|
-
/(?:BLE|Lowlevel|Protocol V2) response timeout/i.test(candidate.message ?? '')
|
|
46
|
+
/Lowlevel response timeout/i.test(candidate.message ?? '')
|
|
50
47
|
);
|
|
51
48
|
}
|
|
52
49
|
|
|
@@ -122,9 +119,6 @@ export async function writeProtocolV2File(options: ProtocolV2FileWriteOptions) {
|
|
|
122
119
|
let chunks = 0;
|
|
123
120
|
let lastMessage: Record<string, unknown> | undefined;
|
|
124
121
|
const startTime = Date.now();
|
|
125
|
-
let rateWindowStartedAt = startTime;
|
|
126
|
-
let rateWindowStartedBytes = 0;
|
|
127
|
-
let rateBytesPerSecond: number | undefined;
|
|
128
122
|
|
|
129
123
|
while (written < dataLength) {
|
|
130
124
|
options.throwIfAborted?.();
|
|
@@ -153,7 +147,7 @@ export async function writeProtocolV2File(options: ProtocolV2FileWriteOptions) {
|
|
|
153
147
|
);
|
|
154
148
|
isWritePending = false;
|
|
155
149
|
} catch (error) {
|
|
156
|
-
if (retryCount >= maxChunkRetries || !
|
|
150
|
+
if (retryCount >= maxChunkRetries || !isRetryableFileWriteTimeout(error)) throw error;
|
|
157
151
|
retryCount += 1;
|
|
158
152
|
options.throwIfAborted?.();
|
|
159
153
|
}
|
|
@@ -182,30 +176,16 @@ export async function writeProtocolV2File(options: ProtocolV2FileWriteOptions) {
|
|
|
182
176
|
written =
|
|
183
177
|
rawProcessedByte === undefined ? written + chunk.byteLength : processedByte - startOffset;
|
|
184
178
|
chunks += 1;
|
|
185
|
-
const
|
|
186
|
-
const elapsedMs = now - startTime;
|
|
179
|
+
const elapsedMs = Date.now() - startTime;
|
|
187
180
|
const transferredBytes = Math.min(written, dataLength);
|
|
188
|
-
const rateWindowElapsedMs = now - rateWindowStartedAt;
|
|
189
|
-
if (rateWindowElapsedMs >= FILE_TRANSFER_RATE_WINDOW_MS) {
|
|
190
|
-
const rateWindowBytes = Math.max(transferredBytes - rateWindowStartedBytes, 0);
|
|
191
|
-
rateBytesPerSecond = Math.round((rateWindowBytes / rateWindowElapsedMs) * 1000);
|
|
192
|
-
rateWindowStartedAt = now;
|
|
193
|
-
rateWindowStartedBytes = transferredBytes;
|
|
194
|
-
} else if (rateBytesPerSecond === undefined && elapsedMs > 0) {
|
|
195
|
-
rateBytesPerSecond = Math.round((transferredBytes / elapsedMs) * 1000);
|
|
196
|
-
}
|
|
197
181
|
options.onProgress?.({
|
|
198
182
|
progress: getConfirmedProgress(startOffset + written, totalSize, written, dataLength),
|
|
199
183
|
transferredBytes,
|
|
200
184
|
totalBytes: dataLength,
|
|
201
|
-
rateBytesPerSecond
|
|
185
|
+
rateBytesPerSecond:
|
|
186
|
+
elapsedMs > 0 ? Math.round((transferredBytes / elapsedMs) * 1000) : undefined,
|
|
202
187
|
elapsedMs,
|
|
203
188
|
});
|
|
204
|
-
if (options.paceMs && options.paceMs > 0) {
|
|
205
|
-
await new Promise(resolve => {
|
|
206
|
-
setTimeout(resolve, options.paceMs);
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
189
|
}
|
|
210
190
|
|
|
211
191
|
return {
|
package/src/api/index.ts
CHANGED
|
@@ -3,7 +3,6 @@ export { default as testProtocolV2Ping } from './protocol-v2/Ping';
|
|
|
3
3
|
export { default as preInitialize } from './device/PreInitialize';
|
|
4
4
|
|
|
5
5
|
export { default as searchDevices } from './SearchDevices';
|
|
6
|
-
export { default as detectDeviceConnectProtocol } from './DetectDeviceConnectProtocol';
|
|
7
6
|
export { default as getFeatures } from './GetFeatures';
|
|
8
7
|
export { default as getDeviceState } from './GetDeviceState';
|
|
9
8
|
export { default as getOnekeyFeatures } from './GetOnekeyFeatures';
|
|
@@ -50,7 +49,6 @@ export { default as promptWebDeviceAccess } from './PromptWebDeviceAccess';
|
|
|
50
49
|
export { default as deviceReboot } from './protocol-v2/DeviceReboot';
|
|
51
50
|
export { default as deviceGetOnboardingStatus } from './protocol-v2/DeviceGetOnboardingStatus';
|
|
52
51
|
export { default as deviceUploadWallpaper } from './protocol-v2/DeviceUploadWallpaper';
|
|
53
|
-
export { default as deviceUploadNft } from './protocol-v2/DeviceUploadNft';
|
|
54
52
|
export { default as uploadPortfolio } from './UploadPortfolio';
|
|
55
53
|
|
|
56
54
|
export { default as cipherKeyValue } from './CipherKeyValue';
|
|
@@ -506,7 +506,18 @@ export default class KaspaSignTransaction extends BaseMethod<KaspaSignTransactio
|
|
|
506
506
|
'KaspaSignTransaction: device firmware uses the streaming protocol; every output requires address or addressN'
|
|
507
507
|
);
|
|
508
508
|
}
|
|
509
|
-
|
|
509
|
+
try {
|
|
510
|
+
return await this.signTxStream(typedCall, response);
|
|
511
|
+
} catch (error) {
|
|
512
|
+
// Device rejected our refTxs; the caller decides whether to sign without them.
|
|
513
|
+
if (
|
|
514
|
+
error instanceof HardwareError &&
|
|
515
|
+
String(error.message).toLowerCase().includes('previous transaction id mismatch')
|
|
516
|
+
) {
|
|
517
|
+
throw ERRORS.TypedError(HardwareErrorCode.KaspaPrevTxIdMismatch, String(error.message));
|
|
518
|
+
}
|
|
519
|
+
throw error;
|
|
520
|
+
}
|
|
510
521
|
}
|
|
511
522
|
|
|
512
523
|
// Legacy answer to a streaming-only packet: no prehash material exists.
|
|
@@ -13,9 +13,7 @@ export default class ProtocolInfoRequest extends BaseMethod {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
async run() {
|
|
16
|
-
const res = await this.device.commands.typedCall('ProtocolInfoRequest', 'ProtocolInfo', {
|
|
17
|
-
eventless_wallet_session: true,
|
|
18
|
-
});
|
|
16
|
+
const res = await this.device.commands.typedCall('ProtocolInfoRequest', 'ProtocolInfo', {});
|
|
19
17
|
return Promise.resolve(res.message);
|
|
20
18
|
}
|
|
21
19
|
}
|
|
@@ -118,7 +118,6 @@ export const isProtocolV2DeviceDisconnectedError = (error: unknown) => {
|
|
|
118
118
|
message.includes('connection has timed out unexpectedly') ||
|
|
119
119
|
message.includes('connection error has occured') ||
|
|
120
120
|
message.includes('connection error has occurred') ||
|
|
121
|
-
message.includes('react native ble transport released') ||
|
|
122
121
|
message.includes('multiplatformbleadapter') ||
|
|
123
122
|
message.includes('multipalformebleadapter') ||
|
|
124
123
|
compactMessage.includes('rxerrorerror6') ||
|
|
@@ -4,8 +4,6 @@ import type { Device, DeviceEvents } from '../device/Device';
|
|
|
4
4
|
|
|
5
5
|
export type HardwareUiEventHandlers = {
|
|
6
6
|
pin: (...event: DeviceEvents[typeof DEVICE.PIN]) => void;
|
|
7
|
-
pinOnDevice: (...event: DeviceEvents[typeof DEVICE.PIN_ON_DEVICE]) => void;
|
|
8
|
-
pinOnDeviceComplete: (...event: DeviceEvents[typeof DEVICE.PIN_ON_DEVICE_COMPLETE]) => void;
|
|
9
7
|
button: (...event: DeviceEvents[typeof DEVICE.BUTTON]) => void;
|
|
10
8
|
passphrase: (...event: DeviceEvents[typeof DEVICE.PASSPHRASE]) => void;
|
|
11
9
|
passphraseOnDevice: (...event: DeviceEvents[typeof DEVICE.PASSPHRASE_ON_DEVICE]) => void;
|
|
@@ -17,8 +15,6 @@ export function registerHardwareUiEventListeners(
|
|
|
17
15
|
handlers: HardwareUiEventHandlers
|
|
18
16
|
) {
|
|
19
17
|
device.on(DEVICE.PIN, handlers.pin);
|
|
20
|
-
device.on(DEVICE.PIN_ON_DEVICE, handlers.pinOnDevice);
|
|
21
|
-
device.on(DEVICE.PIN_ON_DEVICE_COMPLETE, handlers.pinOnDeviceComplete);
|
|
22
18
|
device.on(DEVICE.BUTTON, handlers.button);
|
|
23
19
|
device.on(DEVICE.PASSPHRASE, handlers.passphrase);
|
|
24
20
|
device.on(DEVICE.PASSPHRASE_ON_DEVICE, handlers.passphraseOnDevice);
|