@onekeyfe/hd-core 1.2.0-alpha.102 → 1.2.0-alpha.104
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__/base64Data.test.ts +70 -0
- package/__tests__/deviceUploadNft.test.ts +33 -4
- package/__tests__/protocol-v2.test.ts +89 -25
- package/__tests__/resourceBase64Boundary.test.ts +48 -0
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/UploadPortfolio.d.ts +1 -1
- package/dist/api/UploadPortfolio.d.ts.map +1 -1
- package/dist/api/helpers/base64Data.d.ts +16 -0
- package/dist/api/helpers/base64Data.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceUploadNft.d.ts +2 -3
- package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts +2 -3
- package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts.map +1 -1
- package/dist/api/utils.d.ts.map +1 -1
- package/dist/index.d.ts +4 -12
- package/dist/index.js +157 -159
- package/dist/topLevelInject.d.ts.map +1 -1
- package/dist/types/api/protocolV2.d.ts +1 -1
- package/dist/types/api/protocolV2.d.ts.map +1 -1
- package/dist/utils/pro2Nft.d.ts +7 -0
- package/dist/utils/pro2Nft.d.ts.map +1 -1
- package/package.json +6 -4
- package/src/api/FirmwareUpdateV4.ts +8 -7
- package/src/api/UploadPortfolio.ts +9 -2
- package/src/api/helpers/base64Data.ts +85 -0
- package/src/api/protocol-v2/DeviceUploadNft.ts +56 -8
- package/src/api/protocol-v2/DeviceUploadWallpaper.ts +37 -18
- package/src/api/utils.ts +2 -5
- package/src/topLevelInject.ts +2 -4
- package/src/types/api/protocolV2.ts +1 -1
- package/src/utils/pro2Nft.ts +31 -8
- package/__tests__/bridgeBinaryPayload.test.ts +0 -173
- package/dist/utils/bridgeBinaryPayload.d.ts +0 -3
- package/dist/utils/bridgeBinaryPayload.d.ts.map +0 -1
- package/src/utils/bridgeBinaryPayload.ts +0 -137
package/dist/index.js
CHANGED
|
@@ -7,13 +7,14 @@ var sha256 = require('@noble/hashes/sha256');
|
|
|
7
7
|
var utils = require('@noble/hashes/utils');
|
|
8
8
|
var semver = require('semver');
|
|
9
9
|
var hdTransport = require('@onekeyfe/hd-transport');
|
|
10
|
-
var buffer = require('buffer');
|
|
11
10
|
var axios = require('axios');
|
|
12
11
|
var lodash = require('lodash');
|
|
13
12
|
var ByteBuffer = require('bytebuffer');
|
|
14
13
|
var blake2s = require('@noble/hashes/blake2s');
|
|
15
14
|
var BigNumber = require('bignumber.js');
|
|
16
15
|
var JSZip = require('jszip');
|
|
16
|
+
var buffer = require('buffer');
|
|
17
|
+
var jpegJs = require('jpeg-js');
|
|
17
18
|
var sha3 = require('@noble/hashes/sha3');
|
|
18
19
|
var blake2b = require('@noble/hashes/blake2b');
|
|
19
20
|
|
|
@@ -2219,132 +2220,14 @@ function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
|
|
|
2219
2220
|
}
|
|
2220
2221
|
}
|
|
2221
2222
|
|
|
2222
|
-
const BRIDGE_BINARY_PAYLOAD_MARKER = '__onekey_hd_bridge_binary_payload__';
|
|
2223
|
-
const BASE64_PATTERN = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
|
|
2224
|
-
const invalidBinaryPayload = (message) => hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, message);
|
|
2225
|
-
function isPlainObject(value) {
|
|
2226
|
-
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
2227
|
-
return false;
|
|
2228
|
-
const prototype = Object.getPrototypeOf(value);
|
|
2229
|
-
return prototype === Object.prototype || prototype === null;
|
|
2230
|
-
}
|
|
2231
|
-
function isArrayBufferValue(value) {
|
|
2232
|
-
return Boolean(typeof ArrayBuffer !== 'undefined' &&
|
|
2233
|
-
(value instanceof ArrayBuffer ||
|
|
2234
|
-
Object.prototype.toString.call(value) === '[object ArrayBuffer]'));
|
|
2235
|
-
}
|
|
2236
|
-
function isBlobValue(value) {
|
|
2237
|
-
return Boolean(typeof Blob !== 'undefined' &&
|
|
2238
|
-
(value instanceof Blob || Object.prototype.toString.call(value) === '[object Blob]') &&
|
|
2239
|
-
typeof value.arrayBuffer === 'function');
|
|
2240
|
-
}
|
|
2241
|
-
function readBinaryPayload(value) {
|
|
2242
|
-
if (!isPlainObject(value) || !(BRIDGE_BINARY_PAYLOAD_MARKER in value))
|
|
2243
|
-
return undefined;
|
|
2244
|
-
const payload = value;
|
|
2245
|
-
if (payload[BRIDGE_BINARY_PAYLOAD_MARKER] !== 1 ||
|
|
2246
|
-
(payload.type !== 'array-buffer' && payload.type !== 'uint8-array') ||
|
|
2247
|
-
typeof payload.data !== 'string') {
|
|
2248
|
-
throw invalidBinaryPayload('Invalid bridge binary payload');
|
|
2249
|
-
}
|
|
2250
|
-
return payload;
|
|
2251
|
-
}
|
|
2252
|
-
function bytesToPayload(bytes, type) {
|
|
2253
|
-
return {
|
|
2254
|
-
[BRIDGE_BINARY_PAYLOAD_MARKER]: 1,
|
|
2255
|
-
data: buffer.Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString('base64'),
|
|
2256
|
-
type,
|
|
2257
|
-
};
|
|
2258
|
-
}
|
|
2259
|
-
function payloadToBytes(payload) {
|
|
2260
|
-
if (payload.data.length % 4 !== 0 || !BASE64_PATTERN.test(payload.data)) {
|
|
2261
|
-
throw invalidBinaryPayload('Invalid bridge binary payload data');
|
|
2262
|
-
}
|
|
2263
|
-
const decoded = buffer.Buffer.from(payload.data, 'base64');
|
|
2264
|
-
if (decoded.toString('base64') !== payload.data) {
|
|
2265
|
-
throw invalidBinaryPayload('Invalid bridge binary payload data');
|
|
2266
|
-
}
|
|
2267
|
-
return Uint8Array.from(decoded);
|
|
2268
|
-
}
|
|
2269
|
-
function encodeValue(value, seen) {
|
|
2270
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2271
|
-
if (isArrayBufferValue(value)) {
|
|
2272
|
-
return bytesToPayload(new Uint8Array(value), 'array-buffer');
|
|
2273
|
-
}
|
|
2274
|
-
if (typeof ArrayBuffer !== 'undefined' && ArrayBuffer.isView(value)) {
|
|
2275
|
-
return bytesToPayload(new Uint8Array(value.buffer, value.byteOffset, value.byteLength), 'uint8-array');
|
|
2276
|
-
}
|
|
2277
|
-
if (isBlobValue(value)) {
|
|
2278
|
-
return bytesToPayload(new Uint8Array(yield value.arrayBuffer()), 'uint8-array');
|
|
2279
|
-
}
|
|
2280
|
-
const encodedPayload = readBinaryPayload(value);
|
|
2281
|
-
if (encodedPayload)
|
|
2282
|
-
return encodedPayload;
|
|
2283
|
-
if (Array.isArray(value)) {
|
|
2284
|
-
if (seen.has(value))
|
|
2285
|
-
throw invalidBinaryPayload('Circular bridge payload');
|
|
2286
|
-
seen.add(value);
|
|
2287
|
-
try {
|
|
2288
|
-
const encoded = [];
|
|
2289
|
-
for (const item of value) {
|
|
2290
|
-
encoded.push(yield encodeValue(item, seen));
|
|
2291
|
-
}
|
|
2292
|
-
return encoded.some((item, index) => item !== value[index]) ? encoded : value;
|
|
2293
|
-
}
|
|
2294
|
-
finally {
|
|
2295
|
-
seen.delete(value);
|
|
2296
|
-
}
|
|
2297
|
-
}
|
|
2298
|
-
if (!isPlainObject(value))
|
|
2299
|
-
return value;
|
|
2300
|
-
if (seen.has(value))
|
|
2301
|
-
throw invalidBinaryPayload('Circular bridge payload');
|
|
2302
|
-
seen.add(value);
|
|
2303
|
-
try {
|
|
2304
|
-
const entries = [];
|
|
2305
|
-
for (const [key, item] of Object.entries(value)) {
|
|
2306
|
-
entries.push([key, yield encodeValue(item, seen)]);
|
|
2307
|
-
}
|
|
2308
|
-
return entries.some(([key, item]) => item !== value[key]) ? Object.fromEntries(entries) : value;
|
|
2309
|
-
}
|
|
2310
|
-
finally {
|
|
2311
|
-
seen.delete(value);
|
|
2312
|
-
}
|
|
2313
|
-
});
|
|
2314
|
-
}
|
|
2315
|
-
function decodeValue(value) {
|
|
2316
|
-
const payload = readBinaryPayload(value);
|
|
2317
|
-
if (payload) {
|
|
2318
|
-
const bytes = payloadToBytes(payload);
|
|
2319
|
-
return payload.type === 'array-buffer' ? bytes.buffer : bytes;
|
|
2320
|
-
}
|
|
2321
|
-
if (Array.isArray(value)) {
|
|
2322
|
-
const decoded = value.map(decodeValue);
|
|
2323
|
-
return decoded.some((item, index) => item !== value[index]) ? decoded : value;
|
|
2324
|
-
}
|
|
2325
|
-
if (!isPlainObject(value))
|
|
2326
|
-
return value;
|
|
2327
|
-
const entries = Object.entries(value).map(([key, item]) => [key, decodeValue(item)]);
|
|
2328
|
-
return entries.some(([key, item]) => item !== value[key]) ? Object.fromEntries(entries) : value;
|
|
2329
|
-
}
|
|
2330
|
-
function encodeBridgeBinaryPayload(value) {
|
|
2331
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
2332
|
-
return encodeValue(value, new WeakSet());
|
|
2333
|
-
});
|
|
2334
|
-
}
|
|
2335
|
-
function decodeBridgeBinaryPayload(value) {
|
|
2336
|
-
return decodeValue(value);
|
|
2337
|
-
}
|
|
2338
|
-
|
|
2339
2223
|
const eventEmitter = new events.exports();
|
|
2340
2224
|
const topLevelInject = () => {
|
|
2341
2225
|
let lowLevelApi;
|
|
2342
|
-
const call = (params) =>
|
|
2226
|
+
const call = (params) => {
|
|
2343
2227
|
if (!lowLevelApi)
|
|
2344
2228
|
return Promise.resolve(undefined);
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
});
|
|
2229
|
+
return lowLevelApi.call(params);
|
|
2230
|
+
};
|
|
2348
2231
|
const protocolAwareCall = createProtocolAwareCall(call);
|
|
2349
2232
|
const api = Object.assign(Object.assign({ on: (type, fn) => {
|
|
2350
2233
|
eventEmitter.on(type, fn);
|
|
@@ -42841,18 +42724,14 @@ function getCompletePro2NftBasenames(childFiles) {
|
|
|
42841
42724
|
function utf8Length(value) {
|
|
42842
42725
|
return new TextEncoder().encode(value).byteLength;
|
|
42843
42726
|
}
|
|
42844
|
-
function
|
|
42845
|
-
|
|
42846
|
-
|
|
42727
|
+
function buildPro2NftBundleFromEncodedImages(options) {
|
|
42728
|
+
const { image, thumbnail, title, subtitle, timestampMs } = options;
|
|
42729
|
+
if (!(image instanceof Uint8Array) || image.byteLength === 0) {
|
|
42730
|
+
throw invalidParameter$1('Parameter [image] must contain encoded NFT image data.');
|
|
42847
42731
|
}
|
|
42848
|
-
if (!(
|
|
42849
|
-
throw invalidParameter$1(
|
|
42732
|
+
if (!(thumbnail instanceof Uint8Array) || thumbnail.byteLength === 0) {
|
|
42733
|
+
throw invalidParameter$1('Parameter [thumbnail] must contain encoded NFT thumbnail data.');
|
|
42850
42734
|
}
|
|
42851
|
-
}
|
|
42852
|
-
function buildPro2NftBundle(options) {
|
|
42853
|
-
const { image, thumbnail, title, subtitle, timestampMs } = options;
|
|
42854
|
-
assertImage('image', image, PRO2_NFT_IMAGE_WIDTH, PRO2_NFT_IMAGE_HEIGHT);
|
|
42855
|
-
assertImage('thumbnail', thumbnail, PRO2_NFT_THUMBNAIL_WIDTH, PRO2_NFT_THUMBNAIL_HEIGHT);
|
|
42856
42735
|
const titleLength = typeof title === 'string' ? utf8Length(title) : 0;
|
|
42857
42736
|
const subtitleLength = typeof subtitle === 'string' ? utf8Length(subtitle) : Number.POSITIVE_INFINITY;
|
|
42858
42737
|
if (titleLength < 1 || titleLength > 63) {
|
|
@@ -42864,17 +42743,15 @@ function buildPro2NftBundle(options) {
|
|
|
42864
42743
|
if (!Number.isSafeInteger(timestampMs) || timestampMs <= 0) {
|
|
42865
42744
|
throw invalidParameter$1('Parameter [timestampMs] must be a positive safe integer.');
|
|
42866
42745
|
}
|
|
42867
|
-
const encodedImage = encodePro2Image(Object.assign(Object.assign({}, image), { alphaMode: 'black-background' })).data;
|
|
42868
|
-
const encodedThumbnail = encodePro2Image(Object.assign(Object.assign({}, thumbnail), { alphaMode: 'black-background' })).data;
|
|
42869
42746
|
const metadata = new TextEncoder().encode(JSON.stringify({ title, subtitle }));
|
|
42870
42747
|
if (metadata.byteLength === 0 || metadata.byteLength > 512) {
|
|
42871
42748
|
throw invalidParameter$1('Pro2 NFT metadata must contain 1 to 512 UTF-8 bytes.');
|
|
42872
42749
|
}
|
|
42873
|
-
const hash8 = utils.bytesToHex(blake2s.blake2s(
|
|
42750
|
+
const hash8 = utils.bytesToHex(blake2s.blake2s(image)).slice(0, 8);
|
|
42874
42751
|
return {
|
|
42875
42752
|
basename: `nft-${hash8}-${timestampMs}`,
|
|
42876
|
-
image
|
|
42877
|
-
thumbnail
|
|
42753
|
+
image,
|
|
42754
|
+
thumbnail,
|
|
42878
42755
|
metadata,
|
|
42879
42756
|
};
|
|
42880
42757
|
}
|
|
@@ -53942,8 +53819,9 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
53942
53819
|
}
|
|
53943
53820
|
protocolV2StartFirmwareUpdate({ targets, }) {
|
|
53944
53821
|
return __awaiter(this, void 0, void 0, function* () {
|
|
53945
|
-
const
|
|
53946
|
-
|
|
53822
|
+
const startUpdate = () => this.device
|
|
53823
|
+
.getCommands()
|
|
53824
|
+
.typedCall('DeviceFirmwareUpdateRequest', 'Success', { targets }, { timeoutMs: PROTOCOL_V2_START_UPDATE_TIMEOUT });
|
|
53947
53825
|
let response;
|
|
53948
53826
|
try {
|
|
53949
53827
|
response = yield startUpdate();
|
|
@@ -54094,6 +53972,61 @@ class DeviceGetOnboardingStatus extends BaseMethod {
|
|
|
54094
53972
|
}
|
|
54095
53973
|
}
|
|
54096
53974
|
|
|
53975
|
+
const BASE64_PATTERN = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
|
|
53976
|
+
const JPEG_CONTAINER_OVERHEAD_BYTES = 64 * 1024;
|
|
53977
|
+
const JPEG_MAX_MEMORY_USAGE_IN_MB = 32;
|
|
53978
|
+
const JPEG_MAX_RESOLUTION_IN_MP = 1;
|
|
53979
|
+
function decodeCanonicalBase64({ value, parameterName, maxBytes, }) {
|
|
53980
|
+
if (typeof value !== 'string' || value.length === 0) {
|
|
53981
|
+
throw invalidParameter$1(`Parameter [${parameterName}] must be a non-empty Base64 string.`);
|
|
53982
|
+
}
|
|
53983
|
+
if (value.length > Math.ceil(maxBytes / 3) * 4) {
|
|
53984
|
+
throw invalidParameter$1(`Parameter [${parameterName}] exceeds the maximum supported size.`);
|
|
53985
|
+
}
|
|
53986
|
+
if (value.length % 4 !== 0 || !BASE64_PATTERN.test(value)) {
|
|
53987
|
+
throw invalidParameter$1(`Parameter [${parameterName}] must use canonical Base64 encoding.`);
|
|
53988
|
+
}
|
|
53989
|
+
const decoded = buffer.Buffer.from(value, 'base64');
|
|
53990
|
+
if (decoded.byteLength === 0 || decoded.byteLength > maxBytes) {
|
|
53991
|
+
throw invalidParameter$1(`Parameter [${parameterName}] exceeds the maximum supported size.`);
|
|
53992
|
+
}
|
|
53993
|
+
if (decoded.toString('base64') !== value) {
|
|
53994
|
+
throw invalidParameter$1(`Parameter [${parameterName}] must use canonical Base64 encoding.`);
|
|
53995
|
+
}
|
|
53996
|
+
return Uint8Array.from(decoded);
|
|
53997
|
+
}
|
|
53998
|
+
function decodeJpegBase64ToRgba({ jpegBase64, parameterName, expectedWidth, expectedHeight, }) {
|
|
53999
|
+
const jpegBytes = decodeCanonicalBase64({
|
|
54000
|
+
value: jpegBase64,
|
|
54001
|
+
parameterName,
|
|
54002
|
+
maxBytes: expectedWidth * expectedHeight * 8 + JPEG_CONTAINER_OVERHEAD_BYTES,
|
|
54003
|
+
});
|
|
54004
|
+
if (jpegBytes[0] !== 0xff || jpegBytes[1] !== 0xd8) {
|
|
54005
|
+
throw invalidParameter$1(`Parameter [${parameterName}] must contain a JPEG image.`);
|
|
54006
|
+
}
|
|
54007
|
+
let decoded;
|
|
54008
|
+
try {
|
|
54009
|
+
decoded = jpegJs.decode(jpegBytes, {
|
|
54010
|
+
useTArray: true,
|
|
54011
|
+
formatAsRGBA: true,
|
|
54012
|
+
tolerantDecoding: false,
|
|
54013
|
+
maxResolutionInMP: JPEG_MAX_RESOLUTION_IN_MP,
|
|
54014
|
+
maxMemoryUsageInMB: JPEG_MAX_MEMORY_USAGE_IN_MB,
|
|
54015
|
+
});
|
|
54016
|
+
}
|
|
54017
|
+
catch (_a) {
|
|
54018
|
+
throw invalidParameter$1(`Parameter [${parameterName}] must contain a valid JPEG image.`);
|
|
54019
|
+
}
|
|
54020
|
+
if (decoded.width !== expectedWidth || decoded.height !== expectedHeight) {
|
|
54021
|
+
throw invalidParameter$1(`Parameter [${parameterName}] must contain a ${expectedWidth}x${expectedHeight} JPEG image.`);
|
|
54022
|
+
}
|
|
54023
|
+
const expectedLength = expectedWidth * expectedHeight * 4;
|
|
54024
|
+
if (decoded.data.byteLength !== expectedLength) {
|
|
54025
|
+
throw invalidParameter$1(`Decoded parameter [${parameterName}] must contain ${expectedLength} RGBA bytes.`);
|
|
54026
|
+
}
|
|
54027
|
+
return decoded;
|
|
54028
|
+
}
|
|
54029
|
+
|
|
54097
54030
|
const Log$4 = getLogger(exports.LoggerNames.Core);
|
|
54098
54031
|
const MIN_FILE_CHUNK_SIZE = 64;
|
|
54099
54032
|
const FILE_TRANSFER_RATE_WINDOW_MS = 1000;
|
|
@@ -54370,6 +54303,9 @@ function writeProtocolV2File(options) {
|
|
|
54370
54303
|
|
|
54371
54304
|
const WALLPAPER_DIRECTORY = 'vol1:/wallpapers';
|
|
54372
54305
|
const SAFE_FILE_NAME = /^[A-Za-z0-9_-]+(?:\.bin)?$/;
|
|
54306
|
+
const DEVICE_SETTINGS_SET_MESSAGE_TYPE = 60412;
|
|
54307
|
+
const FILESYSTEM_FILE_WRITE_MESSAGE_TYPE$2 = 60805;
|
|
54308
|
+
const FILESYSTEM_DIR_MAKE_MESSAGE_TYPE = 60809;
|
|
54373
54309
|
function normalizeFileName(fileName, data) {
|
|
54374
54310
|
if (fileName !== undefined && (!fileName || !SAFE_FILE_NAME.test(fileName))) {
|
|
54375
54311
|
throw invalidParameter$1('Parameter [fileName] may only contain letters, numbers, underscores, hyphens and an optional .bin suffix.');
|
|
@@ -54388,26 +54324,40 @@ class DeviceUploadWallpaper extends BaseMethod {
|
|
|
54388
54324
|
return ['V2'];
|
|
54389
54325
|
}
|
|
54390
54326
|
init() {
|
|
54391
|
-
const {
|
|
54392
|
-
if (width !== PRO2_WALLPAPER_WIDTH || height !== PRO2_WALLPAPER_HEIGHT) {
|
|
54393
|
-
throw invalidParameter$1(`Pro2 wallpaper dimensions must be ${PRO2_WALLPAPER_WIDTH}x${PRO2_WALLPAPER_HEIGHT}.`);
|
|
54394
|
-
}
|
|
54395
|
-
if (!(rgba instanceof ArrayBuffer) && !ArrayBuffer.isView(rgba)) {
|
|
54396
|
-
throw invalidParameter$1('Parameter [rgba] must be an ArrayBuffer or Uint8Array.');
|
|
54397
|
-
}
|
|
54327
|
+
const { jpegBase64, fileName, chunkSize } = this.payload;
|
|
54398
54328
|
if (chunkSize !== undefined && (!Number.isInteger(chunkSize) || chunkSize <= 0)) {
|
|
54399
54329
|
throw invalidParameter$1('Parameter [chunkSize] must be a positive integer.');
|
|
54400
54330
|
}
|
|
54401
|
-
const
|
|
54402
|
-
|
|
54403
|
-
:
|
|
54404
|
-
|
|
54331
|
+
const decoded = decodeJpegBase64ToRgba({
|
|
54332
|
+
jpegBase64,
|
|
54333
|
+
parameterName: 'jpegBase64',
|
|
54334
|
+
expectedWidth: PRO2_WALLPAPER_WIDTH,
|
|
54335
|
+
expectedHeight: PRO2_WALLPAPER_HEIGHT,
|
|
54336
|
+
});
|
|
54337
|
+
this.encoded = encodePro2Wallpaper({
|
|
54338
|
+
width: PRO2_WALLPAPER_WIDTH,
|
|
54339
|
+
height: PRO2_WALLPAPER_HEIGHT,
|
|
54340
|
+
rgba: decoded.data,
|
|
54341
|
+
});
|
|
54405
54342
|
this.path = `${WALLPAPER_DIRECTORY}/${normalizeFileName(fileName, this.encoded.data)}`;
|
|
54406
|
-
this.params = {
|
|
54343
|
+
this.params = { jpegBase64, fileName, chunkSize };
|
|
54407
54344
|
this.unlockPolicy = 'none';
|
|
54408
54345
|
this.skipForceUpdateCheck = true;
|
|
54409
54346
|
this.useDevicePassphraseState = false;
|
|
54410
54347
|
}
|
|
54348
|
+
assertCapabilities() {
|
|
54349
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
54350
|
+
const protocolInfo = yield this.device.ensureProtocolV2RuntimeContext();
|
|
54351
|
+
const requiredMessageTypes = [
|
|
54352
|
+
DEVICE_SETTINGS_SET_MESSAGE_TYPE,
|
|
54353
|
+
FILESYSTEM_FILE_WRITE_MESSAGE_TYPE$2,
|
|
54354
|
+
FILESYSTEM_DIR_MAKE_MESSAGE_TYPE,
|
|
54355
|
+
];
|
|
54356
|
+
if (requiredMessageTypes.some(messageType => !supportsProtocolV2Message(protocolInfo, messageType))) {
|
|
54357
|
+
throw hdShared.createDeviceNotSupportMethodError(this.name, this.device.getCurrentFirmwareType());
|
|
54358
|
+
}
|
|
54359
|
+
});
|
|
54360
|
+
}
|
|
54411
54361
|
ensureDirectory() {
|
|
54412
54362
|
return __awaiter(this, void 0, void 0, function* () {
|
|
54413
54363
|
if (this.directoryReady)
|
|
@@ -54457,6 +54407,7 @@ class DeviceUploadWallpaper extends BaseMethod {
|
|
|
54457
54407
|
const { encoded } = this;
|
|
54458
54408
|
if (!encoded)
|
|
54459
54409
|
throw invalidParameter$1('Wallpaper data has not been initialized.');
|
|
54410
|
+
yield this.assertCapabilities();
|
|
54460
54411
|
yield this.ensureDirectory();
|
|
54461
54412
|
yield this.upload();
|
|
54462
54413
|
const response = yield this.device.commands.typedCall('DeviceSettingsSet', 'Success', {
|
|
@@ -54481,7 +54432,7 @@ class DeviceUploadNft extends BaseMethod {
|
|
|
54481
54432
|
return ['V2'];
|
|
54482
54433
|
}
|
|
54483
54434
|
init() {
|
|
54484
|
-
const {
|
|
54435
|
+
const { imageJpegBase64, thumbnailJpegBase64, title, subtitle, timestampMs = Date.now(), chunkSize = PRO2_NFT_DEFAULT_CHUNK_SIZE, paceMs = PRO2_NFT_DEFAULT_PACE_MS, timeoutMs = PRO2_NFT_DEFAULT_TIMEOUT_MS, } = this.payload;
|
|
54485
54436
|
if (!Number.isInteger(chunkSize) ||
|
|
54486
54437
|
chunkSize < PRO2_NFT_MIN_CHUNK_SIZE ||
|
|
54487
54438
|
chunkSize > PRO2_NFT_MAX_CHUNK_SIZE) {
|
|
@@ -54493,8 +54444,51 @@ class DeviceUploadNft extends BaseMethod {
|
|
|
54493
54444
|
if (!Number.isInteger(timeoutMs) || timeoutMs <= 0) {
|
|
54494
54445
|
throw invalidParameter$1('Parameter [timeoutMs] must be a positive integer.');
|
|
54495
54446
|
}
|
|
54496
|
-
|
|
54497
|
-
|
|
54447
|
+
const encodedImage = (() => {
|
|
54448
|
+
const decoded = decodeJpegBase64ToRgba({
|
|
54449
|
+
jpegBase64: imageJpegBase64,
|
|
54450
|
+
parameterName: 'imageJpegBase64',
|
|
54451
|
+
expectedWidth: PRO2_NFT_IMAGE_WIDTH,
|
|
54452
|
+
expectedHeight: PRO2_NFT_IMAGE_HEIGHT,
|
|
54453
|
+
});
|
|
54454
|
+
return encodePro2Image({
|
|
54455
|
+
width: PRO2_NFT_IMAGE_WIDTH,
|
|
54456
|
+
height: PRO2_NFT_IMAGE_HEIGHT,
|
|
54457
|
+
rgba: decoded.data,
|
|
54458
|
+
alphaMode: 'black-background',
|
|
54459
|
+
}).data;
|
|
54460
|
+
})();
|
|
54461
|
+
const encodedThumbnail = (() => {
|
|
54462
|
+
const decoded = decodeJpegBase64ToRgba({
|
|
54463
|
+
jpegBase64: thumbnailJpegBase64,
|
|
54464
|
+
parameterName: 'thumbnailJpegBase64',
|
|
54465
|
+
expectedWidth: PRO2_NFT_THUMBNAIL_WIDTH,
|
|
54466
|
+
expectedHeight: PRO2_NFT_THUMBNAIL_HEIGHT,
|
|
54467
|
+
});
|
|
54468
|
+
return encodePro2Image({
|
|
54469
|
+
width: PRO2_NFT_THUMBNAIL_WIDTH,
|
|
54470
|
+
height: PRO2_NFT_THUMBNAIL_HEIGHT,
|
|
54471
|
+
rgba: decoded.data,
|
|
54472
|
+
alphaMode: 'black-background',
|
|
54473
|
+
}).data;
|
|
54474
|
+
})();
|
|
54475
|
+
this.bundle = buildPro2NftBundleFromEncodedImages({
|
|
54476
|
+
image: encodedImage,
|
|
54477
|
+
thumbnail: encodedThumbnail,
|
|
54478
|
+
title,
|
|
54479
|
+
subtitle,
|
|
54480
|
+
timestampMs,
|
|
54481
|
+
});
|
|
54482
|
+
this.params = {
|
|
54483
|
+
imageJpegBase64,
|
|
54484
|
+
thumbnailJpegBase64,
|
|
54485
|
+
title,
|
|
54486
|
+
subtitle,
|
|
54487
|
+
timestampMs,
|
|
54488
|
+
chunkSize,
|
|
54489
|
+
paceMs,
|
|
54490
|
+
timeoutMs,
|
|
54491
|
+
};
|
|
54498
54492
|
this.unlockPolicy = 'none';
|
|
54499
54493
|
this.skipForceUpdateCheck = true;
|
|
54500
54494
|
this.useDevicePassphraseState = false;
|
|
@@ -54637,11 +54631,17 @@ class FileWrite extends BaseMethod {
|
|
|
54637
54631
|
|
|
54638
54632
|
const PORTFOLIO_PENDING_PATH = 'vol1:/portfolio/portfolio.okpkg.pending';
|
|
54639
54633
|
const PORTFOLIO_CHUNK_SIZE = 2048;
|
|
54634
|
+
const PORTFOLIO_PACKAGE_MAX_BYTES = 128 * 1024;
|
|
54640
54635
|
const FILESYSTEM_FILE_WRITE_MESSAGE_TYPE = 60805;
|
|
54641
54636
|
const PORTFOLIO_UPDATE_MESSAGE_TYPE = 61400;
|
|
54642
54637
|
class UploadPortfolio extends FileWrite {
|
|
54643
54638
|
init() {
|
|
54644
|
-
const {
|
|
54639
|
+
const { packageBase64, timeoutMs } = this.payload;
|
|
54640
|
+
const packageBytes = decodeCanonicalBase64({
|
|
54641
|
+
value: packageBase64,
|
|
54642
|
+
parameterName: 'packageBase64',
|
|
54643
|
+
maxBytes: PORTFOLIO_PACKAGE_MAX_BYTES,
|
|
54644
|
+
});
|
|
54645
54645
|
this.payload = Object.assign(Object.assign({}, this.payload), { path: PORTFOLIO_PENDING_PATH, offset: 0, data: packageBytes, chunkSize: PORTFOLIO_CHUNK_SIZE, overwrite: true, append: false, emitProgress: false, timeoutMs });
|
|
54646
54646
|
super.init();
|
|
54647
54647
|
this.unlockPolicy = 'none';
|
|
@@ -64541,15 +64541,13 @@ var ApiMethods = /*#__PURE__*/Object.freeze({
|
|
|
64541
64541
|
|
|
64542
64542
|
const publicMethodRegistry = ApiMethods;
|
|
64543
64543
|
function findMethod(message) {
|
|
64544
|
-
const
|
|
64545
|
-
const normalizedMessage = payload === message.payload ? message : Object.assign(Object.assign({}, message), { payload });
|
|
64546
|
-
const { method } = payload;
|
|
64544
|
+
const { method } = message.payload;
|
|
64547
64545
|
if (typeof method !== 'string') {
|
|
64548
64546
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, 'Method is not set');
|
|
64549
64547
|
}
|
|
64550
64548
|
const MethodConstructor = publicMethodRegistry[method];
|
|
64551
64549
|
if (MethodConstructor) {
|
|
64552
|
-
return new MethodConstructor(
|
|
64550
|
+
return new MethodConstructor(message);
|
|
64553
64551
|
}
|
|
64554
64552
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, `Method ${method} is not set`);
|
|
64555
64553
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"topLevelInject.d.ts","sourceRoot":"","sources":["../src/topLevelInject.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"topLevelInject.d.ts","sourceRoot":"","sources":["../src/topLevelInject.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAG3C,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACtB,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;CACvB;AAID,eAAO,MAAM,cAAc,eAoD1B,CAAC"}
|
|
@@ -24,7 +24,7 @@ export declare function deviceGetOnboardingStatus(connectId: string, params?: Co
|
|
|
24
24
|
export declare function deviceUploadWallpaper(connectId: string, params: CommonParams & DeviceUploadWallpaperParams): Response<DeviceUploadWallpaperResponse>;
|
|
25
25
|
export declare function deviceUploadNft(connectId: string, params: CommonParams & DeviceUploadNftParams): Response<DeviceUploadNftResponse>;
|
|
26
26
|
export declare function uploadPortfolio(connectId: string, params: {
|
|
27
|
-
|
|
27
|
+
packageBase64: string;
|
|
28
28
|
timeoutMs?: number | string;
|
|
29
29
|
}): Response<FileInfo & {
|
|
30
30
|
portfolioUpdated: true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocolV2.d.ts","sourceRoot":"","sources":["../../../src/types/api/protocolV2.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,KAAK,EACV,2BAA2B,EAC3B,6BAA6B,EAC9B,MAAM,6CAA6C,CAAC;AACrD,OAAO,KAAK,EACV,qBAAqB,EACrB,uBAAuB,EACxB,MAAM,uCAAuC,CAAC;AAG/C,YAAY,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACzF,YAAY,EACV,2BAA2B,EAC3B,6BAA6B,GAC9B,MAAM,6CAA6C,CAAC;AACrD,YAAY,EACV,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,uCAAuC,CAAC;AAI/C,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAIF,MAAM,MAAM,wBAAwB,GAAG,YAAY,GAAG;IAEpD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,kBAAkB,CACxC,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,wBAAwB,GAChC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAErB,MAAM,CAAC,OAAO,UAAU,YAAY,CAClC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,GAAG,kBAAkB,GACxC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAErB,MAAM,CAAC,OAAO,UAAU,yBAAyB,CAC/C,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,YAAY,GACpB,QAAQ,CAAC,gBAAgB,CAAC,CAAC;AAE9B,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAC3C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,GAAG,2BAA2B,GACjD,QAAQ,CAAC,6BAA6B,CAAC,CAAC;AAE3C,MAAM,CAAC,OAAO,UAAU,eAAe,CACrC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,GAAG,qBAAqB,GAC3C,QAAQ,CAAC,uBAAuB,CAAC,CAAC;AAErC,MAAM,CAAC,OAAO,UAAU,eAAe,CACrC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE;IACN,
|
|
1
|
+
{"version":3,"file":"protocolV2.d.ts","sourceRoot":"","sources":["../../../src/types/api/protocolV2.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,KAAK,EACV,2BAA2B,EAC3B,6BAA6B,EAC9B,MAAM,6CAA6C,CAAC;AACrD,OAAO,KAAK,EACV,qBAAqB,EACrB,uBAAuB,EACxB,MAAM,uCAAuC,CAAC;AAG/C,YAAY,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACzF,YAAY,EACV,2BAA2B,EAC3B,6BAA6B,GAC9B,MAAM,6CAA6C,CAAC;AACrD,YAAY,EACV,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,uCAAuC,CAAC;AAI/C,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAIF,MAAM,MAAM,wBAAwB,GAAG,YAAY,GAAG;IAEpD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,kBAAkB,CACxC,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,wBAAwB,GAChC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAErB,MAAM,CAAC,OAAO,UAAU,YAAY,CAClC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,GAAG,kBAAkB,GACxC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAErB,MAAM,CAAC,OAAO,UAAU,yBAAyB,CAC/C,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,YAAY,GACpB,QAAQ,CAAC,gBAAgB,CAAC,CAAC;AAE9B,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAC3C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,GAAG,2BAA2B,GACjD,QAAQ,CAAC,6BAA6B,CAAC,CAAC;AAE3C,MAAM,CAAC,OAAO,UAAU,eAAe,CACrC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,GAAG,qBAAqB,GAC3C,QAAQ,CAAC,uBAAuB,CAAC,CAAC;AAErC,MAAM,CAAC,OAAO,UAAU,eAAe,CACrC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE;IACN,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC7B,GACA,QAAQ,CAAC,QAAQ,GAAG;IAAE,gBAAgB,EAAE,IAAI,CAAA;CAAE,CAAC,CAAC"}
|
package/dist/utils/pro2Nft.d.ts
CHANGED
|
@@ -28,4 +28,11 @@ export declare function buildPro2NftBundle(options: {
|
|
|
28
28
|
subtitle: string;
|
|
29
29
|
timestampMs: number;
|
|
30
30
|
}): Pro2NftBundle;
|
|
31
|
+
export declare function buildPro2NftBundleFromEncodedImages(options: {
|
|
32
|
+
image: Uint8Array;
|
|
33
|
+
thumbnail: Uint8Array;
|
|
34
|
+
title: string;
|
|
35
|
+
subtitle: string;
|
|
36
|
+
timestampMs: number;
|
|
37
|
+
}): Pro2NftBundle;
|
|
31
38
|
//# sourceMappingURL=pro2Nft.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pro2Nft.d.ts","sourceRoot":"","sources":["../../src/utils/pro2Nft.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,oBAAoB,MAAM,CAAC;AACxC,eAAO,MAAM,qBAAqB,MAAM,CAAC;AACzC,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAC5C,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAC7C,eAAO,MAAM,kBAAkB,cAAc,CAAC;AAC9C,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAChD,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAC1C,eAAO,MAAM,2BAA2B,QAAS,CAAC;AAClD,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,eAAO,MAAM,uBAAuB,OAAO,CAAC;AAC5C,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,UAAU,GAAG,WAAW,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,UAAU,CAAC;IACtB,QAAQ,EAAE,UAAU,CAAC;CACtB,CAAC;AAiCF,wBAAgB,2BAA2B,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAiB5E;AAsBD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE;IAC1C,KAAK,EAAE,YAAY,CAAC;IACpB,SAAS,EAAE,YAAY,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,aAAa,
|
|
1
|
+
{"version":3,"file":"pro2Nft.d.ts","sourceRoot":"","sources":["../../src/utils/pro2Nft.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,oBAAoB,MAAM,CAAC;AACxC,eAAO,MAAM,qBAAqB,MAAM,CAAC;AACzC,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAC5C,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAC7C,eAAO,MAAM,kBAAkB,cAAc,CAAC;AAC9C,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAChD,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAC1C,eAAO,MAAM,2BAA2B,QAAS,CAAC;AAClD,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,eAAO,MAAM,uBAAuB,OAAO,CAAC;AAC5C,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,UAAU,GAAG,WAAW,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,UAAU,CAAC;IACtB,QAAQ,EAAE,UAAU,CAAC;CACtB,CAAC;AAiCF,wBAAgB,2BAA2B,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAiB5E;AAsBD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE;IAC1C,KAAK,EAAE,YAAY,CAAC;IACpB,SAAS,EAAE,YAAY,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,aAAa,CAgBhB;AAED,wBAAgB,mCAAmC,CAAC,OAAO,EAAE;IAC3D,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,UAAU,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,aAAa,CAiChB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-core",
|
|
3
|
-
"version": "1.2.0-alpha.
|
|
3
|
+
"version": "1.2.0-alpha.104",
|
|
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,11 +25,13 @@
|
|
|
25
25
|
"url": "https://github.com/OneKeyHQ/hardware-js-sdk/issues"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@onekeyfe/hd-shared": "1.2.0-alpha.
|
|
29
|
-
"@onekeyfe/hd-transport": "1.2.0-alpha.
|
|
28
|
+
"@onekeyfe/hd-shared": "1.2.0-alpha.104",
|
|
29
|
+
"@onekeyfe/hd-transport": "1.2.0-alpha.104",
|
|
30
30
|
"axios": "1.15.2",
|
|
31
31
|
"bignumber.js": "^9.0.2",
|
|
32
|
+
"buffer": "^6.0.3",
|
|
32
33
|
"bytebuffer": "^5.0.1",
|
|
34
|
+
"jpeg-js": "^0.4.4",
|
|
33
35
|
"jszip": "^3.10.1",
|
|
34
36
|
"parse-uri": "^1.0.7",
|
|
35
37
|
"semver": "^7.3.7"
|
|
@@ -44,5 +46,5 @@
|
|
|
44
46
|
"@types/w3c-web-usb": "^1.0.10",
|
|
45
47
|
"@types/web-bluetooth": "^0.0.21"
|
|
46
48
|
},
|
|
47
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "32d75f15aadfa59e4f02f1acb24dc6e5aada94c8"
|
|
48
50
|
}
|
|
@@ -3068,14 +3068,15 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
3068
3068
|
}: {
|
|
3069
3069
|
targets: Array<{ target_id: number; path: string }>;
|
|
3070
3070
|
}) {
|
|
3071
|
-
const commands = this.device.getCommands();
|
|
3072
3071
|
const startUpdate = () =>
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3072
|
+
this.device
|
|
3073
|
+
.getCommands()
|
|
3074
|
+
.typedCall(
|
|
3075
|
+
'DeviceFirmwareUpdateRequest',
|
|
3076
|
+
'Success',
|
|
3077
|
+
{ targets },
|
|
3078
|
+
{ timeoutMs: PROTOCOL_V2_START_UPDATE_TIMEOUT }
|
|
3079
|
+
);
|
|
3079
3080
|
let response: ProtocolV2FirmwareUpdateStartResponse;
|
|
3080
3081
|
try {
|
|
3081
3082
|
response = await startUpdate();
|
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
import { createDeviceNotSupportMethodError } from '@onekeyfe/hd-shared';
|
|
2
2
|
|
|
3
3
|
import { supportsProtocolV2Message } from '../protocols/protocol-v2/features';
|
|
4
|
+
import { decodeCanonicalBase64 } from './helpers/base64Data';
|
|
4
5
|
import FileWrite from './FileWrite';
|
|
5
6
|
|
|
6
7
|
export type UploadPortfolioParams = {
|
|
7
|
-
|
|
8
|
+
packageBase64: string;
|
|
8
9
|
timeoutMs?: number | string;
|
|
9
10
|
};
|
|
10
11
|
|
|
11
12
|
const PORTFOLIO_PENDING_PATH = 'vol1:/portfolio/portfolio.okpkg.pending';
|
|
12
13
|
const PORTFOLIO_CHUNK_SIZE = 2048;
|
|
14
|
+
const PORTFOLIO_PACKAGE_MAX_BYTES = 128 * 1024;
|
|
13
15
|
const FILESYSTEM_FILE_WRITE_MESSAGE_TYPE = 60805;
|
|
14
16
|
const PORTFOLIO_UPDATE_MESSAGE_TYPE = 61400;
|
|
15
17
|
|
|
16
18
|
export default class UploadPortfolio extends FileWrite {
|
|
17
19
|
init() {
|
|
18
|
-
const {
|
|
20
|
+
const { packageBase64, timeoutMs } = this.payload as UploadPortfolioParams;
|
|
21
|
+
const packageBytes = decodeCanonicalBase64({
|
|
22
|
+
value: packageBase64,
|
|
23
|
+
parameterName: 'packageBase64',
|
|
24
|
+
maxBytes: PORTFOLIO_PACKAGE_MAX_BYTES,
|
|
25
|
+
});
|
|
19
26
|
this.payload = {
|
|
20
27
|
...this.payload,
|
|
21
28
|
path: PORTFOLIO_PENDING_PATH,
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { Buffer } from 'buffer';
|
|
2
|
+
import { decode as decodeJpeg } from 'jpeg-js';
|
|
3
|
+
|
|
4
|
+
import { invalidParameter } from './filesystemValidation';
|
|
5
|
+
|
|
6
|
+
const BASE64_PATTERN = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
|
|
7
|
+
const JPEG_CONTAINER_OVERHEAD_BYTES = 64 * 1024;
|
|
8
|
+
const JPEG_MAX_MEMORY_USAGE_IN_MB = 32;
|
|
9
|
+
const JPEG_MAX_RESOLUTION_IN_MP = 1;
|
|
10
|
+
|
|
11
|
+
export function decodeCanonicalBase64({
|
|
12
|
+
value,
|
|
13
|
+
parameterName,
|
|
14
|
+
maxBytes,
|
|
15
|
+
}: {
|
|
16
|
+
value: unknown;
|
|
17
|
+
parameterName: string;
|
|
18
|
+
maxBytes: number;
|
|
19
|
+
}): Uint8Array {
|
|
20
|
+
if (typeof value !== 'string' || value.length === 0) {
|
|
21
|
+
throw invalidParameter(`Parameter [${parameterName}] must be a non-empty Base64 string.`);
|
|
22
|
+
}
|
|
23
|
+
if (value.length > Math.ceil(maxBytes / 3) * 4) {
|
|
24
|
+
throw invalidParameter(`Parameter [${parameterName}] exceeds the maximum supported size.`);
|
|
25
|
+
}
|
|
26
|
+
if (value.length % 4 !== 0 || !BASE64_PATTERN.test(value)) {
|
|
27
|
+
throw invalidParameter(`Parameter [${parameterName}] must use canonical Base64 encoding.`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const decoded = Buffer.from(value, 'base64');
|
|
31
|
+
if (decoded.byteLength === 0 || decoded.byteLength > maxBytes) {
|
|
32
|
+
throw invalidParameter(`Parameter [${parameterName}] exceeds the maximum supported size.`);
|
|
33
|
+
}
|
|
34
|
+
if (decoded.toString('base64') !== value) {
|
|
35
|
+
throw invalidParameter(`Parameter [${parameterName}] must use canonical Base64 encoding.`);
|
|
36
|
+
}
|
|
37
|
+
return Uint8Array.from(decoded);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function decodeJpegBase64ToRgba({
|
|
41
|
+
jpegBase64,
|
|
42
|
+
parameterName,
|
|
43
|
+
expectedWidth,
|
|
44
|
+
expectedHeight,
|
|
45
|
+
}: {
|
|
46
|
+
jpegBase64: unknown;
|
|
47
|
+
parameterName: string;
|
|
48
|
+
expectedWidth: number;
|
|
49
|
+
expectedHeight: number;
|
|
50
|
+
}): { width: number; height: number; data: Uint8Array } {
|
|
51
|
+
const jpegBytes = decodeCanonicalBase64({
|
|
52
|
+
value: jpegBase64,
|
|
53
|
+
parameterName,
|
|
54
|
+
maxBytes: expectedWidth * expectedHeight * 8 + JPEG_CONTAINER_OVERHEAD_BYTES,
|
|
55
|
+
});
|
|
56
|
+
if (jpegBytes[0] !== 0xff || jpegBytes[1] !== 0xd8) {
|
|
57
|
+
throw invalidParameter(`Parameter [${parameterName}] must contain a JPEG image.`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
let decoded: { width: number; height: number; data: Uint8Array };
|
|
61
|
+
try {
|
|
62
|
+
decoded = decodeJpeg(jpegBytes, {
|
|
63
|
+
useTArray: true,
|
|
64
|
+
formatAsRGBA: true,
|
|
65
|
+
tolerantDecoding: false,
|
|
66
|
+
maxResolutionInMP: JPEG_MAX_RESOLUTION_IN_MP,
|
|
67
|
+
maxMemoryUsageInMB: JPEG_MAX_MEMORY_USAGE_IN_MB,
|
|
68
|
+
});
|
|
69
|
+
} catch {
|
|
70
|
+
throw invalidParameter(`Parameter [${parameterName}] must contain a valid JPEG image.`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (decoded.width !== expectedWidth || decoded.height !== expectedHeight) {
|
|
74
|
+
throw invalidParameter(
|
|
75
|
+
`Parameter [${parameterName}] must contain a ${expectedWidth}x${expectedHeight} JPEG image.`
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
const expectedLength = expectedWidth * expectedHeight * 4;
|
|
79
|
+
if (decoded.data.byteLength !== expectedLength) {
|
|
80
|
+
throw invalidParameter(
|
|
81
|
+
`Decoded parameter [${parameterName}] must contain ${expectedLength} RGBA bytes.`
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
return decoded;
|
|
85
|
+
}
|