@onekeyfe/hd-core 1.2.0-alpha.21 → 1.2.0-alpha.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__tests__/DeviceCommands.test.ts +85 -0
- package/__tests__/connectSettings.test.ts +47 -5
- package/__tests__/device-identity.test.ts +24 -2
- package/__tests__/device-settings.test.ts +2 -2
- package/__tests__/device-wallet-session-store.test.ts +152 -7
- package/__tests__/firmware-update/check-all-firmware-release.test.ts +86 -0
- package/__tests__/firmware-update/firmware-artifact-source.test.ts +119 -0
- package/__tests__/firmware-update/firmware-host-binding.test.ts +70 -0
- package/__tests__/firmware-update/firmware-update-capabilities.test.ts +13 -0
- package/__tests__/firmware-update/firmware-update-plan.test.ts +326 -0
- package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +213 -0
- package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +39 -30
- package/__tests__/firmware-update/firmware-upload-source.test.ts +70 -0
- package/__tests__/logBlockEvent.test.ts +17 -0
- package/__tests__/open-wallet-session.test.ts +311 -12
- package/__tests__/pro2Wallpaper.test.ts +7 -18
- package/__tests__/protocol-v2-unlock-policy.test.ts +45 -0
- package/__tests__/protocol-v2.test.ts +685 -177
- package/__tests__/public-device-state-api.test.ts +69 -62
- package/__tests__/public-pro2-api-boundary.test.ts +8 -34
- package/dist/api/BaseMethod.d.ts +2 -1
- package/dist/api/BaseMethod.d.ts.map +1 -1
- package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
- package/dist/api/ClearSessionCache.d.ts.map +1 -1
- package/dist/api/FirmwareUpdate.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV2.d.ts +11 -0
- package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV3.d.ts +7 -3
- package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV4.d.ts +29 -10
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/GetPassphraseState.d.ts.map +1 -1
- package/dist/api/OpenWalletSession.d.ts.map +1 -1
- package/dist/api/conflux/ConfluxGetAddress.d.ts +1 -0
- package/dist/api/conflux/ConfluxGetAddress.d.ts.map +1 -1
- package/dist/api/conflux/ConfluxSignMessage.d.ts +1 -0
- package/dist/api/conflux/ConfluxSignMessage.d.ts.map +1 -1
- package/dist/api/conflux/ConfluxSignMessageCIP23.d.ts +1 -0
- package/dist/api/conflux/ConfluxSignMessageCIP23.d.ts.map +1 -1
- package/dist/api/conflux/ConfluxSignTransaction.d.ts +1 -0
- package/dist/api/conflux/ConfluxSignTransaction.d.ts.map +1 -1
- package/dist/api/device/DeviceUnlock.d.ts +1 -1
- package/dist/api/device/DeviceUnlock.d.ts.map +1 -1
- package/dist/api/device/DeviceUpdateBootloader.d.ts +5 -1
- package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
- package/dist/api/device/DeviceWipe.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareArtifactSource.d.ts +25 -0
- package/dist/api/firmware/FirmwareArtifactSource.d.ts.map +1 -0
- package/dist/api/firmware/FirmwareHostBinding.d.ts +6 -0
- package/dist/api/firmware/FirmwareHostBinding.d.ts.map +1 -0
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +7 -0
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts +3 -0
- package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts.map +1 -0
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts +23 -0
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +1 -0
- package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts +30 -0
- package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +1 -0
- package/dist/api/firmware/getBinary.d.ts +7 -0
- package/dist/api/firmware/getBinary.d.ts.map +1 -1
- package/dist/api/firmware/updateBootloader.d.ts +2 -0
- package/dist/api/firmware/updateBootloader.d.ts.map +1 -1
- package/dist/api/firmware/uploadFirmware.d.ts +9 -1
- package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
- package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
- package/dist/api/index.d.ts +0 -17
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/nexa/NexaSignTransaction.d.ts +1 -0
- package/dist/api/nexa/NexaSignTransaction.d.ts.map +1 -1
- package/dist/api/stellar/StellarSignTransaction.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/data-manager/DataManager.d.ts +1 -0
- package/dist/data-manager/DataManager.d.ts.map +1 -1
- package/dist/data-manager/connectSettings.d.ts.map +1 -1
- package/dist/device/Device.d.ts +3 -2
- package/dist/device/Device.d.ts.map +1 -1
- package/dist/device/DeviceCommands.d.ts.map +1 -1
- package/dist/device/DeviceStateMapper.d.ts.map +1 -1
- package/dist/device/DeviceStateProjector.d.ts.map +1 -1
- package/dist/events/device.d.ts +1 -0
- package/dist/events/device.d.ts.map +1 -1
- package/dist/events/logBlockEvent.d.ts.map +1 -1
- package/dist/events/ui-request.d.ts +1 -0
- package/dist/events/ui-request.d.ts.map +1 -1
- package/dist/index.d.ts +273 -230
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3060 -1676
- package/dist/inject.d.ts.map +1 -1
- package/dist/lowLevelInject.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/settingsUnlockPolicy.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/unlockPolicy.d.ts +4 -0
- package/dist/protocols/protocol-v2/unlockPolicy.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
- package/dist/topLevelInject.d.ts.map +1 -1
- package/dist/types/api/checkAllFirmwareRelease.d.ts +3 -0
- package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
- package/dist/types/api/deviceUnlock.d.ts +2 -2
- package/dist/types/api/deviceUnlock.d.ts.map +1 -1
- package/dist/types/api/deviceUpdateBootloader.d.ts +6 -0
- package/dist/types/api/deviceUpdateBootloader.d.ts.map +1 -1
- package/dist/types/api/export.d.ts +4 -1
- package/dist/types/api/export.d.ts.map +1 -1
- package/dist/types/api/firmwareUpdate.d.ts +69 -0
- package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
- package/dist/types/api/firmwareUpdateCapabilities.d.ts +9 -0
- package/dist/types/api/firmwareUpdateCapabilities.d.ts.map +1 -0
- package/dist/types/api/firmwareUpdatePlan.d.ts +27 -0
- package/dist/types/api/firmwareUpdatePlan.d.ts.map +1 -0
- package/dist/types/api/firmwareUpdatePreparedPlan.d.ts +42 -0
- package/dist/types/api/firmwareUpdatePreparedPlan.d.ts.map +1 -0
- package/dist/types/api/getPassphraseState.d.ts.map +1 -1
- package/dist/types/api/index.d.ts +10 -19
- package/dist/types/api/index.d.ts.map +1 -1
- package/dist/types/api/openWalletSession.d.ts +1 -0
- package/dist/types/api/openWalletSession.d.ts.map +1 -1
- package/dist/types/api/protocolV2.d.ts +3 -76
- package/dist/types/api/protocolV2.d.ts.map +1 -1
- package/dist/types/api/sessionCache.d.ts +4 -1
- package/dist/types/api/sessionCache.d.ts.map +1 -1
- package/dist/types/settings.d.ts +13 -0
- package/dist/types/settings.d.ts.map +1 -1
- package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
- package/dist/utils/deviceInfoUtils.d.ts.map +1 -1
- package/dist/utils/patch.d.ts +1 -1
- package/dist/utils/patch.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/api/BaseMethod.ts +8 -3
- package/src/api/CheckAllFirmwareRelease.ts +23 -3
- package/src/api/ClearSessionCache.ts +4 -0
- package/src/api/FirmwareUpdate.ts +8 -1
- package/src/api/FirmwareUpdateV2.ts +292 -120
- package/src/api/FirmwareUpdateV3.ts +256 -55
- package/src/api/FirmwareUpdateV4.ts +821 -331
- package/src/api/GetPassphraseState.ts +11 -5
- package/src/api/OpenWalletSession.ts +74 -25
- package/src/api/UploadPortfolio.ts +1 -1
- package/src/api/conflux/ConfluxGetAddress.ts +2 -0
- package/src/api/conflux/ConfluxSignMessage.ts +2 -0
- package/src/api/conflux/ConfluxSignMessageCIP23.ts +2 -0
- package/src/api/conflux/ConfluxSignTransaction.ts +2 -0
- package/src/api/device/DeviceChangePin.ts +1 -1
- package/src/api/device/DeviceUnlock.ts +1 -2
- package/src/api/device/DeviceUpdateBootloader.ts +122 -6
- package/src/api/device/DeviceWipe.ts +3 -1
- package/src/api/firmware/FirmwareArtifactSource.ts +278 -0
- package/src/api/firmware/FirmwareHostBinding.ts +100 -0
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +50 -0
- package/src/api/firmware/FirmwareUpdateCapabilities.ts +9 -0
- package/src/api/firmware/FirmwareUpdatePlan.ts +621 -0
- package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +392 -0
- package/src/api/firmware/updateBootloader.ts +19 -4
- package/src/api/firmware/uploadFirmware.ts +140 -22
- package/src/api/helpers/protocolV2FileWrite.ts +6 -0
- package/src/api/index.ts +0 -18
- package/src/api/nexa/NexaSignTransaction.ts +2 -0
- package/src/api/protocol-v2/DeviceUploadWallpaper.ts +1 -1
- package/src/core/index.ts +1 -0
- package/src/data/messages/messages-protocol-v2.json +35 -1
- package/src/data-manager/DataManager.ts +33 -33
- package/src/data-manager/connectSettings.ts +11 -0
- package/src/device/Device.ts +80 -67
- package/src/device/DeviceCommands.ts +76 -159
- package/src/device/DeviceStateMapper.ts +18 -1
- package/src/device/DeviceStateProjector.ts +7 -1
- package/src/events/device.ts +1 -0
- package/src/events/logBlockEvent.ts +1 -14
- package/src/events/ui-request.ts +1 -0
- package/src/index.ts +5 -0
- package/src/inject.ts +22 -25
- package/src/lowLevelInject.ts +5 -1
- package/src/protocols/protocol-v2/settingsUnlockPolicy.ts +2 -3
- package/src/protocols/protocol-v2/unlockPolicy.ts +105 -0
- package/src/protocols/protocol-v2/unlockRetry.ts +1 -3
- package/src/protocols/protocol-v2/walletSession.ts +86 -9
- package/src/topLevelInject.ts +5 -1
- package/src/types/api/checkAllFirmwareRelease.ts +3 -0
- package/src/types/api/deviceUnlock.ts +2 -5
- package/src/types/api/deviceUpdateBootloader.ts +6 -0
- package/src/types/api/export.ts +18 -0
- package/src/types/api/firmwareUpdate.ts +76 -0
- package/src/types/api/firmwareUpdateCapabilities.ts +9 -0
- package/src/types/api/firmwareUpdatePlan.ts +36 -0
- package/src/types/api/firmwareUpdatePreparedPlan.ts +53 -0
- package/src/types/api/getPassphraseState.ts +4 -3
- package/src/types/api/index.ts +14 -34
- package/src/types/api/openWalletSession.ts +2 -0
- package/src/types/api/protocolV2.ts +3 -156
- package/src/types/api/sessionCache.ts +9 -4
- package/src/types/settings.ts +13 -0
- package/src/utils/deviceFeaturesUtils.ts +5 -1
- package/src/utils/deviceInfoUtils.ts +3 -16
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ERRORS, HardwareError, HardwareErrorCode } from '@onekeyfe/hd-shared';
|
|
2
2
|
import {
|
|
3
3
|
DeviceErrorCode,
|
|
4
|
+
DeviceSessionErrorCode,
|
|
4
5
|
type FailureType,
|
|
5
6
|
type Messages,
|
|
6
7
|
type Transport,
|
|
@@ -8,7 +9,6 @@ import {
|
|
|
8
9
|
} from '@onekeyfe/hd-transport';
|
|
9
10
|
|
|
10
11
|
import TransportManager from '../data-manager/TransportManager';
|
|
11
|
-
import DataManager from '../data-manager/DataManager';
|
|
12
12
|
import { LoggerNames, getLogger, patchFeatures } from '../utils';
|
|
13
13
|
import { DEVICE, type PassphraseRequestPayload } from '../events';
|
|
14
14
|
import { DeviceModelToTypes } from '../types';
|
|
@@ -38,10 +38,6 @@ type TypedCallResponseMap = {
|
|
|
38
38
|
};
|
|
39
39
|
export type DefaultMessageResponse = TypedCallResponseMap[MessageKey];
|
|
40
40
|
|
|
41
|
-
const MAX_DEBUG_ARRAY_ITEMS = 20;
|
|
42
|
-
const MAX_DEBUG_OBJECT_KEYS = 40;
|
|
43
|
-
const MAX_DEBUG_STRING_LENGTH = 512;
|
|
44
|
-
const MAX_DEBUG_DEPTH = 4;
|
|
45
41
|
const HIGH_VOLUME_DEBUG_CALLS = new Set([
|
|
46
42
|
'FilesystemFileRead',
|
|
47
43
|
'FilesystemFileWrite',
|
|
@@ -52,106 +48,16 @@ const HIGH_VOLUME_DEBUG_CALLS = new Set([
|
|
|
52
48
|
'FirmwareUpload',
|
|
53
49
|
'ResourceAck',
|
|
54
50
|
]);
|
|
55
|
-
const
|
|
51
|
+
const DEVICE_SESSION_CALLS = new Set([
|
|
52
|
+
'DeviceSessionGet',
|
|
53
|
+
'DeviceSessionAskPin',
|
|
54
|
+
'DeviceSessionAskPassphrase',
|
|
55
|
+
]);
|
|
56
56
|
|
|
57
57
|
function shouldReduceDebugForCall(type: string) {
|
|
58
58
|
return HIGH_VOLUME_DEBUG_CALLS.has(type);
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
function shouldBlockDebugForCall(type: string) {
|
|
62
|
-
return SENSITIVE_DEBUG_CALLS.has(type);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function getBinaryByteLength(value: unknown): number | undefined {
|
|
66
|
-
if (value instanceof ArrayBuffer) {
|
|
67
|
-
return value.byteLength;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (ArrayBuffer.isView(value)) {
|
|
71
|
-
return value.byteLength;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if (typeof Blob !== 'undefined' && value instanceof Blob) {
|
|
75
|
-
return value.size;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return undefined;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function summarizeRedactedData(value: unknown): string {
|
|
82
|
-
const byteLength = getBinaryByteLength(value);
|
|
83
|
-
if (byteLength !== undefined) {
|
|
84
|
-
return `[redacted data: ${byteLength} bytes]`;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
if (typeof value === 'string') {
|
|
88
|
-
return `[redacted data: string length=${value.length}]`;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (Array.isArray(value)) {
|
|
92
|
-
return `[redacted data: array length=${value.length}]`;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
if (value && typeof value === 'object') {
|
|
96
|
-
return `[redacted data: object keys=${Object.keys(value).length}]`;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
return `[redacted data: ${typeof value}]`;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function sanitizeDebugPayload(value: unknown, key = '', depth = 0): unknown {
|
|
103
|
-
if (key === 'data' && value !== null && value !== undefined) {
|
|
104
|
-
return summarizeRedactedData(value);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// Redact passphrase-bearing keys as defense in depth so wallet identifiers and
|
|
108
|
-
// host passphrases cannot reach diagnostic logs through a future call path.
|
|
109
|
-
if (key && /passphrase/i.test(key)) {
|
|
110
|
-
return '[redacted passphrase]';
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
const byteLength = getBinaryByteLength(value);
|
|
114
|
-
if (byteLength !== undefined) {
|
|
115
|
-
return `[binary: ${byteLength} bytes]`;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
if (typeof value === 'string') {
|
|
119
|
-
return value.length > MAX_DEBUG_STRING_LENGTH
|
|
120
|
-
? `${value.slice(0, MAX_DEBUG_STRING_LENGTH)}... (len=${value.length})`
|
|
121
|
-
: value;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (!value || typeof value !== 'object') {
|
|
125
|
-
return value;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if (depth >= MAX_DEBUG_DEPTH) {
|
|
129
|
-
return Array.isArray(value)
|
|
130
|
-
? `[array length=${value.length}]`
|
|
131
|
-
: `[object keys=${Object.keys(value).length}]`;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if (Array.isArray(value)) {
|
|
135
|
-
const items = value
|
|
136
|
-
.slice(0, MAX_DEBUG_ARRAY_ITEMS)
|
|
137
|
-
.map(item => sanitizeDebugPayload(item, key, depth + 1));
|
|
138
|
-
if (value.length > MAX_DEBUG_ARRAY_ITEMS) {
|
|
139
|
-
items.push(`... (${value.length - MAX_DEBUG_ARRAY_ITEMS} more)`);
|
|
140
|
-
}
|
|
141
|
-
return items;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const entries = Object.entries(value).slice(0, MAX_DEBUG_OBJECT_KEYS);
|
|
145
|
-
const sanitized: Record<string, unknown> = {};
|
|
146
|
-
entries.forEach(([entryKey, entryValue]) => {
|
|
147
|
-
sanitized[entryKey] = sanitizeDebugPayload(entryValue, entryKey, depth + 1);
|
|
148
|
-
});
|
|
149
|
-
if (Object.keys(value).length > MAX_DEBUG_OBJECT_KEYS) {
|
|
150
|
-
sanitized.__truncated__ = `${Object.keys(value).length - MAX_DEBUG_OBJECT_KEYS} more keys`;
|
|
151
|
-
}
|
|
152
|
-
return sanitized;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
61
|
/**
|
|
156
62
|
* Interactive acknowledgements must not inherit timeoutMs from the original call.
|
|
157
63
|
* User confirmation and PIN/passphrase entry have unbounded think time. Preserve only
|
|
@@ -337,20 +243,27 @@ export class DeviceCommands {
|
|
|
337
243
|
if (this.disposed) {
|
|
338
244
|
return;
|
|
339
245
|
}
|
|
340
|
-
this.
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
246
|
+
const activeCall = this.callPromise;
|
|
247
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
248
|
+
const cancellation = (async () => {
|
|
249
|
+
await this.dispose(true);
|
|
250
|
+
await activeCall?.catch(() => undefined);
|
|
251
|
+
})();
|
|
252
|
+
|
|
253
|
+
try {
|
|
254
|
+
await Promise.race([
|
|
255
|
+
cancellation,
|
|
256
|
+
new Promise<void>(resolve => {
|
|
257
|
+
timer = setTimeout(resolve, 10 * 1000);
|
|
258
|
+
}),
|
|
259
|
+
]);
|
|
260
|
+
} finally {
|
|
261
|
+
if (timer) clearTimeout(timer);
|
|
262
|
+
if (this.callPromise === activeCall) {
|
|
352
263
|
this.callPromise = undefined;
|
|
353
264
|
}
|
|
265
|
+
// The cancellation work may finish after the bounded wait.
|
|
266
|
+
cancellation.catch(() => undefined);
|
|
354
267
|
}
|
|
355
268
|
}
|
|
356
269
|
|
|
@@ -369,14 +282,15 @@ export class DeviceCommands {
|
|
|
369
282
|
const promise = this.transport.call(this.mainId, type, msg ?? {}, options) as any;
|
|
370
283
|
this.callPromise = promise;
|
|
371
284
|
const res = await promise;
|
|
372
|
-
if (
|
|
373
|
-
LogCore.debug('[DeviceCommands] [call] Received', res.type, res.message);
|
|
374
|
-
} else if (!shouldReduceDebug) {
|
|
285
|
+
if (!shouldReduceDebug) {
|
|
375
286
|
LogCore.debug('[DeviceCommands] [call] Received', res.type);
|
|
376
287
|
}
|
|
377
288
|
return res;
|
|
378
289
|
} catch (error) {
|
|
379
|
-
LogCore.debug('[DeviceCommands] [call] Received error',
|
|
290
|
+
LogCore.debug('[DeviceCommands] [call] Received error', {
|
|
291
|
+
request: type,
|
|
292
|
+
errorCode: error?.errorCode,
|
|
293
|
+
});
|
|
380
294
|
if (error.errorCode === HardwareErrorCode.BleDeviceBondError) {
|
|
381
295
|
return {
|
|
382
296
|
type: 'BleDeviceBondError',
|
|
@@ -397,9 +311,6 @@ export class DeviceCommands {
|
|
|
397
311
|
}
|
|
398
312
|
}
|
|
399
313
|
|
|
400
|
-
if (responseData) {
|
|
401
|
-
Log.debug('error response', responseData);
|
|
402
|
-
}
|
|
403
314
|
if (responseError === 'device disconnected during action') {
|
|
404
315
|
return { type: 'BridgeDeviceDisconnected', message: { error: responseError } } as any;
|
|
405
316
|
}
|
|
@@ -444,32 +355,6 @@ export class DeviceCommands {
|
|
|
444
355
|
);
|
|
445
356
|
}
|
|
446
357
|
|
|
447
|
-
// Structured log of actual outgoing payloads (skip acks)
|
|
448
|
-
try {
|
|
449
|
-
const skipTypes: MessageKey[] = [
|
|
450
|
-
'ButtonAck',
|
|
451
|
-
'PinMatrixAck',
|
|
452
|
-
'PassphraseAck',
|
|
453
|
-
'Cancel',
|
|
454
|
-
'DeviceSessionGet',
|
|
455
|
-
'BixinPinInputOnDevice',
|
|
456
|
-
'FilesystemFileRead',
|
|
457
|
-
'FilesystemFileWrite',
|
|
458
|
-
'FileRead',
|
|
459
|
-
'FileWrite',
|
|
460
|
-
'EmmcFileRead',
|
|
461
|
-
'EmmcFileWrite',
|
|
462
|
-
'FirmwareUpload',
|
|
463
|
-
'ResourceAck',
|
|
464
|
-
] as any;
|
|
465
|
-
if (!skipTypes.includes(type) && !shouldBlockDebugForCall(type) && msg) {
|
|
466
|
-
// Use debug channel to avoid noise escalation
|
|
467
|
-
Log.debug('[DeviceCommands] [typedCall] Sending payload', type, sanitizeDebugPayload(msg));
|
|
468
|
-
}
|
|
469
|
-
} catch (e) {
|
|
470
|
-
// ignore logging errors
|
|
471
|
-
}
|
|
472
|
-
|
|
473
358
|
const expectedTypes = Array.isArray(resType) ? resType : resType.split('|');
|
|
474
359
|
const response = await this._commonCall(type, msg, {
|
|
475
360
|
...options,
|
|
@@ -487,14 +372,11 @@ export class DeviceCommands {
|
|
|
487
372
|
// throw bridge network error
|
|
488
373
|
if (error instanceof HardwareError) {
|
|
489
374
|
if (error.errorCode === HardwareErrorCode.ResponseUnexpectTypeError) {
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
response: sanitizeDebugPayload(response.message),
|
|
496
|
-
});
|
|
497
|
-
}
|
|
375
|
+
Log.debug('[DeviceCommands] [typedCall] Unexpected response type', {
|
|
376
|
+
request: type,
|
|
377
|
+
expected: resType,
|
|
378
|
+
received: response.type,
|
|
379
|
+
});
|
|
498
380
|
// Do not intercept CallMethodError
|
|
499
381
|
// Do not intercept “assertType: Response of unexpected type” error
|
|
500
382
|
// Blocking the above two messages will not know what the specific error message is, and the specific error should be handled by the subsequent business logic.
|
|
@@ -533,12 +415,11 @@ export class DeviceCommands {
|
|
|
533
415
|
options?: TransportCallOptions
|
|
534
416
|
): Promise<DefaultMessageResponse> {
|
|
535
417
|
try {
|
|
536
|
-
if (shouldReduceDebugForCall(callType)
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
Log.debug('_filterCommonTypes: ', sanitizeDebugPayload(res));
|
|
418
|
+
if (!shouldReduceDebugForCall(callType)) {
|
|
419
|
+
Log.debug('_filterCommonTypes: ', {
|
|
420
|
+
request: callType,
|
|
421
|
+
response: res.type,
|
|
422
|
+
});
|
|
542
423
|
}
|
|
543
424
|
} catch (error) {
|
|
544
425
|
// ignore
|
|
@@ -599,6 +480,42 @@ export class DeviceCommands {
|
|
|
599
480
|
const isLegacyProtocolV2LockedFailure =
|
|
600
481
|
this.device.isProtocolV2() && /^device (?:is )?locked$/i.test(normalizedMessage);
|
|
601
482
|
if (
|
|
483
|
+
DEVICE_SESSION_CALLS.has(callType) &&
|
|
484
|
+
subcode === DeviceSessionErrorCode.DeviceSessionError_InvalidSession
|
|
485
|
+
) {
|
|
486
|
+
error = ERRORS.TypedError(HardwareErrorCode.WalletSessionInvalid, message, {
|
|
487
|
+
failureCode: code,
|
|
488
|
+
subcode,
|
|
489
|
+
firmwareMessage: message,
|
|
490
|
+
});
|
|
491
|
+
} else if (
|
|
492
|
+
DEVICE_SESSION_CALLS.has(callType) &&
|
|
493
|
+
subcode === DeviceSessionErrorCode.DeviceSessionError_UserCancelled
|
|
494
|
+
) {
|
|
495
|
+
error = ERRORS.TypedError(HardwareErrorCode.ActionCancelled, message, {
|
|
496
|
+
failureCode: code,
|
|
497
|
+
subcode,
|
|
498
|
+
firmwareMessage: message,
|
|
499
|
+
});
|
|
500
|
+
} else if (
|
|
501
|
+
DEVICE_SESSION_CALLS.has(callType) &&
|
|
502
|
+
subcode === DeviceSessionErrorCode.DeviceSessionError_AttachPinUnavailable
|
|
503
|
+
) {
|
|
504
|
+
error = ERRORS.TypedError(HardwareErrorCode.DeviceCheckUnlockTypeError, message, {
|
|
505
|
+
failureCode: code,
|
|
506
|
+
subcode,
|
|
507
|
+
firmwareMessage: message,
|
|
508
|
+
});
|
|
509
|
+
} else if (
|
|
510
|
+
DEVICE_SESSION_CALLS.has(callType) &&
|
|
511
|
+
subcode === DeviceSessionErrorCode.DeviceSessionError_PassphraseDisabled
|
|
512
|
+
) {
|
|
513
|
+
error = ERRORS.TypedError(HardwareErrorCode.DeviceNotOpenedPassphrase, message, {
|
|
514
|
+
failureCode: code,
|
|
515
|
+
subcode,
|
|
516
|
+
firmwareMessage: message,
|
|
517
|
+
});
|
|
518
|
+
} else if (
|
|
602
519
|
subcode === DeviceErrorCode.DeviceError_ActionCancelled ||
|
|
603
520
|
isLegacyProtocolV2ActionCancelledFailure
|
|
604
521
|
) {
|
|
@@ -29,6 +29,23 @@ const definedEntries = <T extends Record<string, unknown>>(value: T): T =>
|
|
|
29
29
|
Object.entries(value).filter(([, fieldValue]) => fieldValue !== undefined)
|
|
30
30
|
) as T;
|
|
31
31
|
|
|
32
|
+
const sanitizeRawFeatures = (features: Features): Features['raw'] => {
|
|
33
|
+
if (!features.raw) return undefined;
|
|
34
|
+
|
|
35
|
+
const raw = { ...features.raw };
|
|
36
|
+
if (raw.protocolV1Features) {
|
|
37
|
+
const { session_id: _sessionId, ...protocolV1Features } = raw.protocolV1Features;
|
|
38
|
+
const compatibilityFields = protocolV1Features as typeof protocolV1Features & {
|
|
39
|
+
sessionId?: string;
|
|
40
|
+
passphraseState?: string;
|
|
41
|
+
};
|
|
42
|
+
delete compatibilityFields.sessionId;
|
|
43
|
+
delete compatibilityFields.passphraseState;
|
|
44
|
+
raw.protocolV1Features = compatibilityFields as PROTO.Features;
|
|
45
|
+
}
|
|
46
|
+
return raw;
|
|
47
|
+
};
|
|
48
|
+
|
|
32
49
|
const imageVersion = (image?: DeviceFirmwareImageInfo | null) => image?.version ?? undefined;
|
|
33
50
|
|
|
34
51
|
const bytesToHex = (value: unknown): string | undefined => {
|
|
@@ -127,7 +144,7 @@ export const mapFeaturesToState = (features: Features): DeviceStatePatch => ({
|
|
|
127
144
|
},
|
|
128
145
|
capabilities: features.capabilities,
|
|
129
146
|
verification: definedEntries(features.verify ?? {}),
|
|
130
|
-
raw: features
|
|
147
|
+
raw: sanitizeRawFeatures(features),
|
|
131
148
|
});
|
|
132
149
|
|
|
133
150
|
export const mapProtocolV1FeaturesToState = (
|
|
@@ -16,6 +16,12 @@ export const projectFeatures = (state: StoredDeviceState): Features => {
|
|
|
16
16
|
delete publicRawFeatures.session_id;
|
|
17
17
|
delete publicRawFeatures.sessionId;
|
|
18
18
|
delete publicRawFeatures.passphraseState;
|
|
19
|
+
const publicRaw = snapshot.raw
|
|
20
|
+
? {
|
|
21
|
+
...snapshot.raw,
|
|
22
|
+
protocolV1Features: publicRawFeatures,
|
|
23
|
+
}
|
|
24
|
+
: undefined;
|
|
19
25
|
const rawOneKeyFeatures = snapshot.raw?.protocolV1OneKeyFeatures ?? {};
|
|
20
26
|
const bootloaderMode =
|
|
21
27
|
snapshot.protocol === 'V1'
|
|
@@ -84,7 +90,7 @@ export const projectFeatures = (state: StoredDeviceState): Features => {
|
|
|
84
90
|
se04BootVersion: snapshot.versions.se04Boot,
|
|
85
91
|
seVersion: snapshot.versions.se ?? null,
|
|
86
92
|
verify: snapshot.verification,
|
|
87
|
-
raw:
|
|
93
|
+
raw: publicRaw,
|
|
88
94
|
device_id: snapshot.identity.deviceId ?? undefined,
|
|
89
95
|
ble_name: snapshot.identity.bleName ?? undefined,
|
|
90
96
|
passphrase_protection: snapshot.status.passphraseProtection ?? undefined,
|
package/src/events/device.ts
CHANGED
|
@@ -54,6 +54,7 @@ export interface DeviceButtonRequestPayload extends Omit<PROTO.ButtonRequest, 'c
|
|
|
54
54
|
|
|
55
55
|
export type PassphraseRequestPayload = {
|
|
56
56
|
existsAttachPinUser?: boolean;
|
|
57
|
+
deviceOnly?: boolean;
|
|
57
58
|
source?: 'wallet-session-coordinator';
|
|
58
59
|
reason?: 'open-wallet' | 'session-recovery';
|
|
59
60
|
expectedPassphraseState?: string;
|
|
@@ -5,15 +5,6 @@ export const LogBlockEvent: Set<string> = new Set([
|
|
|
5
5
|
UI_RESPONSE.RECEIVE_PASSPHRASE,
|
|
6
6
|
]);
|
|
7
7
|
|
|
8
|
-
const LogBlockMethod: Set<string> = new Set([
|
|
9
|
-
'evmSignTypedData',
|
|
10
|
-
'openWalletSession',
|
|
11
|
-
'deviceUploadWallpaper',
|
|
12
|
-
'uploadPortfolio',
|
|
13
|
-
'fileWrite',
|
|
14
|
-
'fileRead',
|
|
15
|
-
]);
|
|
16
|
-
|
|
17
8
|
export function getLogBlockLabel(message: unknown): string | undefined {
|
|
18
9
|
if (!message || typeof message !== 'object') return undefined;
|
|
19
10
|
|
|
@@ -28,9 +19,5 @@ export function getLogBlockLabel(message: unknown): string | undefined {
|
|
|
28
19
|
}
|
|
29
20
|
|
|
30
21
|
const methodName = method ?? payload?.method;
|
|
31
|
-
|
|
32
|
-
return methodName;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return undefined;
|
|
22
|
+
return methodName;
|
|
36
23
|
}
|
package/src/events/ui-request.ts
CHANGED
|
@@ -107,6 +107,7 @@ export interface UiRequestPassphrase {
|
|
|
107
107
|
device: Device;
|
|
108
108
|
passphraseState?: string;
|
|
109
109
|
existsAttachPinUser?: boolean;
|
|
110
|
+
deviceOnly?: boolean;
|
|
110
111
|
source?: 'wallet-session-coordinator';
|
|
111
112
|
reason?: 'open-wallet' | 'session-recovery';
|
|
112
113
|
expectedPassphraseState?: string;
|
package/src/index.ts
CHANGED
|
@@ -19,6 +19,11 @@ export * from './types';
|
|
|
19
19
|
export { whitelist, whitelistExtension } from './data/config';
|
|
20
20
|
export { executeCallback, cleanupCallback };
|
|
21
21
|
export { preloadSessionCache } from './device/Device';
|
|
22
|
+
export {
|
|
23
|
+
getFirmwareUpdateHostBindingGeneration,
|
|
24
|
+
registerFirmwareUpdateHostBinding,
|
|
25
|
+
unregisterFirmwareUpdateHostBinding,
|
|
26
|
+
} from './api/firmware/FirmwareHostBinding';
|
|
22
27
|
|
|
23
28
|
const HardwareSdk = ({
|
|
24
29
|
init,
|
package/src/inject.ts
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { getFirmwareUpdateCapabilities } from './api/firmware/FirmwareUpdateCapabilities';
|
|
2
|
+
import {
|
|
3
|
+
prepareFirmwareUpdatePlan,
|
|
4
|
+
validateFirmwareUpdatePreparedPlan,
|
|
5
|
+
} from './api/firmware/FirmwareUpdatePreparedPlan';
|
|
6
|
+
import {
|
|
7
|
+
getFirmwareUpdateHostBindingGeneration,
|
|
8
|
+
registerFirmwareUpdateHostBinding,
|
|
9
|
+
unregisterFirmwareUpdateHostBinding,
|
|
10
|
+
} from './api/firmware/FirmwareHostBinding';
|
|
11
|
+
|
|
2
12
|
import type { EventEmitter } from 'events';
|
|
3
13
|
import type { CallMethod } from './events';
|
|
14
|
+
import type { Unsuccessful } from './types';
|
|
4
15
|
import type { CoreApi } from './types/api';
|
|
5
16
|
import type { AllNetworkAddress } from './types/api/allNetworkGetAddress';
|
|
6
17
|
|
|
@@ -68,7 +79,10 @@ export const inject = ({
|
|
|
68
79
|
|
|
69
80
|
call,
|
|
70
81
|
|
|
71
|
-
dispose
|
|
82
|
+
dispose: async () => {
|
|
83
|
+
unregisterFirmwareUpdateHostBinding();
|
|
84
|
+
await dispose();
|
|
85
|
+
},
|
|
72
86
|
|
|
73
87
|
uiResponse,
|
|
74
88
|
|
|
@@ -99,6 +113,12 @@ export const createCoreApi = (
|
|
|
99
113
|
| 'updateSettings'
|
|
100
114
|
| 'switchTransport'
|
|
101
115
|
> => ({
|
|
116
|
+
getFirmwareUpdateCapabilities,
|
|
117
|
+
registerFirmwareUpdateHostBinding,
|
|
118
|
+
unregisterFirmwareUpdateHostBinding,
|
|
119
|
+
getFirmwareUpdateHostBindingGeneration,
|
|
120
|
+
prepareFirmwareUpdatePlan,
|
|
121
|
+
validateFirmwareUpdatePreparedPlan,
|
|
102
122
|
getLogs: () => call({ method: 'getLogs' }),
|
|
103
123
|
clearSessionCache: params => call({ ...params, method: 'clearSessionCache' }),
|
|
104
124
|
/**
|
|
@@ -160,30 +180,7 @@ export const createCoreApi = (
|
|
|
160
180
|
call({ ...params, connectId, method: 'deviceGetOnboardingStatus' }),
|
|
161
181
|
deviceUploadWallpaper: (connectId, params) =>
|
|
162
182
|
call({ ...params, connectId, method: 'deviceUploadWallpaper' }),
|
|
163
|
-
deviceInfoGet: (connectId, params) => call({ ...params, connectId, method: 'deviceInfoGet' }),
|
|
164
|
-
deviceStatusGet: (connectId, params) => call({ ...params, connectId, method: 'deviceStatusGet' }),
|
|
165
|
-
protocolInfoRequest: (connectId, params) =>
|
|
166
|
-
call({ ...params, connectId, method: 'protocolInfoRequest' }),
|
|
167
|
-
ping: (connectId, params) => call({ ...params, connectId, method: 'ping' }),
|
|
168
|
-
deviceFirmwareUpdate: (connectId, params) =>
|
|
169
|
-
call({ ...params, connectId, method: 'deviceFirmwareUpdate' }),
|
|
170
|
-
deviceGetFirmwareUpdateStatus: (connectId, params) =>
|
|
171
|
-
call({ ...params, connectId, method: 'deviceGetFirmwareUpdateStatus' }),
|
|
172
|
-
deviceFactoryInfoSet: (connectId, params) =>
|
|
173
|
-
call({ ...params, connectId, method: 'deviceFactoryInfoSet' }),
|
|
174
|
-
deviceFactoryInfoGet: (connectId, params) =>
|
|
175
|
-
call({ ...params, connectId, method: 'deviceFactoryInfoGet' }),
|
|
176
|
-
filesystemPermissionFix: (connectId, params) =>
|
|
177
|
-
call({ ...params, connectId, method: 'filesystemPermissionFix' }),
|
|
178
|
-
filesystemFormat: connectId => call({ connectId, method: 'filesystemFormat' }),
|
|
179
183
|
uploadPortfolio: (connectId, params) => call({ ...params, connectId, method: 'uploadPortfolio' }),
|
|
180
|
-
fileRead: (connectId, params) => call({ ...params, connectId, method: 'fileRead' }),
|
|
181
|
-
fileWrite: (connectId, params) => call({ ...params, connectId, method: 'fileWrite' }),
|
|
182
|
-
fileDelete: (connectId, params) => call({ ...params, connectId, method: 'fileDelete' }),
|
|
183
|
-
dirList: (connectId, params) => call({ ...params, connectId, method: 'dirList' }),
|
|
184
|
-
dirMake: (connectId, params) => call({ ...params, connectId, method: 'dirMake' }),
|
|
185
|
-
dirRemove: (connectId, params) => call({ ...params, connectId, method: 'dirRemove' }),
|
|
186
|
-
pathInfo: (connectId, params) => call({ ...params, connectId, method: 'pathInfo' }),
|
|
187
184
|
deviceRecovery: (connectId, params) => call({ ...params, connectId, method: 'deviceRecovery' }),
|
|
188
185
|
deviceReset: (connectId, params) => call({ ...params, connectId, method: 'deviceReset' }),
|
|
189
186
|
deviceSettings: (connectId, params) => call({ ...params, connectId, method: 'deviceSettings' }),
|
package/src/lowLevelInject.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createCoreApi } from './inject';
|
|
2
|
+
import { unregisterFirmwareUpdateHostBinding } from './api/firmware/FirmwareHostBinding';
|
|
2
3
|
|
|
3
4
|
import type { EventEmitter } from 'events';
|
|
4
5
|
import type { CallMethod, CoreMessage } from './events';
|
|
@@ -43,7 +44,10 @@ export const lowLevelInject = ({
|
|
|
43
44
|
|
|
44
45
|
call,
|
|
45
46
|
|
|
46
|
-
dispose
|
|
47
|
+
dispose: async () => {
|
|
48
|
+
unregisterFirmwareUpdateHostBinding();
|
|
49
|
+
await dispose();
|
|
50
|
+
},
|
|
47
51
|
|
|
48
52
|
uiResponse,
|
|
49
53
|
|
|
@@ -3,7 +3,6 @@ import type { UnlockPolicy } from '../../api/BaseMethod';
|
|
|
3
3
|
import type { ProtocolV2InteractionDescriptor } from './uiInteraction';
|
|
4
4
|
|
|
5
5
|
const LOCK_FREE_DEVICE_SETTINGS = new Set<keyof DeviceSettings>([
|
|
6
|
-
'label',
|
|
7
6
|
'language',
|
|
8
7
|
'brightness',
|
|
9
8
|
'haptic_feedback',
|
|
@@ -12,7 +11,7 @@ const LOCK_FREE_DEVICE_SETTINGS = new Set<keyof DeviceSettings>([
|
|
|
12
11
|
export const getProtocolV2SettingsUnlockPolicy = (settings: DeviceSettings): UnlockPolicy =>
|
|
13
12
|
Object.keys(settings).every(key => LOCK_FREE_DEVICE_SETTINGS.has(key as keyof DeviceSettings))
|
|
14
13
|
? 'none'
|
|
15
|
-
: '
|
|
14
|
+
: 'unlock-before-run';
|
|
16
15
|
|
|
17
16
|
export type ProtocolV2SettingsOperation =
|
|
18
17
|
| {
|
|
@@ -32,7 +31,7 @@ export const getProtocolV2SettingsBehavior = (
|
|
|
32
31
|
} => {
|
|
33
32
|
if (operation.kind === 'page') {
|
|
34
33
|
return {
|
|
35
|
-
unlockPolicy: '
|
|
34
|
+
unlockPolicy: 'unlock-before-run',
|
|
36
35
|
uiInteraction: {
|
|
37
36
|
request: 'button',
|
|
38
37
|
source: 'method-lifecycle',
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
export type UnlockPolicy = 'none' | 'unlock-before-run' | 'retry-on-locked';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Protocol V2 methods that are safe to replay after a locked response.
|
|
5
|
+
*
|
|
6
|
+
* Keep this as an exact allowlist. Name-pattern matching can silently make a new
|
|
7
|
+
* state-changing method replayable when it happens to share a suffix.
|
|
8
|
+
*/
|
|
9
|
+
export const PROTOCOL_V2_RETRY_ON_LOCKED_METHODS = [
|
|
10
|
+
'cipherKeyValue',
|
|
11
|
+
'allNetworkGetAddress',
|
|
12
|
+
'allNetworkGetAddressByLoop',
|
|
13
|
+
'btcGetAddress',
|
|
14
|
+
'btcGetPublicKey',
|
|
15
|
+
'btcSignMessage',
|
|
16
|
+
'btcSignPsbt',
|
|
17
|
+
'btcSignTransaction',
|
|
18
|
+
'btcVerifyMessage',
|
|
19
|
+
'confluxGetAddress',
|
|
20
|
+
'confluxSignMessage',
|
|
21
|
+
'confluxSignTransaction',
|
|
22
|
+
'evmGetAddress',
|
|
23
|
+
'evmGetPublicKey',
|
|
24
|
+
'evmSignMessage',
|
|
25
|
+
'evmSignTransaction',
|
|
26
|
+
'evmSignTypedData',
|
|
27
|
+
'evmVerifyMessage',
|
|
28
|
+
'starcoinGetAddress',
|
|
29
|
+
'starcoinGetPublicKey',
|
|
30
|
+
'starcoinSignMessage',
|
|
31
|
+
'starcoinSignTransaction',
|
|
32
|
+
'starcoinVerifyMessage',
|
|
33
|
+
'nemGetAddress',
|
|
34
|
+
'nemSignTransaction',
|
|
35
|
+
'solGetAddress',
|
|
36
|
+
'solSignTransaction',
|
|
37
|
+
'solSignOffchainMessage',
|
|
38
|
+
'solSignMessage',
|
|
39
|
+
'stellarGetAddress',
|
|
40
|
+
'stellarSignTransaction',
|
|
41
|
+
'tronGetAddress',
|
|
42
|
+
'tronSignMessage',
|
|
43
|
+
'tronSignTransaction',
|
|
44
|
+
'nearGetAddress',
|
|
45
|
+
'nearSignTransaction',
|
|
46
|
+
'aptosGetAddress',
|
|
47
|
+
'aptosGetPublicKey',
|
|
48
|
+
'aptosSignTransaction',
|
|
49
|
+
'aptosSignMessage',
|
|
50
|
+
'aptosSignInMessage',
|
|
51
|
+
'algoGetAddress',
|
|
52
|
+
'algoSignTransaction',
|
|
53
|
+
'cosmosGetAddress',
|
|
54
|
+
'cosmosGetPublicKey',
|
|
55
|
+
'cosmosSignTransaction',
|
|
56
|
+
'xrpGetAddress',
|
|
57
|
+
'xrpSignTransaction',
|
|
58
|
+
'suiGetAddress',
|
|
59
|
+
'suiGetPublicKey',
|
|
60
|
+
'suiSignMessage',
|
|
61
|
+
'suiSignTransaction',
|
|
62
|
+
'cardanoGetAddress',
|
|
63
|
+
'cardanoGetPublicKey',
|
|
64
|
+
'cardanoSignTransaction',
|
|
65
|
+
'cardanoSignMessage',
|
|
66
|
+
'filecoinGetAddress',
|
|
67
|
+
'filecoinSignTransaction',
|
|
68
|
+
'polkadotGetAddress',
|
|
69
|
+
'polkadotSignTransaction',
|
|
70
|
+
'kaspaGetAddress',
|
|
71
|
+
'kaspaSignTransaction',
|
|
72
|
+
'nexaGetAddress',
|
|
73
|
+
'nexaSignTransaction',
|
|
74
|
+
'nostrGetPublicKey',
|
|
75
|
+
'nostrSignEvent',
|
|
76
|
+
'nostrEncryptMessage',
|
|
77
|
+
'nostrDecryptMessage',
|
|
78
|
+
'nostrSignSchnorr',
|
|
79
|
+
'lnurlAuth',
|
|
80
|
+
'nervosGetAddress',
|
|
81
|
+
'nervosSignTransaction',
|
|
82
|
+
'dnxGetAddress',
|
|
83
|
+
'dnxSignTransaction',
|
|
84
|
+
'tonGetAddress',
|
|
85
|
+
'tonSignMessage',
|
|
86
|
+
'tonSignProof',
|
|
87
|
+
'tonSignData',
|
|
88
|
+
'scdoGetAddress',
|
|
89
|
+
'scdoSignTransaction',
|
|
90
|
+
'scdoSignMessage',
|
|
91
|
+
'alephiumGetAddress',
|
|
92
|
+
'alephiumSignTransaction',
|
|
93
|
+
'alephiumSignMessage',
|
|
94
|
+
'benfenGetAddress',
|
|
95
|
+
'benfenGetPublicKey',
|
|
96
|
+
'benfenSignMessage',
|
|
97
|
+
'benfenSignTransaction',
|
|
98
|
+
'neoGetAddress',
|
|
99
|
+
'neoSignTransaction',
|
|
100
|
+
] as const;
|
|
101
|
+
|
|
102
|
+
const retryOnLockedMethods = new Set<string>(PROTOCOL_V2_RETRY_ON_LOCKED_METHODS);
|
|
103
|
+
|
|
104
|
+
export const getProtocolV2UnlockPolicy = (methodName: string): UnlockPolicy =>
|
|
105
|
+
retryOnLockedMethods.has(methodName) ? 'retry-on-locked' : 'none';
|
|
@@ -25,9 +25,7 @@ export async function runMethodWithUnlockRetry(
|
|
|
25
25
|
) {
|
|
26
26
|
const shouldEmitUi = isProtocolV2UiEnabled(method);
|
|
27
27
|
const shouldUnlockBeforeRun =
|
|
28
|
-
device.isProtocolV2() &&
|
|
29
|
-
method.unlockPolicy === 'retry-on-locked' &&
|
|
30
|
-
device.features?.unlocked === false;
|
|
28
|
+
device.isProtocolV2() && method.unlockPolicy !== 'none' && device.features?.unlocked === false;
|
|
31
29
|
|
|
32
30
|
if (shouldUnlockBeforeRun) {
|
|
33
31
|
if (shouldEmitUi) {
|