@onekeyfe/hd-core 1.2.1-alpha.0 → 1.2.2-alpha.0
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__/deviceUploadNft.test.ts +41 -0
- package/__tests__/evmSignTypedData.test.ts +42 -0
- package/__tests__/firmware-update/firmware-update-v4-install-poll.test.ts +21 -322
- package/__tests__/pro2HostAssetPackage.test.ts +58 -0
- package/__tests__/protocol-v2.test.ts +46 -1
- package/dist/api/FirmwareUpdateV4.d.ts +0 -1
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/evm/EVMSignTypedData.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts.map +1 -1
- package/dist/index.js +273 -45
- package/dist/utils/pro2HostAssetPackage.d.ts +8 -0
- package/dist/utils/pro2HostAssetPackage.d.ts.map +1 -0
- package/package.json +4 -4
- package/src/api/FirmwareUpdateV4.ts +13 -31
- package/src/api/evm/EVMSignTypedData.ts +1 -0
- package/src/api/protocol-v2/DeviceUploadNft.ts +28 -8
- package/src/api/protocol-v2/DeviceUploadWallpaper.ts +19 -8
- package/src/utils/pro2HostAssetPackage.ts +315 -0
package/dist/index.js
CHANGED
|
@@ -42623,7 +42623,7 @@ function invalidParameter$2(message) {
|
|
|
42623
42623
|
function asBytes(rgba) {
|
|
42624
42624
|
return rgba instanceof Uint8Array ? rgba : new Uint8Array(rgba);
|
|
42625
42625
|
}
|
|
42626
|
-
function align(value, boundary) {
|
|
42626
|
+
function align$1(value, boundary) {
|
|
42627
42627
|
return Math.ceil(value / boundary) * boundary;
|
|
42628
42628
|
}
|
|
42629
42629
|
function encodePro2Image(options) {
|
|
@@ -42651,7 +42651,7 @@ function encodePro2Image(options) {
|
|
|
42651
42651
|
}
|
|
42652
42652
|
}
|
|
42653
42653
|
const colorFormat = hasTransparency ? 'RGB565A8' : 'RGB565';
|
|
42654
|
-
const stride = align(width * 2, 4);
|
|
42654
|
+
const stride = align$1(width * 2, 4);
|
|
42655
42655
|
const alphaStride = stride / 2;
|
|
42656
42656
|
const rgbSize = stride * height;
|
|
42657
42657
|
const alphaSize = hasTransparency ? alphaStride * height : 0;
|
|
@@ -52302,13 +52302,6 @@ const isProtocolV2FirmwareStatusEndpointUnavailable = (error) => {
|
|
|
52302
52302
|
message.includes('message handler not found') ||
|
|
52303
52303
|
message.includes('unsupported message'));
|
|
52304
52304
|
};
|
|
52305
|
-
const isProtocolV2InstallResponseTimeout = (error) => {
|
|
52306
|
-
if (!error || typeof error !== 'object')
|
|
52307
|
-
return false;
|
|
52308
|
-
const { code } = error;
|
|
52309
|
-
return (code === 'response-timeout' ||
|
|
52310
|
-
/\bresponse timeout\b/i.test(getProtocolV2UnknownErrorText(error)));
|
|
52311
|
-
};
|
|
52312
52305
|
const isProtocolV2TerminalInstallStatusError = (error) => {
|
|
52313
52306
|
var _a;
|
|
52314
52307
|
return hdShared.isBleStaleBondHardwareError(error) ||
|
|
@@ -52436,7 +52429,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
52436
52429
|
this.protocolV2CompletedTargetIds = new Set();
|
|
52437
52430
|
this.protocolV2InstallBaselineVersions = new Map();
|
|
52438
52431
|
this.protocolV2InstallNeedsReconnect = false;
|
|
52439
|
-
this.protocolV2InstallDisconnectObserved = false;
|
|
52440
52432
|
this.protocolV2InstallTerminalSuccessObserved = false;
|
|
52441
52433
|
this.protocolV2LastTransferProgressAt = 0;
|
|
52442
52434
|
}
|
|
@@ -53907,15 +53899,15 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
53907
53899
|
return __awaiter(this, void 0, void 0, function* () {
|
|
53908
53900
|
const expectedTargetIds = new Set(targets.map(target => target.target_id));
|
|
53909
53901
|
const expectedPaths = new Map(targets.map(target => [target.target_id, target.path]));
|
|
53910
|
-
const
|
|
53902
|
+
const isBleCoprocessorInstall = this.isBleReconnect() &&
|
|
53903
|
+
expectedTargetIds.has(ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_COPROCESSOR);
|
|
53911
53904
|
const startTime = Date.now();
|
|
53912
53905
|
let lastError;
|
|
53913
53906
|
let shouldReconnect = this.protocolV2InstallNeedsReconnect;
|
|
53914
53907
|
this.protocolV2InstallNeedsReconnect = false;
|
|
53915
53908
|
let deviceInfo;
|
|
53916
53909
|
let bleInstallLinkReady = false;
|
|
53917
|
-
let installStatusDisconnectObserved =
|
|
53918
|
-
this.protocolV2InstallDisconnectObserved = false;
|
|
53910
|
+
let installStatusDisconnectObserved = false;
|
|
53919
53911
|
let installReconnectObserved = false;
|
|
53920
53912
|
let finishedStatusSnapshotKey;
|
|
53921
53913
|
let finishedStatusSnapshotPolls = 0;
|
|
@@ -53923,17 +53915,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
53923
53915
|
let installEvidenceObserved = this.protocolV2InstallTerminalSuccessObserved;
|
|
53924
53916
|
let currentInstallStatusObserved = false;
|
|
53925
53917
|
const liveTargetIds = new Set();
|
|
53926
|
-
const recordBleInstallDisconnect = (error) => {
|
|
53927
|
-
if (!isBleInstall ||
|
|
53928
|
-
!isProtocolV2DeviceDisconnectedError(error) ||
|
|
53929
|
-
isProtocolV2InstallResponseTimeout(error)) {
|
|
53930
|
-
return;
|
|
53931
|
-
}
|
|
53932
|
-
installStatusDisconnectObserved = true;
|
|
53933
|
-
installReconnectObserved = false;
|
|
53934
|
-
finishedStatusSnapshotKey = undefined;
|
|
53935
|
-
finishedStatusSnapshotPolls = 0;
|
|
53936
|
-
};
|
|
53937
53918
|
while (Date.now() - startTime < PROTOCOL_V2_INSTALL_TIMEOUT) {
|
|
53938
53919
|
this.throwIfAborted();
|
|
53939
53920
|
try {
|
|
@@ -54120,7 +54101,13 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
54120
54101
|
}
|
|
54121
54102
|
}
|
|
54122
54103
|
else {
|
|
54123
|
-
|
|
54104
|
+
if (isBleCoprocessorInstall &&
|
|
54105
|
+
isProtocolV2DeviceDisconnectedError(error) &&
|
|
54106
|
+
!isProtocolV2ResponseTimeout(error)) {
|
|
54107
|
+
installStatusDisconnectObserved = true;
|
|
54108
|
+
finishedStatusSnapshotKey = undefined;
|
|
54109
|
+
finishedStatusSnapshotPolls = 0;
|
|
54110
|
+
}
|
|
54124
54111
|
shouldReconnect = true;
|
|
54125
54112
|
deviceInfo = undefined;
|
|
54126
54113
|
bleInstallLinkReady = false;
|
|
@@ -54141,7 +54128,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
54141
54128
|
((_b = error.params) === null || _b === void 0 ? void 0 : _b.firmwareUpdateCode) === 'FirmwareInstallStatusUnavailable') {
|
|
54142
54129
|
throw error;
|
|
54143
54130
|
}
|
|
54144
|
-
recordBleInstallDisconnect(error);
|
|
54145
54131
|
shouldReconnect = true;
|
|
54146
54132
|
deviceInfo = undefined;
|
|
54147
54133
|
bleInstallLinkReady = false;
|
|
@@ -54391,7 +54377,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
54391
54377
|
return __awaiter(this, void 0, void 0, function* () {
|
|
54392
54378
|
this.protocolV2LastRuntimeProbeFeatures = undefined;
|
|
54393
54379
|
this.protocolV2InstallNeedsReconnect = false;
|
|
54394
|
-
this.protocolV2InstallDisconnectObserved = false;
|
|
54395
54380
|
this.protocolV2InstallTerminalSuccessObserved = false;
|
|
54396
54381
|
const commands = this.device.getCommands();
|
|
54397
54382
|
yield commands.typedCall('DeviceFirmwareUpdateStage', 'Success', { targets });
|
|
@@ -54419,7 +54404,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
54419
54404
|
}
|
|
54420
54405
|
Log$6.log('[FirmwareUpdateV4] transport released while writing install request; continue status polling');
|
|
54421
54406
|
this.protocolV2InstallNeedsReconnect = true;
|
|
54422
|
-
this.protocolV2InstallDisconnectObserved = !isProtocolV2InstallResponseTimeout(error);
|
|
54423
54407
|
}
|
|
54424
54408
|
});
|
|
54425
54409
|
}
|
|
@@ -54612,7 +54596,234 @@ function decodeJpegBase64ToRgba({ jpegBase64, parameterName, expectedWidth, expe
|
|
|
54612
54596
|
return decoded;
|
|
54613
54597
|
}
|
|
54614
54598
|
|
|
54599
|
+
const PRO2_HOST_ASSET_PACKAGE_MIN_VERSION = '1.0.1';
|
|
54600
|
+
const CONTAINER_HEADER_SIZE = 0x5f90;
|
|
54601
|
+
const CONTAINER_HEADER_HASH_INPUT_LENGTH = 0x240;
|
|
54602
|
+
const CONTAINER_HASH_SECTION_OFFSET = 0x200;
|
|
54603
|
+
const CONTAINER_SIGNATURE_ALGORITHM_OFFSET = 0x408;
|
|
54604
|
+
const CONTAINER_HEADER_MAGIC = 0x50504b4f;
|
|
54605
|
+
const CONTAINER_HEADER_VERSION = 1;
|
|
54606
|
+
const CONTAINER_RESOURCE_TYPE_MAGIC = 0x43534552;
|
|
54607
|
+
const CONTAINER_ED25519_SIGNATURE_ALGORITHM = 0x71717171;
|
|
54608
|
+
const ARCHIVE_MAGIC = 0x52414b4f;
|
|
54609
|
+
const ARCHIVE_VERSION = 1;
|
|
54610
|
+
const ARCHIVE_HEADER_SIZE = 42;
|
|
54611
|
+
const ARCHIVE_ENTRY_SIZE = 296;
|
|
54612
|
+
const ARCHIVE_ENTRY_NAME_MAX_LENGTH = 255;
|
|
54613
|
+
const ARCHIVE_COMPRESS_LZ4_BLOCKED = 1;
|
|
54614
|
+
const ARCHIVE_ALIGNMENT = 4;
|
|
54615
|
+
const LZ4_BLOCK_SIZE_LOG2 = 12;
|
|
54616
|
+
const LZ4_MIN_MATCH = 4;
|
|
54617
|
+
const LZ4_LAST_LITERALS = 5;
|
|
54618
|
+
const LZ4_MATCH_FIND_LIMIT = 12;
|
|
54619
|
+
const LZ4_MAX_OFFSET = 0xffff;
|
|
54620
|
+
const LZ4_LENGTH_MASK = 15;
|
|
54621
|
+
const LZ4_HASH_LOG = 16;
|
|
54622
|
+
const LZ4_HASH_MULTIPLIER = 2654435761;
|
|
54623
|
+
const LZ4_SKIP_TRIGGER = 6;
|
|
54624
|
+
const HOST_ASSET_PACKAGE_MAX_SIZE = 4 * 1024 * 1024;
|
|
54625
|
+
function supportsPro2HostAssetPackage(firmwareVersion) {
|
|
54626
|
+
return Boolean(firmwareVersion &&
|
|
54627
|
+
semver__default["default"].valid(firmwareVersion) &&
|
|
54628
|
+
semver__default["default"].gte(firmwareVersion, PRO2_HOST_ASSET_PACKAGE_MIN_VERSION));
|
|
54629
|
+
}
|
|
54630
|
+
function align(value) {
|
|
54631
|
+
return (value + ARCHIVE_ALIGNMENT - 1) & ~(ARCHIVE_ALIGNMENT - 1);
|
|
54632
|
+
}
|
|
54633
|
+
function concatBytes(parts) {
|
|
54634
|
+
const output = new Uint8Array(parts.reduce((length, part) => length + part.byteLength, 0));
|
|
54635
|
+
let offset = 0;
|
|
54636
|
+
for (const part of parts) {
|
|
54637
|
+
output.set(part, offset);
|
|
54638
|
+
offset += part.byteLength;
|
|
54639
|
+
}
|
|
54640
|
+
return output;
|
|
54641
|
+
}
|
|
54642
|
+
function writeExtendedLength(output, offset, length) {
|
|
54643
|
+
let remaining = length;
|
|
54644
|
+
let nextOffset = offset;
|
|
54645
|
+
while (remaining >= 255) {
|
|
54646
|
+
output[nextOffset] = 255;
|
|
54647
|
+
nextOffset += 1;
|
|
54648
|
+
remaining -= 255;
|
|
54649
|
+
}
|
|
54650
|
+
output[nextOffset] = remaining;
|
|
54651
|
+
return nextOffset + 1;
|
|
54652
|
+
}
|
|
54653
|
+
function copyBytes(output, outputOffset, input, inputOffset, length) {
|
|
54654
|
+
output.set(input.subarray(inputOffset, inputOffset + length), outputOffset);
|
|
54655
|
+
return outputOffset + length;
|
|
54656
|
+
}
|
|
54657
|
+
function emitSequence(output, outputOffset, input, anchor, literalLength, matchOffset, matchLengthCode) {
|
|
54658
|
+
const tokenOffset = outputOffset;
|
|
54659
|
+
let nextOffset = outputOffset + 1;
|
|
54660
|
+
let token = 0;
|
|
54661
|
+
if (literalLength >= LZ4_LENGTH_MASK) {
|
|
54662
|
+
token = LZ4_LENGTH_MASK << 4;
|
|
54663
|
+
nextOffset = writeExtendedLength(output, nextOffset, literalLength - LZ4_LENGTH_MASK);
|
|
54664
|
+
}
|
|
54665
|
+
else {
|
|
54666
|
+
token = literalLength << 4;
|
|
54667
|
+
}
|
|
54668
|
+
nextOffset = copyBytes(output, nextOffset, input, anchor, literalLength);
|
|
54669
|
+
output[nextOffset] = matchOffset & 0xff;
|
|
54670
|
+
output[nextOffset + 1] = (matchOffset >>> 8) & 0xff;
|
|
54671
|
+
nextOffset += 2;
|
|
54672
|
+
if (matchLengthCode >= LZ4_LENGTH_MASK) {
|
|
54673
|
+
token |= LZ4_LENGTH_MASK;
|
|
54674
|
+
nextOffset = writeExtendedLength(output, nextOffset, matchLengthCode - LZ4_LENGTH_MASK);
|
|
54675
|
+
}
|
|
54676
|
+
else {
|
|
54677
|
+
token |= matchLengthCode;
|
|
54678
|
+
}
|
|
54679
|
+
output[tokenOffset] = token;
|
|
54680
|
+
return nextOffset;
|
|
54681
|
+
}
|
|
54682
|
+
function emitLastLiterals(output, outputOffset, input, anchor, literalLength) {
|
|
54683
|
+
const tokenOffset = outputOffset;
|
|
54684
|
+
let nextOffset = outputOffset + 1;
|
|
54685
|
+
if (literalLength >= LZ4_LENGTH_MASK) {
|
|
54686
|
+
output[tokenOffset] = LZ4_LENGTH_MASK << 4;
|
|
54687
|
+
nextOffset = writeExtendedLength(output, nextOffset, literalLength - LZ4_LENGTH_MASK);
|
|
54688
|
+
}
|
|
54689
|
+
else {
|
|
54690
|
+
output[tokenOffset] = literalLength << 4;
|
|
54691
|
+
}
|
|
54692
|
+
return copyBytes(output, nextOffset, input, anchor, literalLength);
|
|
54693
|
+
}
|
|
54694
|
+
function compressRawLz4Block(input, hashTable) {
|
|
54695
|
+
const output = new Uint8Array(input.byteLength + Math.floor(input.byteLength / 255) + 16);
|
|
54696
|
+
const inputView = new DataView(input.buffer, input.byteOffset, input.byteLength);
|
|
54697
|
+
const matchFindLimit = input.byteLength - LZ4_MATCH_FIND_LIMIT;
|
|
54698
|
+
const matchExtendLimit = input.byteLength - LZ4_LAST_LITERALS;
|
|
54699
|
+
let anchor = 0;
|
|
54700
|
+
let inputOffset = 0;
|
|
54701
|
+
let outputOffset = 0;
|
|
54702
|
+
let searchMatchCount = 1 << LZ4_SKIP_TRIGGER;
|
|
54703
|
+
hashTable.fill(0);
|
|
54704
|
+
while (inputOffset < matchFindLimit) {
|
|
54705
|
+
const sequence = inputView.getUint32(inputOffset, true);
|
|
54706
|
+
const hash = Math.imul(sequence, LZ4_HASH_MULTIPLIER) >>> (32 - LZ4_HASH_LOG);
|
|
54707
|
+
const candidate = hashTable[hash] - 1;
|
|
54708
|
+
hashTable[hash] = inputOffset + 1;
|
|
54709
|
+
const hasMatch = !(candidate < 0 ||
|
|
54710
|
+
inputOffset - candidate > LZ4_MAX_OFFSET ||
|
|
54711
|
+
inputView.getUint32(candidate, true) !== sequence);
|
|
54712
|
+
if (!hasMatch) {
|
|
54713
|
+
inputOffset += searchMatchCount >> LZ4_SKIP_TRIGGER;
|
|
54714
|
+
searchMatchCount += 1;
|
|
54715
|
+
}
|
|
54716
|
+
else {
|
|
54717
|
+
searchMatchCount = 1 << LZ4_SKIP_TRIGGER;
|
|
54718
|
+
let matchEnd = inputOffset + LZ4_MIN_MATCH;
|
|
54719
|
+
let reference = candidate + LZ4_MIN_MATCH;
|
|
54720
|
+
while (matchEnd < matchExtendLimit && input[matchEnd] === input[reference]) {
|
|
54721
|
+
matchEnd += 1;
|
|
54722
|
+
reference += 1;
|
|
54723
|
+
}
|
|
54724
|
+
outputOffset = emitSequence(output, outputOffset, input, anchor, inputOffset - anchor, inputOffset - candidate, matchEnd - inputOffset - LZ4_MIN_MATCH);
|
|
54725
|
+
inputOffset = matchEnd;
|
|
54726
|
+
anchor = inputOffset;
|
|
54727
|
+
}
|
|
54728
|
+
}
|
|
54729
|
+
outputOffset = emitLastLiterals(output, outputOffset, input, anchor, input.byteLength - anchor);
|
|
54730
|
+
return output.slice(0, outputOffset);
|
|
54731
|
+
}
|
|
54732
|
+
function encodeLz4Blocked(data) {
|
|
54733
|
+
const blockSize = 1 << LZ4_BLOCK_SIZE_LOG2;
|
|
54734
|
+
const blockCount = Math.ceil(data.byteLength / blockSize);
|
|
54735
|
+
const hashTable = new Uint32Array(1 << LZ4_HASH_LOG);
|
|
54736
|
+
const blocks = [];
|
|
54737
|
+
const header = new Uint8Array(8 + blockCount * 4);
|
|
54738
|
+
const headerView = new DataView(header.buffer);
|
|
54739
|
+
headerView.setUint16(0, blockCount, true);
|
|
54740
|
+
headerView.setUint16(2, LZ4_BLOCK_SIZE_LOG2, true);
|
|
54741
|
+
for (let index = 0; index < blockCount; index += 1) {
|
|
54742
|
+
const block = compressRawLz4Block(data.subarray(index * blockSize, Math.min((index + 1) * blockSize, data.byteLength)), hashTable);
|
|
54743
|
+
headerView.setUint32(8 + index * 4, block.byteLength, true);
|
|
54744
|
+
blocks.push(block);
|
|
54745
|
+
}
|
|
54746
|
+
return concatBytes([header, ...blocks]);
|
|
54747
|
+
}
|
|
54748
|
+
const CRC32_TABLE = (() => {
|
|
54749
|
+
const table = new Uint32Array(256);
|
|
54750
|
+
for (let index = 0; index < table.length; index += 1) {
|
|
54751
|
+
let value = index;
|
|
54752
|
+
for (let bit = 0; bit < 8; bit += 1) {
|
|
54753
|
+
value = value & 1 ? 0xedb88320 ^ (value >>> 1) : value >>> 1;
|
|
54754
|
+
}
|
|
54755
|
+
table[index] = value >>> 0;
|
|
54756
|
+
}
|
|
54757
|
+
return table;
|
|
54758
|
+
})();
|
|
54759
|
+
function crc32(data) {
|
|
54760
|
+
let value = 0xffffffff;
|
|
54761
|
+
for (const byte of data) {
|
|
54762
|
+
value = CRC32_TABLE[(value ^ byte) & 0xff] ^ (value >>> 8);
|
|
54763
|
+
}
|
|
54764
|
+
return (value ^ 0xffffffff) >>> 0;
|
|
54765
|
+
}
|
|
54766
|
+
function buildArchive(entries) {
|
|
54767
|
+
const textEncoder = new TextEncoder();
|
|
54768
|
+
let dataOffset = ARCHIVE_HEADER_SIZE + entries.length * ARCHIVE_ENTRY_SIZE;
|
|
54769
|
+
const encodedEntries = entries.map(entry => {
|
|
54770
|
+
const nameBytes = textEncoder.encode(entry.name);
|
|
54771
|
+
if (!entry.name || nameBytes.byteLength > ARCHIVE_ENTRY_NAME_MAX_LENGTH) {
|
|
54772
|
+
throw new Error('Pro2 host asset package entry names must contain 1 to 255 UTF-8 bytes.');
|
|
54773
|
+
}
|
|
54774
|
+
if (!(entry.data instanceof Uint8Array) || entry.data.byteLength === 0) {
|
|
54775
|
+
throw new Error(`Pro2 host asset package entry [${entry.name}] must not be empty.`);
|
|
54776
|
+
}
|
|
54777
|
+
const compressed = encodeLz4Blocked(entry.data);
|
|
54778
|
+
const offset = align(dataOffset);
|
|
54779
|
+
dataOffset = offset + compressed.byteLength;
|
|
54780
|
+
return Object.assign(Object.assign({}, entry), { nameBytes, compressed, offset });
|
|
54781
|
+
});
|
|
54782
|
+
const archive = new Uint8Array(dataOffset);
|
|
54783
|
+
const view = new DataView(archive.buffer);
|
|
54784
|
+
view.setUint32(0, ARCHIVE_MAGIC, true);
|
|
54785
|
+
view.setUint32(4, ARCHIVE_VERSION, true);
|
|
54786
|
+
view.setUint16(8, encodedEntries.length, true);
|
|
54787
|
+
encodedEntries.forEach((entry, index) => {
|
|
54788
|
+
const recordOffset = ARCHIVE_HEADER_SIZE + index * ARCHIVE_ENTRY_SIZE;
|
|
54789
|
+
archive[recordOffset] = entry.nameBytes.byteLength;
|
|
54790
|
+
archive.set(entry.nameBytes, recordOffset + 1);
|
|
54791
|
+
view.setUint32(recordOffset + 0x100, entry.offset, true);
|
|
54792
|
+
view.setUint32(recordOffset + 0x104, entry.data.byteLength, true);
|
|
54793
|
+
view.setUint32(recordOffset + 0x108, entry.compressed.byteLength, true);
|
|
54794
|
+
view.setUint32(recordOffset + 0x10c, crc32(entry.data), true);
|
|
54795
|
+
view.setUint32(recordOffset + 0x110, crc32(entry.compressed), true);
|
|
54796
|
+
archive[recordOffset + 0x114] = ARCHIVE_COMPRESS_LZ4_BLOCKED;
|
|
54797
|
+
archive.set(entry.compressed, entry.offset);
|
|
54798
|
+
});
|
|
54799
|
+
return archive;
|
|
54800
|
+
}
|
|
54801
|
+
function buildPro2HostAssetPackage(entries) {
|
|
54802
|
+
if (entries.length === 0 || new Set(entries.map(entry => entry.name)).size !== entries.length) {
|
|
54803
|
+
throw new Error('Pro2 host asset package entries must have unique, non-empty names.');
|
|
54804
|
+
}
|
|
54805
|
+
const payload = buildArchive(entries);
|
|
54806
|
+
const header = new Uint8Array(CONTAINER_HEADER_SIZE);
|
|
54807
|
+
const view = new DataView(header.buffer);
|
|
54808
|
+
view.setUint32(0, CONTAINER_HEADER_MAGIC, true);
|
|
54809
|
+
view.setUint32(4, CONTAINER_HEADER_VERSION, true);
|
|
54810
|
+
view.setUint32(8, CONTAINER_RESOURCE_TYPE_MAGIC, true);
|
|
54811
|
+
view.setUint32(0x0c, CONTAINER_HEADER_SIZE, true);
|
|
54812
|
+
view.setUint32(0x10, 1, true);
|
|
54813
|
+
view.setUint32(0x14, payload.byteLength, true);
|
|
54814
|
+
header.set(sha3.sha3_512(payload), CONTAINER_HASH_SECTION_OFFSET);
|
|
54815
|
+
header.set(sha3.sha3_512(header.subarray(0, CONTAINER_HEADER_HASH_INPUT_LENGTH)), 0x240);
|
|
54816
|
+
view.setUint32(CONTAINER_SIGNATURE_ALGORITHM_OFFSET, CONTAINER_ED25519_SIGNATURE_ALGORITHM, true);
|
|
54817
|
+
const packageData = concatBytes([header, payload]);
|
|
54818
|
+
if (packageData.byteLength > HOST_ASSET_PACKAGE_MAX_SIZE) {
|
|
54819
|
+
throw new Error('Pro2 host asset package exceeds the firmware 4 MiB limit.');
|
|
54820
|
+
}
|
|
54821
|
+
return packageData;
|
|
54822
|
+
}
|
|
54823
|
+
|
|
54615
54824
|
const WALLPAPER_DIRECTORY = 'vol1:/wallpapers';
|
|
54825
|
+
const WALLPAPER_PACKAGE_PATH = `${WALLPAPER_DIRECTORY}/wallpaper.okpkg`;
|
|
54826
|
+
const WALLPAPER_PACKAGE_ENTRY = 'wallpaper.bin';
|
|
54616
54827
|
const SAFE_FILE_NAME = /^[A-Za-z0-9_-]+(?:\.bin)?$/;
|
|
54617
54828
|
const DEVICE_SETTINGS_SET_MESSAGE_TYPE = 60412;
|
|
54618
54829
|
const FILESYSTEM_FILE_WRITE_MESSAGE_TYPE$2 = 60805;
|
|
@@ -54688,18 +54899,15 @@ class DeviceUploadWallpaper extends BaseMethod {
|
|
|
54688
54899
|
this.directoryReady = true;
|
|
54689
54900
|
});
|
|
54690
54901
|
}
|
|
54691
|
-
upload() {
|
|
54902
|
+
upload(path, data) {
|
|
54692
54903
|
return __awaiter(this, void 0, void 0, function* () {
|
|
54693
54904
|
if (this.uploaded)
|
|
54694
54905
|
return;
|
|
54695
|
-
const { encoded } = this;
|
|
54696
|
-
if (!encoded)
|
|
54697
|
-
throw invalidParameter$1('Wallpaper data has not been initialized.');
|
|
54698
54906
|
yield writeProtocolV2File({
|
|
54699
54907
|
commands: this.device.commands,
|
|
54700
|
-
path
|
|
54701
|
-
data
|
|
54702
|
-
totalSize:
|
|
54908
|
+
path,
|
|
54909
|
+
data,
|
|
54910
|
+
totalSize: data.byteLength,
|
|
54703
54911
|
chunkSize: this.params.chunkSize,
|
|
54704
54912
|
maxChunkRetries: 3,
|
|
54705
54913
|
overwrite: true,
|
|
@@ -54722,7 +54930,13 @@ class DeviceUploadWallpaper extends BaseMethod {
|
|
|
54722
54930
|
throw invalidParameter$1('Wallpaper data has not been initialized.');
|
|
54723
54931
|
yield this.assertCapabilities();
|
|
54724
54932
|
yield this.ensureDirectory();
|
|
54725
|
-
|
|
54933
|
+
const useHostAssetPackage = supportsPro2HostAssetPackage(this.device.getCurrentFirmwareVersionString());
|
|
54934
|
+
const data = useHostAssetPackage
|
|
54935
|
+
? buildPro2HostAssetPackage([{ name: WALLPAPER_PACKAGE_ENTRY, data: encoded.data }])
|
|
54936
|
+
: encoded.data;
|
|
54937
|
+
if (useHostAssetPackage)
|
|
54938
|
+
this.path = WALLPAPER_PACKAGE_PATH;
|
|
54939
|
+
yield this.upload(this.path, data);
|
|
54726
54940
|
const response = yield this.device.commands.typedCall('DeviceSettingsSet', 'Success', {
|
|
54727
54941
|
settings: { wallpaper_path: this.path },
|
|
54728
54942
|
});
|
|
@@ -54736,7 +54950,7 @@ class DeviceUploadWallpaper extends BaseMethod {
|
|
|
54736
54950
|
}
|
|
54737
54951
|
return {
|
|
54738
54952
|
path: this.path,
|
|
54739
|
-
size:
|
|
54953
|
+
size: data.byteLength,
|
|
54740
54954
|
colorFormat: encoded.colorFormat,
|
|
54741
54955
|
message: (_a = response.message) === null || _a === void 0 ? void 0 : _a.message,
|
|
54742
54956
|
};
|
|
@@ -54815,14 +55029,14 @@ class DeviceUploadNft extends BaseMethod {
|
|
|
54815
55029
|
this.skipForceUpdateCheck = true;
|
|
54816
55030
|
this.useDevicePassphraseState = false;
|
|
54817
55031
|
}
|
|
54818
|
-
assertCapabilities() {
|
|
55032
|
+
assertCapabilities(useHostAssetPackage) {
|
|
54819
55033
|
return __awaiter(this, void 0, void 0, function* () {
|
|
54820
55034
|
const protocolInfo = yield this.device.ensureProtocolV2RuntimeContext();
|
|
54821
55035
|
const hasFileWrite = supportsProtocolV2Message(protocolInfo, FILESYSTEM_FILE_WRITE_MESSAGE_TYPE$1);
|
|
54822
55036
|
const hasPathInfo = supportsProtocolV2Message(protocolInfo, FILESYSTEM_PATH_INFO_QUERY_MESSAGE_TYPE);
|
|
54823
55037
|
const hasDirList = supportsProtocolV2Message(protocolInfo, FILESYSTEM_DIR_LIST_MESSAGE_TYPE);
|
|
54824
55038
|
const hasNftUpdate = supportsProtocolV2Message(protocolInfo, NFT_UPDATE_MESSAGE_TYPE);
|
|
54825
|
-
if (!hasFileWrite || !
|
|
55039
|
+
if (!hasFileWrite || !hasNftUpdate || (!useHostAssetPackage && (!hasPathInfo || !hasDirList))) {
|
|
54826
55040
|
throw hdShared.createDeviceNotSupportMethodError(this.name, this.device.getCurrentFirmwareType());
|
|
54827
55041
|
}
|
|
54828
55042
|
});
|
|
@@ -54853,15 +55067,28 @@ class DeviceUploadNft extends BaseMethod {
|
|
|
54853
55067
|
const { bundle } = this;
|
|
54854
55068
|
if (!bundle)
|
|
54855
55069
|
throw invalidParameter$1('NFT data has not been initialized.');
|
|
54856
|
-
|
|
55070
|
+
const useHostAssetPackage = supportsPro2HostAssetPackage(this.device.getCurrentFirmwareVersionString());
|
|
55071
|
+
yield this.assertCapabilities(useHostAssetPackage);
|
|
54857
55072
|
this.throwIfAborted();
|
|
54858
|
-
|
|
55073
|
+
if (!useHostAssetPackage)
|
|
55074
|
+
yield this.assertStorageCapacity(bundle.basename);
|
|
54859
55075
|
this.throwIfAborted();
|
|
54860
|
-
const
|
|
55076
|
+
const extractedFiles = [
|
|
54861
55077
|
{ path: `${PRO2_NFT_DIRECTORY}/${bundle.basename}.bin`, data: bundle.image },
|
|
54862
55078
|
{ path: `${PRO2_NFT_DIRECTORY}/${bundle.basename}_m.bin`, data: bundle.thumbnail },
|
|
54863
55079
|
{ path: `${PRO2_NFT_DIRECTORY}/${bundle.basename}.json`, data: bundle.metadata },
|
|
54864
55080
|
];
|
|
55081
|
+
const files = useHostAssetPackage
|
|
55082
|
+
? [
|
|
55083
|
+
{
|
|
55084
|
+
path: `${PRO2_NFT_DIRECTORY}/${bundle.basename}.okpkg`,
|
|
55085
|
+
data: buildPro2HostAssetPackage(extractedFiles.map(file => ({
|
|
55086
|
+
name: file.path.slice(`${PRO2_NFT_DIRECTORY}/`.length),
|
|
55087
|
+
data: file.data,
|
|
55088
|
+
}))),
|
|
55089
|
+
},
|
|
55090
|
+
]
|
|
55091
|
+
: extractedFiles;
|
|
54865
55092
|
const totalSize = files.reduce((sum, file) => sum + file.data.byteLength, 0);
|
|
54866
55093
|
let transferredBeforeFile = 0;
|
|
54867
55094
|
for (const file of files) {
|
|
@@ -54890,9 +55117,9 @@ class DeviceUploadNft extends BaseMethod {
|
|
|
54890
55117
|
const response = yield this.updateNft(bundle.basename);
|
|
54891
55118
|
return {
|
|
54892
55119
|
basename: bundle.basename,
|
|
54893
|
-
imagePath:
|
|
54894
|
-
thumbnailPath:
|
|
54895
|
-
metadataPath:
|
|
55120
|
+
imagePath: extractedFiles[0].path,
|
|
55121
|
+
thumbnailPath: extractedFiles[1].path,
|
|
55122
|
+
metadataPath: extractedFiles[2].path,
|
|
54896
55123
|
totalSize,
|
|
54897
55124
|
nftUpdated: true,
|
|
54898
55125
|
message: (_a = response.message) === null || _a === void 0 ? void 0 : _a.message,
|
|
@@ -58187,6 +58414,7 @@ class EVMSignTypedData extends BaseMethod {
|
|
|
58187
58414
|
const currentDeviceType = this.device.getCurrentDeviceType();
|
|
58188
58415
|
const supportBiggerDataVersion = '4.4.0';
|
|
58189
58416
|
const supportBiggerData = DeviceModelToTypes.model_classic1s.includes(currentDeviceType) ||
|
|
58417
|
+
DeviceModelToTypes.model_pro2.includes(currentDeviceType) ||
|
|
58190
58418
|
(DeviceModelToTypes.model_touch.includes(currentDeviceType) &&
|
|
58191
58419
|
semver__default["default"].gte(currentVersion, supportBiggerDataVersion));
|
|
58192
58420
|
if (supportBiggerData) {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const PRO2_HOST_ASSET_PACKAGE_MIN_VERSION = "1.0.1";
|
|
2
|
+
export type Pro2HostAssetPackageEntry = {
|
|
3
|
+
name: string;
|
|
4
|
+
data: Uint8Array;
|
|
5
|
+
};
|
|
6
|
+
export declare function supportsPro2HostAssetPackage(firmwareVersion: string | undefined): boolean;
|
|
7
|
+
export declare function buildPro2HostAssetPackage(entries: Pro2HostAssetPackageEntry[]): Uint8Array;
|
|
8
|
+
//# sourceMappingURL=pro2HostAssetPackage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pro2HostAssetPackage.d.ts","sourceRoot":"","sources":["../../src/utils/pro2HostAssetPackage.ts"],"names":[],"mappings":"AAyBA,eAAO,MAAM,mCAAmC,UAAU,CAAC;AA4B3D,MAAM,MAAM,yBAAyB,GAAG;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;CAClB,CAAC;AAQF,wBAAgB,4BAA4B,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAMzF;AA6ND,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,yBAAyB,EAAE,GAAG,UAAU,CAuB1F"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-core",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2-alpha.0",
|
|
4
4
|
"description": "Core processes and APIs for communicating with OneKey hardware devices.",
|
|
5
5
|
"author": "OneKey",
|
|
6
6
|
"homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"url": "https://github.com/OneKeyHQ/hardware-js-sdk/issues"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@onekeyfe/hd-shared": "1.2.
|
|
29
|
-
"@onekeyfe/hd-transport": "1.2.
|
|
28
|
+
"@onekeyfe/hd-shared": "1.2.2-alpha.0",
|
|
29
|
+
"@onekeyfe/hd-transport": "1.2.2-alpha.0",
|
|
30
30
|
"axios": "1.15.2",
|
|
31
31
|
"bignumber.js": "^9.0.2",
|
|
32
32
|
"buffer": "^6.0.3",
|
|
@@ -46,5 +46,5 @@
|
|
|
46
46
|
"@types/w3c-web-usb": "^1.0.10",
|
|
47
47
|
"@types/web-bluetooth": "^0.0.21"
|
|
48
48
|
},
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "9c18d7073728621179d58252e07fb3385b865226"
|
|
50
50
|
}
|
|
@@ -374,15 +374,6 @@ const isProtocolV2FirmwareStatusEndpointUnavailable = (error: unknown) => {
|
|
|
374
374
|
);
|
|
375
375
|
};
|
|
376
376
|
|
|
377
|
-
const isProtocolV2InstallResponseTimeout = (error: unknown) => {
|
|
378
|
-
if (!error || typeof error !== 'object') return false;
|
|
379
|
-
const { code } = error as { code?: number | string };
|
|
380
|
-
return (
|
|
381
|
-
code === 'response-timeout' ||
|
|
382
|
-
/\bresponse timeout\b/i.test(getProtocolV2UnknownErrorText(error))
|
|
383
|
-
);
|
|
384
|
-
};
|
|
385
|
-
|
|
386
377
|
const isProtocolV2TerminalInstallStatusError = (error: unknown) =>
|
|
387
378
|
isBleStaleBondHardwareError(error) ||
|
|
388
379
|
(error instanceof HardwareError &&
|
|
@@ -574,8 +565,6 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
574
565
|
|
|
575
566
|
private protocolV2InstallNeedsReconnect = false;
|
|
576
567
|
|
|
577
|
-
private protocolV2InstallDisconnectObserved = false;
|
|
578
|
-
|
|
579
568
|
private protocolV2InstallTerminalSuccessObserved = false;
|
|
580
569
|
|
|
581
570
|
private protocolV2LastRuntimeProbeFeatures?: Features;
|
|
@@ -2528,7 +2517,9 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2528
2517
|
) {
|
|
2529
2518
|
const expectedTargetIds = new Set(targets.map(target => target.target_id));
|
|
2530
2519
|
const expectedPaths = new Map(targets.map(target => [target.target_id, target.path]));
|
|
2531
|
-
const
|
|
2520
|
+
const isBleCoprocessorInstall =
|
|
2521
|
+
this.isBleReconnect() &&
|
|
2522
|
+
expectedTargetIds.has(ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_COPROCESSOR);
|
|
2532
2523
|
const startTime = Date.now();
|
|
2533
2524
|
let lastError: unknown;
|
|
2534
2525
|
// The loader may release either USB or BLE as installation starts. Recovery reconnects
|
|
@@ -2537,8 +2528,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2537
2528
|
this.protocolV2InstallNeedsReconnect = false;
|
|
2538
2529
|
let deviceInfo: ProtocolV2DeviceInfo | undefined;
|
|
2539
2530
|
let bleInstallLinkReady = false;
|
|
2540
|
-
let installStatusDisconnectObserved =
|
|
2541
|
-
this.protocolV2InstallDisconnectObserved = false;
|
|
2531
|
+
let installStatusDisconnectObserved = false;
|
|
2542
2532
|
let installReconnectObserved = false;
|
|
2543
2533
|
let finishedStatusSnapshotKey: string | undefined;
|
|
2544
2534
|
let finishedStatusSnapshotPolls = 0;
|
|
@@ -2546,19 +2536,6 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2546
2536
|
let installEvidenceObserved = this.protocolV2InstallTerminalSuccessObserved;
|
|
2547
2537
|
let currentInstallStatusObserved = false;
|
|
2548
2538
|
const liveTargetIds = new Set<number>();
|
|
2549
|
-
const recordBleInstallDisconnect = (error: unknown) => {
|
|
2550
|
-
if (
|
|
2551
|
-
!isBleInstall ||
|
|
2552
|
-
!isProtocolV2DeviceDisconnectedError(error) ||
|
|
2553
|
-
isProtocolV2InstallResponseTimeout(error)
|
|
2554
|
-
) {
|
|
2555
|
-
return;
|
|
2556
|
-
}
|
|
2557
|
-
installStatusDisconnectObserved = true;
|
|
2558
|
-
installReconnectObserved = false;
|
|
2559
|
-
finishedStatusSnapshotKey = undefined;
|
|
2560
|
-
finishedStatusSnapshotPolls = 0;
|
|
2561
|
-
};
|
|
2562
2539
|
|
|
2563
2540
|
while (Date.now() - startTime < PROTOCOL_V2_INSTALL_TIMEOUT) {
|
|
2564
2541
|
// A transport release caused by an explicit workflow cancellation must not
|
|
@@ -2810,7 +2787,15 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2810
2787
|
);
|
|
2811
2788
|
}
|
|
2812
2789
|
} else {
|
|
2813
|
-
|
|
2790
|
+
if (
|
|
2791
|
+
isBleCoprocessorInstall &&
|
|
2792
|
+
isProtocolV2DeviceDisconnectedError(error) &&
|
|
2793
|
+
!isProtocolV2ResponseTimeout(error)
|
|
2794
|
+
) {
|
|
2795
|
+
installStatusDisconnectObserved = true;
|
|
2796
|
+
finishedStatusSnapshotKey = undefined;
|
|
2797
|
+
finishedStatusSnapshotPolls = 0;
|
|
2798
|
+
}
|
|
2814
2799
|
shouldReconnect = true;
|
|
2815
2800
|
deviceInfo = undefined;
|
|
2816
2801
|
bleInstallLinkReady = false;
|
|
@@ -2835,7 +2820,6 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2835
2820
|
) {
|
|
2836
2821
|
throw error;
|
|
2837
2822
|
}
|
|
2838
|
-
recordBleInstallDisconnect(error);
|
|
2839
2823
|
shouldReconnect = true;
|
|
2840
2824
|
deviceInfo = undefined;
|
|
2841
2825
|
bleInstallLinkReady = false;
|
|
@@ -3170,7 +3154,6 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
3170
3154
|
}) {
|
|
3171
3155
|
this.protocolV2LastRuntimeProbeFeatures = undefined;
|
|
3172
3156
|
this.protocolV2InstallNeedsReconnect = false;
|
|
3173
|
-
this.protocolV2InstallDisconnectObserved = false;
|
|
3174
3157
|
this.protocolV2InstallTerminalSuccessObserved = false;
|
|
3175
3158
|
const commands = this.device.getCommands();
|
|
3176
3159
|
await commands.typedCall('DeviceFirmwareUpdateStage', 'Success', { targets });
|
|
@@ -3213,7 +3196,6 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
3213
3196
|
'[FirmwareUpdateV4] transport released while writing install request; continue status polling'
|
|
3214
3197
|
);
|
|
3215
3198
|
this.protocolV2InstallNeedsReconnect = true;
|
|
3216
|
-
this.protocolV2InstallDisconnectObserved = !isProtocolV2InstallResponseTimeout(error);
|
|
3217
3199
|
}
|
|
3218
3200
|
}
|
|
3219
3201
|
|
|
@@ -360,6 +360,7 @@ export default class EVMSignTypedData extends BaseMethod<EVMSignTypedDataParams>
|
|
|
360
360
|
|
|
361
361
|
const supportBiggerData =
|
|
362
362
|
DeviceModelToTypes.model_classic1s.includes(currentDeviceType) ||
|
|
363
|
+
DeviceModelToTypes.model_pro2.includes(currentDeviceType) ||
|
|
363
364
|
(DeviceModelToTypes.model_touch.includes(currentDeviceType) &&
|
|
364
365
|
semver.gte(currentVersion, supportBiggerDataVersion));
|
|
365
366
|
|