@onekeyfe/hd-core 1.2.2-alpha.100 → 1.2.2-alpha.2
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 +20 -4
- package/__tests__/DeviceCommands.test.ts +13 -0
- package/__tests__/check-all-firmware-release-protocol-v2.test.ts +0 -2
- package/__tests__/check-firmware-release-protocol-v2.test.ts +0 -2
- package/__tests__/device-lifecycle-events.test.ts +19 -0
- package/__tests__/deviceUploadNft.test.ts +68 -0
- package/__tests__/evmSignTypedData.test.ts +42 -0
- package/__tests__/firmware-update/firmware-update-v4-install-poll.test.ts +825 -12
- package/__tests__/open-wallet-session.test.ts +144 -37
- package/__tests__/pro2HostAssetPackage.test.ts +58 -0
- package/__tests__/protocol-v2-resources.test.ts +7 -4
- package/__tests__/protocol-v2-unlock-policy.test.ts +35 -1
- package/__tests__/protocol-v2.test.ts +720 -51
- package/dist/api/FirmwareUpdateV4.d.ts +4 -0
- package/dist/api/FirmwareUpdateV4.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/evm/EVMSignTypedData.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +2 -2
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
- package/dist/api/firmware/getBinary.d.ts +2 -2
- package/dist/api/protocol-v2/DeviceGetFirmwareUpdateStatus.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts.map +1 -1
- package/dist/api/protocol-v2/helpers.d.ts.map +1 -1
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/device/Device.d.ts +1 -1
- package/dist/device/Device.d.ts.map +1 -1
- package/dist/device/DeviceConnector.d.ts +1 -1
- package/dist/device/DeviceConnector.d.ts.map +1 -1
- package/dist/events/ui-request.d.ts +3 -0
- package/dist/events/ui-request.d.ts.map +1 -1
- package/dist/index.d.ts +21 -5
- package/dist/index.js +2278 -1435
- package/dist/protocols/protocol-v2/resources.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts +2 -0
- package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/walletSession.d.ts +3 -0
- package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
- package/dist/types/settings.d.ts +2 -2
- package/dist/types/settings.d.ts.map +1 -1
- package/dist/utils/deviceFeaturesUtils.d.ts +3 -0
- package/dist/utils/deviceFeaturesUtils.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/pro2HostAssetPackage.d.ts +8 -0
- package/dist/utils/pro2HostAssetPackage.d.ts.map +1 -0
- package/package.json +4 -4
- package/src/api/FirmwareUpdateV4.ts +434 -75
- package/src/api/OpenWalletSession.ts +39 -9
- package/src/api/allnetwork/AllNetworkGetAddressBase.ts +2 -1
- package/src/api/evm/EVMSignTypedData.ts +1 -0
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +9 -3
- package/src/api/protocol-v2/DeviceGetFirmwareUpdateStatus.ts +7 -1
- package/src/api/protocol-v2/DeviceUploadNft.ts +31 -8
- package/src/api/protocol-v2/DeviceUploadWallpaper.ts +27 -8
- package/src/api/protocol-v2/helpers.ts +8 -0
- package/src/core/index.ts +121 -10
- package/src/data/messages/messages-protocol-v2.json +1541 -1332
- package/src/device/Device.ts +3 -1
- package/src/device/DeviceConnector.ts +7 -3
- package/src/events/ui-request.ts +3 -0
- package/src/protocols/protocol-v2/resources.ts +9 -1
- package/src/protocols/protocol-v2/unlockPolicyRunner.ts +8 -1
- package/src/protocols/protocol-v2/walletSession.ts +88 -50
- package/src/types/settings.ts +4 -2
- package/src/utils/deviceFeaturesUtils.ts +4 -0
- package/src/utils/pro2HostAssetPackage.ts +354 -0
package/src/device/Device.ts
CHANGED
|
@@ -2005,7 +2005,8 @@ export class Device extends EventEmitter {
|
|
|
2005
2005
|
passphraseState?: string,
|
|
2006
2006
|
useEmptyPassphrase?: boolean,
|
|
2007
2007
|
skipPassphraseCheck?: boolean,
|
|
2008
|
-
deriveCardano?: boolean
|
|
2008
|
+
deriveCardano?: boolean,
|
|
2009
|
+
mainPinSelected?: boolean
|
|
2009
2010
|
) {
|
|
2010
2011
|
if (this.isUnacquired()) return false;
|
|
2011
2012
|
|
|
@@ -2016,6 +2017,7 @@ export class Device extends EventEmitter {
|
|
|
2016
2017
|
onlyMainPin: useEmptyPassphrase,
|
|
2017
2018
|
deriveCardano,
|
|
2018
2019
|
rejectAttachPinForMainWallet: useEmptyPassphrase === true,
|
|
2020
|
+
mainPinSelected,
|
|
2019
2021
|
});
|
|
2020
2022
|
|
|
2021
2023
|
// Main wallet and unlock Attach Pin, throw safe error
|
|
@@ -96,7 +96,8 @@ export default class DeviceConnector {
|
|
|
96
96
|
forceCleanRunPromise?: boolean,
|
|
97
97
|
expectedProtocol?: HardwareConnectProtocol,
|
|
98
98
|
protocolHint?: HardwareConnectProtocol,
|
|
99
|
-
forceProtocolDetection?: boolean
|
|
99
|
+
forceProtocolDetection?: boolean,
|
|
100
|
+
skipProtocolProbe?: boolean
|
|
100
101
|
) {
|
|
101
102
|
Log.debug('acquire', path, session, expectedProtocol, protocolHint);
|
|
102
103
|
const env = DataManager.getSettings('env');
|
|
@@ -104,13 +105,15 @@ export default class DeviceConnector {
|
|
|
104
105
|
const transport = this.getActiveTransport();
|
|
105
106
|
let res;
|
|
106
107
|
if (DataManager.isBleConnect(env)) {
|
|
107
|
-
|
|
108
|
+
const acquireInput: Parameters<Transport['acquire']>[0] = {
|
|
108
109
|
uuid: path,
|
|
109
110
|
forceCleanRunPromise,
|
|
110
111
|
expectedProtocol,
|
|
111
112
|
protocolHint,
|
|
112
113
|
forceProtocolDetection,
|
|
113
|
-
|
|
114
|
+
skipProtocolProbe,
|
|
115
|
+
};
|
|
116
|
+
res = await transport.acquire(acquireInput);
|
|
114
117
|
} else {
|
|
115
118
|
res = await transport.acquire({
|
|
116
119
|
path,
|
|
@@ -118,6 +121,7 @@ export default class DeviceConnector {
|
|
|
118
121
|
expectedProtocol,
|
|
119
122
|
protocolHint,
|
|
120
123
|
forceProtocolDetection,
|
|
124
|
+
skipProtocolProbe,
|
|
121
125
|
});
|
|
122
126
|
}
|
|
123
127
|
if (expectedProtocol) {
|
package/src/events/ui-request.ts
CHANGED
|
@@ -189,6 +189,9 @@ export interface FirmwareProgress {
|
|
|
189
189
|
totalBytes?: number;
|
|
190
190
|
rateBytesPerSecond?: number;
|
|
191
191
|
elapsedMs?: number;
|
|
192
|
+
installTargetId?: number;
|
|
193
|
+
installPhase?: 'prepare' | 'install' | 'verify';
|
|
194
|
+
installPhaseProgress?: number;
|
|
192
195
|
};
|
|
193
196
|
}
|
|
194
197
|
|
|
@@ -59,7 +59,15 @@ export function isProtocolV2ResourceArchiveEntryName(entryName: string): boolean
|
|
|
59
59
|
return (
|
|
60
60
|
fileName.length > 0 &&
|
|
61
61
|
!fileName.startsWith('.') &&
|
|
62
|
-
!parts.some(
|
|
62
|
+
!parts.some(
|
|
63
|
+
part =>
|
|
64
|
+
!part ||
|
|
65
|
+
part === '.' ||
|
|
66
|
+
part === '..' ||
|
|
67
|
+
part === '.DS_Store' ||
|
|
68
|
+
part.startsWith('._') ||
|
|
69
|
+
part.toUpperCase() === '__MACOSX'
|
|
70
|
+
)
|
|
63
71
|
);
|
|
64
72
|
}
|
|
65
73
|
|
|
@@ -14,10 +14,14 @@ const Log = getLogger(LoggerNames.Core);
|
|
|
14
14
|
|
|
15
15
|
export type ProtocolV2UnlockContext = {
|
|
16
16
|
preflightCompleted: boolean;
|
|
17
|
+
preflightStatusRefreshed?: boolean;
|
|
18
|
+
preflightMainPinSelected?: boolean;
|
|
17
19
|
};
|
|
18
20
|
|
|
19
21
|
export const createProtocolV2UnlockContext = (): ProtocolV2UnlockContext => ({
|
|
20
22
|
preflightCompleted: false,
|
|
23
|
+
preflightStatusRefreshed: false,
|
|
24
|
+
preflightMainPinSelected: false,
|
|
21
25
|
});
|
|
22
26
|
|
|
23
27
|
type RunnableMethod = Pick<
|
|
@@ -100,11 +104,12 @@ export async function runMethodWithUnlockPolicy<T = unknown>(
|
|
|
100
104
|
await afterStatusBeforeUnlock?.();
|
|
101
105
|
|
|
102
106
|
if (!status.unlocked) {
|
|
107
|
+
const preUnlockPinType = resolvePreUnlockPinType(method);
|
|
103
108
|
const unlockInteraction: HardwareUiInteractionMeta | undefined = shouldCoordinateUi
|
|
104
109
|
? uiCoordinator.enterUnlockInteraction(method.name)
|
|
105
110
|
: undefined;
|
|
106
111
|
const unlockedStatus = await device.unlockDevice(
|
|
107
|
-
|
|
112
|
+
preUnlockPinType,
|
|
108
113
|
shouldCoordinateUi
|
|
109
114
|
? { emitUiEvent: false, interaction: unlockInteraction }
|
|
110
115
|
: {
|
|
@@ -120,9 +125,11 @@ export async function runMethodWithUnlockPolicy<T = unknown>(
|
|
|
120
125
|
'Protocol V2 device remained locked after the unlock flow.'
|
|
121
126
|
);
|
|
122
127
|
}
|
|
128
|
+
context.preflightMainPinSelected = preUnlockPinType === DeviceSessionPinType.Main;
|
|
123
129
|
Log.debug('Protocol V2 pre-unlock completed', { method: method.name });
|
|
124
130
|
}
|
|
125
131
|
|
|
132
|
+
context.preflightStatusRefreshed = true;
|
|
126
133
|
context.preflightCompleted = true;
|
|
127
134
|
}
|
|
128
135
|
|
|
@@ -63,35 +63,46 @@ const negotiateEventlessWalletSession = async (device: Device) => {
|
|
|
63
63
|
const getDeviceSession = async (device: Device, request: DeviceSessionGet) =>
|
|
64
64
|
device.commands.typedCall('DeviceSessionGet', 'DeviceSession', request);
|
|
65
65
|
|
|
66
|
+
const buildDeviceSessionSeedDomains = (deriveCardano?: boolean): DeviceSessionSeedDomain[] =>
|
|
67
|
+
deriveCardano === undefined
|
|
68
|
+
? []
|
|
69
|
+
: [
|
|
70
|
+
DeviceSessionSeedDomain.SeedDomain_Standard,
|
|
71
|
+
...(deriveCardano ? [DeviceSessionSeedDomain.SeedDomain_Cardano] : []),
|
|
72
|
+
];
|
|
73
|
+
|
|
74
|
+
// Seed domains are applied when creating a passphrase session, not when reading/resuming one.
|
|
75
|
+
// Current firmware rejects unknown DeviceSessionGet fields, including leftover seed_domains.
|
|
66
76
|
const buildDeviceSessionGetRequest = ({
|
|
67
77
|
sessionId,
|
|
68
78
|
expectedPassphraseState,
|
|
69
|
-
deriveCardano,
|
|
70
79
|
}: {
|
|
71
80
|
sessionId?: string;
|
|
72
81
|
expectedPassphraseState?: string;
|
|
73
|
-
deriveCardano?: boolean;
|
|
74
82
|
} = {}): DeviceSessionGet => ({
|
|
75
83
|
...(sessionId ? { session_id: sessionId } : {}),
|
|
76
84
|
...(expectedPassphraseState ? { btc_test_address: expectedPassphraseState } : {}),
|
|
77
|
-
seed_domains:
|
|
78
|
-
deriveCardano === undefined
|
|
79
|
-
? []
|
|
80
|
-
: [
|
|
81
|
-
DeviceSessionSeedDomain.SeedDomain_Standard,
|
|
82
|
-
...(deriveCardano ? [DeviceSessionSeedDomain.SeedDomain_Cardano] : []),
|
|
83
|
-
],
|
|
84
85
|
});
|
|
85
86
|
|
|
86
|
-
const askDevicePassphrase = async (
|
|
87
|
-
|
|
87
|
+
const askDevicePassphrase = async (
|
|
88
|
+
device: Device,
|
|
89
|
+
requestPayload: Omit<DeviceSessionAskPassphrase, 'seed_domains'>,
|
|
90
|
+
deriveCardano?: boolean,
|
|
91
|
+
onStatusRefreshed?: () => void
|
|
92
|
+
) => {
|
|
93
|
+
await device.commands.typedCall('DeviceSessionAskPassphrase', 'Success', {
|
|
94
|
+
...requestPayload,
|
|
95
|
+
seed_domains: buildDeviceSessionSeedDomains(deriveCardano),
|
|
96
|
+
});
|
|
88
97
|
await refreshProtocolV2DeviceStatus(device);
|
|
98
|
+
onStatusRefreshed?.();
|
|
89
99
|
};
|
|
90
100
|
|
|
91
101
|
const selectDeviceSession = async (
|
|
92
102
|
device: Device,
|
|
93
103
|
expectedPassphraseState?: string,
|
|
94
|
-
deriveCardano?: boolean
|
|
104
|
+
deriveCardano?: boolean,
|
|
105
|
+
onStatusRefreshed?: () => void
|
|
95
106
|
) => {
|
|
96
107
|
const existsAttachPinUser = device.features?.attachToPinEnabled === true;
|
|
97
108
|
const metadata = {
|
|
@@ -153,15 +164,21 @@ const selectDeviceSession = async (
|
|
|
153
164
|
emitUiEvent: false,
|
|
154
165
|
interaction: attachPinInteraction,
|
|
155
166
|
});
|
|
156
|
-
|
|
167
|
+
onStatusRefreshed?.();
|
|
168
|
+
return getDeviceSession(device, buildDeviceSessionGetRequest());
|
|
157
169
|
}
|
|
158
170
|
|
|
159
171
|
if (hasHostPassphrase) {
|
|
160
|
-
await askDevicePassphrase(
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
172
|
+
await askDevicePassphrase(
|
|
173
|
+
device,
|
|
174
|
+
{
|
|
175
|
+
passphrase: hostPassphrase,
|
|
176
|
+
on_device: false,
|
|
177
|
+
},
|
|
178
|
+
deriveCardano,
|
|
179
|
+
onStatusRefreshed
|
|
180
|
+
);
|
|
181
|
+
return getDeviceSession(device, buildDeviceSessionGetRequest());
|
|
165
182
|
}
|
|
166
183
|
|
|
167
184
|
const passphraseOnDeviceInteraction = device.createProtocolV2UiPhaseMetadata?.(
|
|
@@ -172,8 +189,8 @@ const selectDeviceSession = async (
|
|
|
172
189
|
...metadata,
|
|
173
190
|
...(passphraseOnDeviceInteraction ? { interaction: passphraseOnDeviceInteraction } : {}),
|
|
174
191
|
});
|
|
175
|
-
await askDevicePassphrase(device, { on_device: true });
|
|
176
|
-
return getDeviceSession(device, buildDeviceSessionGetRequest(
|
|
192
|
+
await askDevicePassphrase(device, { on_device: true }, deriveCardano, onStatusRefreshed);
|
|
193
|
+
return getDeviceSession(device, buildDeviceSessionGetRequest());
|
|
177
194
|
};
|
|
178
195
|
|
|
179
196
|
export async function getProtocolV2WalletSession(
|
|
@@ -191,6 +208,8 @@ export async function getProtocolV2WalletSession(
|
|
|
191
208
|
deriveCardano?: boolean;
|
|
192
209
|
/** Read the wallet already selected by Attach PIN without reopening wallet selection. */
|
|
193
210
|
readCurrentAttachPinSession?: boolean;
|
|
211
|
+
/** The current call already selected the Main PIN during its unlock preflight. */
|
|
212
|
+
mainPinSelected?: boolean;
|
|
194
213
|
}
|
|
195
214
|
) {
|
|
196
215
|
const forceWalletSelection =
|
|
@@ -227,10 +246,16 @@ export async function getProtocolV2WalletSession(
|
|
|
227
246
|
: undefined;
|
|
228
247
|
let response;
|
|
229
248
|
let resumed = false;
|
|
230
|
-
let
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
249
|
+
let walletStatusRefreshed = false;
|
|
250
|
+
const markWalletStatusRefreshed = () => {
|
|
251
|
+
walletStatusRefreshed = true;
|
|
252
|
+
};
|
|
253
|
+
let mainPinAuthenticated =
|
|
254
|
+
options?.mainPinSelected === true ||
|
|
255
|
+
(options?.onlyMainPin === true &&
|
|
256
|
+
device.features?.unlocked === true &&
|
|
257
|
+
device.features?.unlockedAttachPin === false);
|
|
258
|
+
let standardWalletSelected = options?.mainPinSelected === true;
|
|
234
259
|
|
|
235
260
|
const clearCurrentWalletSession = () => {
|
|
236
261
|
if (options?.onlyMainPin) {
|
|
@@ -242,6 +267,7 @@ export async function getProtocolV2WalletSession(
|
|
|
242
267
|
|
|
243
268
|
const rejectMismatchedAttachPinWallet = async () => {
|
|
244
269
|
const features = await refreshProtocolV2DeviceStatus(device);
|
|
270
|
+
markWalletStatusRefreshed();
|
|
245
271
|
if (features.unlockedAttachPin !== true) {
|
|
246
272
|
return;
|
|
247
273
|
}
|
|
@@ -265,30 +291,43 @@ export async function getProtocolV2WalletSession(
|
|
|
265
291
|
}
|
|
266
292
|
|
|
267
293
|
const selectMainPin = async (force = false) => {
|
|
268
|
-
if (force || !
|
|
294
|
+
if (force || !mainPinAuthenticated) {
|
|
269
295
|
await device.unlockDevice(DeviceSessionPinType.Main, {
|
|
270
296
|
source: 'wallet-session-coordinator',
|
|
271
297
|
reason: expectedPassphraseState ? 'session-recovery' : 'open-wallet',
|
|
272
298
|
deviceOnly: true,
|
|
273
299
|
});
|
|
274
|
-
|
|
300
|
+
markWalletStatusRefreshed();
|
|
301
|
+
mainPinAuthenticated = true;
|
|
302
|
+
standardWalletSelected = true;
|
|
275
303
|
}
|
|
276
304
|
};
|
|
277
305
|
|
|
278
306
|
const selectStandardWallet = async () => {
|
|
279
|
-
// Main PIN authenticates the device; an empty host passphrase selects the standard derivation.
|
|
280
|
-
await selectMainPin();
|
|
281
307
|
if (device.features?.passphraseProtection === true) {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
308
|
+
// Main PIN authenticates the device; an empty host passphrase selects the standard derivation.
|
|
309
|
+
await selectMainPin();
|
|
310
|
+
await askDevicePassphrase(
|
|
311
|
+
device,
|
|
312
|
+
{
|
|
313
|
+
passphrase: '',
|
|
314
|
+
on_device: false,
|
|
315
|
+
},
|
|
316
|
+
options?.deriveCardano,
|
|
317
|
+
markWalletStatusRefreshed
|
|
318
|
+
);
|
|
319
|
+
standardWalletSelected = true;
|
|
320
|
+
} else if (!standardWalletSelected) {
|
|
321
|
+
// Without passphrase protection there is no empty-passphrase selector.
|
|
322
|
+
// Main PIN selection is the only authoritative switch back to the standard wallet.
|
|
323
|
+
await selectMainPin(true);
|
|
286
324
|
}
|
|
287
325
|
};
|
|
288
326
|
|
|
289
327
|
if (readCurrentAttachPinSession) {
|
|
290
328
|
const status = await requestProtocolV2DeviceStatus(device);
|
|
291
329
|
device.updateProtocolV2Status(status);
|
|
330
|
+
markWalletStatusRefreshed();
|
|
292
331
|
if (
|
|
293
332
|
status.unlocked !== true ||
|
|
294
333
|
status.passphrase_enabled !== true ||
|
|
@@ -297,10 +336,7 @@ export async function getProtocolV2WalletSession(
|
|
|
297
336
|
device.clearInternalState();
|
|
298
337
|
throw ERRORS.TypedError(HardwareErrorCode.DeviceCheckUnlockTypeError);
|
|
299
338
|
}
|
|
300
|
-
response = await getDeviceSession(
|
|
301
|
-
device,
|
|
302
|
-
buildDeviceSessionGetRequest({ deriveCardano: options?.deriveCardano })
|
|
303
|
-
);
|
|
339
|
+
response = await getDeviceSession(device, buildDeviceSessionGetRequest());
|
|
304
340
|
} else if (options?.onlyMainPin) {
|
|
305
341
|
expectedPassphraseState = cachedStandardSession?.passphraseState;
|
|
306
342
|
if (cachedStandardSession) {
|
|
@@ -313,7 +349,6 @@ export async function getProtocolV2WalletSession(
|
|
|
313
349
|
buildDeviceSessionGetRequest({
|
|
314
350
|
sessionId: cachedStandardSession.sessionId,
|
|
315
351
|
expectedPassphraseState,
|
|
316
|
-
deriveCardano: options?.deriveCardano,
|
|
317
352
|
})
|
|
318
353
|
);
|
|
319
354
|
resumed = true;
|
|
@@ -328,10 +363,7 @@ export async function getProtocolV2WalletSession(
|
|
|
328
363
|
|
|
329
364
|
if (!response) {
|
|
330
365
|
await selectStandardWallet();
|
|
331
|
-
response = await getDeviceSession(
|
|
332
|
-
device,
|
|
333
|
-
buildDeviceSessionGetRequest({ deriveCardano: options?.deriveCardano })
|
|
334
|
-
);
|
|
366
|
+
response = await getDeviceSession(device, buildDeviceSessionGetRequest());
|
|
335
367
|
}
|
|
336
368
|
} else if (cachedSessionId && expectedPassphraseState) {
|
|
337
369
|
try {
|
|
@@ -340,7 +372,6 @@ export async function getProtocolV2WalletSession(
|
|
|
340
372
|
buildDeviceSessionGetRequest({
|
|
341
373
|
sessionId: cachedSessionId,
|
|
342
374
|
expectedPassphraseState,
|
|
343
|
-
deriveCardano: options?.deriveCardano,
|
|
344
375
|
})
|
|
345
376
|
);
|
|
346
377
|
resumed = true;
|
|
@@ -357,7 +388,6 @@ export async function getProtocolV2WalletSession(
|
|
|
357
388
|
device,
|
|
358
389
|
buildDeviceSessionGetRequest({
|
|
359
390
|
expectedPassphraseState,
|
|
360
|
-
deriveCardano: options?.deriveCardano,
|
|
361
391
|
})
|
|
362
392
|
);
|
|
363
393
|
} catch (error) {
|
|
@@ -372,7 +402,12 @@ export async function getProtocolV2WalletSession(
|
|
|
372
402
|
device.clearInternalState();
|
|
373
403
|
throw ERRORS.TypedError(HardwareErrorCode.WalletSessionInvalid);
|
|
374
404
|
}
|
|
375
|
-
response = await selectDeviceSession(
|
|
405
|
+
response = await selectDeviceSession(
|
|
406
|
+
device,
|
|
407
|
+
expectedPassphraseState,
|
|
408
|
+
options?.deriveCardano,
|
|
409
|
+
markWalletStatusRefreshed
|
|
410
|
+
);
|
|
376
411
|
}
|
|
377
412
|
|
|
378
413
|
let { message } = response;
|
|
@@ -396,13 +431,15 @@ export async function getProtocolV2WalletSession(
|
|
|
396
431
|
if (options?.onlyMainPin) {
|
|
397
432
|
device.clearStandardInternalState?.();
|
|
398
433
|
await selectStandardWallet();
|
|
399
|
-
response = await getDeviceSession(
|
|
400
|
-
device,
|
|
401
|
-
buildDeviceSessionGetRequest({ deriveCardano: options?.deriveCardano })
|
|
402
|
-
);
|
|
434
|
+
response = await getDeviceSession(device, buildDeviceSessionGetRequest());
|
|
403
435
|
} else {
|
|
404
436
|
device.clearInternalState();
|
|
405
|
-
response = await selectDeviceSession(
|
|
437
|
+
response = await selectDeviceSession(
|
|
438
|
+
device,
|
|
439
|
+
expectedPassphraseState,
|
|
440
|
+
options?.deriveCardano,
|
|
441
|
+
markWalletStatusRefreshed
|
|
442
|
+
);
|
|
406
443
|
}
|
|
407
444
|
message = response.message;
|
|
408
445
|
try {
|
|
@@ -438,7 +475,7 @@ export async function getProtocolV2WalletSession(
|
|
|
438
475
|
let unlockedAttachPin: boolean | undefined;
|
|
439
476
|
if (readCurrentAttachPinSession) {
|
|
440
477
|
unlockedAttachPin = true;
|
|
441
|
-
} else if (
|
|
478
|
+
} else if (mainPinAuthenticated) {
|
|
442
479
|
unlockedAttachPin = false;
|
|
443
480
|
}
|
|
444
481
|
|
|
@@ -447,6 +484,7 @@ export async function getProtocolV2WalletSession(
|
|
|
447
484
|
newSession: message.session_id,
|
|
448
485
|
unlockedAttachPin,
|
|
449
486
|
resumed,
|
|
487
|
+
walletStatusRefreshed,
|
|
450
488
|
};
|
|
451
489
|
}
|
|
452
490
|
|
package/src/types/settings.ts
CHANGED
|
@@ -77,7 +77,8 @@ export type IProtocolV2Resources = {
|
|
|
77
77
|
/** STM32 firmware config */
|
|
78
78
|
export type IFirmwareReleaseInfo = {
|
|
79
79
|
required: boolean;
|
|
80
|
-
|
|
80
|
+
/** Legacy release artifact URL. Protocol V2 releases use component URLs. */
|
|
81
|
+
url?: string;
|
|
81
82
|
/**
|
|
82
83
|
* Firmware type (bitcoinonly or universal)
|
|
83
84
|
* This field is not present in the remote config, but will be inferred from the firmware field name
|
|
@@ -106,7 +107,8 @@ export type IFirmwareReleaseInfo = {
|
|
|
106
107
|
bootloaderChangelog?: {
|
|
107
108
|
[k in ILocale]: string;
|
|
108
109
|
};
|
|
109
|
-
|
|
110
|
+
/** Legacy release artifact SHA-256. Protocol V2 releases use component fingerprints. */
|
|
111
|
+
fingerprint?: string;
|
|
110
112
|
expectedSize?: number;
|
|
111
113
|
version: IVersionArray;
|
|
112
114
|
changelog: {
|
|
@@ -110,6 +110,7 @@ export const getPassphraseStateWithRefreshDeviceInfo = async (
|
|
|
110
110
|
initSession?: boolean;
|
|
111
111
|
deriveCardano?: boolean;
|
|
112
112
|
rejectAttachPinForMainWallet?: boolean;
|
|
113
|
+
mainPinSelected?: boolean;
|
|
113
114
|
}
|
|
114
115
|
) => {
|
|
115
116
|
if (device.isProtocolV2()) {
|
|
@@ -127,6 +128,7 @@ export const getPassphraseStateWithRefreshDeviceInfo = async (
|
|
|
127
128
|
onlyMainPin: options?.onlyMainPin,
|
|
128
129
|
deriveCardano: options?.deriveCardano,
|
|
129
130
|
rejectAttachPinForMainWallet: options?.rejectAttachPinForMainWallet,
|
|
131
|
+
mainPinSelected: options?.mainPinSelected,
|
|
130
132
|
});
|
|
131
133
|
}
|
|
132
134
|
|
|
@@ -194,6 +196,7 @@ export const getPassphraseState = async (
|
|
|
194
196
|
initSession?: boolean;
|
|
195
197
|
deriveCardano?: boolean;
|
|
196
198
|
rejectAttachPinForMainWallet?: boolean;
|
|
199
|
+
mainPinSelected?: boolean;
|
|
197
200
|
}
|
|
198
201
|
): Promise<{
|
|
199
202
|
passphraseState: string | undefined;
|
|
@@ -216,6 +219,7 @@ export const getPassphraseState = async (
|
|
|
216
219
|
onlyMainPin: options?.onlyMainPin,
|
|
217
220
|
deriveCardano: options?.deriveCardano,
|
|
218
221
|
rejectAttachPinForMainWallet: options?.rejectAttachPinForMainWallet,
|
|
222
|
+
mainPinSelected: options?.mainPinSelected,
|
|
219
223
|
});
|
|
220
224
|
}
|
|
221
225
|
|