@onekeyfe/hd-core 1.2.2-alpha.5 → 1.2.2-alpha.6
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__/open-wallet-session.test.ts +318 -20
- package/__tests__/protocol-v2.test.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +110 -27
- package/dist/protocols/protocol-v2/walletSession.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/data/messages/messages-protocol-v2.json +39 -10
- package/src/protocols/protocol-v2/walletSession.ts +95 -15
|
@@ -76,9 +76,7 @@ const deviceSessionHasCardano = (message: { seed_domains?: DeviceSessionSeedDoma
|
|
|
76
76
|
Array.isArray(message.seed_domains) &&
|
|
77
77
|
message.seed_domains.includes(DeviceSessionSeedDomain.SeedDomain_Cardano);
|
|
78
78
|
|
|
79
|
-
//
|
|
80
|
-
// only resumes or reads the current session; firmware rejects unknown Get
|
|
81
|
-
// fields, including leftover seed_domains.
|
|
79
|
+
// origin/dev Get is read/resume only. Seed generation lives on AskPassphrase.
|
|
82
80
|
const buildDeviceSessionGetRequest = ({
|
|
83
81
|
sessionId,
|
|
84
82
|
expectedPassphraseState,
|
|
@@ -171,7 +169,22 @@ const selectDeviceSession = async (
|
|
|
171
169
|
interaction: attachPinInteraction,
|
|
172
170
|
});
|
|
173
171
|
onStatusRefreshed?.();
|
|
174
|
-
|
|
172
|
+
if (deriveCardano === true) {
|
|
173
|
+
await askDevicePassphrase(
|
|
174
|
+
device,
|
|
175
|
+
{ passphrase: '', on_device: false },
|
|
176
|
+
true,
|
|
177
|
+
onStatusRefreshed
|
|
178
|
+
);
|
|
179
|
+
// Firmware AskPassphrase Success clears unlocked_by_attach_to_pin.
|
|
180
|
+
// Identity is still the Attach PIN wallet; keep the SDK flag so a later
|
|
181
|
+
// passphrase picker still locks instead of prompting.
|
|
182
|
+
if (device.features) {
|
|
183
|
+
device.features.unlockedAttachPin = true;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
const attachPinSession = await getDeviceSession(device, buildDeviceSessionGetRequest());
|
|
187
|
+
return Object.assign(attachPinSession, { viaAttachPin: true as const });
|
|
175
188
|
}
|
|
176
189
|
|
|
177
190
|
if (hasHostPassphrase) {
|
|
@@ -221,6 +234,10 @@ export async function getProtocolV2WalletSession(
|
|
|
221
234
|
const forceWalletSelection =
|
|
222
235
|
options?.forceWalletSelection === true || options?.initSession === true;
|
|
223
236
|
const readCurrentAttachPinSession = options?.readCurrentAttachPinSession === true;
|
|
237
|
+
const sessionIsAttachPinWallet = (session?: { viaAttachPin?: boolean }) =>
|
|
238
|
+
readCurrentAttachPinSession ||
|
|
239
|
+
session?.viaAttachPin === true ||
|
|
240
|
+
device.features?.unlockedAttachPin === true;
|
|
224
241
|
|
|
225
242
|
if (forceWalletSelection) {
|
|
226
243
|
if (options.onlyMainPin) {
|
|
@@ -271,6 +288,38 @@ export async function getProtocolV2WalletSession(
|
|
|
271
288
|
}
|
|
272
289
|
};
|
|
273
290
|
|
|
291
|
+
const sessionGetRequest = ({
|
|
292
|
+
sessionId,
|
|
293
|
+
expectedPassphraseState: passphraseState,
|
|
294
|
+
}: {
|
|
295
|
+
sessionId?: string;
|
|
296
|
+
expectedPassphraseState?: string;
|
|
297
|
+
} = {}) =>
|
|
298
|
+
buildDeviceSessionGetRequest({
|
|
299
|
+
sessionId,
|
|
300
|
+
expectedPassphraseState: passphraseState,
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
const askEmptyPassphraseAndGet = async ({
|
|
304
|
+
deriveCardano,
|
|
305
|
+
keepAttachPin,
|
|
306
|
+
}: {
|
|
307
|
+
deriveCardano?: boolean;
|
|
308
|
+
keepAttachPin?: boolean;
|
|
309
|
+
} = {}) => {
|
|
310
|
+
await askDevicePassphrase(
|
|
311
|
+
device,
|
|
312
|
+
{ passphrase: '', on_device: false },
|
|
313
|
+
deriveCardano,
|
|
314
|
+
markWalletStatusRefreshed
|
|
315
|
+
);
|
|
316
|
+
if (keepAttachPin && device.features) {
|
|
317
|
+
device.features.unlockedAttachPin = true;
|
|
318
|
+
}
|
|
319
|
+
const session = await getDeviceSession(device, buildDeviceSessionGetRequest());
|
|
320
|
+
return keepAttachPin ? Object.assign(session, { viaAttachPin: true as const }) : session;
|
|
321
|
+
};
|
|
322
|
+
|
|
274
323
|
const rejectMismatchedAttachPinWallet = async () => {
|
|
275
324
|
const features = await refreshProtocolV2DeviceStatus(device);
|
|
276
325
|
markWalletStatusRefreshed();
|
|
@@ -292,6 +341,19 @@ export async function getProtocolV2WalletSession(
|
|
|
292
341
|
throw ERRORS.TypedError(HardwareErrorCode.DeviceCheckUnlockTypeError);
|
|
293
342
|
};
|
|
294
343
|
|
|
344
|
+
// The passphrase picker would prompt. Empty host AskPassphrase does not;
|
|
345
|
+
// that path is Attach PIN / standard Cardano. Switching to a different
|
|
346
|
+
// passphrase wallet still locks first.
|
|
347
|
+
const lockAttachPinBeforePassphraseSelection = async () => {
|
|
348
|
+
if (readCurrentAttachPinSession || options?.onlyMainPin) {
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
if (device.features?.unlockedAttachPin !== true) {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
await rejectMismatchedAttachPinWallet();
|
|
355
|
+
};
|
|
356
|
+
|
|
295
357
|
if (options?.onlyMainPin && options.rejectAttachPinForMainWallet) {
|
|
296
358
|
await rejectMismatchedAttachPinWallet();
|
|
297
359
|
}
|
|
@@ -342,7 +404,7 @@ export async function getProtocolV2WalletSession(
|
|
|
342
404
|
device.clearInternalState();
|
|
343
405
|
throw ERRORS.TypedError(HardwareErrorCode.DeviceCheckUnlockTypeError);
|
|
344
406
|
}
|
|
345
|
-
response = await getDeviceSession(device,
|
|
407
|
+
response = await getDeviceSession(device, sessionGetRequest());
|
|
346
408
|
} else if (options?.onlyMainPin) {
|
|
347
409
|
expectedPassphraseState = cachedStandardSession?.passphraseState;
|
|
348
410
|
if (cachedStandardSession) {
|
|
@@ -352,7 +414,7 @@ export async function getProtocolV2WalletSession(
|
|
|
352
414
|
}
|
|
353
415
|
response = await getDeviceSession(
|
|
354
416
|
device,
|
|
355
|
-
|
|
417
|
+
sessionGetRequest({
|
|
356
418
|
sessionId: cachedStandardSession.sessionId,
|
|
357
419
|
expectedPassphraseState,
|
|
358
420
|
})
|
|
@@ -369,13 +431,13 @@ export async function getProtocolV2WalletSession(
|
|
|
369
431
|
|
|
370
432
|
if (!response) {
|
|
371
433
|
await selectStandardWallet();
|
|
372
|
-
response = await getDeviceSession(device,
|
|
434
|
+
response = await getDeviceSession(device, sessionGetRequest());
|
|
373
435
|
}
|
|
374
436
|
} else if (cachedSessionId && expectedPassphraseState) {
|
|
375
437
|
try {
|
|
376
438
|
response = await getDeviceSession(
|
|
377
439
|
device,
|
|
378
|
-
|
|
440
|
+
sessionGetRequest({
|
|
379
441
|
sessionId: cachedSessionId,
|
|
380
442
|
expectedPassphraseState,
|
|
381
443
|
})
|
|
@@ -392,7 +454,7 @@ export async function getProtocolV2WalletSession(
|
|
|
392
454
|
try {
|
|
393
455
|
response = await getDeviceSession(
|
|
394
456
|
device,
|
|
395
|
-
|
|
457
|
+
sessionGetRequest({
|
|
396
458
|
expectedPassphraseState,
|
|
397
459
|
})
|
|
398
460
|
);
|
|
@@ -408,6 +470,7 @@ export async function getProtocolV2WalletSession(
|
|
|
408
470
|
device.clearInternalState();
|
|
409
471
|
throw ERRORS.TypedError(HardwareErrorCode.WalletSessionInvalid);
|
|
410
472
|
}
|
|
473
|
+
await lockAttachPinBeforePassphraseSelection();
|
|
411
474
|
response = await selectDeviceSession(
|
|
412
475
|
device,
|
|
413
476
|
expectedPassphraseState,
|
|
@@ -437,9 +500,10 @@ export async function getProtocolV2WalletSession(
|
|
|
437
500
|
if (options?.onlyMainPin) {
|
|
438
501
|
device.clearStandardInternalState?.();
|
|
439
502
|
await selectStandardWallet();
|
|
440
|
-
response = await getDeviceSession(device,
|
|
503
|
+
response = await getDeviceSession(device, sessionGetRequest());
|
|
441
504
|
} else {
|
|
442
505
|
device.clearInternalState();
|
|
506
|
+
await lockAttachPinBeforePassphraseSelection();
|
|
443
507
|
response = await selectDeviceSession(
|
|
444
508
|
device,
|
|
445
509
|
expectedPassphraseState,
|
|
@@ -465,18 +529,25 @@ export async function getProtocolV2WalletSession(
|
|
|
465
529
|
}
|
|
466
530
|
}
|
|
467
531
|
|
|
468
|
-
//
|
|
469
|
-
//
|
|
532
|
+
// origin/dev generates Cardano on AskPassphrase, not Get. Empty host
|
|
533
|
+
// passphrase is the Attach PIN / standard-wallet secret. Hidden wallets
|
|
534
|
+
// still need a real passphrase Ask. Passphrase-off Get auto-requests Cardano.
|
|
470
535
|
if (options?.deriveCardano === true && !deviceSessionHasCardano(message)) {
|
|
471
536
|
if (options?.resumeOnly) {
|
|
472
537
|
device.clearInternalState();
|
|
473
538
|
throw ERRORS.TypedError(HardwareErrorCode.WalletSessionInvalid);
|
|
474
539
|
}
|
|
475
540
|
resumed = false;
|
|
476
|
-
|
|
477
|
-
|
|
541
|
+
const previousAddress = message.btc_test_address;
|
|
542
|
+
if (sessionIsAttachPinWallet(response)) {
|
|
543
|
+
response = await askEmptyPassphraseAndGet({ deriveCardano: true, keepAttachPin: true });
|
|
544
|
+
} else if (device.features?.passphraseProtection === false) {
|
|
478
545
|
response = await getDeviceSession(device, buildDeviceSessionGetRequest());
|
|
546
|
+
} else if (options?.onlyMainPin) {
|
|
547
|
+
await selectMainPin();
|
|
548
|
+
response = await askEmptyPassphraseAndGet({ deriveCardano: true });
|
|
479
549
|
} else {
|
|
550
|
+
await lockAttachPinBeforePassphraseSelection();
|
|
480
551
|
response = await selectDeviceSession(
|
|
481
552
|
device,
|
|
482
553
|
expectedPassphraseState,
|
|
@@ -495,6 +566,15 @@ export async function getProtocolV2WalletSession(
|
|
|
495
566
|
}
|
|
496
567
|
throw error;
|
|
497
568
|
}
|
|
569
|
+
if (previousAddress && previousAddress !== message.btc_test_address) {
|
|
570
|
+
await rejectMismatchedAttachPinWallet();
|
|
571
|
+
clearCurrentWalletSession();
|
|
572
|
+
throw ERRORS.TypedError(HardwareErrorCode.DeviceCheckPassphraseStateError);
|
|
573
|
+
}
|
|
574
|
+
if (!deviceSessionHasCardano(message)) {
|
|
575
|
+
clearCurrentWalletSession();
|
|
576
|
+
throw ERRORS.TypedError(HardwareErrorCode.WalletSessionInvalid);
|
|
577
|
+
}
|
|
498
578
|
}
|
|
499
579
|
|
|
500
580
|
const internalStateArgs = [
|
|
@@ -511,7 +591,7 @@ export async function getProtocolV2WalletSession(
|
|
|
511
591
|
}
|
|
512
592
|
|
|
513
593
|
let unlockedAttachPin: boolean | undefined;
|
|
514
|
-
if (readCurrentAttachPinSession) {
|
|
594
|
+
if (readCurrentAttachPinSession || sessionIsAttachPinWallet(response)) {
|
|
515
595
|
unlockedAttachPin = true;
|
|
516
596
|
} else if (mainPinAuthenticated) {
|
|
517
597
|
unlockedAttachPin = false;
|