@onekeyfe/hd-core 1.2.0-alpha.36 → 1.2.0-alpha.39
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 +5 -1
- package/__tests__/deviceUploadNft.test.ts +187 -0
- package/__tests__/homescreen.test.ts +41 -1
- package/__tests__/logBlockEvent.test.ts +1 -1
- package/__tests__/open-wallet-session.test.ts +161 -44
- package/__tests__/pro2Nft.test.ts +108 -0
- package/__tests__/protocol-v2-unlock-policy.test.ts +86 -35
- package/__tests__/protocol-v2.test.ts +168 -444
- package/__tests__/public-pro2-api-boundary.test.ts +1 -0
- package/__tests__/uiProgressThrottle.test.ts +74 -0
- package/dist/api/BaseMethod.d.ts +3 -1
- package/dist/api/BaseMethod.d.ts.map +1 -1
- package/dist/api/OpenWalletSession.d.ts.map +1 -1
- package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +0 -1
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
- package/dist/api/helpers/protocolV2FileWrite.d.ts +2 -0
- package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceUploadNft.d.ts +30 -0
- package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/events/logBlockEvent.d.ts.map +1 -1
- package/dist/index.d.ts +34 -2
- package/dist/index.js +544 -496
- package/dist/inject.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/unlockPolicy.d.ts +1 -3
- package/dist/protocols/protocol-v2/unlockPolicy.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts +22 -0
- package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
- package/dist/types/api/index.d.ts +2 -1
- package/dist/types/api/index.d.ts.map +1 -1
- package/dist/types/api/protocolV2.d.ts +3 -0
- package/dist/types/api/protocolV2.d.ts.map +1 -1
- package/dist/utils/homescreen.d.ts +4 -0
- 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/pro2Nft.d.ts +29 -0
- package/dist/utils/pro2Nft.d.ts.map +1 -0
- package/dist/utils/pro2Wallpaper.d.ts +10 -0
- package/dist/utils/pro2Wallpaper.d.ts.map +1 -1
- package/dist/utils/uiProgressThrottle.d.ts +3 -0
- package/dist/utils/uiProgressThrottle.d.ts.map +1 -0
- package/package.json +4 -4
- package/src/api/BaseMethod.ts +7 -9
- package/src/api/OpenWalletSession.ts +37 -15
- package/src/api/allnetwork/AllNetworkGetAddressBase.ts +29 -30
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +0 -7
- package/src/api/helpers/protocolV2FileWrite.ts +11 -4
- package/src/api/index.ts +1 -0
- package/src/api/protocol-v2/DeviceUploadNft.ts +166 -0
- package/src/core/index.ts +83 -82
- package/src/data/messages/messages-protocol-v2.json +10 -15
- package/src/events/logBlockEvent.ts +1 -0
- package/src/inject.ts +1 -0
- package/src/protocols/protocol-v2/unlockPolicy.ts +1 -105
- package/src/protocols/protocol-v2/unlockPolicyRunner.ts +117 -0
- package/src/protocols/protocol-v2/walletSession.ts +18 -51
- package/src/types/api/index.ts +2 -0
- package/src/types/api/protocolV2.ts +13 -0
- package/src/utils/homescreen.ts +32 -6
- package/src/utils/index.ts +6 -1
- package/src/utils/pro2Nft.ts +91 -0
- package/src/utils/pro2Wallpaper.ts +35 -8
- package/src/utils/uiProgressThrottle.ts +63 -0
- package/dist/api/firmware/progressThrottle.d.ts +0 -3
- package/dist/api/firmware/progressThrottle.d.ts.map +0 -1
- package/dist/protocols/protocol-v2/lockedError.d.ts +0 -2
- package/dist/protocols/protocol-v2/lockedError.d.ts.map +0 -1
- package/dist/protocols/protocol-v2/unlockRetry.d.ts +0 -10
- package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +0 -1
- package/src/api/firmware/progressThrottle.ts +0 -44
- package/src/protocols/protocol-v2/lockedError.ts +0 -10
- package/src/protocols/protocol-v2/unlockRetry.ts +0 -131
package/dist/index.js
CHANGED
|
@@ -8,9 +8,9 @@ var hdShared = require('@onekeyfe/hd-shared');
|
|
|
8
8
|
var axios = require('axios');
|
|
9
9
|
var lodash = require('lodash');
|
|
10
10
|
var ByteBuffer = require('bytebuffer');
|
|
11
|
-
var BigNumber = require('bignumber.js');
|
|
12
|
-
var utils = require('@noble/hashes/utils');
|
|
13
11
|
var blake2s = require('@noble/hashes/blake2s');
|
|
12
|
+
var utils = require('@noble/hashes/utils');
|
|
13
|
+
var BigNumber = require('bignumber.js');
|
|
14
14
|
var sha256 = require('@noble/hashes/sha256');
|
|
15
15
|
var JSZip = require('jszip');
|
|
16
16
|
var sha3 = require('@noble/hashes/sha3');
|
|
@@ -146,6 +146,7 @@ const createCoreApi = (call) => ({
|
|
|
146
146
|
deviceReboot: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'deviceReboot' })),
|
|
147
147
|
deviceGetOnboardingStatus: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'deviceGetOnboardingStatus' })),
|
|
148
148
|
deviceUploadWallpaper: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'deviceUploadWallpaper' })),
|
|
149
|
+
deviceUploadNft: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'deviceUploadNft' })),
|
|
149
150
|
uploadPortfolio: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'uploadPortfolio' })),
|
|
150
151
|
deviceRecovery: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'deviceRecovery' })),
|
|
151
152
|
deviceReset: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'deviceReset' })),
|
|
@@ -26271,6 +26272,7 @@ var nested = {
|
|
|
26271
26272
|
MessageType_DeviceSessionAskPin: 61202,
|
|
26272
26273
|
MessageType_DeviceSessionAskPassphrase: 61203,
|
|
26273
26274
|
MessageType_PortfolioUpdate: 61400,
|
|
26275
|
+
MessageType_NftUpdate: 61500,
|
|
26274
26276
|
MessageType_OnboardingStatusGet: 61600,
|
|
26275
26277
|
MessageType_OnboardingStatus: 61601
|
|
26276
26278
|
},
|
|
@@ -38049,26 +38051,11 @@ var nested = {
|
|
|
38049
38051
|
DeviceSessionError_Busy: 5
|
|
38050
38052
|
}
|
|
38051
38053
|
},
|
|
38052
|
-
DeviceSessionSeedDomain: {
|
|
38053
|
-
values: {
|
|
38054
|
-
SeedDomain_Standard: 1,
|
|
38055
|
-
SeedDomain_Cardano: 2
|
|
38056
|
-
}
|
|
38057
|
-
},
|
|
38058
38054
|
DeviceSessionGet: {
|
|
38059
38055
|
fields: {
|
|
38060
38056
|
session_id: {
|
|
38061
38057
|
type: "bytes",
|
|
38062
38058
|
id: 1
|
|
38063
|
-
},
|
|
38064
|
-
btc_test_address: {
|
|
38065
|
-
type: "string",
|
|
38066
|
-
id: 2
|
|
38067
|
-
},
|
|
38068
|
-
seed_domains: {
|
|
38069
|
-
rule: "repeated",
|
|
38070
|
-
type: "DeviceSessionSeedDomain",
|
|
38071
|
-
id: 3
|
|
38072
38059
|
}
|
|
38073
38060
|
}
|
|
38074
38061
|
},
|
|
@@ -38404,6 +38391,15 @@ var nested = {
|
|
|
38404
38391
|
}
|
|
38405
38392
|
}
|
|
38406
38393
|
},
|
|
38394
|
+
NftUpdate: {
|
|
38395
|
+
fields: {
|
|
38396
|
+
file_name_no_ext: {
|
|
38397
|
+
rule: "required",
|
|
38398
|
+
type: "string",
|
|
38399
|
+
id: 1
|
|
38400
|
+
}
|
|
38401
|
+
}
|
|
38402
|
+
},
|
|
38407
38403
|
OnboardingStep: {
|
|
38408
38404
|
values: {
|
|
38409
38405
|
ONBOARDING_STEP_UNKNOWN: 0,
|
|
@@ -39982,6 +39978,7 @@ const LogBlockEvent = new Set([
|
|
|
39982
39978
|
]);
|
|
39983
39979
|
const LogLabelMethod = new Set([
|
|
39984
39980
|
'openWalletSession',
|
|
39981
|
+
'deviceUploadNft',
|
|
39985
39982
|
'deviceUploadWallpaper',
|
|
39986
39983
|
'uploadPortfolio',
|
|
39987
39984
|
'fileWrite',
|
|
@@ -40103,41 +40100,15 @@ function refreshProtocolV2DeviceStatus(device) {
|
|
|
40103
40100
|
return device.updateProtocolV2Status(status);
|
|
40104
40101
|
});
|
|
40105
40102
|
}
|
|
40106
|
-
function ensureProtocolV2WalletSessionUnlocked(device) {
|
|
40107
|
-
var _a, _b, _c;
|
|
40108
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
40109
|
-
if (!device.isProtocolV2() || ((_a = device.isBootloader) === null || _a === void 0 ? void 0 : _a.call(device)) || ((_b = device.isRomloader) === null || _b === void 0 ? void 0 : _b.call(device))) {
|
|
40110
|
-
return false;
|
|
40111
|
-
}
|
|
40112
|
-
yield refreshProtocolV2DeviceStatus(device);
|
|
40113
|
-
if (((_c = device.state) === null || _c === void 0 ? void 0 : _c.status.unlocked) !== false) {
|
|
40114
|
-
return false;
|
|
40115
|
-
}
|
|
40116
|
-
yield device.unlockDevice(hdTransport.DeviceSessionPinType.Main, {
|
|
40117
|
-
source: 'unlock-coordinator',
|
|
40118
|
-
reason: 'device-locked',
|
|
40119
|
-
deviceOnly: true,
|
|
40120
|
-
});
|
|
40121
|
-
return true;
|
|
40122
|
-
});
|
|
40123
|
-
}
|
|
40124
40103
|
const negotiateEventlessWalletSession = (device) => __awaiter(void 0, void 0, void 0, function* () {
|
|
40125
40104
|
yield device.ensureProtocolV2RuntimeContext();
|
|
40126
40105
|
});
|
|
40127
|
-
const getDeviceSession = (device, request
|
|
40128
|
-
const payload = deriveCardano === undefined
|
|
40129
|
-
? request
|
|
40130
|
-
: Object.assign(Object.assign({}, request), { seed_domains: [
|
|
40131
|
-
hdTransport.DeviceSessionSeedDomain.SeedDomain_Standard,
|
|
40132
|
-
...(deriveCardano ? [hdTransport.DeviceSessionSeedDomain.SeedDomain_Cardano] : []),
|
|
40133
|
-
] });
|
|
40134
|
-
return device.commands.typedCall('DeviceSessionGet', 'DeviceSession', payload);
|
|
40135
|
-
});
|
|
40106
|
+
const getDeviceSession = (device, request) => __awaiter(void 0, void 0, void 0, function* () { return device.commands.typedCall('DeviceSessionGet', 'DeviceSession', request); });
|
|
40136
40107
|
const askDevicePassphrase = (device, requestPayload) => __awaiter(void 0, void 0, void 0, function* () {
|
|
40137
40108
|
yield device.commands.typedCall('DeviceSessionAskPassphrase', 'Success', requestPayload);
|
|
40138
40109
|
yield refreshProtocolV2DeviceStatus(device);
|
|
40139
40110
|
});
|
|
40140
|
-
const selectDeviceSession = (device, expectedPassphraseState
|
|
40111
|
+
const selectDeviceSession = (device, expectedPassphraseState) => __awaiter(void 0, void 0, void 0, function* () {
|
|
40141
40112
|
var _a, _b, _c;
|
|
40142
40113
|
const existsAttachPinUser = ((_a = device.features) === null || _a === void 0 ? void 0 : _a.attachToPinEnabled) === true;
|
|
40143
40114
|
const metadata = Object.assign({ source: 'wallet-session-coordinator', reason: expectedPassphraseState ? 'session-recovery' : 'open-wallet' }, (expectedPassphraseState ? { expectedPassphraseState } : {}));
|
|
@@ -40170,18 +40141,18 @@ const selectDeviceSession = (device, expectedPassphraseState, deriveCardano) =>
|
|
|
40170
40141
|
emitUiEvent: false,
|
|
40171
40142
|
interaction: attachPinInteraction,
|
|
40172
40143
|
});
|
|
40173
|
-
return getDeviceSession(device, {}
|
|
40144
|
+
return getDeviceSession(device, {});
|
|
40174
40145
|
}
|
|
40175
40146
|
if (hasHostPassphrase) {
|
|
40176
40147
|
yield askDevicePassphrase(device, {
|
|
40177
40148
|
passphrase: hostPassphrase,
|
|
40178
40149
|
on_device: false,
|
|
40179
40150
|
});
|
|
40180
|
-
return getDeviceSession(device, {}
|
|
40151
|
+
return getDeviceSession(device, {});
|
|
40181
40152
|
}
|
|
40182
40153
|
device.emit(DEVICE.PASSPHRASE_ON_DEVICE, device, Object.assign(Object.assign({}, metadata), (passphraseInteraction ? { interaction: passphraseInteraction } : {})));
|
|
40183
40154
|
yield askDevicePassphrase(device, { on_device: true });
|
|
40184
|
-
return getDeviceSession(device, {}
|
|
40155
|
+
return getDeviceSession(device, {});
|
|
40185
40156
|
});
|
|
40186
40157
|
function getProtocolV2WalletSession(device, options) {
|
|
40187
40158
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
@@ -40253,8 +40224,7 @@ function getProtocolV2WalletSession(device, options) {
|
|
|
40253
40224
|
}
|
|
40254
40225
|
response = yield getDeviceSession(device, {
|
|
40255
40226
|
session_id: cachedStandardSession.sessionId,
|
|
40256
|
-
|
|
40257
|
-
}, options === null || options === void 0 ? void 0 : options.deriveCardano);
|
|
40227
|
+
});
|
|
40258
40228
|
resumed = true;
|
|
40259
40229
|
}
|
|
40260
40230
|
catch (error) {
|
|
@@ -40267,15 +40237,14 @@ function getProtocolV2WalletSession(device, options) {
|
|
|
40267
40237
|
}
|
|
40268
40238
|
if (!response) {
|
|
40269
40239
|
yield selectMainWallet();
|
|
40270
|
-
response = yield getDeviceSession(device, {}
|
|
40240
|
+
response = yield getDeviceSession(device, {});
|
|
40271
40241
|
}
|
|
40272
40242
|
}
|
|
40273
40243
|
else if (cachedSessionId && expectedPassphraseState) {
|
|
40274
40244
|
try {
|
|
40275
40245
|
response = yield getDeviceSession(device, {
|
|
40276
40246
|
session_id: cachedSessionId,
|
|
40277
|
-
|
|
40278
|
-
}, options === null || options === void 0 ? void 0 : options.deriveCardano);
|
|
40247
|
+
});
|
|
40279
40248
|
resumed = true;
|
|
40280
40249
|
}
|
|
40281
40250
|
catch (error) {
|
|
@@ -40288,7 +40257,7 @@ function getProtocolV2WalletSession(device, options) {
|
|
|
40288
40257
|
}
|
|
40289
40258
|
else if (expectedPassphraseState) {
|
|
40290
40259
|
try {
|
|
40291
|
-
response = yield getDeviceSession(device, {
|
|
40260
|
+
response = yield getDeviceSession(device, {});
|
|
40292
40261
|
}
|
|
40293
40262
|
catch (error) {
|
|
40294
40263
|
if ((options === null || options === void 0 ? void 0 : options.resumeOnly) || !isWalletSessionInvalidError(error)) {
|
|
@@ -40301,7 +40270,7 @@ function getProtocolV2WalletSession(device, options) {
|
|
|
40301
40270
|
device.clearInternalState();
|
|
40302
40271
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.WalletSessionInvalid);
|
|
40303
40272
|
}
|
|
40304
|
-
response = yield selectDeviceSession(device, expectedPassphraseState
|
|
40273
|
+
response = yield selectDeviceSession(device, expectedPassphraseState);
|
|
40305
40274
|
}
|
|
40306
40275
|
let { message } = response;
|
|
40307
40276
|
try {
|
|
@@ -40326,11 +40295,11 @@ function getProtocolV2WalletSession(device, options) {
|
|
|
40326
40295
|
if (options === null || options === void 0 ? void 0 : options.onlyMainPin) {
|
|
40327
40296
|
(_f = device.clearStandardInternalState) === null || _f === void 0 ? void 0 : _f.call(device);
|
|
40328
40297
|
yield selectMainWallet(true);
|
|
40329
|
-
response = yield getDeviceSession(device, {}
|
|
40298
|
+
response = yield getDeviceSession(device, {});
|
|
40330
40299
|
}
|
|
40331
40300
|
else {
|
|
40332
40301
|
device.clearInternalState();
|
|
40333
|
-
response = yield selectDeviceSession(device, expectedPassphraseState
|
|
40302
|
+
response = yield selectDeviceSession(device, expectedPassphraseState);
|
|
40334
40303
|
}
|
|
40335
40304
|
message = response.message;
|
|
40336
40305
|
try {
|
|
@@ -40372,15 +40341,6 @@ function getProtocolV2WalletSession(device, options) {
|
|
|
40372
40341
|
};
|
|
40373
40342
|
});
|
|
40374
40343
|
}
|
|
40375
|
-
function restoreProtocolV2WalletSession(device, expectedPassphraseState, deriveCardano) {
|
|
40376
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
40377
|
-
return getProtocolV2WalletSession(device, {
|
|
40378
|
-
expectedPassphraseState,
|
|
40379
|
-
resumeOnly: true,
|
|
40380
|
-
deriveCardano,
|
|
40381
|
-
});
|
|
40382
|
-
});
|
|
40383
|
-
}
|
|
40384
40344
|
|
|
40385
40345
|
const getSupportProtocolV1MessageSchema = (features) => {
|
|
40386
40346
|
var _a;
|
|
@@ -40980,7 +40940,8 @@ function asBytes(rgba) {
|
|
|
40980
40940
|
function align(value, boundary) {
|
|
40981
40941
|
return Math.ceil(value / boundary) * boundary;
|
|
40982
40942
|
}
|
|
40983
|
-
function
|
|
40943
|
+
function encodePro2Image(options) {
|
|
40944
|
+
var _a;
|
|
40984
40945
|
const { width, height } = options;
|
|
40985
40946
|
if (!Number.isInteger(width) || width <= 0 || width > 0xffff) {
|
|
40986
40947
|
throw invalidParameter$2('Wallpaper width must be an integer between 1 and 65535.');
|
|
@@ -40993,11 +40954,14 @@ function encodePro2Wallpaper(options) {
|
|
|
40993
40954
|
if (rgba.byteLength !== expectedLength) {
|
|
40994
40955
|
throw invalidParameter$2(`Wallpaper RGBA data length must be ${expectedLength} bytes, received ${rgba.byteLength}.`);
|
|
40995
40956
|
}
|
|
40957
|
+
const alphaMode = (_a = options.alphaMode) !== null && _a !== void 0 ? _a : 'preserve';
|
|
40996
40958
|
let hasTransparency = false;
|
|
40997
|
-
|
|
40998
|
-
|
|
40999
|
-
|
|
41000
|
-
|
|
40959
|
+
if (alphaMode === 'preserve') {
|
|
40960
|
+
for (let index = 3; index < rgba.length; index += 4) {
|
|
40961
|
+
if (rgba[index] !== 0xff) {
|
|
40962
|
+
hasTransparency = true;
|
|
40963
|
+
break;
|
|
40964
|
+
}
|
|
41001
40965
|
}
|
|
41002
40966
|
}
|
|
41003
40967
|
const colorFormat = hasTransparency ? 'RGB565A8' : 'RGB565';
|
|
@@ -41018,9 +40982,19 @@ function encodePro2Wallpaper(options) {
|
|
|
41018
40982
|
for (let x = 0; x < width; x += 1) {
|
|
41019
40983
|
const sourceOffset = (y * width + x) * 4;
|
|
41020
40984
|
const thresholdIndex = ((y & 7) << 3) + (x & 7);
|
|
41021
|
-
const
|
|
41022
|
-
const
|
|
41023
|
-
|
|
40985
|
+
const alpha = rgba[sourceOffset + 3];
|
|
40986
|
+
const redChannel = alphaMode === 'black-background'
|
|
40987
|
+
? Math.round((rgba[sourceOffset] * alpha) / 0xff)
|
|
40988
|
+
: rgba[sourceOffset];
|
|
40989
|
+
const greenChannel = alphaMode === 'black-background'
|
|
40990
|
+
? Math.round((rgba[sourceOffset + 1] * alpha) / 0xff)
|
|
40991
|
+
: rgba[sourceOffset + 1];
|
|
40992
|
+
const blueChannel = alphaMode === 'black-background'
|
|
40993
|
+
? Math.round((rgba[sourceOffset + 2] * alpha) / 0xff)
|
|
40994
|
+
: rgba[sourceOffset + 2];
|
|
40995
|
+
const red = Math.min(redChannel + RED_THRESHOLD[thresholdIndex], 0xff) & 0xf8;
|
|
40996
|
+
const green = Math.min(greenChannel + GREEN_THRESHOLD[thresholdIndex], 0xff) & 0xfc;
|
|
40997
|
+
const blue = Math.min(blueChannel + BLUE_THRESHOLD[thresholdIndex], 0xff) & 0xf8;
|
|
41024
40998
|
const rgb565 = ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);
|
|
41025
40999
|
const rgbOffset = 12 + y * stride + x * 2;
|
|
41026
41000
|
data[rgbOffset] = rgb565 & 0xff;
|
|
@@ -41032,6 +41006,148 @@ function encodePro2Wallpaper(options) {
|
|
|
41032
41006
|
}
|
|
41033
41007
|
return { data, colorFormat };
|
|
41034
41008
|
}
|
|
41009
|
+
function encodePro2Wallpaper(options) {
|
|
41010
|
+
return encodePro2Image(options);
|
|
41011
|
+
}
|
|
41012
|
+
|
|
41013
|
+
const invalidParameter$1 = (message) => hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, message);
|
|
41014
|
+
function validateNonEmptyString(value, name) {
|
|
41015
|
+
if (typeof value !== 'string' || value.trim().length === 0) {
|
|
41016
|
+
throw invalidParameter$1(`Parameter [${name}] is required and must be a non-empty string.`);
|
|
41017
|
+
}
|
|
41018
|
+
return value;
|
|
41019
|
+
}
|
|
41020
|
+
const PROTOCOL_V2_FILESYSTEM_VOLUMES = new Set(['vol0', 'vol1']);
|
|
41021
|
+
const MAX_PROTOCOL_V2_FILESYSTEM_PATH_BYTES = 127;
|
|
41022
|
+
function getUtf8ByteLength$1(value) {
|
|
41023
|
+
return Array.from(value).reduce((length, character) => {
|
|
41024
|
+
var _a;
|
|
41025
|
+
const codePoint = (_a = character.codePointAt(0)) !== null && _a !== void 0 ? _a : 0;
|
|
41026
|
+
if (codePoint <= 0x7f)
|
|
41027
|
+
return length + 1;
|
|
41028
|
+
if (codePoint <= 0x7ff)
|
|
41029
|
+
return length + 2;
|
|
41030
|
+
if (codePoint <= 0xffff)
|
|
41031
|
+
return length + 3;
|
|
41032
|
+
return length + 4;
|
|
41033
|
+
}, 0);
|
|
41034
|
+
}
|
|
41035
|
+
function validateProtocolV2FilesystemPath(value, name, options = {}) {
|
|
41036
|
+
const rawPath = validateNonEmptyString(value, name).trim();
|
|
41037
|
+
const containsUnsupportedCharacter = Array.from(rawPath).some(character => {
|
|
41038
|
+
const codePoint = character.charCodeAt(0);
|
|
41039
|
+
return codePoint <= 0x1f || codePoint === 0x7f || character === '\\';
|
|
41040
|
+
});
|
|
41041
|
+
if (containsUnsupportedCharacter) {
|
|
41042
|
+
throw invalidParameter$1(`Parameter [${name}] contains unsupported path characters.`);
|
|
41043
|
+
}
|
|
41044
|
+
const match = /^([a-zA-Z0-9]+):(.*)$/.exec(rawPath);
|
|
41045
|
+
if (!match) {
|
|
41046
|
+
throw invalidParameter$1(`Parameter [${name}] must use a supported Protocol V2 filesystem volume.`);
|
|
41047
|
+
}
|
|
41048
|
+
const volume = match[1].toLowerCase();
|
|
41049
|
+
if (!PROTOCOL_V2_FILESYSTEM_VOLUMES.has(volume)) {
|
|
41050
|
+
throw invalidParameter$1(`Parameter [${name}] uses an unsupported filesystem volume.`);
|
|
41051
|
+
}
|
|
41052
|
+
const rawSuffix = match[2];
|
|
41053
|
+
if (rawSuffix.length === 0) {
|
|
41054
|
+
if (options.allowVolumeRoot)
|
|
41055
|
+
return `${volume}:`;
|
|
41056
|
+
throw invalidParameter$1(`Parameter [${name}] must identify a filesystem entry.`);
|
|
41057
|
+
}
|
|
41058
|
+
const suffix = rawSuffix.startsWith('/') ? rawSuffix : `/${rawSuffix}`;
|
|
41059
|
+
const segments = suffix.slice(1).split('/');
|
|
41060
|
+
if (segments.some(segment => segment.length === 0 || segment === '.' || segment === '..')) {
|
|
41061
|
+
throw invalidParameter$1(`Parameter [${name}] contains an invalid path segment.`);
|
|
41062
|
+
}
|
|
41063
|
+
const canonicalPath = `${volume}:${rawSuffix.startsWith('/') ? '/' : ''}${segments.join('/')}`;
|
|
41064
|
+
if (getUtf8ByteLength$1(canonicalPath) > MAX_PROTOCOL_V2_FILESYSTEM_PATH_BYTES) {
|
|
41065
|
+
throw invalidParameter$1(`Parameter [${name}] exceeds the maximum filesystem path length.`);
|
|
41066
|
+
}
|
|
41067
|
+
return canonicalPath;
|
|
41068
|
+
}
|
|
41069
|
+
function validateNonNegativeInteger(value, name, defaultValue) {
|
|
41070
|
+
if (value === undefined || value === null) {
|
|
41071
|
+
if (defaultValue !== undefined)
|
|
41072
|
+
return defaultValue;
|
|
41073
|
+
throw invalidParameter$1(`Missing required parameter: ${name}`);
|
|
41074
|
+
}
|
|
41075
|
+
const numeric = typeof value === 'string' && value.trim() !== '' ? Number(value) : value;
|
|
41076
|
+
if (typeof numeric !== 'number' || !Number.isSafeInteger(numeric) || numeric < 0) {
|
|
41077
|
+
throw invalidParameter$1(`Parameter [${name}] must be a non-negative integer.`);
|
|
41078
|
+
}
|
|
41079
|
+
return numeric;
|
|
41080
|
+
}
|
|
41081
|
+
function validateOptionalNonNegativeInteger(value, name) {
|
|
41082
|
+
if (value === undefined || value === null)
|
|
41083
|
+
return undefined;
|
|
41084
|
+
return validateNonNegativeInteger(value, name);
|
|
41085
|
+
}
|
|
41086
|
+
function validateOptionalPercentage(value, name) {
|
|
41087
|
+
const numeric = validateOptionalNonNegativeInteger(value, name);
|
|
41088
|
+
if (numeric === undefined)
|
|
41089
|
+
return undefined;
|
|
41090
|
+
if (numeric > 100) {
|
|
41091
|
+
throw invalidParameter$1(`Parameter [${name}] must be between 0 and 100.`);
|
|
41092
|
+
}
|
|
41093
|
+
return numeric;
|
|
41094
|
+
}
|
|
41095
|
+
function validateRequiredData(value, name) {
|
|
41096
|
+
if (value === undefined || value === null) {
|
|
41097
|
+
throw invalidParameter$1(`Missing required parameter: ${name}`);
|
|
41098
|
+
}
|
|
41099
|
+
}
|
|
41100
|
+
|
|
41101
|
+
const PRO2_NFT_IMAGE_WIDTH = 540;
|
|
41102
|
+
const PRO2_NFT_IMAGE_HEIGHT = 540;
|
|
41103
|
+
const PRO2_NFT_THUMBNAIL_WIDTH = 263;
|
|
41104
|
+
const PRO2_NFT_THUMBNAIL_HEIGHT = 263;
|
|
41105
|
+
const PRO2_NFT_DIRECTORY = 'vol1:/nft';
|
|
41106
|
+
const PRO2_NFT_DEFAULT_CHUNK_SIZE = 512;
|
|
41107
|
+
const PRO2_NFT_DEFAULT_PACE_MS = 20;
|
|
41108
|
+
const PRO2_NFT_DEFAULT_TIMEOUT_MS = 15000;
|
|
41109
|
+
const PRO2_NFT_MIN_CHUNK_SIZE = 64;
|
|
41110
|
+
const PRO2_NFT_MAX_CHUNK_SIZE = 2048;
|
|
41111
|
+
function utf8Length(value) {
|
|
41112
|
+
return new TextEncoder().encode(value).byteLength;
|
|
41113
|
+
}
|
|
41114
|
+
function assertImage(name, image, expectedWidth, expectedHeight) {
|
|
41115
|
+
if (image.width !== expectedWidth || image.height !== expectedHeight) {
|
|
41116
|
+
throw invalidParameter$1(`Pro2 NFT ${name} dimensions must be ${expectedWidth}x${expectedHeight}.`);
|
|
41117
|
+
}
|
|
41118
|
+
if (!(image.rgba instanceof ArrayBuffer) && !ArrayBuffer.isView(image.rgba)) {
|
|
41119
|
+
throw invalidParameter$1(`Parameter [${name}.rgba] must be an ArrayBuffer or Uint8Array.`);
|
|
41120
|
+
}
|
|
41121
|
+
}
|
|
41122
|
+
function buildPro2NftBundle(options) {
|
|
41123
|
+
const { image, thumbnail, title, subtitle, timestampMs } = options;
|
|
41124
|
+
assertImage('image', image, PRO2_NFT_IMAGE_WIDTH, PRO2_NFT_IMAGE_HEIGHT);
|
|
41125
|
+
assertImage('thumbnail', thumbnail, PRO2_NFT_THUMBNAIL_WIDTH, PRO2_NFT_THUMBNAIL_HEIGHT);
|
|
41126
|
+
const titleLength = typeof title === 'string' ? utf8Length(title) : 0;
|
|
41127
|
+
const subtitleLength = typeof subtitle === 'string' ? utf8Length(subtitle) : Number.POSITIVE_INFINITY;
|
|
41128
|
+
if (titleLength < 1 || titleLength > 63) {
|
|
41129
|
+
throw invalidParameter$1('Pro2 NFT title must contain 1 to 63 UTF-8 bytes.');
|
|
41130
|
+
}
|
|
41131
|
+
if (subtitleLength > 95) {
|
|
41132
|
+
throw invalidParameter$1('Pro2 NFT subtitle must contain at most 95 UTF-8 bytes.');
|
|
41133
|
+
}
|
|
41134
|
+
if (!Number.isSafeInteger(timestampMs) || timestampMs <= 0) {
|
|
41135
|
+
throw invalidParameter$1('Parameter [timestampMs] must be a positive safe integer.');
|
|
41136
|
+
}
|
|
41137
|
+
const encodedImage = encodePro2Image(Object.assign(Object.assign({}, image), { alphaMode: 'black-background' })).data;
|
|
41138
|
+
const encodedThumbnail = encodePro2Image(Object.assign(Object.assign({}, thumbnail), { alphaMode: 'black-background' })).data;
|
|
41139
|
+
const metadata = new TextEncoder().encode(JSON.stringify({ title, subtitle }));
|
|
41140
|
+
if (metadata.byteLength === 0 || metadata.byteLength > 512) {
|
|
41141
|
+
throw invalidParameter$1('Pro2 NFT metadata must contain 1 to 512 UTF-8 bytes.');
|
|
41142
|
+
}
|
|
41143
|
+
const hash8 = utils.bytesToHex(blake2s.blake2s(encodedImage)).slice(0, 8);
|
|
41144
|
+
return {
|
|
41145
|
+
basename: `nft-${hash8}-${timestampMs}`,
|
|
41146
|
+
image: encodedImage,
|
|
41147
|
+
thumbnail: encodedThumbnail,
|
|
41148
|
+
metadata,
|
|
41149
|
+
};
|
|
41150
|
+
}
|
|
41035
41151
|
|
|
41036
41152
|
const getT1Data = () => ({
|
|
41037
41153
|
default: {
|
|
@@ -41315,14 +41431,27 @@ const getHomeScreenDefaultList = (features) => {
|
|
|
41315
41431
|
}
|
|
41316
41432
|
return Object.keys(data);
|
|
41317
41433
|
};
|
|
41434
|
+
const getNftSize = ({ deviceType, thumbnail, }) => {
|
|
41435
|
+
var _a;
|
|
41436
|
+
const sizes = {
|
|
41437
|
+
touch: {
|
|
41438
|
+
full: { width: 480, height: 800 },
|
|
41439
|
+
thumbnail: { width: 238, height: 238 },
|
|
41440
|
+
},
|
|
41441
|
+
pro: {
|
|
41442
|
+
full: { width: 480, height: 800 },
|
|
41443
|
+
thumbnail: { width: 226, height: 226, radius: 40 },
|
|
41444
|
+
},
|
|
41445
|
+
pro2: {
|
|
41446
|
+
full: { width: PRO2_NFT_IMAGE_WIDTH, height: PRO2_NFT_IMAGE_HEIGHT },
|
|
41447
|
+
thumbnail: { width: PRO2_NFT_THUMBNAIL_WIDTH, height: PRO2_NFT_THUMBNAIL_HEIGHT },
|
|
41448
|
+
},
|
|
41449
|
+
};
|
|
41450
|
+
return (_a = sizes[deviceType]) === null || _a === void 0 ? void 0 : _a[thumbnail ? 'thumbnail' : 'full'];
|
|
41451
|
+
};
|
|
41318
41452
|
const getHomeScreenSize = ({ deviceType, homeScreenType, thumbnail, }) => {
|
|
41319
41453
|
if (deviceType === hdShared.EDeviceType.Pro2) {
|
|
41320
|
-
return thumbnail
|
|
41321
|
-
? undefined
|
|
41322
|
-
: {
|
|
41323
|
-
width: PRO2_WALLPAPER_WIDTH,
|
|
41324
|
-
height: PRO2_WALLPAPER_HEIGHT,
|
|
41325
|
-
};
|
|
41454
|
+
return thumbnail ? undefined : { width: PRO2_WALLPAPER_WIDTH, height: PRO2_WALLPAPER_HEIGHT };
|
|
41326
41455
|
}
|
|
41327
41456
|
const sizes = {
|
|
41328
41457
|
touch: {
|
|
@@ -44537,101 +44666,6 @@ const getBootloaderReleaseInfo = ({ features, willUpdateFirmwareVersion, firmwar
|
|
|
44537
44666
|
};
|
|
44538
44667
|
};
|
|
44539
44668
|
|
|
44540
|
-
const PROTOCOL_V2_RETRY_ON_LOCKED_METHODS = [
|
|
44541
|
-
'cipherKeyValue',
|
|
44542
|
-
'allNetworkGetAddress',
|
|
44543
|
-
'allNetworkGetAddressByLoop',
|
|
44544
|
-
'btcGetAddress',
|
|
44545
|
-
'btcGetPublicKey',
|
|
44546
|
-
'btcSignMessage',
|
|
44547
|
-
'btcSignPsbt',
|
|
44548
|
-
'btcSignTransaction',
|
|
44549
|
-
'btcVerifyMessage',
|
|
44550
|
-
'confluxGetAddress',
|
|
44551
|
-
'confluxSignMessage',
|
|
44552
|
-
'confluxSignTransaction',
|
|
44553
|
-
'evmGetAddress',
|
|
44554
|
-
'evmGetPublicKey',
|
|
44555
|
-
'evmSignMessage',
|
|
44556
|
-
'evmSignTransaction',
|
|
44557
|
-
'evmSignTypedData',
|
|
44558
|
-
'evmVerifyMessage',
|
|
44559
|
-
'starcoinGetAddress',
|
|
44560
|
-
'starcoinGetPublicKey',
|
|
44561
|
-
'starcoinSignMessage',
|
|
44562
|
-
'starcoinSignTransaction',
|
|
44563
|
-
'starcoinVerifyMessage',
|
|
44564
|
-
'nemGetAddress',
|
|
44565
|
-
'nemSignTransaction',
|
|
44566
|
-
'solGetAddress',
|
|
44567
|
-
'solSignTransaction',
|
|
44568
|
-
'solSignOffchainMessage',
|
|
44569
|
-
'solSignMessage',
|
|
44570
|
-
'stellarGetAddress',
|
|
44571
|
-
'stellarSignTransaction',
|
|
44572
|
-
'tronGetAddress',
|
|
44573
|
-
'tronSignMessage',
|
|
44574
|
-
'tronSignTransaction',
|
|
44575
|
-
'nearGetAddress',
|
|
44576
|
-
'nearSignTransaction',
|
|
44577
|
-
'aptosGetAddress',
|
|
44578
|
-
'aptosGetPublicKey',
|
|
44579
|
-
'aptosSignTransaction',
|
|
44580
|
-
'aptosSignMessage',
|
|
44581
|
-
'aptosSignInMessage',
|
|
44582
|
-
'algoGetAddress',
|
|
44583
|
-
'algoSignTransaction',
|
|
44584
|
-
'cosmosGetAddress',
|
|
44585
|
-
'cosmosGetPublicKey',
|
|
44586
|
-
'cosmosSignTransaction',
|
|
44587
|
-
'xrpGetAddress',
|
|
44588
|
-
'xrpSignTransaction',
|
|
44589
|
-
'suiGetAddress',
|
|
44590
|
-
'suiGetPublicKey',
|
|
44591
|
-
'suiSignMessage',
|
|
44592
|
-
'suiSignTransaction',
|
|
44593
|
-
'cardanoGetAddress',
|
|
44594
|
-
'cardanoGetPublicKey',
|
|
44595
|
-
'cardanoSignTransaction',
|
|
44596
|
-
'cardanoSignMessage',
|
|
44597
|
-
'filecoinGetAddress',
|
|
44598
|
-
'filecoinSignTransaction',
|
|
44599
|
-
'polkadotGetAddress',
|
|
44600
|
-
'polkadotSignTransaction',
|
|
44601
|
-
'kaspaGetAddress',
|
|
44602
|
-
'kaspaSignTransaction',
|
|
44603
|
-
'nexaGetAddress',
|
|
44604
|
-
'nexaSignTransaction',
|
|
44605
|
-
'nostrGetPublicKey',
|
|
44606
|
-
'nostrSignEvent',
|
|
44607
|
-
'nostrEncryptMessage',
|
|
44608
|
-
'nostrDecryptMessage',
|
|
44609
|
-
'nostrSignSchnorr',
|
|
44610
|
-
'lnurlAuth',
|
|
44611
|
-
'nervosGetAddress',
|
|
44612
|
-
'nervosSignTransaction',
|
|
44613
|
-
'dnxGetAddress',
|
|
44614
|
-
'dnxSignTransaction',
|
|
44615
|
-
'tonGetAddress',
|
|
44616
|
-
'tonSignMessage',
|
|
44617
|
-
'tonSignProof',
|
|
44618
|
-
'tonSignData',
|
|
44619
|
-
'scdoGetAddress',
|
|
44620
|
-
'scdoSignTransaction',
|
|
44621
|
-
'scdoSignMessage',
|
|
44622
|
-
'alephiumGetAddress',
|
|
44623
|
-
'alephiumSignTransaction',
|
|
44624
|
-
'alephiumSignMessage',
|
|
44625
|
-
'benfenGetAddress',
|
|
44626
|
-
'benfenGetPublicKey',
|
|
44627
|
-
'benfenSignMessage',
|
|
44628
|
-
'benfenSignTransaction',
|
|
44629
|
-
'neoGetAddress',
|
|
44630
|
-
'neoSignTransaction',
|
|
44631
|
-
];
|
|
44632
|
-
const retryOnLockedMethods = new Set(PROTOCOL_V2_RETRY_ON_LOCKED_METHODS);
|
|
44633
|
-
const getProtocolV2UnlockPolicy = (methodName) => retryOnLockedMethods.has(methodName) ? 'retry-on-locked' : 'none';
|
|
44634
|
-
|
|
44635
44669
|
const Log$d = getLogger(exports.LoggerNames.Method);
|
|
44636
44670
|
const isEvmLedgerLegacyPathWithHighIndex = (path) => {
|
|
44637
44671
|
let addressN;
|
|
@@ -44709,7 +44743,6 @@ class BaseMethod {
|
|
|
44709
44743
|
this.useDevice = true;
|
|
44710
44744
|
this.allowDeviceMode = [UI_REQUEST.NOT_INITIALIZE];
|
|
44711
44745
|
this.requireDeviceMode = [];
|
|
44712
|
-
this.unlockPolicy = getProtocolV2UnlockPolicy(this.name);
|
|
44713
44746
|
}
|
|
44714
44747
|
getVersionRange() {
|
|
44715
44748
|
return {};
|
|
@@ -44847,7 +44880,7 @@ class TestInitializeDeviceDuration extends BaseMethod {
|
|
|
44847
44880
|
}
|
|
44848
44881
|
|
|
44849
44882
|
const PROTOCOL_V2_PING_MAX_MESSAGE_BYTES = 63;
|
|
44850
|
-
const getUtf8ByteLength
|
|
44883
|
+
const getUtf8ByteLength = (value) => Array.from(value).reduce((length, character) => {
|
|
44851
44884
|
var _a;
|
|
44852
44885
|
const codePoint = (_a = character.codePointAt(0)) !== null && _a !== void 0 ? _a : 0;
|
|
44853
44886
|
if (codePoint <= 0x7f)
|
|
@@ -44863,7 +44896,7 @@ function validateProtocolV2PingMessage(value) {
|
|
|
44863
44896
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, 'Protocol V2 Ping message must be a string.');
|
|
44864
44897
|
}
|
|
44865
44898
|
const message = value !== null && value !== void 0 ? value : '';
|
|
44866
|
-
if (getUtf8ByteLength
|
|
44899
|
+
if (getUtf8ByteLength(message) > PROTOCOL_V2_PING_MAX_MESSAGE_BYTES) {
|
|
44867
44900
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, `Protocol V2 Ping message must not exceed ${PROTOCOL_V2_PING_MAX_MESSAGE_BYTES} UTF-8 bytes.`);
|
|
44868
44901
|
}
|
|
44869
44902
|
return message;
|
|
@@ -45183,37 +45216,37 @@ function parseChainId(chainId) {
|
|
|
45183
45216
|
throw new Error(`Invalid chainId ${chainId}`);
|
|
45184
45217
|
}
|
|
45185
45218
|
|
|
45186
|
-
const invalidParameter
|
|
45219
|
+
const invalidParameter = (message) => hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, message);
|
|
45187
45220
|
const invalidResponse = (message) => hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodError, message);
|
|
45188
45221
|
const validateParams = (values, fields) => {
|
|
45189
45222
|
fields.forEach(field => {
|
|
45190
45223
|
const existsProp = Object.prototype.hasOwnProperty.call(values, field.name);
|
|
45191
45224
|
if (!existsProp && field.required) {
|
|
45192
|
-
throw invalidParameter
|
|
45225
|
+
throw invalidParameter(`Missing required parameter: ${field.name}`);
|
|
45193
45226
|
}
|
|
45194
45227
|
const value = values[field.name];
|
|
45195
45228
|
if (value && field.type) {
|
|
45196
45229
|
switch (field.type) {
|
|
45197
45230
|
case 'array':
|
|
45198
45231
|
if (!Array.isArray(value)) {
|
|
45199
|
-
throw invalidParameter
|
|
45232
|
+
throw invalidParameter(`Parameter [${field.name}] is of type invalid and should be [${field.type}].`);
|
|
45200
45233
|
}
|
|
45201
45234
|
else if (!field.allowEmpty && value.length < 1) {
|
|
45202
|
-
throw invalidParameter
|
|
45235
|
+
throw invalidParameter(`Parameter "${field.name}" is empty.`);
|
|
45203
45236
|
}
|
|
45204
45237
|
break;
|
|
45205
45238
|
case 'uint':
|
|
45206
45239
|
if (typeof value !== 'string' && typeof value !== 'number') {
|
|
45207
|
-
throw invalidParameter
|
|
45240
|
+
throw invalidParameter(`Parameter [${field.name}] has invalid type. "string|number" expected.`);
|
|
45208
45241
|
}
|
|
45209
45242
|
if ((typeof value === 'number' && !Number.isSafeInteger(value)) ||
|
|
45210
45243
|
!/^(?:[1-9]\d*|\d)$/.test(value.toString().replace(/^-/, field.allowNegative ? '' : '-'))) {
|
|
45211
|
-
throw invalidParameter
|
|
45244
|
+
throw invalidParameter(`Parameter [${field.name}] has invalid value "${value}". Integer representation expected.`);
|
|
45212
45245
|
}
|
|
45213
45246
|
break;
|
|
45214
45247
|
case 'bigNumber':
|
|
45215
45248
|
if (typeof value !== 'string') {
|
|
45216
|
-
throw invalidParameter
|
|
45249
|
+
throw invalidParameter(`Parameter [${field.name}] is of type invalid and should be [string].`);
|
|
45217
45250
|
}
|
|
45218
45251
|
try {
|
|
45219
45252
|
const bn = new BigNumber__default["default"](value);
|
|
@@ -45222,12 +45255,12 @@ const validateParams = (values, fields) => {
|
|
|
45222
45255
|
}
|
|
45223
45256
|
}
|
|
45224
45257
|
catch (error) {
|
|
45225
|
-
throw invalidParameter
|
|
45258
|
+
throw invalidParameter(`Parameter [${field.name}] is of type invalid and should be [${field.type}].`);
|
|
45226
45259
|
}
|
|
45227
45260
|
break;
|
|
45228
45261
|
case 'buffer': {
|
|
45229
45262
|
if (typeof value === 'undefined' || value === null) {
|
|
45230
|
-
throw invalidParameter
|
|
45263
|
+
throw invalidParameter(`Parameter [${field.name}] is of type invalid and should be [buffer].`);
|
|
45231
45264
|
}
|
|
45232
45265
|
const isNodeBuffer = typeof Buffer !== 'undefined' &&
|
|
45233
45266
|
typeof Buffer.isBuffer === 'function' &&
|
|
@@ -45240,18 +45273,18 @@ const validateParams = (values, fields) => {
|
|
|
45240
45273
|
typeof ArrayBuffer.isView === 'function' &&
|
|
45241
45274
|
ArrayBuffer.isView(value);
|
|
45242
45275
|
if (!isNodeBuffer && !isCustomBuffer && !isArrayBuffer && !isArrayBufferView) {
|
|
45243
|
-
throw invalidParameter
|
|
45276
|
+
throw invalidParameter(`Parameter [${field.name}] is of type invalid and should be [buffer].`);
|
|
45244
45277
|
}
|
|
45245
45278
|
break;
|
|
45246
45279
|
}
|
|
45247
45280
|
case 'hexString':
|
|
45248
45281
|
if (typeof value !== 'string' || !isHexString(addHexPrefix(value))) {
|
|
45249
|
-
throw invalidParameter
|
|
45282
|
+
throw invalidParameter(`Parameter [${field.name}] is of type invalid and should be [${field.type}].`);
|
|
45250
45283
|
}
|
|
45251
45284
|
break;
|
|
45252
45285
|
default:
|
|
45253
45286
|
if (typeof value !== field.type) {
|
|
45254
|
-
throw invalidParameter
|
|
45287
|
+
throw invalidParameter(`Parameter [${field.name}] is of type invalid and should be [${field.type}].`);
|
|
45255
45288
|
}
|
|
45256
45289
|
break;
|
|
45257
45290
|
}
|
|
@@ -45285,10 +45318,10 @@ function validateResult(result, nonNullableFields, options) {
|
|
|
45285
45318
|
|
|
45286
45319
|
const requiredString = (value, name) => {
|
|
45287
45320
|
if (value === undefined || value === null) {
|
|
45288
|
-
throw invalidParameter
|
|
45321
|
+
throw invalidParameter(`Missing required parameter: ${name}`);
|
|
45289
45322
|
}
|
|
45290
45323
|
if (typeof value !== 'string' || !value.trim()) {
|
|
45291
|
-
throw invalidParameter
|
|
45324
|
+
throw invalidParameter(`Parameter [${name}] must be a non-empty string.`);
|
|
45292
45325
|
}
|
|
45293
45326
|
return value.trim();
|
|
45294
45327
|
};
|
|
@@ -45306,20 +45339,20 @@ const requireHiddenWalletResponse = (session) => {
|
|
|
45306
45339
|
};
|
|
45307
45340
|
const normalizeParams = (payload) => {
|
|
45308
45341
|
if (payload.mode === undefined) {
|
|
45309
|
-
throw invalidParameter
|
|
45342
|
+
throw invalidParameter('Parameter [mode] is required.');
|
|
45310
45343
|
}
|
|
45311
45344
|
if (payload.mode !== OpenWalletSessionMode.Standard &&
|
|
45312
45345
|
payload.mode !== OpenWalletSessionMode.SelectHidden &&
|
|
45313
45346
|
payload.mode !== OpenWalletSessionMode.ResumeHidden) {
|
|
45314
|
-
throw invalidParameter
|
|
45347
|
+
throw invalidParameter('Parameter [mode] must be one of standard, select-hidden, or resume-hidden.');
|
|
45315
45348
|
}
|
|
45316
45349
|
if (payload.useEmptyPassphrase !== undefined || payload.initSession !== undefined) {
|
|
45317
|
-
throw invalidParameter
|
|
45350
|
+
throw invalidParameter('Legacy parameters [useEmptyPassphrase] and [initSession] are not supported by openWalletSession.');
|
|
45318
45351
|
}
|
|
45319
45352
|
if (payload.mode === OpenWalletSessionMode.Standard ||
|
|
45320
45353
|
payload.mode === OpenWalletSessionMode.SelectHidden) {
|
|
45321
45354
|
if (payload.deviceId !== undefined || payload.passphraseState !== undefined) {
|
|
45322
|
-
throw invalidParameter
|
|
45355
|
+
throw invalidParameter('Parameters [deviceId] and [passphraseState] are only allowed with mode [resume-hidden].');
|
|
45323
45356
|
}
|
|
45324
45357
|
return { mode: payload.mode };
|
|
45325
45358
|
}
|
|
@@ -45342,28 +45375,39 @@ class OpenWalletSession extends BaseMethod {
|
|
|
45342
45375
|
run() {
|
|
45343
45376
|
return __awaiter(this, void 0, void 0, function* () {
|
|
45344
45377
|
const isProtocolV2 = this.device.isProtocolV2();
|
|
45345
|
-
|
|
45378
|
+
let state = yield this.device.getDeviceState({ refreshSections: ['status'] });
|
|
45346
45379
|
let currentDeviceId = state.identity.deviceId;
|
|
45380
|
+
const hasAuthoritativeProtocolV2WalletStatus = (candidate) => candidate.status.unlocked === true &&
|
|
45381
|
+
typeof candidate.status.passphraseProtection === 'boolean' &&
|
|
45382
|
+
typeof candidate.status.unlockedAttachPin === 'boolean';
|
|
45383
|
+
const requireAuthoritativeProtocolV2WalletStatus = (candidate) => {
|
|
45384
|
+
if (!hasAuthoritativeProtocolV2WalletStatus(candidate)) {
|
|
45385
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInitializeFailed);
|
|
45386
|
+
}
|
|
45387
|
+
return candidate;
|
|
45388
|
+
};
|
|
45347
45389
|
const requireDeviceId = () => {
|
|
45348
45390
|
if (!currentDeviceId) {
|
|
45349
45391
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInitializeFailed);
|
|
45350
45392
|
}
|
|
45351
45393
|
return currentDeviceId;
|
|
45352
45394
|
};
|
|
45353
|
-
const
|
|
45354
|
-
|
|
45355
|
-
currentDeviceId =
|
|
45356
|
-
return
|
|
45395
|
+
const refreshProtocolV2DeviceState = () => __awaiter(this, void 0, void 0, function* () {
|
|
45396
|
+
state = yield this.device.getDeviceState({ refreshSections: ['status'] });
|
|
45397
|
+
currentDeviceId = state.identity.deviceId;
|
|
45398
|
+
return state;
|
|
45357
45399
|
});
|
|
45358
|
-
const
|
|
45359
|
-
if (isProtocolV2 && state
|
|
45400
|
+
const ensureProtocolV2WalletStatus = () => __awaiter(this, void 0, void 0, function* () {
|
|
45401
|
+
if (isProtocolV2 && !hasAuthoritativeProtocolV2WalletStatus(state)) {
|
|
45360
45402
|
yield this.device.unlockDevice(hdTransport.DeviceSessionPinType.Main, {
|
|
45361
45403
|
source: 'unlock-coordinator',
|
|
45362
45404
|
reason: 'device-locked',
|
|
45363
45405
|
deviceOnly: true,
|
|
45364
45406
|
method: 'openWalletSession',
|
|
45365
45407
|
});
|
|
45408
|
+
requireAuthoritativeProtocolV2WalletStatus(yield refreshProtocolV2DeviceState());
|
|
45366
45409
|
}
|
|
45410
|
+
return state;
|
|
45367
45411
|
});
|
|
45368
45412
|
const protocol = isProtocolV2 ? 'V2' : 'V1';
|
|
45369
45413
|
if (this.params.mode === OpenWalletSessionMode.Standard) {
|
|
@@ -45372,14 +45416,19 @@ class OpenWalletSession extends BaseMethod {
|
|
|
45372
45416
|
? yield getProtocolV2WalletSession(this.device, {
|
|
45373
45417
|
onlyMainPin: true,
|
|
45374
45418
|
deriveCardano: this.payload.deriveCardano,
|
|
45375
|
-
selectMainWalletBeforeRestore: state
|
|
45419
|
+
selectMainWalletBeforeRestore: !hasAuthoritativeProtocolV2WalletStatus(state) ||
|
|
45420
|
+
state.status.unlockedAttachPin === true,
|
|
45376
45421
|
})
|
|
45377
45422
|
: yield getPassphraseStateWithRefreshDeviceInfo(this.device, {
|
|
45378
45423
|
onlyMainPin: true,
|
|
45379
45424
|
initSession: this.payload.initSession,
|
|
45380
45425
|
});
|
|
45381
|
-
const
|
|
45382
|
-
|
|
45426
|
+
const refreshedState = isProtocolV2
|
|
45427
|
+
? requireAuthoritativeProtocolV2WalletStatus(yield refreshProtocolV2DeviceState())
|
|
45428
|
+
: state;
|
|
45429
|
+
const deviceId = requireDeviceId();
|
|
45430
|
+
if (session.unlockedAttachPin ||
|
|
45431
|
+
(isProtocolV2 && refreshedState.status.unlockedAttachPin === true)) {
|
|
45383
45432
|
try {
|
|
45384
45433
|
yield this.device.lockDevice();
|
|
45385
45434
|
}
|
|
@@ -45398,8 +45447,8 @@ class OpenWalletSession extends BaseMethod {
|
|
|
45398
45447
|
}
|
|
45399
45448
|
if (this.params.mode === OpenWalletSessionMode.ResumeHidden) {
|
|
45400
45449
|
if (isProtocolV2) {
|
|
45401
|
-
yield
|
|
45402
|
-
const refreshedDeviceId =
|
|
45450
|
+
yield ensureProtocolV2WalletStatus();
|
|
45451
|
+
const refreshedDeviceId = requireDeviceId();
|
|
45403
45452
|
if (refreshedDeviceId !== this.params.deviceId) {
|
|
45404
45453
|
deviceWalletSessionStore.delete(this.params.deviceId, this.params.passphraseState);
|
|
45405
45454
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckDeviceIdError);
|
|
@@ -45435,15 +45484,18 @@ class OpenWalletSession extends BaseMethod {
|
|
|
45435
45484
|
return Object.assign(Object.assign({ protocol, walletType: 'hidden', deviceId }, requireHiddenWalletResponse(session)), { resumed: wasResumed(session) || (!isProtocolV2 && session.newSession === cachedSessionId) });
|
|
45436
45485
|
}
|
|
45437
45486
|
this.device.passphraseState = undefined;
|
|
45438
|
-
yield
|
|
45487
|
+
yield ensureProtocolV2WalletStatus();
|
|
45439
45488
|
const session = isProtocolV2
|
|
45440
45489
|
? yield getProtocolV2WalletSession(this.device, {
|
|
45441
45490
|
forceWalletSelection: true,
|
|
45442
45491
|
deriveCardano: this.payload.deriveCardano,
|
|
45443
45492
|
})
|
|
45444
45493
|
: yield getPassphraseStateWithRefreshDeviceInfo(this.device, { initSession: true });
|
|
45445
|
-
const
|
|
45446
|
-
|
|
45494
|
+
const refreshedState = isProtocolV2
|
|
45495
|
+
? requireAuthoritativeProtocolV2WalletStatus(yield refreshProtocolV2DeviceState())
|
|
45496
|
+
: state;
|
|
45497
|
+
const deviceId = requireDeviceId();
|
|
45498
|
+
if (isProtocolV2 && refreshedState.status.passphraseProtection !== true) {
|
|
45447
45499
|
this.device.clearInternalState();
|
|
45448
45500
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceNotOpenedPassphrase);
|
|
45449
45501
|
}
|
|
@@ -45487,7 +45539,7 @@ class GetLogs extends BaseMethod {
|
|
|
45487
45539
|
class ClearSessionCache extends BaseMethod {
|
|
45488
45540
|
init() {
|
|
45489
45541
|
if (this.payload.passphraseState !== undefined && !this.payload.deviceId) {
|
|
45490
|
-
throw invalidParameter
|
|
45542
|
+
throw invalidParameter('Parameter [deviceId] is required with [passphraseState].');
|
|
45491
45543
|
}
|
|
45492
45544
|
this.useDevice = false;
|
|
45493
45545
|
this.useDevicePassphraseState = false;
|
|
@@ -45977,94 +46029,6 @@ class DeviceBackup extends BaseMethod {
|
|
|
45977
46029
|
}
|
|
45978
46030
|
}
|
|
45979
46031
|
|
|
45980
|
-
const invalidParameter = (message) => hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, message);
|
|
45981
|
-
function validateNonEmptyString(value, name) {
|
|
45982
|
-
if (typeof value !== 'string' || value.trim().length === 0) {
|
|
45983
|
-
throw invalidParameter(`Parameter [${name}] is required and must be a non-empty string.`);
|
|
45984
|
-
}
|
|
45985
|
-
return value;
|
|
45986
|
-
}
|
|
45987
|
-
const PROTOCOL_V2_FILESYSTEM_VOLUMES = new Set(['vol0', 'vol1']);
|
|
45988
|
-
const MAX_PROTOCOL_V2_FILESYSTEM_PATH_BYTES = 127;
|
|
45989
|
-
function getUtf8ByteLength(value) {
|
|
45990
|
-
return Array.from(value).reduce((length, character) => {
|
|
45991
|
-
var _a;
|
|
45992
|
-
const codePoint = (_a = character.codePointAt(0)) !== null && _a !== void 0 ? _a : 0;
|
|
45993
|
-
if (codePoint <= 0x7f)
|
|
45994
|
-
return length + 1;
|
|
45995
|
-
if (codePoint <= 0x7ff)
|
|
45996
|
-
return length + 2;
|
|
45997
|
-
if (codePoint <= 0xffff)
|
|
45998
|
-
return length + 3;
|
|
45999
|
-
return length + 4;
|
|
46000
|
-
}, 0);
|
|
46001
|
-
}
|
|
46002
|
-
function validateProtocolV2FilesystemPath(value, name, options = {}) {
|
|
46003
|
-
const rawPath = validateNonEmptyString(value, name).trim();
|
|
46004
|
-
const containsUnsupportedCharacter = Array.from(rawPath).some(character => {
|
|
46005
|
-
const codePoint = character.charCodeAt(0);
|
|
46006
|
-
return codePoint <= 0x1f || codePoint === 0x7f || character === '\\';
|
|
46007
|
-
});
|
|
46008
|
-
if (containsUnsupportedCharacter) {
|
|
46009
|
-
throw invalidParameter(`Parameter [${name}] contains unsupported path characters.`);
|
|
46010
|
-
}
|
|
46011
|
-
const match = /^([a-zA-Z0-9]+):(.*)$/.exec(rawPath);
|
|
46012
|
-
if (!match) {
|
|
46013
|
-
throw invalidParameter(`Parameter [${name}] must use a supported Protocol V2 filesystem volume.`);
|
|
46014
|
-
}
|
|
46015
|
-
const volume = match[1].toLowerCase();
|
|
46016
|
-
if (!PROTOCOL_V2_FILESYSTEM_VOLUMES.has(volume)) {
|
|
46017
|
-
throw invalidParameter(`Parameter [${name}] uses an unsupported filesystem volume.`);
|
|
46018
|
-
}
|
|
46019
|
-
const rawSuffix = match[2];
|
|
46020
|
-
if (rawSuffix.length === 0) {
|
|
46021
|
-
if (options.allowVolumeRoot)
|
|
46022
|
-
return `${volume}:`;
|
|
46023
|
-
throw invalidParameter(`Parameter [${name}] must identify a filesystem entry.`);
|
|
46024
|
-
}
|
|
46025
|
-
const suffix = rawSuffix.startsWith('/') ? rawSuffix : `/${rawSuffix}`;
|
|
46026
|
-
const segments = suffix.slice(1).split('/');
|
|
46027
|
-
if (segments.some(segment => segment.length === 0 || segment === '.' || segment === '..')) {
|
|
46028
|
-
throw invalidParameter(`Parameter [${name}] contains an invalid path segment.`);
|
|
46029
|
-
}
|
|
46030
|
-
const canonicalPath = `${volume}:${rawSuffix.startsWith('/') ? '/' : ''}${segments.join('/')}`;
|
|
46031
|
-
if (getUtf8ByteLength(canonicalPath) > MAX_PROTOCOL_V2_FILESYSTEM_PATH_BYTES) {
|
|
46032
|
-
throw invalidParameter(`Parameter [${name}] exceeds the maximum filesystem path length.`);
|
|
46033
|
-
}
|
|
46034
|
-
return canonicalPath;
|
|
46035
|
-
}
|
|
46036
|
-
function validateNonNegativeInteger(value, name, defaultValue) {
|
|
46037
|
-
if (value === undefined || value === null) {
|
|
46038
|
-
if (defaultValue !== undefined)
|
|
46039
|
-
return defaultValue;
|
|
46040
|
-
throw invalidParameter(`Missing required parameter: ${name}`);
|
|
46041
|
-
}
|
|
46042
|
-
const numeric = typeof value === 'string' && value.trim() !== '' ? Number(value) : value;
|
|
46043
|
-
if (typeof numeric !== 'number' || !Number.isSafeInteger(numeric) || numeric < 0) {
|
|
46044
|
-
throw invalidParameter(`Parameter [${name}] must be a non-negative integer.`);
|
|
46045
|
-
}
|
|
46046
|
-
return numeric;
|
|
46047
|
-
}
|
|
46048
|
-
function validateOptionalNonNegativeInteger(value, name) {
|
|
46049
|
-
if (value === undefined || value === null)
|
|
46050
|
-
return undefined;
|
|
46051
|
-
return validateNonNegativeInteger(value, name);
|
|
46052
|
-
}
|
|
46053
|
-
function validateOptionalPercentage(value, name) {
|
|
46054
|
-
const numeric = validateOptionalNonNegativeInteger(value, name);
|
|
46055
|
-
if (numeric === undefined)
|
|
46056
|
-
return undefined;
|
|
46057
|
-
if (numeric > 100) {
|
|
46058
|
-
throw invalidParameter(`Parameter [${name}] must be between 0 and 100.`);
|
|
46059
|
-
}
|
|
46060
|
-
return numeric;
|
|
46061
|
-
}
|
|
46062
|
-
function validateRequiredData(value, name) {
|
|
46063
|
-
if (value === undefined || value === null) {
|
|
46064
|
-
throw invalidParameter(`Missing required parameter: ${name}`);
|
|
46065
|
-
}
|
|
46066
|
-
}
|
|
46067
|
-
|
|
46068
46032
|
class DeviceChangePin extends BaseMethod {
|
|
46069
46033
|
getSupportedProtocols() {
|
|
46070
46034
|
return ['V1', 'V2'];
|
|
@@ -46089,7 +46053,7 @@ class DeviceChangePin extends BaseMethod {
|
|
|
46089
46053
|
return __awaiter(this, void 0, void 0, function* () {
|
|
46090
46054
|
if (this.device.isProtocolV2()) {
|
|
46091
46055
|
if (this.params.remove) {
|
|
46092
|
-
throw invalidParameter('Parameter [remove=true] is not supported by the Pro2 device PIN page.');
|
|
46056
|
+
throw invalidParameter$1('Parameter [remove=true] is not supported by the Pro2 device PIN page.');
|
|
46093
46057
|
}
|
|
46094
46058
|
const res = yield this.device.commands.typedCall('DeviceSettingsPageShow', 'Success', {
|
|
46095
46059
|
page: hdTransport.DeviceSettingsPage.DevicePinChange,
|
|
@@ -46298,7 +46262,7 @@ const getProtocolV2SettingsBehavior = (operation) => {
|
|
|
46298
46262
|
const assertSettingsSupported = (payload, unsupported, protocol) => {
|
|
46299
46263
|
const provided = unsupported.filter(key => payload[key] !== undefined);
|
|
46300
46264
|
if (provided.length > 0) {
|
|
46301
|
-
throw invalidParameter(`${protocol} does not support settings: ${provided.join(', ')}.`);
|
|
46265
|
+
throw invalidParameter$1(`${protocol} does not support settings: ${provided.join(', ')}.`);
|
|
46302
46266
|
}
|
|
46303
46267
|
};
|
|
46304
46268
|
const assertProtocolV2SettingValues = (payload, capabilities) => {
|
|
@@ -46306,7 +46270,7 @@ const assertProtocolV2SettingValues = (payload, capabilities) => {
|
|
|
46306
46270
|
if (payload.brightness !== undefined &&
|
|
46307
46271
|
brightnessRange &&
|
|
46308
46272
|
(payload.brightness < brightnessRange.min || payload.brightness > brightnessRange.max)) {
|
|
46309
|
-
throw invalidParameter(`Protocol V2 brightness must be between ${brightnessRange.min} and ${brightnessRange.max}.`);
|
|
46273
|
+
throw invalidParameter$1(`Protocol V2 brightness must be between ${brightnessRange.min} and ${brightnessRange.max}.`);
|
|
46310
46274
|
}
|
|
46311
46275
|
const delayFields = [
|
|
46312
46276
|
['autoLockDelayMs', capabilities.autoLockDelayOptions],
|
|
@@ -46315,7 +46279,7 @@ const assertProtocolV2SettingValues = (payload, capabilities) => {
|
|
|
46315
46279
|
delayFields.forEach(([field, options]) => {
|
|
46316
46280
|
const value = payload[field];
|
|
46317
46281
|
if (value !== undefined && !options.some(option => option.valueMs === value)) {
|
|
46318
|
-
throw invalidParameter(`Protocol V2 ${field} must be one of: ${options.map(option => option.valueMs).join(', ')}.`);
|
|
46282
|
+
throw invalidParameter$1(`Protocol V2 ${field} must be one of: ${options.map(option => option.valueMs).join(', ')}.`);
|
|
46319
46283
|
}
|
|
46320
46284
|
});
|
|
46321
46285
|
};
|
|
@@ -46403,10 +46367,10 @@ class DeviceSettings extends BaseMethod {
|
|
|
46403
46367
|
const hasPassphrasePage = requestedPassphrase !== undefined;
|
|
46404
46368
|
const hasAirgapPage = requestedAirgap !== undefined;
|
|
46405
46369
|
if (hasPassphrasePage && hasAirgapPage) {
|
|
46406
|
-
throw invalidParameter('Protocol V2 passphrase and air-gap settings must be changed in separate calls.');
|
|
46370
|
+
throw invalidParameter$1('Protocol V2 passphrase and air-gap settings must be changed in separate calls.');
|
|
46407
46371
|
}
|
|
46408
46372
|
if ((hasPassphrasePage || hasAirgapPage) && Object.keys(settings).length > 0) {
|
|
46409
|
-
throw invalidParameter('Protocol V2 on-device settings must not be combined with direct settings.');
|
|
46373
|
+
throw invalidParameter$1('Protocol V2 on-device settings must not be combined with direct settings.');
|
|
46410
46374
|
}
|
|
46411
46375
|
if (requestedPassphrase !== undefined) {
|
|
46412
46376
|
const current = yield this.device.getDeviceState({ refreshSections: ['status'] });
|
|
@@ -46441,7 +46405,7 @@ class DeviceSettings extends BaseMethod {
|
|
|
46441
46405
|
return res.message;
|
|
46442
46406
|
}
|
|
46443
46407
|
if (Object.keys(settings).length === 0) {
|
|
46444
|
-
throw invalidParameter('No Protocol V2 compatible setting provided.');
|
|
46408
|
+
throw invalidParameter$1('No Protocol V2 compatible setting provided.');
|
|
46445
46409
|
}
|
|
46446
46410
|
const res = yield this.device.commands.typedCall('DeviceSettingsSet', 'Success', {
|
|
46447
46411
|
settings,
|
|
@@ -46453,7 +46417,7 @@ class DeviceSettings extends BaseMethod {
|
|
|
46453
46417
|
const capabilities = getDeviceSettingsCapabilities(this.device.getCurrentDeviceType(), 'V1');
|
|
46454
46418
|
if (this.payload.safetyChecks !== undefined &&
|
|
46455
46419
|
!capabilities.safetyCheckOptions.some(option => option.value === this.payload.safetyChecks)) {
|
|
46456
|
-
throw invalidParameter(`Protocol V1 safetyChecks must be one of: ${capabilities.safetyCheckOptions
|
|
46420
|
+
throw invalidParameter$1(`Protocol V1 safetyChecks must be one of: ${capabilities.safetyCheckOptions
|
|
46457
46421
|
.map(option => option.value)
|
|
46458
46422
|
.join(', ')}.`);
|
|
46459
46423
|
}
|
|
@@ -47228,35 +47192,6 @@ class DeviceFullyUploadResource extends BaseMethod {
|
|
|
47228
47192
|
}
|
|
47229
47193
|
}
|
|
47230
47194
|
|
|
47231
|
-
const DEFAULT_FIRMWARE_PROGRESS_INTERVAL_MS = 250;
|
|
47232
|
-
const createFirmwareProgressThrottle = (intervalMs = DEFAULT_FIRMWARE_PROGRESS_INTERVAL_MS) => {
|
|
47233
|
-
const stateByType = new Map();
|
|
47234
|
-
return (progress, progressType) => {
|
|
47235
|
-
if (progressType !== 'transferData') {
|
|
47236
|
-
return true;
|
|
47237
|
-
}
|
|
47238
|
-
const normalizedProgress = Math.max(0, Math.min(100, Math.floor(progress)));
|
|
47239
|
-
if (normalizedProgress === 0 || normalizedProgress === 100) {
|
|
47240
|
-
stateByType.set(progressType, {
|
|
47241
|
-
lastEmittedAt: Date.now(),
|
|
47242
|
-
lastProgress: normalizedProgress,
|
|
47243
|
-
});
|
|
47244
|
-
return true;
|
|
47245
|
-
}
|
|
47246
|
-
const now = Date.now();
|
|
47247
|
-
const state = stateByType.get(progressType);
|
|
47248
|
-
if (state &&
|
|
47249
|
-
(state.lastProgress === normalizedProgress || now - state.lastEmittedAt < intervalMs)) {
|
|
47250
|
-
return false;
|
|
47251
|
-
}
|
|
47252
|
-
stateByType.set(progressType, {
|
|
47253
|
-
lastEmittedAt: now,
|
|
47254
|
-
lastProgress: normalizedProgress,
|
|
47255
|
-
});
|
|
47256
|
-
return true;
|
|
47257
|
-
};
|
|
47258
|
-
};
|
|
47259
|
-
|
|
47260
47195
|
const Log$9 = getLogger(exports.LoggerNames.Method);
|
|
47261
47196
|
const SESSION_ERROR$1 = 'session not found';
|
|
47262
47197
|
const FIRMWARE_UPDATE_CONFIRM = 'Firmware install confirmed';
|
|
@@ -47270,7 +47205,6 @@ class FirmwareUpdateBaseMethod extends BaseMethod {
|
|
|
47270
47205
|
constructor() {
|
|
47271
47206
|
super(...arguments);
|
|
47272
47207
|
this.checkPromise = null;
|
|
47273
|
-
this.shouldPostFirmwareProgress = createFirmwareProgressThrottle();
|
|
47274
47208
|
this.postTipMessage = (message) => {
|
|
47275
47209
|
this.postMessage(createUiMessage(UI_REQUEST.FIRMWARE_TIP, {
|
|
47276
47210
|
device: this.device.toMessageObject(),
|
|
@@ -47285,9 +47219,6 @@ class FirmwareUpdateBaseMethod extends BaseMethod {
|
|
|
47285
47219
|
}));
|
|
47286
47220
|
};
|
|
47287
47221
|
this.postProgressMessage = (progress, progressType) => {
|
|
47288
|
-
if (!this.shouldPostFirmwareProgress(progress, progressType)) {
|
|
47289
|
-
return;
|
|
47290
|
-
}
|
|
47291
47222
|
this.postMessage(createUiMessage(UI_REQUEST.FIRMWARE_PROGRESS, {
|
|
47292
47223
|
device: this.device.toMessageObject(),
|
|
47293
47224
|
progress,
|
|
@@ -50118,14 +50049,15 @@ class DeviceGetOnboardingStatus extends BaseMethod {
|
|
|
50118
50049
|
}
|
|
50119
50050
|
|
|
50120
50051
|
const MIN_FILE_CHUNK_SIZE = 64;
|
|
50121
|
-
function
|
|
50052
|
+
function isProtocolV2ResponseTimeout(error) {
|
|
50122
50053
|
var _a, _b;
|
|
50123
50054
|
if (!error || typeof error !== 'object')
|
|
50124
50055
|
return false;
|
|
50125
50056
|
const candidate = error;
|
|
50126
50057
|
const code = (_a = candidate.errorCode) !== null && _a !== void 0 ? _a : candidate.code;
|
|
50127
50058
|
return (code === hdShared.HardwareErrorCode.BleTimeoutError ||
|
|
50128
|
-
|
|
50059
|
+
code === 'response-timeout' ||
|
|
50060
|
+
/(?:BLE|Lowlevel|Protocol V2) response timeout/i.test((_b = candidate.message) !== null && _b !== void 0 ? _b : ''));
|
|
50129
50061
|
}
|
|
50130
50062
|
function getProtocolV2FileChunkLimit() {
|
|
50131
50063
|
const env = DataManager.getSettings('env');
|
|
@@ -50212,7 +50144,7 @@ function writeProtocolV2File(options) {
|
|
|
50212
50144
|
isWritePending = false;
|
|
50213
50145
|
}
|
|
50214
50146
|
catch (error) {
|
|
50215
|
-
if (retryCount >= maxChunkRetries || !
|
|
50147
|
+
if (retryCount >= maxChunkRetries || !isProtocolV2ResponseTimeout(error))
|
|
50216
50148
|
throw error;
|
|
50217
50149
|
retryCount += 1;
|
|
50218
50150
|
(_h = options.throwIfAborted) === null || _h === void 0 ? void 0 : _h.call(options);
|
|
@@ -50243,6 +50175,11 @@ function writeProtocolV2File(options) {
|
|
|
50243
50175
|
rateBytesPerSecond: elapsedMs > 0 ? Math.round((transferredBytes / elapsedMs) * 1000) : undefined,
|
|
50244
50176
|
elapsedMs,
|
|
50245
50177
|
});
|
|
50178
|
+
if (options.paceMs && options.paceMs > 0) {
|
|
50179
|
+
yield new Promise(resolve => {
|
|
50180
|
+
setTimeout(resolve, options.paceMs);
|
|
50181
|
+
});
|
|
50182
|
+
}
|
|
50246
50183
|
}
|
|
50247
50184
|
return Object.assign(Object.assign({}, lastMessage), { path: options.path, offset: startOffset, total_size: totalSize, processed_byte: startOffset + written, chunks });
|
|
50248
50185
|
});
|
|
@@ -50252,7 +50189,7 @@ const WALLPAPER_DIRECTORY = 'vol1:/wallpapers';
|
|
|
50252
50189
|
const SAFE_FILE_NAME = /^[A-Za-z0-9_-]+(?:\.bin)?$/;
|
|
50253
50190
|
function normalizeFileName(fileName, data) {
|
|
50254
50191
|
if (fileName !== undefined && (!fileName || !SAFE_FILE_NAME.test(fileName))) {
|
|
50255
|
-
throw invalidParameter('Parameter [fileName] may only contain letters, numbers, underscores, hyphens and an optional .bin suffix.');
|
|
50192
|
+
throw invalidParameter$1('Parameter [fileName] may only contain letters, numbers, underscores, hyphens and an optional .bin suffix.');
|
|
50256
50193
|
}
|
|
50257
50194
|
const baseName = fileName !== null && fileName !== void 0 ? fileName : `wallpaper-${utils.bytesToHex(blake2s.blake2s(data)).slice(0, 12)}`;
|
|
50258
50195
|
return baseName.endsWith('.bin') ? baseName : `${baseName}.bin`;
|
|
@@ -50270,13 +50207,13 @@ class DeviceUploadWallpaper extends BaseMethod {
|
|
|
50270
50207
|
init() {
|
|
50271
50208
|
const { width, height, rgba, fileName, chunkSize } = this.payload;
|
|
50272
50209
|
if (width !== PRO2_WALLPAPER_WIDTH || height !== PRO2_WALLPAPER_HEIGHT) {
|
|
50273
|
-
throw invalidParameter(`Pro2 wallpaper dimensions must be ${PRO2_WALLPAPER_WIDTH}x${PRO2_WALLPAPER_HEIGHT}.`);
|
|
50210
|
+
throw invalidParameter$1(`Pro2 wallpaper dimensions must be ${PRO2_WALLPAPER_WIDTH}x${PRO2_WALLPAPER_HEIGHT}.`);
|
|
50274
50211
|
}
|
|
50275
50212
|
if (!(rgba instanceof ArrayBuffer) && !ArrayBuffer.isView(rgba)) {
|
|
50276
|
-
throw invalidParameter('Parameter [rgba] must be an ArrayBuffer or Uint8Array.');
|
|
50213
|
+
throw invalidParameter$1('Parameter [rgba] must be an ArrayBuffer or Uint8Array.');
|
|
50277
50214
|
}
|
|
50278
50215
|
if (chunkSize !== undefined && (!Number.isInteger(chunkSize) || chunkSize <= 0)) {
|
|
50279
|
-
throw invalidParameter('Parameter [chunkSize] must be a positive integer.');
|
|
50216
|
+
throw invalidParameter$1('Parameter [chunkSize] must be a positive integer.');
|
|
50280
50217
|
}
|
|
50281
50218
|
const rgbaBytes = rgba instanceof ArrayBuffer
|
|
50282
50219
|
? rgba
|
|
@@ -50311,7 +50248,7 @@ class DeviceUploadWallpaper extends BaseMethod {
|
|
|
50311
50248
|
return;
|
|
50312
50249
|
const { encoded } = this;
|
|
50313
50250
|
if (!encoded)
|
|
50314
|
-
throw invalidParameter('Wallpaper data has not been initialized.');
|
|
50251
|
+
throw invalidParameter$1('Wallpaper data has not been initialized.');
|
|
50315
50252
|
yield writeProtocolV2File({
|
|
50316
50253
|
commands: this.device.commands,
|
|
50317
50254
|
path: this.path,
|
|
@@ -50336,7 +50273,7 @@ class DeviceUploadWallpaper extends BaseMethod {
|
|
|
50336
50273
|
return __awaiter(this, void 0, void 0, function* () {
|
|
50337
50274
|
const { encoded } = this;
|
|
50338
50275
|
if (!encoded)
|
|
50339
|
-
throw invalidParameter('Wallpaper data has not been initialized.');
|
|
50276
|
+
throw invalidParameter$1('Wallpaper data has not been initialized.');
|
|
50340
50277
|
yield this.ensureDirectory();
|
|
50341
50278
|
yield this.upload();
|
|
50342
50279
|
const response = yield this.device.commands.typedCall('DeviceSettingsSet', 'Success', {
|
|
@@ -50352,6 +50289,108 @@ class DeviceUploadWallpaper extends BaseMethod {
|
|
|
50352
50289
|
}
|
|
50353
50290
|
}
|
|
50354
50291
|
|
|
50292
|
+
const FILESYSTEM_FILE_WRITE_MESSAGE_TYPE = 60805;
|
|
50293
|
+
const NFT_UPDATE_MESSAGE_TYPE = 61500;
|
|
50294
|
+
class DeviceUploadNft extends BaseMethod {
|
|
50295
|
+
getSupportedProtocols() {
|
|
50296
|
+
return ['V2'];
|
|
50297
|
+
}
|
|
50298
|
+
init() {
|
|
50299
|
+
const { image, thumbnail, 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;
|
|
50300
|
+
if (!Number.isInteger(chunkSize) ||
|
|
50301
|
+
chunkSize < PRO2_NFT_MIN_CHUNK_SIZE ||
|
|
50302
|
+
chunkSize > PRO2_NFT_MAX_CHUNK_SIZE) {
|
|
50303
|
+
throw invalidParameter$1(`Parameter [chunkSize] must be an integer between ${PRO2_NFT_MIN_CHUNK_SIZE} and ${PRO2_NFT_MAX_CHUNK_SIZE}.`);
|
|
50304
|
+
}
|
|
50305
|
+
if (!Number.isInteger(paceMs) || paceMs < 0) {
|
|
50306
|
+
throw invalidParameter$1('Parameter [paceMs] must be a non-negative integer.');
|
|
50307
|
+
}
|
|
50308
|
+
if (!Number.isInteger(timeoutMs) || timeoutMs <= 0) {
|
|
50309
|
+
throw invalidParameter$1('Parameter [timeoutMs] must be a positive integer.');
|
|
50310
|
+
}
|
|
50311
|
+
this.bundle = buildPro2NftBundle({ image, thumbnail, title, subtitle, timestampMs });
|
|
50312
|
+
this.params = { image, thumbnail, title, subtitle, timestampMs, chunkSize, paceMs, timeoutMs };
|
|
50313
|
+
this.unlockPolicy = 'none';
|
|
50314
|
+
this.skipForceUpdateCheck = true;
|
|
50315
|
+
this.useDevicePassphraseState = false;
|
|
50316
|
+
}
|
|
50317
|
+
assertCapabilities() {
|
|
50318
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
50319
|
+
const protocolInfo = yield this.device.ensureProtocolV2RuntimeContext();
|
|
50320
|
+
const hasFileWrite = supportsProtocolV2Message(protocolInfo, FILESYSTEM_FILE_WRITE_MESSAGE_TYPE);
|
|
50321
|
+
const hasNftUpdate = supportsProtocolV2Message(protocolInfo, NFT_UPDATE_MESSAGE_TYPE);
|
|
50322
|
+
if (!hasFileWrite || !hasNftUpdate) {
|
|
50323
|
+
throw hdShared.createDeviceNotSupportMethodError(this.name, this.device.getCurrentFirmwareType());
|
|
50324
|
+
}
|
|
50325
|
+
});
|
|
50326
|
+
}
|
|
50327
|
+
updateNft(basename) {
|
|
50328
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
50329
|
+
const params = { file_name_no_ext: basename };
|
|
50330
|
+
const options = { timeoutMs: this.params.timeoutMs };
|
|
50331
|
+
try {
|
|
50332
|
+
return yield this.device.commands.typedCall('NftUpdate', 'Success', params, options);
|
|
50333
|
+
}
|
|
50334
|
+
catch (error) {
|
|
50335
|
+
if (!isProtocolV2ResponseTimeout(error)) {
|
|
50336
|
+
throw error;
|
|
50337
|
+
}
|
|
50338
|
+
this.throwIfAborted();
|
|
50339
|
+
return this.device.commands.typedCall('NftUpdate', 'Success', params, options);
|
|
50340
|
+
}
|
|
50341
|
+
});
|
|
50342
|
+
}
|
|
50343
|
+
run() {
|
|
50344
|
+
var _a;
|
|
50345
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
50346
|
+
const { bundle } = this;
|
|
50347
|
+
if (!bundle)
|
|
50348
|
+
throw invalidParameter$1('NFT data has not been initialized.');
|
|
50349
|
+
yield this.assertCapabilities();
|
|
50350
|
+
const files = [
|
|
50351
|
+
{ path: `${PRO2_NFT_DIRECTORY}/${bundle.basename}.bin`, data: bundle.image },
|
|
50352
|
+
{ path: `${PRO2_NFT_DIRECTORY}/${bundle.basename}_m.bin`, data: bundle.thumbnail },
|
|
50353
|
+
{ path: `${PRO2_NFT_DIRECTORY}/${bundle.basename}.json`, data: bundle.metadata },
|
|
50354
|
+
];
|
|
50355
|
+
const totalSize = files.reduce((sum, file) => sum + file.data.byteLength, 0);
|
|
50356
|
+
let transferredBeforeFile = 0;
|
|
50357
|
+
for (const file of files) {
|
|
50358
|
+
const transferredAtFileStart = transferredBeforeFile;
|
|
50359
|
+
yield writeProtocolV2File({
|
|
50360
|
+
commands: this.device.commands,
|
|
50361
|
+
path: file.path,
|
|
50362
|
+
data: file.data,
|
|
50363
|
+
totalSize: file.data.byteLength,
|
|
50364
|
+
chunkSize: this.params.chunkSize,
|
|
50365
|
+
timeoutMs: this.params.timeoutMs,
|
|
50366
|
+
paceMs: this.params.paceMs,
|
|
50367
|
+
overwrite: true,
|
|
50368
|
+
append: false,
|
|
50369
|
+
throwIfAborted: () => this.throwIfAborted(),
|
|
50370
|
+
onProgress: progress => {
|
|
50371
|
+
if (typeof this.postMessage !== 'function')
|
|
50372
|
+
return;
|
|
50373
|
+
const transferredBytes = transferredAtFileStart + progress.transferredBytes;
|
|
50374
|
+
this.postMessage(createUiMessage(UI_REQUEST.DEVICE_PROGRESS, Object.assign(Object.assign({}, progress), { progress: Math.floor((transferredBytes / totalSize) * 100), transferredBytes, totalBytes: totalSize })));
|
|
50375
|
+
},
|
|
50376
|
+
});
|
|
50377
|
+
transferredBeforeFile += file.data.byteLength;
|
|
50378
|
+
}
|
|
50379
|
+
this.throwIfAborted();
|
|
50380
|
+
const response = yield this.updateNft(bundle.basename);
|
|
50381
|
+
return {
|
|
50382
|
+
basename: bundle.basename,
|
|
50383
|
+
imagePath: files[0].path,
|
|
50384
|
+
thumbnailPath: files[1].path,
|
|
50385
|
+
metadataPath: files[2].path,
|
|
50386
|
+
totalSize,
|
|
50387
|
+
nftUpdated: true,
|
|
50388
|
+
message: (_a = response.message) === null || _a === void 0 ? void 0 : _a.message,
|
|
50389
|
+
};
|
|
50390
|
+
});
|
|
50391
|
+
}
|
|
50392
|
+
}
|
|
50393
|
+
|
|
50355
50394
|
class FileWrite extends BaseMethod {
|
|
50356
50395
|
getSupportedProtocols() {
|
|
50357
50396
|
return ['V2'];
|
|
@@ -50476,13 +50515,6 @@ class CipherKeyValue extends BaseMethod {
|
|
|
50476
50515
|
}
|
|
50477
50516
|
}
|
|
50478
50517
|
|
|
50479
|
-
function isDeviceLockedError(error) {
|
|
50480
|
-
return (typeof error === 'object' &&
|
|
50481
|
-
error !== null &&
|
|
50482
|
-
'errorCode' in error &&
|
|
50483
|
-
error.errorCode === hdShared.HardwareErrorCode.DeviceLocked);
|
|
50484
|
-
}
|
|
50485
|
-
|
|
50486
50518
|
const isProtocolV2UiEnabled = (method) => method.protocolV2UiMode !== 'none';
|
|
50487
50519
|
const getDisplayState = (value) => {
|
|
50488
50520
|
const visited = new Set();
|
|
@@ -50607,93 +50639,51 @@ class ProtocolV2UiInteractionCoordinator {
|
|
|
50607
50639
|
}
|
|
50608
50640
|
|
|
50609
50641
|
const Log$3 = getLogger(exports.LoggerNames.Core);
|
|
50610
|
-
const
|
|
50611
|
-
|
|
50612
|
-
const expectedPassphraseState = ((_a = method.payload) === null || _a === void 0 ? void 0 : _a.useEmptyPassphrase)
|
|
50613
|
-
? undefined
|
|
50614
|
-
: (_c = (_b = method.payload) === null || _b === void 0 ? void 0 : _b.passphraseState) !== null && _c !== void 0 ? _c : device.passphraseState;
|
|
50615
|
-
if (!method.useDevicePassphraseState ||
|
|
50616
|
-
typeof expectedPassphraseState !== 'string' ||
|
|
50617
|
-
expectedPassphraseState.length === 0) {
|
|
50618
|
-
return;
|
|
50619
|
-
}
|
|
50620
|
-
yield restoreProtocolV2WalletSession(device, expectedPassphraseState);
|
|
50621
|
-
Log$3.debug('Protocol V2 wallet session restored after unlock', { method: method.name });
|
|
50642
|
+
const createProtocolV2UnlockContext = () => ({
|
|
50643
|
+
preflightCompleted: false,
|
|
50622
50644
|
});
|
|
50623
|
-
function
|
|
50624
|
-
var _a, _b
|
|
50645
|
+
function runMethodWithUnlockPolicy(method, device, options = {}) {
|
|
50646
|
+
var _a, _b;
|
|
50625
50647
|
return __awaiter(this, void 0, void 0, function* () {
|
|
50648
|
+
const { context = createProtocolV2UnlockContext(), uiCoordinator, afterStatusBeforeUnlock, prepare, run: configuredRun, } = options;
|
|
50649
|
+
const run = configuredRun !== null && configuredRun !== void 0 ? configuredRun : (() => method.run());
|
|
50650
|
+
method.protocolV2UnlockContext = context;
|
|
50626
50651
|
const shouldEmitUi = isProtocolV2UiEnabled(method);
|
|
50627
50652
|
const shouldCoordinateUi = shouldEmitUi && uiCoordinator !== undefined;
|
|
50628
|
-
const
|
|
50629
|
-
|
|
50630
|
-
method.unlockPolicy === 'unlock-before-run' &&
|
|
50653
|
+
const requiresPreUnlock = device.isProtocolV2() &&
|
|
50654
|
+
(method.useDevicePassphraseState || method.unlockPolicy === 'unlock-before-run') &&
|
|
50631
50655
|
!((_a = device.isBootloader) === null || _a === void 0 ? void 0 : _a.call(device)) &&
|
|
50632
50656
|
!((_b = device.isRomloader) === null || _b === void 0 ? void 0 : _b.call(device));
|
|
50633
|
-
if (
|
|
50634
|
-
yield refreshProtocolV2DeviceStatus(device);
|
|
50635
|
-
|
|
50636
|
-
|
|
50637
|
-
|
|
50638
|
-
|
|
50639
|
-
!
|
|
50640
|
-
|
|
50641
|
-
|
|
50642
|
-
|
|
50643
|
-
|
|
50644
|
-
|
|
50645
|
-
|
|
50646
|
-
|
|
50647
|
-
|
|
50648
|
-
|
|
50649
|
-
|
|
50650
|
-
|
|
50651
|
-
|
|
50652
|
-
|
|
50653
|
-
|
|
50654
|
-
|
|
50655
|
-
if (shouldCoordinateUi) {
|
|
50656
|
-
uiCoordinator === null || uiCoordinator === void 0 ? void 0 : uiCoordinator.enterMethodInteraction(resolveProtocolV2UiInteraction(method));
|
|
50657
|
+
if (requiresPreUnlock && !context.preflightCompleted) {
|
|
50658
|
+
const status = yield refreshProtocolV2DeviceStatus(device);
|
|
50659
|
+
if (typeof (status === null || status === void 0 ? void 0 : status.unlocked) !== 'boolean') {
|
|
50660
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 DeviceStatus did not report an explicit unlock state.');
|
|
50661
|
+
}
|
|
50662
|
+
yield (afterStatusBeforeUnlock === null || afterStatusBeforeUnlock === void 0 ? void 0 : afterStatusBeforeUnlock());
|
|
50663
|
+
if (!status.unlocked) {
|
|
50664
|
+
const unlockInteraction = shouldCoordinateUi
|
|
50665
|
+
? uiCoordinator.enterUnlockInteraction(method.name)
|
|
50666
|
+
: undefined;
|
|
50667
|
+
const unlockedStatus = yield device.unlockDevice(undefined, shouldCoordinateUi
|
|
50668
|
+
? { emitUiEvent: false, interaction: unlockInteraction }
|
|
50669
|
+
: {
|
|
50670
|
+
source: 'unlock-coordinator',
|
|
50671
|
+
reason: 'device-locked',
|
|
50672
|
+
deviceOnly: true,
|
|
50673
|
+
method: method.name,
|
|
50674
|
+
});
|
|
50675
|
+
if ((unlockedStatus === null || unlockedStatus === void 0 ? void 0 : unlockedStatus.unlocked) !== true) {
|
|
50676
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 device remained locked after the unlock flow.');
|
|
50677
|
+
}
|
|
50678
|
+
Log$3.debug('Protocol V2 pre-unlock completed', { method: method.name });
|
|
50657
50679
|
}
|
|
50658
|
-
|
|
50680
|
+
context.preflightCompleted = true;
|
|
50659
50681
|
}
|
|
50682
|
+
yield (prepare === null || prepare === void 0 ? void 0 : prepare());
|
|
50660
50683
|
if (shouldCoordinateUi) {
|
|
50661
|
-
uiCoordinator
|
|
50662
|
-
}
|
|
50663
|
-
try {
|
|
50664
|
-
return yield method.run();
|
|
50665
|
-
}
|
|
50666
|
-
catch (error) {
|
|
50667
|
-
if (!isProtocolV2 || method.unlockPolicy !== 'retry-on-locked' || !isDeviceLockedError(error)) {
|
|
50668
|
-
throw error;
|
|
50669
|
-
}
|
|
50670
|
-
Log$3.debug('Protocol V2 unlock retry triggered', { method: method.name });
|
|
50671
|
-
const unlockInteraction = shouldCoordinateUi
|
|
50672
|
-
? uiCoordinator === null || uiCoordinator === void 0 ? void 0 : uiCoordinator.enterUnlockInteraction(method.name)
|
|
50673
|
-
: undefined;
|
|
50674
|
-
yield device.unlockDevice(undefined, shouldCoordinateUi
|
|
50675
|
-
? { emitUiEvent: false, interaction: unlockInteraction }
|
|
50676
|
-
: {
|
|
50677
|
-
source: 'unlock-coordinator',
|
|
50678
|
-
reason: 'device-locked',
|
|
50679
|
-
deviceOnly: true,
|
|
50680
|
-
method: method.name,
|
|
50681
|
-
});
|
|
50682
|
-
Log$3.debug('Protocol V2 unlock completed', { method: method.name });
|
|
50683
|
-
yield restoreExpectedWalletSessionAfterUnlock(method, device);
|
|
50684
|
-
if (shouldCoordinateUi) {
|
|
50685
|
-
uiCoordinator === null || uiCoordinator === void 0 ? void 0 : uiCoordinator.resumeMethodInteraction();
|
|
50686
|
-
}
|
|
50687
|
-
try {
|
|
50688
|
-
const response = yield method.run();
|
|
50689
|
-
Log$3.debug('Protocol V2 method retry completed', { method: method.name, success: true });
|
|
50690
|
-
return response;
|
|
50691
|
-
}
|
|
50692
|
-
catch (retryError) {
|
|
50693
|
-
Log$3.debug('Protocol V2 method retry completed', { method: method.name, success: false });
|
|
50694
|
-
throw retryError;
|
|
50695
|
-
}
|
|
50684
|
+
uiCoordinator.enterMethodInteraction(resolveProtocolV2UiInteraction(method));
|
|
50696
50685
|
}
|
|
50686
|
+
return run();
|
|
50697
50687
|
});
|
|
50698
50688
|
}
|
|
50699
50689
|
|
|
@@ -50972,25 +50962,26 @@ class AllNetworkGetAddressBase extends BaseMethod {
|
|
|
50972
50962
|
this.device.on(DEVICE.PIN, onSignalAbort);
|
|
50973
50963
|
this.device.on(DEVICE.PASSPHRASE, onSignalAbort);
|
|
50974
50964
|
preCheckDeviceSupport(this.device, method);
|
|
50975
|
-
|
|
50976
|
-
|
|
50977
|
-
|
|
50978
|
-
|
|
50979
|
-
|
|
50980
|
-
|
|
50981
|
-
|
|
50982
|
-
|
|
50983
|
-
|
|
50984
|
-
|
|
50985
|
-
|
|
50986
|
-
|
|
50987
|
-
|
|
50988
|
-
|
|
50989
|
-
|
|
50990
|
-
|
|
50991
|
-
|
|
50992
|
-
|
|
50993
|
-
|
|
50965
|
+
const response = yield runMethodWithUnlockPolicy(method, this.device, {
|
|
50966
|
+
context: this.protocolV2UnlockContext,
|
|
50967
|
+
prepare: () => __awaiter(this, void 0, void 0, function* () {
|
|
50968
|
+
if (this.temporarySafetyCheckPrompted) {
|
|
50969
|
+
method.temporarySafetyCheckPrompted = true;
|
|
50970
|
+
}
|
|
50971
|
+
else {
|
|
50972
|
+
const appliedTemporarySafetyCheck = yield method.checkSafetyLevelOnTestNet();
|
|
50973
|
+
if (appliedTemporarySafetyCheck) {
|
|
50974
|
+
this.temporarySafetyCheckPrompted = true;
|
|
50975
|
+
}
|
|
50976
|
+
}
|
|
50977
|
+
if (this.device.isProtocolV2() && this.payload.passphraseState) {
|
|
50978
|
+
const passphraseStateSafety = yield this.device.checkPassphraseStateSafety(this.payload.passphraseState, false, this.payload.skipPassphraseCheck);
|
|
50979
|
+
if (!passphraseStateSafety) {
|
|
50980
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckPassphraseStateError);
|
|
50981
|
+
}
|
|
50982
|
+
}
|
|
50983
|
+
}),
|
|
50984
|
+
});
|
|
50994
50985
|
if (!Array.isArray(response) || response.length === 0) {
|
|
50995
50986
|
throw new Error('No response');
|
|
50996
50987
|
}
|
|
@@ -60235,6 +60226,7 @@ var ApiMethods = /*#__PURE__*/Object.freeze({
|
|
|
60235
60226
|
deviceReboot: DeviceReboot,
|
|
60236
60227
|
deviceGetOnboardingStatus: DeviceGetOnboardingStatus,
|
|
60237
60228
|
deviceUploadWallpaper: DeviceUploadWallpaper,
|
|
60229
|
+
deviceUploadNft: DeviceUploadNft,
|
|
60238
60230
|
uploadPortfolio: UploadPortfolio,
|
|
60239
60231
|
cipherKeyValue: CipherKeyValue,
|
|
60240
60232
|
allNetworkGetAddress: AllNetworkGetAddress,
|
|
@@ -60619,6 +60611,44 @@ const getSynchronize = (mutex) => {
|
|
|
60619
60611
|
return (action, lockId) => lock(lockId).then(unlock => Promise.resolve().then(action).finally(unlock));
|
|
60620
60612
|
};
|
|
60621
60613
|
|
|
60614
|
+
const DEFAULT_UI_PROGRESS_INTERVAL_MS = 250;
|
|
60615
|
+
const normalizeProgress = (progress) => {
|
|
60616
|
+
if (typeof progress !== 'number' || !Number.isFinite(progress)) {
|
|
60617
|
+
return undefined;
|
|
60618
|
+
}
|
|
60619
|
+
return Math.max(0, Math.min(100, Math.floor(progress)));
|
|
60620
|
+
};
|
|
60621
|
+
const createUiProgressMessageFilter = (intervalMs = DEFAULT_UI_PROGRESS_INTERVAL_MS, now = Date.now) => {
|
|
60622
|
+
const stateByType = new Map();
|
|
60623
|
+
return (message) => {
|
|
60624
|
+
if (!('event' in message) ||
|
|
60625
|
+
message.event !== UI_EVENT ||
|
|
60626
|
+
(message.type !== UI_REQUEST.DEVICE_PROGRESS && message.type !== UI_REQUEST.FIRMWARE_PROGRESS)) {
|
|
60627
|
+
return true;
|
|
60628
|
+
}
|
|
60629
|
+
const key = message.type === UI_REQUEST.FIRMWARE_PROGRESS
|
|
60630
|
+
? `${message.type}:${message.payload.progressType}`
|
|
60631
|
+
: message.type;
|
|
60632
|
+
const progress = normalizeProgress(message.payload.progress);
|
|
60633
|
+
const currentTime = now();
|
|
60634
|
+
const state = stateByType.get(key);
|
|
60635
|
+
if (!state) {
|
|
60636
|
+
stateByType.set(key, { lastEmittedAt: currentTime, lastProgress: progress });
|
|
60637
|
+
return true;
|
|
60638
|
+
}
|
|
60639
|
+
const isBoundary = progress === 0 || progress === 100;
|
|
60640
|
+
if (isBoundary && progress === state.lastProgress) {
|
|
60641
|
+
return false;
|
|
60642
|
+
}
|
|
60643
|
+
const startsNewPhase = progress !== undefined && state.lastProgress !== undefined && progress < state.lastProgress;
|
|
60644
|
+
if (!isBoundary && !startsNewPhase && currentTime - state.lastEmittedAt < intervalMs) {
|
|
60645
|
+
return false;
|
|
60646
|
+
}
|
|
60647
|
+
stateByType.set(key, { lastEmittedAt: currentTime, lastProgress: progress });
|
|
60648
|
+
return true;
|
|
60649
|
+
};
|
|
60650
|
+
};
|
|
60651
|
+
|
|
60622
60652
|
const Log = getLogger(exports.LoggerNames.Core);
|
|
60623
60653
|
const PRE_INITIALIZE_TTL_MS = 60 * 1000;
|
|
60624
60654
|
const preWarmInflight = new Map();
|
|
@@ -60684,7 +60714,12 @@ const callAPI = (context, message) => __awaiter(void 0, void 0, void 0, function
|
|
|
60684
60714
|
try {
|
|
60685
60715
|
method = findMethod(message);
|
|
60686
60716
|
method.connector = _connector;
|
|
60687
|
-
|
|
60717
|
+
const shouldPostMessage = createUiProgressMessageFilter();
|
|
60718
|
+
method.postMessage = event => {
|
|
60719
|
+
if (shouldPostMessage(event)) {
|
|
60720
|
+
postMessage(event);
|
|
60721
|
+
}
|
|
60722
|
+
};
|
|
60688
60723
|
(_a = method.setContext) === null || _a === void 0 ? void 0 : _a.call(method, context);
|
|
60689
60724
|
method.requestContext = createRequestContext(method.responseID, method.name, {
|
|
60690
60725
|
sdkInstanceId: context.sdkInstanceId,
|
|
@@ -60871,7 +60906,7 @@ const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, voi
|
|
|
60871
60906
|
}
|
|
60872
60907
|
yield waitForPendingPromise(getPrePendingCallPromise, setPrePendingCallPromise);
|
|
60873
60908
|
const inner = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
60874
|
-
var _j, _k
|
|
60909
|
+
var _j, _k;
|
|
60875
60910
|
method.assertProtocolSupported(device.getProtocol(), device.getCurrentFirmwareType());
|
|
60876
60911
|
const versionRange = device.getCurrentMethodVersionRange(type => method.getVersionRange()[type]);
|
|
60877
60912
|
const currentFirmwareVersion = (_j = device.getCurrentFirmwareVersionString()) !== null && _j !== void 0 ? _j : '0.0.0';
|
|
@@ -60940,48 +60975,60 @@ const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, voi
|
|
|
60940
60975
|
}
|
|
60941
60976
|
return Promise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceUnexpectedMode, unexpectedMode));
|
|
60942
60977
|
}
|
|
60943
|
-
if (method.deviceId && method.checkDeviceId) {
|
|
60944
|
-
const isSameDeviceID = yield checkLiveDeviceId(device, method.deviceId);
|
|
60945
|
-
if (!isSameDeviceID) {
|
|
60946
|
-
return Promise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckDeviceIdError));
|
|
60947
|
-
}
|
|
60948
|
-
}
|
|
60949
|
-
method.checkFirmwareRelease();
|
|
60950
|
-
method.checkDeviceSupportFeature();
|
|
60951
|
-
if (_deviceList && device.features && !device.isProtocolV2()) {
|
|
60952
|
-
yield TransportManager.reconfigure(device.features);
|
|
60953
|
-
}
|
|
60954
|
-
checkPassphraseEnableState(method, device.features);
|
|
60955
|
-
if (shouldCheckPassphraseState(method, device)) {
|
|
60956
|
-
const support = device.supportNewPassphrase();
|
|
60957
|
-
if (!support.support) {
|
|
60958
|
-
return Promise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceNotSupportPassphrase, `Device not support passphrase, please update to ${support.require}`, {
|
|
60959
|
-
require: support.require,
|
|
60960
|
-
}));
|
|
60961
|
-
}
|
|
60962
|
-
yield ensureProtocolV2WalletSessionUnlocked(device);
|
|
60963
|
-
const passphraseStateSafety = yield device.checkPassphraseStateSafety((_l = method.payload) === null || _l === void 0 ? void 0 : _l.passphraseState, (_m = method.payload) === null || _m === void 0 ? void 0 : _m.useEmptyPassphrase, (_o = method.payload) === null || _o === void 0 ? void 0 : _o.skipPassphraseCheck, hasDeriveCardano(method));
|
|
60964
|
-
checkPassphraseEnableState(method, device.features);
|
|
60965
|
-
if (!passphraseStateSafety) {
|
|
60966
|
-
DevicePool.clearDeviceCache(method.payload.connectId);
|
|
60967
|
-
return Promise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckPassphraseStateError));
|
|
60968
|
-
}
|
|
60969
|
-
if (!device.isProtocolV2()) {
|
|
60970
|
-
postMessage(createUiMessage(UI_REQUEST.CLOSE_UI_PIN_WINDOW));
|
|
60971
|
-
}
|
|
60972
|
-
}
|
|
60973
|
-
try {
|
|
60974
|
-
yield method.checkSafetyLevelOnTestNet();
|
|
60975
|
-
}
|
|
60976
|
-
catch (e) {
|
|
60977
|
-
const error = e instanceof hdShared.HardwareError
|
|
60978
|
-
? e
|
|
60979
|
-
: hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'open safety check failed.');
|
|
60980
|
-
throw error;
|
|
60981
|
-
}
|
|
60982
|
-
(_q = (_p = method.device) === null || _p === void 0 ? void 0 : _p.commands) === null || _q === void 0 ? void 0 : _q.checkDisposed();
|
|
60983
60978
|
try {
|
|
60984
|
-
|
|
60979
|
+
let deviceIdCheckedDuringUnlockPreflight = false;
|
|
60980
|
+
const response = yield runMethodWithUnlockPolicy(method, device, {
|
|
60981
|
+
uiCoordinator: protocolV2UiCoordinator,
|
|
60982
|
+
afterStatusBeforeUnlock: () => {
|
|
60983
|
+
if (method.deviceId && method.checkDeviceId) {
|
|
60984
|
+
if (!device.checkDeviceId(method.deviceId)) {
|
|
60985
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckDeviceIdError);
|
|
60986
|
+
}
|
|
60987
|
+
deviceIdCheckedDuringUnlockPreflight = true;
|
|
60988
|
+
}
|
|
60989
|
+
},
|
|
60990
|
+
prepare: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
60991
|
+
var _l, _m, _o, _p, _q;
|
|
60992
|
+
if (method.deviceId && method.checkDeviceId && !deviceIdCheckedDuringUnlockPreflight) {
|
|
60993
|
+
const isSameDeviceID = yield checkLiveDeviceId(device, method.deviceId);
|
|
60994
|
+
if (!isSameDeviceID) {
|
|
60995
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckDeviceIdError);
|
|
60996
|
+
}
|
|
60997
|
+
}
|
|
60998
|
+
method.checkFirmwareRelease();
|
|
60999
|
+
method.checkDeviceSupportFeature();
|
|
61000
|
+
if (_deviceList && device.features && !device.isProtocolV2()) {
|
|
61001
|
+
yield TransportManager.reconfigure(device.features);
|
|
61002
|
+
}
|
|
61003
|
+
checkPassphraseEnableState(method, device.features);
|
|
61004
|
+
if (shouldCheckPassphraseState(method, device)) {
|
|
61005
|
+
const support = device.supportNewPassphrase();
|
|
61006
|
+
if (!support.support) {
|
|
61007
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceNotSupportPassphrase, `Device not support passphrase, please update to ${support.require}`, {
|
|
61008
|
+
require: support.require,
|
|
61009
|
+
});
|
|
61010
|
+
}
|
|
61011
|
+
const passphraseStateSafety = yield device.checkPassphraseStateSafety((_l = method.payload) === null || _l === void 0 ? void 0 : _l.passphraseState, (_m = method.payload) === null || _m === void 0 ? void 0 : _m.useEmptyPassphrase, (_o = method.payload) === null || _o === void 0 ? void 0 : _o.skipPassphraseCheck, hasDeriveCardano(method));
|
|
61012
|
+
checkPassphraseEnableState(method, device.features);
|
|
61013
|
+
if (!passphraseStateSafety) {
|
|
61014
|
+
DevicePool.clearDeviceCache(method.payload.connectId);
|
|
61015
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckPassphraseStateError);
|
|
61016
|
+
}
|
|
61017
|
+
if (!device.isProtocolV2()) {
|
|
61018
|
+
postMessage(createUiMessage(UI_REQUEST.CLOSE_UI_PIN_WINDOW));
|
|
61019
|
+
}
|
|
61020
|
+
}
|
|
61021
|
+
try {
|
|
61022
|
+
yield method.checkSafetyLevelOnTestNet();
|
|
61023
|
+
}
|
|
61024
|
+
catch (e) {
|
|
61025
|
+
throw e instanceof hdShared.HardwareError
|
|
61026
|
+
? e
|
|
61027
|
+
: hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'open safety check failed.');
|
|
61028
|
+
}
|
|
61029
|
+
(_q = (_p = method.device) === null || _p === void 0 ? void 0 : _p.commands) === null || _q === void 0 ? void 0 : _q.checkDisposed();
|
|
61030
|
+
}),
|
|
61031
|
+
});
|
|
60985
61032
|
messageResponse = createResponseMessage(method.responseID, true, response);
|
|
60986
61033
|
requestQueue.resolveRequest(method.responseID, messageResponse);
|
|
60987
61034
|
completeMethodRequestContext(method);
|
|
@@ -61820,6 +61867,7 @@ exports.getLog = getLog;
|
|
|
61820
61867
|
exports.getLogBlockLabel = getLogBlockLabel;
|
|
61821
61868
|
exports.getLogger = getLogger;
|
|
61822
61869
|
exports.getMethodVersionRange = getMethodVersionRange;
|
|
61870
|
+
exports.getNftSize = getNftSize;
|
|
61823
61871
|
exports.getOutputScriptType = getOutputScriptType;
|
|
61824
61872
|
exports.getSDKVersion = getSDKVersion;
|
|
61825
61873
|
exports.getSafeLogPayload = getSafeLogPayload;
|