@bitgo-beta/passkey-crypto 0.0.1-beta.4 → 0.0.1-beta.400

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.
Files changed (63) hide show
  1. package/dist/src/attachPasskeyToWallet.d.ts +11 -0
  2. package/dist/src/attachPasskeyToWallet.d.ts.map +1 -0
  3. package/dist/src/attachPasskeyToWallet.js +68 -0
  4. package/dist/src/derivePasskeyPrfKey.d.ts +14 -0
  5. package/dist/src/derivePasskeyPrfKey.d.ts.map +1 -0
  6. package/dist/src/derivePasskeyPrfKey.js +68 -0
  7. package/dist/src/index.d.ts +8 -3
  8. package/dist/src/index.d.ts.map +1 -1
  9. package/dist/src/index.js +16 -6
  10. package/dist/src/prfHelpers.d.ts.map +1 -1
  11. package/dist/src/prfHelpers.js +19 -4
  12. package/dist/src/registerPasskey.d.ts +9 -0
  13. package/dist/src/registerPasskey.d.ts.map +1 -0
  14. package/dist/src/registerPasskey.js +93 -0
  15. package/dist/src/removePasskeyFromAccount.d.ts +11 -0
  16. package/dist/src/removePasskeyFromAccount.d.ts.map +1 -0
  17. package/dist/src/removePasskeyFromAccount.js +15 -0
  18. package/dist/src/removePasskeyFromWallet.d.ts +9 -0
  19. package/dist/src/removePasskeyFromWallet.d.ts.map +1 -0
  20. package/dist/src/removePasskeyFromWallet.js +22 -0
  21. package/dist/test/integration/helpers/fixtures.d.ts +12 -0
  22. package/dist/test/integration/helpers/fixtures.d.ts.map +1 -0
  23. package/dist/test/integration/helpers/fixtures.js +15 -0
  24. package/dist/test/integration/helpers/mockBitGo.d.ts +27 -0
  25. package/dist/test/integration/helpers/mockBitGo.d.ts.map +1 -0
  26. package/dist/test/integration/helpers/mockBitGo.js +148 -0
  27. package/dist/test/integration/helpers/mockProvider.d.ts +5 -0
  28. package/dist/test/integration/helpers/mockProvider.d.ts.map +1 -0
  29. package/dist/test/integration/helpers/mockProvider.js +37 -0
  30. package/dist/test/integration/passkeyLifecycle.test.d.ts +2 -0
  31. package/dist/test/integration/passkeyLifecycle.test.d.ts.map +1 -0
  32. package/dist/test/integration/passkeyLifecycle.test.js +152 -0
  33. package/dist/test/unit/attachPasskeyToWallet.test.d.ts +2 -0
  34. package/dist/test/unit/attachPasskeyToWallet.test.d.ts.map +1 -0
  35. package/dist/test/unit/attachPasskeyToWallet.test.js +224 -0
  36. package/dist/test/unit/base64url.test.d.ts +2 -0
  37. package/dist/test/unit/base64url.test.d.ts.map +1 -0
  38. package/dist/test/unit/base64url.test.js +75 -0
  39. package/dist/test/unit/deriveEnterpriseSalt.test.js +8 -4
  40. package/dist/test/unit/derivePasskeyPrfKey.test.d.ts +2 -0
  41. package/dist/test/unit/derivePasskeyPrfKey.test.d.ts.map +1 -0
  42. package/dist/test/unit/derivePasskeyPrfKey.test.js +152 -0
  43. package/dist/test/unit/registerPasskey.test.d.ts +2 -0
  44. package/dist/test/unit/registerPasskey.test.d.ts.map +1 -0
  45. package/dist/test/unit/registerPasskey.test.js +155 -0
  46. package/dist/test/unit/removePasskeyFromAccount.test.d.ts +2 -0
  47. package/dist/test/unit/removePasskeyFromAccount.test.d.ts.map +1 -0
  48. package/dist/test/unit/removePasskeyFromAccount.test.js +88 -0
  49. package/dist/test/unit/removePasskeyFromWallet.test.d.ts +2 -0
  50. package/dist/test/unit/removePasskeyFromWallet.test.d.ts.map +1 -0
  51. package/dist/test/unit/removePasskeyFromWallet.test.js +170 -0
  52. package/dist/tsconfig.tsbuildinfo +1 -1
  53. package/package.json +8 -6
  54. package/LICENSE +0 -191
  55. package/dist/src/deriveEnterpriseSalt.d.ts +0 -12
  56. package/dist/src/deriveEnterpriseSalt.d.ts.map +0 -1
  57. package/dist/src/deriveEnterpriseSalt.js +0 -56
  58. package/dist/src/derivePassword.d.ts +0 -11
  59. package/dist/src/derivePassword.d.ts.map +0 -1
  60. package/dist/src/derivePassword.js +0 -16
  61. package/dist/src/webAuthnTypes.d.ts +0 -18
  62. package/dist/src/webAuthnTypes.d.ts.map +0 -1
  63. package/dist/src/webAuthnTypes.js +0 -3
@@ -0,0 +1,11 @@
1
+ import { BitGoBase, EncryptionVersion, Keychain, type WebAuthnOtpDevice, type WebAuthnProvider } from '@bitgo-beta/sdk-core';
2
+ export declare function attachPasskeyToWallet(params: {
3
+ bitgo: BitGoBase;
4
+ coin: string;
5
+ walletId: string;
6
+ device: WebAuthnOtpDevice;
7
+ existingPassphrase: string;
8
+ provider: WebAuthnProvider;
9
+ encryptionVersion?: EncryptionVersion;
10
+ }): Promise<Keychain>;
11
+ //# sourceMappingURL=attachPasskeyToWallet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachPasskeyToWallet.d.ts","sourceRoot":"","sources":["../../src/attachPasskeyToWallet.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,QAAQ,EAIR,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACtB,MAAM,sBAAsB,CAAC;AAE9B,wBAAsB,qBAAqB,CAAC,MAAM,EAAE;IAClD,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC,GAAG,OAAO,CAAC,QAAQ,CAAC,CA4EpB"}
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.attachPasskeyToWallet = attachPasskeyToWallet;
4
+ const sdk_core_1 = require("@bitgo-beta/sdk-core");
5
+ async function attachPasskeyToWallet(params) {
6
+ const { bitgo, coin, walletId, device, existingPassphrase, provider, encryptionVersion } = params;
7
+ // Throw early if PRF extension is not supported
8
+ if (!device.prfSalt) {
9
+ throw new Error('PRF extension not supported by this device. Please use a different passkey.');
10
+ }
11
+ const baseCoin = bitgo.coin(coin);
12
+ // Fetch wallet and validate it is a hot wallet
13
+ const wallet = await baseCoin.wallets().get({ id: walletId });
14
+ if (wallet.type() !== 'hot') {
15
+ throw new Error(`Wallet ${walletId} is not a hot wallet. Only hot wallets support passkey attachment.`);
16
+ }
17
+ const walletData = wallet.toJSON();
18
+ const enterpriseId = walletData.enterprise;
19
+ if (!enterpriseId) {
20
+ throw new Error(`Wallet ${walletId} has no enterprise.`);
21
+ }
22
+ // Fetch the user keychain — iterates keys until it finds one with encryptedPrv
23
+ const keychain = await wallet.getEncryptedUserKeychain();
24
+ const keychainId = keychain.id;
25
+ // Derive enterprise-scoped salt (base64url; same encoding is used as the
26
+ // PRF eval input and as the server-stored prfSalt so the bytes fed to the
27
+ // authenticator match between attach and derive).
28
+ const prfSalt = (0, sdk_core_1.deriveEnterpriseSalt)(device.prfSalt, enterpriseId);
29
+ // Decrypt private key with existing passphrase
30
+ const privateKey = await bitgo.decrypt({ password: existingPassphrase, input: keychain.encryptedPrv });
31
+ // Decode credentialId from base64url to ArrayBuffer for allowCredentials.
32
+ // The WebAuthn spec requires allowCredentials to be non-empty when using evalByCredential,
33
+ // and each entry must correspond to a key in the evalByCredential map.
34
+ const credentialIdBuffer = (0, sdk_core_1.base64UrlToBuffer)(device.credentialId).buffer;
35
+ // PRF assertion — evalByCredential maps this device's credentialId to the
36
+ // base64url enterprise salt. The provider layer is responsible for decoding
37
+ // base64url to raw bytes before handing it to the WebAuthn PRF extension.
38
+ const authResult = await provider.get({
39
+ publicKey: {
40
+ allowCredentials: [{ type: 'public-key', id: credentialIdBuffer }],
41
+ },
42
+ evalByCredential: { [device.credentialId]: prfSalt },
43
+ });
44
+ if (!authResult.prfResult) {
45
+ throw new Error('PRF assertion did not return a result.');
46
+ }
47
+ const prfPassword = (0, sdk_core_1.derivePassword)(authResult.prfResult);
48
+ const encryptedPrv = await bitgo.encrypt({
49
+ password: prfPassword,
50
+ input: privateKey,
51
+ encryptionVersion,
52
+ // Bind to this enterprise via AES-GCM AAD — moving this blob to another enterprise
53
+ // or tampering with the stored adata field invalidates the GCM tag.
54
+ adata: enterpriseId,
55
+ });
56
+ const updatedKeychain = await bitgo
57
+ .put(bitgo.url(`/${coin}/key/${keychainId}`, 2))
58
+ .send({
59
+ webauthnInfo: {
60
+ prfSalt,
61
+ otpDeviceId: device.id,
62
+ encryptedPrv,
63
+ },
64
+ })
65
+ .result();
66
+ return updatedKeychain;
67
+ }
68
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXR0YWNoUGFzc2tleVRvV2FsbGV0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2F0dGFjaFBhc3NrZXlUb1dhbGxldC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQVdBLHNEQW9GQztBQS9GRCxtREFTOEI7QUFFdkIsS0FBSyxVQUFVLHFCQUFxQixDQUFDLE1BUTNDO0lBQ0MsTUFBTSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxrQkFBa0IsRUFBRSxRQUFRLEVBQUUsaUJBQWlCLEVBQUUsR0FBRyxNQUFNLENBQUM7SUFFbEcsZ0RBQWdEO0lBQ2hELElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDcEIsTUFBTSxJQUFJLEtBQUssQ0FBQyw2RUFBNkUsQ0FBQyxDQUFDO0lBQ2pHLENBQUM7SUFFRCxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBRWxDLCtDQUErQztJQUMvQyxNQUFNLE1BQU0sR0FBRyxNQUFNLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztJQUU5RCxJQUFJLE1BQU0sQ0FBQyxJQUFJLEVBQUUsS0FBSyxLQUFLLEVBQUUsQ0FBQztRQUM1QixNQUFNLElBQUksS0FBSyxDQUFDLFVBQVUsUUFBUSxvRUFBb0UsQ0FBQyxDQUFDO0lBQzFHLENBQUM7SUFFRCxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUM7SUFDbkMsTUFBTSxZQUFZLEdBQUcsVUFBVSxDQUFDLFVBQVUsQ0FBQztJQUMzQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDbEIsTUFBTSxJQUFJLEtBQUssQ0FBQyxVQUFVLFFBQVEscUJBQXFCLENBQUMsQ0FBQztJQUMzRCxDQUFDO0lBRUQsK0VBQStFO0lBQy9FLE1BQU0sUUFBUSxHQUFHLE1BQU0sTUFBTSxDQUFDLHdCQUF3QixFQUFFLENBQUM7SUFDekQsTUFBTSxVQUFVLEdBQUcsUUFBUSxDQUFDLEVBQUUsQ0FBQztJQUUvQix5RUFBeUU7SUFDekUsMEVBQTBFO0lBQzFFLGtEQUFrRDtJQUNsRCxNQUFNLE9BQU8sR0FBRyxJQUFBLCtCQUFvQixFQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsWUFBWSxDQUFDLENBQUM7SUFFbkUsK0NBQStDO0lBQy9DLE1BQU0sVUFBVSxHQUFHLE1BQU0sS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFLFFBQVEsRUFBRSxrQkFBa0IsRUFBRSxLQUFLLEVBQUUsUUFBUSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUM7SUFFdkcsMEVBQTBFO0lBQzFFLDJGQUEyRjtJQUMzRix1RUFBdUU7SUFDdkUsTUFBTSxrQkFBa0IsR0FBRyxJQUFBLDRCQUFpQixFQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFFekUsMEVBQTBFO0lBQzFFLDRFQUE0RTtJQUM1RSwwRUFBMEU7SUFDMUUsTUFBTSxVQUFVLEdBQUcsTUFBTSxRQUFRLENBQUMsR0FBRyxDQUFDO1FBQ3BDLFNBQVMsRUFBRTtZQUNULGdCQUFnQixFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLEVBQUUsRUFBRSxrQkFBa0IsRUFBRSxDQUFDO1NBQzlCO1FBQ3RDLGdCQUFnQixFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLEVBQUUsT0FBTyxFQUFFO0tBQ3JELENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxVQUFVLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDMUIsTUFBTSxJQUFJLEtBQUssQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO0lBQzVELENBQUM7SUFFRCxNQUFNLFdBQVcsR0FBRyxJQUFBLHlCQUFjLEVBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3pELE1BQU0sWUFBWSxHQUFHLE1BQU0sS0FBSyxDQUFDLE9BQU8sQ0FBQztRQUN2QyxRQUFRLEVBQUUsV0FBVztRQUNyQixLQUFLLEVBQUUsVUFBVTtRQUNqQixpQkFBaUI7UUFDakIsbUZBQW1GO1FBQ25GLG9FQUFvRTtRQUNwRSxLQUFLLEVBQUUsWUFBWTtLQUNwQixDQUFDLENBQUM7SUFFSCxNQUFNLGVBQWUsR0FBRyxNQUFNLEtBQUs7U0FDaEMsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxJQUFJLFFBQVEsVUFBVSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7U0FDL0MsSUFBSSxDQUFDO1FBQ0osWUFBWSxFQUFFO1lBQ1osT0FBTztZQUNQLFdBQVcsRUFBRSxNQUFNLENBQUMsRUFBRTtZQUN0QixZQUFZO1NBQ2I7S0FDRixDQUFDO1NBQ0QsTUFBTSxFQUFFLENBQUM7SUFFWixPQUFPLGVBQTJCLENBQUM7QUFDckMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEJpdEdvQmFzZSxcbiAgRW5jcnlwdGlvblZlcnNpb24sXG4gIEtleWNoYWluLFxuICBiYXNlNjRVcmxUb0J1ZmZlcixcbiAgZGVyaXZlRW50ZXJwcmlzZVNhbHQsXG4gIGRlcml2ZVBhc3N3b3JkLFxuICB0eXBlIFdlYkF1dGhuT3RwRGV2aWNlLFxuICB0eXBlIFdlYkF1dGhuUHJvdmlkZXIsXG59IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGF0dGFjaFBhc3NrZXlUb1dhbGxldChwYXJhbXM6IHtcbiAgYml0Z286IEJpdEdvQmFzZTtcbiAgY29pbjogc3RyaW5nO1xuICB3YWxsZXRJZDogc3RyaW5nO1xuICBkZXZpY2U6IFdlYkF1dGhuT3RwRGV2aWNlO1xuICBleGlzdGluZ1Bhc3NwaHJhc2U6IHN0cmluZztcbiAgcHJvdmlkZXI6IFdlYkF1dGhuUHJvdmlkZXI7XG4gIGVuY3J5cHRpb25WZXJzaW9uPzogRW5jcnlwdGlvblZlcnNpb247XG59KTogUHJvbWlzZTxLZXljaGFpbj4ge1xuICBjb25zdCB7IGJpdGdvLCBjb2luLCB3YWxsZXRJZCwgZGV2aWNlLCBleGlzdGluZ1Bhc3NwaHJhc2UsIHByb3ZpZGVyLCBlbmNyeXB0aW9uVmVyc2lvbiB9ID0gcGFyYW1zO1xuXG4gIC8vIFRocm93IGVhcmx5IGlmIFBSRiBleHRlbnNpb24gaXMgbm90IHN1cHBvcnRlZFxuICBpZiAoIWRldmljZS5wcmZTYWx0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdQUkYgZXh0ZW5zaW9uIG5vdCBzdXBwb3J0ZWQgYnkgdGhpcyBkZXZpY2UuIFBsZWFzZSB1c2UgYSBkaWZmZXJlbnQgcGFzc2tleS4nKTtcbiAgfVxuXG4gIGNvbnN0IGJhc2VDb2luID0gYml0Z28uY29pbihjb2luKTtcblxuICAvLyBGZXRjaCB3YWxsZXQgYW5kIHZhbGlkYXRlIGl0IGlzIGEgaG90IHdhbGxldFxuICBjb25zdCB3YWxsZXQgPSBhd2FpdCBiYXNlQ29pbi53YWxsZXRzKCkuZ2V0KHsgaWQ6IHdhbGxldElkIH0pO1xuXG4gIGlmICh3YWxsZXQudHlwZSgpICE9PSAnaG90Jykge1xuICAgIHRocm93IG5ldyBFcnJvcihgV2FsbGV0ICR7d2FsbGV0SWR9IGlzIG5vdCBhIGhvdCB3YWxsZXQuIE9ubHkgaG90IHdhbGxldHMgc3VwcG9ydCBwYXNza2V5IGF0dGFjaG1lbnQuYCk7XG4gIH1cblxuICBjb25zdCB3YWxsZXREYXRhID0gd2FsbGV0LnRvSlNPTigpO1xuICBjb25zdCBlbnRlcnByaXNlSWQgPSB3YWxsZXREYXRhLmVudGVycHJpc2U7XG4gIGlmICghZW50ZXJwcmlzZUlkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBXYWxsZXQgJHt3YWxsZXRJZH0gaGFzIG5vIGVudGVycHJpc2UuYCk7XG4gIH1cblxuICAvLyBGZXRjaCB0aGUgdXNlciBrZXljaGFpbiDigJQgaXRlcmF0ZXMga2V5cyB1bnRpbCBpdCBmaW5kcyBvbmUgd2l0aCBlbmNyeXB0ZWRQcnZcbiAgY29uc3Qga2V5Y2hhaW4gPSBhd2FpdCB3YWxsZXQuZ2V0RW5jcnlwdGVkVXNlcktleWNoYWluKCk7XG4gIGNvbnN0IGtleWNoYWluSWQgPSBrZXljaGFpbi5pZDtcblxuICAvLyBEZXJpdmUgZW50ZXJwcmlzZS1zY29wZWQgc2FsdCAoYmFzZTY0dXJsOyBzYW1lIGVuY29kaW5nIGlzIHVzZWQgYXMgdGhlXG4gIC8vIFBSRiBldmFsIGlucHV0IGFuZCBhcyB0aGUgc2VydmVyLXN0b3JlZCBwcmZTYWx0IHNvIHRoZSBieXRlcyBmZWQgdG8gdGhlXG4gIC8vIGF1dGhlbnRpY2F0b3IgbWF0Y2ggYmV0d2VlbiBhdHRhY2ggYW5kIGRlcml2ZSkuXG4gIGNvbnN0IHByZlNhbHQgPSBkZXJpdmVFbnRlcnByaXNlU2FsdChkZXZpY2UucHJmU2FsdCwgZW50ZXJwcmlzZUlkKTtcblxuICAvLyBEZWNyeXB0IHByaXZhdGUga2V5IHdpdGggZXhpc3RpbmcgcGFzc3BocmFzZVxuICBjb25zdCBwcml2YXRlS2V5ID0gYXdhaXQgYml0Z28uZGVjcnlwdCh7IHBhc3N3b3JkOiBleGlzdGluZ1Bhc3NwaHJhc2UsIGlucHV0OiBrZXljaGFpbi5lbmNyeXB0ZWRQcnYgfSk7XG5cbiAgLy8gRGVjb2RlIGNyZWRlbnRpYWxJZCBmcm9tIGJhc2U2NHVybCB0byBBcnJheUJ1ZmZlciBmb3IgYWxsb3dDcmVkZW50aWFscy5cbiAgLy8gVGhlIFdlYkF1dGhuIHNwZWMgcmVxdWlyZXMgYWxsb3dDcmVkZW50aWFscyB0byBiZSBub24tZW1wdHkgd2hlbiB1c2luZyBldmFsQnlDcmVkZW50aWFsLFxuICAvLyBhbmQgZWFjaCBlbnRyeSBtdXN0IGNvcnJlc3BvbmQgdG8gYSBrZXkgaW4gdGhlIGV2YWxCeUNyZWRlbnRpYWwgbWFwLlxuICBjb25zdCBjcmVkZW50aWFsSWRCdWZmZXIgPSBiYXNlNjRVcmxUb0J1ZmZlcihkZXZpY2UuY3JlZGVudGlhbElkKS5idWZmZXI7XG5cbiAgLy8gUFJGIGFzc2VydGlvbiDigJQgZXZhbEJ5Q3JlZGVudGlhbCBtYXBzIHRoaXMgZGV2aWNlJ3MgY3JlZGVudGlhbElkIHRvIHRoZVxuICAvLyBiYXNlNjR1cmwgZW50ZXJwcmlzZSBzYWx0LiBUaGUgcHJvdmlkZXIgbGF5ZXIgaXMgcmVzcG9uc2libGUgZm9yIGRlY29kaW5nXG4gIC8vIGJhc2U2NHVybCB0byByYXcgYnl0ZXMgYmVmb3JlIGhhbmRpbmcgaXQgdG8gdGhlIFdlYkF1dGhuIFBSRiBleHRlbnNpb24uXG4gIGNvbnN0IGF1dGhSZXN1bHQgPSBhd2FpdCBwcm92aWRlci5nZXQoe1xuICAgIHB1YmxpY0tleToge1xuICAgICAgYWxsb3dDcmVkZW50aWFsczogW3sgdHlwZTogJ3B1YmxpYy1rZXknLCBpZDogY3JlZGVudGlhbElkQnVmZmVyIH1dLFxuICAgIH0gYXMgUHVibGljS2V5Q3JlZGVudGlhbFJlcXVlc3RPcHRpb25zLFxuICAgIGV2YWxCeUNyZWRlbnRpYWw6IHsgW2RldmljZS5jcmVkZW50aWFsSWRdOiBwcmZTYWx0IH0sXG4gIH0pO1xuXG4gIGlmICghYXV0aFJlc3VsdC5wcmZSZXN1bHQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1BSRiBhc3NlcnRpb24gZGlkIG5vdCByZXR1cm4gYSByZXN1bHQuJyk7XG4gIH1cblxuICBjb25zdCBwcmZQYXNzd29yZCA9IGRlcml2ZVBhc3N3b3JkKGF1dGhSZXN1bHQucHJmUmVzdWx0KTtcbiAgY29uc3QgZW5jcnlwdGVkUHJ2ID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7XG4gICAgcGFzc3dvcmQ6IHByZlBhc3N3b3JkLFxuICAgIGlucHV0OiBwcml2YXRlS2V5LFxuICAgIGVuY3J5cHRpb25WZXJzaW9uLFxuICAgIC8vIEJpbmQgdG8gdGhpcyBlbnRlcnByaXNlIHZpYSBBRVMtR0NNIEFBRCDigJQgbW92aW5nIHRoaXMgYmxvYiB0byBhbm90aGVyIGVudGVycHJpc2VcbiAgICAvLyBvciB0YW1wZXJpbmcgd2l0aCB0aGUgc3RvcmVkIGFkYXRhIGZpZWxkIGludmFsaWRhdGVzIHRoZSBHQ00gdGFnLlxuICAgIGFkYXRhOiBlbnRlcnByaXNlSWQsXG4gIH0pO1xuXG4gIGNvbnN0IHVwZGF0ZWRLZXljaGFpbiA9IGF3YWl0IGJpdGdvXG4gICAgLnB1dChiaXRnby51cmwoYC8ke2NvaW59L2tleS8ke2tleWNoYWluSWR9YCwgMikpXG4gICAgLnNlbmQoe1xuICAgICAgd2ViYXV0aG5JbmZvOiB7XG4gICAgICAgIHByZlNhbHQsXG4gICAgICAgIG90cERldmljZUlkOiBkZXZpY2UuaWQsXG4gICAgICAgIGVuY3J5cHRlZFBydixcbiAgICAgIH0sXG4gICAgfSlcbiAgICAucmVzdWx0KCk7XG5cbiAgcmV0dXJuIHVwZGF0ZWRLZXljaGFpbiBhcyBLZXljaGFpbjtcbn1cbiJdfQ==
@@ -0,0 +1,14 @@
1
+ import { type BitGoBase, type IWallet, type WebAuthnProvider } from '@bitgo-beta/sdk-core';
2
+ /**
3
+ * Derives a wallet passphrase from a passkey PRF output.
4
+ *
5
+ * Fetches the wallet's user keychain, triggers a WebAuthn assertion with PRF
6
+ * evaluation, and returns a hex-encoded passphrase suitable for use as
7
+ * walletPassphrase in signing calls.
8
+ */
9
+ export declare function derivePasskeyPrfKey(params: {
10
+ bitgo: BitGoBase;
11
+ wallet: IWallet;
12
+ provider: WebAuthnProvider;
13
+ }): Promise<string>;
14
+ //# sourceMappingURL=derivePasskeyPrfKey.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"derivePasskeyPrfKey.d.ts","sourceRoot":"","sources":["../../src/derivePasskeyPrfKey.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,OAAO,EAGZ,KAAK,gBAAgB,EACtB,MAAM,sBAAsB,CAAC;AA+B9B;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE;IAChD,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,gBAAgB,CAAC;CAC5B,GAAG,OAAO,CAAC,MAAM,CAAC,CA4ClB"}
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.derivePasskeyPrfKey = derivePasskeyPrfKey;
4
+ const sdk_core_1 = require("@bitgo-beta/sdk-core");
5
+ const prfHelpers_1 = require("./prfHelpers");
6
+ function webauthnDevicesFromKeychain(keychain) {
7
+ const lower = keychain.webauthnDevices;
8
+ if (lower !== undefined && lower.length > 0) {
9
+ return lower;
10
+ }
11
+ const upper = keychain.webAuthnDevices;
12
+ if (upper !== undefined && upper.length > 0) {
13
+ return upper;
14
+ }
15
+ return undefined;
16
+ }
17
+ function challengeFromAuthResponse(body) {
18
+ if (typeof body !== 'object' || body === null) {
19
+ throw new Error('Invalid assertion challenge response');
20
+ }
21
+ const rec = body;
22
+ if (typeof rec.challenge !== 'string') {
23
+ throw new Error('Invalid assertion challenge response');
24
+ }
25
+ return rec.challenge;
26
+ }
27
+ /**
28
+ * Derives a wallet passphrase from a passkey PRF output.
29
+ *
30
+ * Fetches the wallet's user keychain, triggers a WebAuthn assertion with PRF
31
+ * evaluation, and returns a hex-encoded passphrase suitable for use as
32
+ * walletPassphrase in signing calls.
33
+ */
34
+ async function derivePasskeyPrfKey(params) {
35
+ const { bitgo, wallet, provider } = params;
36
+ const keychain = await wallet.getEncryptedUserKeychain();
37
+ const devices = webauthnDevicesFromKeychain(keychain);
38
+ if (!devices || devices.length === 0) {
39
+ throw new Error('No passkey devices available');
40
+ }
41
+ const { evalByCredential } = (0, prfHelpers_1.buildEvalByCredential)(devices);
42
+ if (Object.keys(evalByCredential).length === 0) {
43
+ throw new Error('No passkey devices available with a valid PRF salt');
44
+ }
45
+ const challenge = challengeFromAuthResponse(await bitgo.get(bitgo.url('/user/otp/webauthn/auth', 2)).result());
46
+ const allowCredentials = Object.keys(evalByCredential).map((credId) => {
47
+ const nodeBuf = Buffer.from(credId.replace(/-/g, '+').replace(/_/g, '/'), 'base64');
48
+ const id = nodeBuf.buffer.slice(nodeBuf.byteOffset, nodeBuf.byteOffset + nodeBuf.byteLength);
49
+ return {
50
+ type: 'public-key',
51
+ id,
52
+ };
53
+ });
54
+ const publicKey = {
55
+ challenge: new Uint8Array(Buffer.from(challenge, 'base64')),
56
+ allowCredentials,
57
+ };
58
+ const result = await provider.get({
59
+ publicKey,
60
+ evalByCredential,
61
+ });
62
+ (0, prfHelpers_1.matchDeviceByCredentialId)(devices, result.credentialId);
63
+ if (!result.prfResult) {
64
+ throw new Error('PRF output was not returned by the authenticator');
65
+ }
66
+ return (0, sdk_core_1.derivePassword)(result.prfResult);
67
+ }
68
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVyaXZlUGFzc2tleVByZktleS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kZXJpdmVQYXNza2V5UHJmS2V5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBNkNBLGtEQWdEQztBQTdGRCxtREFPOEI7QUFDOUIsNkNBQWdGO0FBT2hGLFNBQVMsMkJBQTJCLENBQUMsUUFBOEI7SUFDakUsTUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLGVBQWUsQ0FBQztJQUN2QyxJQUFJLEtBQUssS0FBSyxTQUFTLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUM1QyxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFDRCxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsZUFBZSxDQUFDO0lBQ3ZDLElBQUksS0FBSyxLQUFLLFNBQVMsSUFBSSxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQzVDLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUNELE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUM7QUFFRCxTQUFTLHlCQUF5QixDQUFDLElBQWE7SUFDOUMsSUFBSSxPQUFPLElBQUksS0FBSyxRQUFRLElBQUksSUFBSSxLQUFLLElBQUksRUFBRSxDQUFDO1FBQzlDLE1BQU0sSUFBSSxLQUFLLENBQUMsc0NBQXNDLENBQUMsQ0FBQztJQUMxRCxDQUFDO0lBQ0QsTUFBTSxHQUFHLEdBQUcsSUFBK0IsQ0FBQztJQUM1QyxJQUFJLE9BQU8sR0FBRyxDQUFDLFNBQVMsS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUN0QyxNQUFNLElBQUksS0FBSyxDQUFDLHNDQUFzQyxDQUFDLENBQUM7SUFDMUQsQ0FBQztJQUNELE9BQU8sR0FBRyxDQUFDLFNBQVMsQ0FBQztBQUN2QixDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0ksS0FBSyxVQUFVLG1CQUFtQixDQUFDLE1BSXpDO0lBQ0MsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLEdBQUcsTUFBTSxDQUFDO0lBRTNDLE1BQU0sUUFBUSxHQUF5QixNQUFNLE1BQU0sQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO0lBQy9FLE1BQU0sT0FBTyxHQUFHLDJCQUEyQixDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBRXRELElBQUksQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUNyQyxNQUFNLElBQUksS0FBSyxDQUFDLDhCQUE4QixDQUFDLENBQUM7SUFDbEQsQ0FBQztJQUVELE1BQU0sRUFBRSxnQkFBZ0IsRUFBRSxHQUFHLElBQUEsa0NBQXFCLEVBQUMsT0FBTyxDQUFDLENBQUM7SUFFNUQsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQy9DLE1BQU0sSUFBSSxLQUFLLENBQUMsb0RBQW9ELENBQUMsQ0FBQztJQUN4RSxDQUFDO0lBRUQsTUFBTSxTQUFTLEdBQUcseUJBQXlCLENBQUMsTUFBTSxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMseUJBQXlCLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBRS9HLE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFO1FBQ3BFLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUNwRixNQUFNLEVBQUUsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLE9BQU8sQ0FBQyxVQUFVLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQzdGLE9BQU87WUFDTCxJQUFJLEVBQUUsWUFBcUI7WUFDM0IsRUFBRTtTQUNILENBQUM7SUFDSixDQUFDLENBQUMsQ0FBQztJQUVILE1BQU0sU0FBUyxHQUFzQztRQUNuRCxTQUFTLEVBQUUsSUFBSSxVQUFVLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDM0QsZ0JBQWdCO0tBQ2pCLENBQUM7SUFFRixNQUFNLE1BQU0sR0FBRyxNQUFNLFFBQVEsQ0FBQyxHQUFHLENBQUM7UUFDaEMsU0FBUztRQUNULGdCQUFnQjtLQUNqQixDQUFDLENBQUM7SUFFSCxJQUFBLHNDQUF5QixFQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUM7SUFFeEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUN0QixNQUFNLElBQUksS0FBSyxDQUFDLGtEQUFrRCxDQUFDLENBQUM7SUFDdEUsQ0FBQztJQUVELE9BQU8sSUFBQSx5QkFBYyxFQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUMxQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgZGVyaXZlUGFzc3dvcmQsXG4gIHR5cGUgQml0R29CYXNlLFxuICB0eXBlIElXYWxsZXQsXG4gIHR5cGUgS2V5Y2hhaW5XZWJhdXRobkRldmljZSxcbiAgdHlwZSBLZXljaGFpbldpdGhFbmNyeXB0ZWRQcnYsXG4gIHR5cGUgV2ViQXV0aG5Qcm92aWRlcixcbn0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuaW1wb3J0IHsgYnVpbGRFdmFsQnlDcmVkZW50aWFsLCBtYXRjaERldmljZUJ5Q3JlZGVudGlhbElkIH0gZnJvbSAnLi9wcmZIZWxwZXJzJztcblxuLyoqIEFQSSBwYXlsb2FkcyBtYXkgdXNlIGVpdGhlciBzcGVsbGluZyBmb3IgdGhlIHdlYmF1dGhuIGRldmljZSBsaXN0LiAqL1xudHlwZSBVc2VyS2V5Y2hhaW5SZXNwb25zZSA9IEtleWNoYWluV2l0aEVuY3J5cHRlZFBydiAmIHtcbiAgd2ViQXV0aG5EZXZpY2VzPzogS2V5Y2hhaW5XZWJhdXRobkRldmljZVtdO1xufTtcblxuZnVuY3Rpb24gd2ViYXV0aG5EZXZpY2VzRnJvbUtleWNoYWluKGtleWNoYWluOiBVc2VyS2V5Y2hhaW5SZXNwb25zZSk6IEtleWNoYWluV2ViYXV0aG5EZXZpY2VbXSB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IGxvd2VyID0ga2V5Y2hhaW4ud2ViYXV0aG5EZXZpY2VzO1xuICBpZiAobG93ZXIgIT09IHVuZGVmaW5lZCAmJiBsb3dlci5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIGxvd2VyO1xuICB9XG4gIGNvbnN0IHVwcGVyID0ga2V5Y2hhaW4ud2ViQXV0aG5EZXZpY2VzO1xuICBpZiAodXBwZXIgIT09IHVuZGVmaW5lZCAmJiB1cHBlci5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIHVwcGVyO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGNoYWxsZW5nZUZyb21BdXRoUmVzcG9uc2UoYm9keTogdW5rbm93bik6IHN0cmluZyB7XG4gIGlmICh0eXBlb2YgYm9keSAhPT0gJ29iamVjdCcgfHwgYm9keSA9PT0gbnVsbCkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBhc3NlcnRpb24gY2hhbGxlbmdlIHJlc3BvbnNlJyk7XG4gIH1cbiAgY29uc3QgcmVjID0gYm9keSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgaWYgKHR5cGVvZiByZWMuY2hhbGxlbmdlICE9PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBhc3NlcnRpb24gY2hhbGxlbmdlIHJlc3BvbnNlJyk7XG4gIH1cbiAgcmV0dXJuIHJlYy5jaGFsbGVuZ2U7XG59XG5cbi8qKlxuICogRGVyaXZlcyBhIHdhbGxldCBwYXNzcGhyYXNlIGZyb20gYSBwYXNza2V5IFBSRiBvdXRwdXQuXG4gKlxuICogRmV0Y2hlcyB0aGUgd2FsbGV0J3MgdXNlciBrZXljaGFpbiwgdHJpZ2dlcnMgYSBXZWJBdXRobiBhc3NlcnRpb24gd2l0aCBQUkZcbiAqIGV2YWx1YXRpb24sIGFuZCByZXR1cm5zIGEgaGV4LWVuY29kZWQgcGFzc3BocmFzZSBzdWl0YWJsZSBmb3IgdXNlIGFzXG4gKiB3YWxsZXRQYXNzcGhyYXNlIGluIHNpZ25pbmcgY2FsbHMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZXJpdmVQYXNza2V5UHJmS2V5KHBhcmFtczoge1xuICBiaXRnbzogQml0R29CYXNlO1xuICB3YWxsZXQ6IElXYWxsZXQ7XG4gIHByb3ZpZGVyOiBXZWJBdXRoblByb3ZpZGVyO1xufSk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IHsgYml0Z28sIHdhbGxldCwgcHJvdmlkZXIgfSA9IHBhcmFtcztcblxuICBjb25zdCBrZXljaGFpbjogVXNlcktleWNoYWluUmVzcG9uc2UgPSBhd2FpdCB3YWxsZXQuZ2V0RW5jcnlwdGVkVXNlcktleWNoYWluKCk7XG4gIGNvbnN0IGRldmljZXMgPSB3ZWJhdXRobkRldmljZXNGcm9tS2V5Y2hhaW4oa2V5Y2hhaW4pO1xuXG4gIGlmICghZGV2aWNlcyB8fCBkZXZpY2VzLmxlbmd0aCA9PT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignTm8gcGFzc2tleSBkZXZpY2VzIGF2YWlsYWJsZScpO1xuICB9XG5cbiAgY29uc3QgeyBldmFsQnlDcmVkZW50aWFsIH0gPSBidWlsZEV2YWxCeUNyZWRlbnRpYWwoZGV2aWNlcyk7XG5cbiAgaWYgKE9iamVjdC5rZXlzKGV2YWxCeUNyZWRlbnRpYWwpLmxlbmd0aCA9PT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignTm8gcGFzc2tleSBkZXZpY2VzIGF2YWlsYWJsZSB3aXRoIGEgdmFsaWQgUFJGIHNhbHQnKTtcbiAgfVxuXG4gIGNvbnN0IGNoYWxsZW5nZSA9IGNoYWxsZW5nZUZyb21BdXRoUmVzcG9uc2UoYXdhaXQgYml0Z28uZ2V0KGJpdGdvLnVybCgnL3VzZXIvb3RwL3dlYmF1dGhuL2F1dGgnLCAyKSkucmVzdWx0KCkpO1xuXG4gIGNvbnN0IGFsbG93Q3JlZGVudGlhbHMgPSBPYmplY3Qua2V5cyhldmFsQnlDcmVkZW50aWFsKS5tYXAoKGNyZWRJZCkgPT4ge1xuICAgIGNvbnN0IG5vZGVCdWYgPSBCdWZmZXIuZnJvbShjcmVkSWQucmVwbGFjZSgvLS9nLCAnKycpLnJlcGxhY2UoL18vZywgJy8nKSwgJ2Jhc2U2NCcpO1xuICAgIGNvbnN0IGlkID0gbm9kZUJ1Zi5idWZmZXIuc2xpY2Uobm9kZUJ1Zi5ieXRlT2Zmc2V0LCBub2RlQnVmLmJ5dGVPZmZzZXQgKyBub2RlQnVmLmJ5dGVMZW5ndGgpO1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiAncHVibGljLWtleScgYXMgY29uc3QsXG4gICAgICBpZCxcbiAgICB9O1xuICB9KTtcblxuICBjb25zdCBwdWJsaWNLZXk6IFB1YmxpY0tleUNyZWRlbnRpYWxSZXF1ZXN0T3B0aW9ucyA9IHtcbiAgICBjaGFsbGVuZ2U6IG5ldyBVaW50OEFycmF5KEJ1ZmZlci5mcm9tKGNoYWxsZW5nZSwgJ2Jhc2U2NCcpKSxcbiAgICBhbGxvd0NyZWRlbnRpYWxzLFxuICB9O1xuXG4gIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHByb3ZpZGVyLmdldCh7XG4gICAgcHVibGljS2V5LFxuICAgIGV2YWxCeUNyZWRlbnRpYWwsXG4gIH0pO1xuXG4gIG1hdGNoRGV2aWNlQnlDcmVkZW50aWFsSWQoZGV2aWNlcywgcmVzdWx0LmNyZWRlbnRpYWxJZCk7XG5cbiAgaWYgKCFyZXN1bHQucHJmUmVzdWx0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdQUkYgb3V0cHV0IHdhcyBub3QgcmV0dXJuZWQgYnkgdGhlIGF1dGhlbnRpY2F0b3InKTtcbiAgfVxuXG4gIHJldHVybiBkZXJpdmVQYXNzd29yZChyZXN1bHQucHJmUmVzdWx0KTtcbn1cbiJdfQ==
@@ -1,5 +1,10 @@
1
- export { derivePassword } from './derivePassword';
2
- export { deriveEnterpriseSalt } from './deriveEnterpriseSalt';
1
+ export { derivePassword } from '@bitgo-beta/sdk-core';
2
+ export { registerPasskey } from './registerPasskey';
3
+ export { deriveEnterpriseSalt } from '@bitgo-beta/sdk-core';
3
4
  export { buildEvalByCredential, matchDeviceByCredentialId } from './prfHelpers';
4
- export type { WebAuthnOtpDevice, PasskeyAuthResult, PasskeyGetOptions, WebAuthnProvider } from './webAuthnTypes';
5
+ export { removePasskeyFromAccount } from './removePasskeyFromAccount';
6
+ export type { WebAuthnOtpDevice, PasskeyAuthResult, PasskeyGetOptions, WebAuthnProvider } from '@bitgo-beta/sdk-core';
7
+ export { removePasskeyFromWallet } from './removePasskeyFromWallet';
8
+ export { attachPasskeyToWallet } from './attachPasskeyToWallet';
9
+ export { derivePasskeyPrfKey } from './derivePasskeyPrfKey';
5
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAChF,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAChF,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACtH,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC"}
package/dist/src/index.js CHANGED
@@ -1,11 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.matchDeviceByCredentialId = exports.buildEvalByCredential = exports.deriveEnterpriseSalt = exports.derivePassword = void 0;
4
- var derivePassword_1 = require("./derivePassword");
5
- Object.defineProperty(exports, "derivePassword", { enumerable: true, get: function () { return derivePassword_1.derivePassword; } });
6
- var deriveEnterpriseSalt_1 = require("./deriveEnterpriseSalt");
7
- Object.defineProperty(exports, "deriveEnterpriseSalt", { enumerable: true, get: function () { return deriveEnterpriseSalt_1.deriveEnterpriseSalt; } });
3
+ exports.derivePasskeyPrfKey = exports.attachPasskeyToWallet = exports.removePasskeyFromWallet = exports.removePasskeyFromAccount = exports.matchDeviceByCredentialId = exports.buildEvalByCredential = exports.deriveEnterpriseSalt = exports.registerPasskey = exports.derivePassword = void 0;
4
+ var sdk_core_1 = require("@bitgo-beta/sdk-core");
5
+ Object.defineProperty(exports, "derivePassword", { enumerable: true, get: function () { return sdk_core_1.derivePassword; } });
6
+ var registerPasskey_1 = require("./registerPasskey");
7
+ Object.defineProperty(exports, "registerPasskey", { enumerable: true, get: function () { return registerPasskey_1.registerPasskey; } });
8
+ var sdk_core_2 = require("@bitgo-beta/sdk-core");
9
+ Object.defineProperty(exports, "deriveEnterpriseSalt", { enumerable: true, get: function () { return sdk_core_2.deriveEnterpriseSalt; } });
8
10
  var prfHelpers_1 = require("./prfHelpers");
9
11
  Object.defineProperty(exports, "buildEvalByCredential", { enumerable: true, get: function () { return prfHelpers_1.buildEvalByCredential; } });
10
12
  Object.defineProperty(exports, "matchDeviceByCredentialId", { enumerable: true, get: function () { return prfHelpers_1.matchDeviceByCredentialId; } });
11
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbURBQWtEO0FBQXpDLGdIQUFBLGNBQWMsT0FBQTtBQUN2QiwrREFBOEQ7QUFBckQsNEhBQUEsb0JBQW9CLE9BQUE7QUFDN0IsMkNBQWdGO0FBQXZFLG1IQUFBLHFCQUFxQixPQUFBO0FBQUUsdUhBQUEseUJBQXlCLE9BQUEiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgeyBkZXJpdmVQYXNzd29yZCB9IGZyb20gJy4vZGVyaXZlUGFzc3dvcmQnO1xuZXhwb3J0IHsgZGVyaXZlRW50ZXJwcmlzZVNhbHQgfSBmcm9tICcuL2Rlcml2ZUVudGVycHJpc2VTYWx0JztcbmV4cG9ydCB7IGJ1aWxkRXZhbEJ5Q3JlZGVudGlhbCwgbWF0Y2hEZXZpY2VCeUNyZWRlbnRpYWxJZCB9IGZyb20gJy4vcHJmSGVscGVycyc7XG5leHBvcnQgdHlwZSB7IFdlYkF1dGhuT3RwRGV2aWNlLCBQYXNza2V5QXV0aFJlc3VsdCwgUGFzc2tleUdldE9wdGlvbnMsIFdlYkF1dGhuUHJvdmlkZXIgfSBmcm9tICcuL3dlYkF1dGhuVHlwZXMnO1xuIl19
13
+ var removePasskeyFromAccount_1 = require("./removePasskeyFromAccount");
14
+ Object.defineProperty(exports, "removePasskeyFromAccount", { enumerable: true, get: function () { return removePasskeyFromAccount_1.removePasskeyFromAccount; } });
15
+ var removePasskeyFromWallet_1 = require("./removePasskeyFromWallet");
16
+ Object.defineProperty(exports, "removePasskeyFromWallet", { enumerable: true, get: function () { return removePasskeyFromWallet_1.removePasskeyFromWallet; } });
17
+ var attachPasskeyToWallet_1 = require("./attachPasskeyToWallet");
18
+ Object.defineProperty(exports, "attachPasskeyToWallet", { enumerable: true, get: function () { return attachPasskeyToWallet_1.attachPasskeyToWallet; } });
19
+ var derivePasskeyPrfKey_1 = require("./derivePasskeyPrfKey");
20
+ Object.defineProperty(exports, "derivePasskeyPrfKey", { enumerable: true, get: function () { return derivePasskeyPrfKey_1.derivePasskeyPrfKey; } });
21
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsaURBQXNEO0FBQTdDLDBHQUFBLGNBQWMsT0FBQTtBQUN2QixxREFBb0Q7QUFBM0Msa0hBQUEsZUFBZSxPQUFBO0FBQ3hCLGlEQUE0RDtBQUFuRCxnSEFBQSxvQkFBb0IsT0FBQTtBQUM3QiwyQ0FBZ0Y7QUFBdkUsbUhBQUEscUJBQXFCLE9BQUE7QUFBRSx1SEFBQSx5QkFBeUIsT0FBQTtBQUN6RCx1RUFBc0U7QUFBN0Qsb0lBQUEsd0JBQXdCLE9BQUE7QUFFakMscUVBQW9FO0FBQTNELGtJQUFBLHVCQUF1QixPQUFBO0FBQ2hDLGlFQUFnRTtBQUF2RCw4SEFBQSxxQkFBcUIsT0FBQTtBQUM5Qiw2REFBNEQ7QUFBbkQsMEhBQUEsbUJBQW1CLE9BQUEiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgeyBkZXJpdmVQYXNzd29yZCB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcbmV4cG9ydCB7IHJlZ2lzdGVyUGFzc2tleSB9IGZyb20gJy4vcmVnaXN0ZXJQYXNza2V5JztcbmV4cG9ydCB7IGRlcml2ZUVudGVycHJpc2VTYWx0IH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuZXhwb3J0IHsgYnVpbGRFdmFsQnlDcmVkZW50aWFsLCBtYXRjaERldmljZUJ5Q3JlZGVudGlhbElkIH0gZnJvbSAnLi9wcmZIZWxwZXJzJztcbmV4cG9ydCB7IHJlbW92ZVBhc3NrZXlGcm9tQWNjb3VudCB9IGZyb20gJy4vcmVtb3ZlUGFzc2tleUZyb21BY2NvdW50JztcbmV4cG9ydCB0eXBlIHsgV2ViQXV0aG5PdHBEZXZpY2UsIFBhc3NrZXlBdXRoUmVzdWx0LCBQYXNza2V5R2V0T3B0aW9ucywgV2ViQXV0aG5Qcm92aWRlciB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcbmV4cG9ydCB7IHJlbW92ZVBhc3NrZXlGcm9tV2FsbGV0IH0gZnJvbSAnLi9yZW1vdmVQYXNza2V5RnJvbVdhbGxldCc7XG5leHBvcnQgeyBhdHRhY2hQYXNza2V5VG9XYWxsZXQgfSBmcm9tICcuL2F0dGFjaFBhc3NrZXlUb1dhbGxldCc7XG5leHBvcnQgeyBkZXJpdmVQYXNza2V5UHJmS2V5IH0gZnJvbSAnLi9kZXJpdmVQYXNza2V5UHJmS2V5JztcbiJdfQ==
@@ -1 +1 @@
1
- {"version":3,"file":"prfHelpers.d.ts","sourceRoot":"","sources":["../../src/prfHelpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG;IAChE,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CAC7C,CAYA;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,cAAc,EAAE,EAAE,YAAY,EAAE,MAAM,GAAG,cAAc,CAMzG"}
1
+ {"version":3,"file":"prfHelpers.d.ts","sourceRoot":"","sources":["../../src/prfHelpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAG1D;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG;IAChE,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CAC7C,CA0BA;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,cAAc,EAAE,EAAE,YAAY,EAAE,MAAM,GAAG,cAAc,CAQzG"}
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.buildEvalByCredential = buildEvalByCredential;
4
4
  exports.matchDeviceByCredentialId = matchDeviceByCredentialId;
5
+ const sdk_core_1 = require("@bitgo-beta/sdk-core");
5
6
  /**
6
7
  * Builds the PRF eval map and credential-to-device lookup from a wallet
7
8
  * keychain's webauthn devices. Devices without a prfSalt are skipped.
@@ -13,8 +14,20 @@ function buildEvalByCredential(devices) {
13
14
  if (!device.prfSalt)
14
15
  continue;
15
16
  const { credID } = device.authenticatorInfo;
16
- evalByCredential[credID] = device.prfSalt;
17
- credIdToDevice.set(credID, device);
17
+ // Normalise credID to base64url (no padding, URL-safe chars) so it matches
18
+ // the key format used by attachPasskeyToWallet (device.credentialId from the
19
+ // browser, which is already base64url). The WebAuthn PRF extension looks up
20
+ // the selected credential's ID against evalByCredential keys — if the encoding
21
+ // differs (e.g. standard base64 with padding/+/), the lookup silently fails and
22
+ // PRF evaluates with no salt, producing a different output.
23
+ const credIdBase64url = (0, sdk_core_1.toBase64Url)(credID);
24
+ // Pass prfSalt through as-is (base64url). attachPasskeyToWallet writes the
25
+ // server-stored salt in the same encoding and feeds the same string to
26
+ // the PRF extension at attach time, so both paths produce the same salt
27
+ // bytes — provided the WebAuthn provider layer decodes base64url before
28
+ // handing the bytes to navigator.credentials.get.
29
+ evalByCredential[credIdBase64url] = device.prfSalt;
30
+ credIdToDevice.set(credIdBase64url, device);
18
31
  }
19
32
  return { evalByCredential, credIdToDevice };
20
33
  }
@@ -23,10 +36,12 @@ function buildEvalByCredential(devices) {
23
36
  * @throws if no matching device is found
24
37
  */
25
38
  function matchDeviceByCredentialId(devices, credentialId) {
26
- const device = devices.find((d) => d.authenticatorInfo.credID === credentialId);
39
+ // Normalise both sides to base64url so padding/char differences don't break matching.
40
+ const needle = (0, sdk_core_1.toBase64Url)(credentialId);
41
+ const device = devices.find((d) => (0, sdk_core_1.toBase64Url)(d.authenticatorInfo.credID) === needle);
27
42
  if (!device) {
28
43
  throw new Error('Could not identify which passkey device was used');
29
44
  }
30
45
  return device;
31
46
  }
32
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJmSGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wcmZIZWxwZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBTUEsc0RBZUM7QUFNRCw4REFNQztBQS9CRDs7O0dBR0c7QUFDSCxTQUFnQixxQkFBcUIsQ0FBQyxPQUF5QjtJQUk3RCxNQUFNLGdCQUFnQixHQUEyQixFQUFFLENBQUM7SUFDcEQsTUFBTSxjQUFjLEdBQUcsSUFBSSxHQUFHLEVBQTBCLENBQUM7SUFFekQsS0FBSyxNQUFNLE1BQU0sSUFBSSxPQUFPLEVBQUUsQ0FBQztRQUM3QixJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU87WUFBRSxTQUFTO1FBQzlCLE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxNQUFNLENBQUMsaUJBQWlCLENBQUM7UUFDNUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQztRQUMxQyxjQUFjLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRUQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLGNBQWMsRUFBRSxDQUFDO0FBQzlDLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFnQix5QkFBeUIsQ0FBQyxPQUF5QixFQUFFLFlBQW9CO0lBQ3ZGLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLEtBQUssWUFBWSxDQUFDLENBQUM7SUFDaEYsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ1osTUFBTSxJQUFJLEtBQUssQ0FBQyxrREFBa0QsQ0FBQyxDQUFDO0lBQ3RFLENBQUM7SUFDRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBXZWJhdXRobkRldmljZSB9IGZyb20gJ0BiaXRnby9wdWJsaWMtdHlwZXMnO1xuXG4vKipcbiAqIEJ1aWxkcyB0aGUgUFJGIGV2YWwgbWFwIGFuZCBjcmVkZW50aWFsLXRvLWRldmljZSBsb29rdXAgZnJvbSBhIHdhbGxldFxuICoga2V5Y2hhaW4ncyB3ZWJhdXRobiBkZXZpY2VzLiBEZXZpY2VzIHdpdGhvdXQgYSBwcmZTYWx0IGFyZSBza2lwcGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRFdmFsQnlDcmVkZW50aWFsKGRldmljZXM6IFdlYmF1dGhuRGV2aWNlW10pOiB7XG4gIGV2YWxCeUNyZWRlbnRpYWw6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIGNyZWRJZFRvRGV2aWNlOiBNYXA8c3RyaW5nLCBXZWJhdXRobkRldmljZT47XG59IHtcbiAgY29uc3QgZXZhbEJ5Q3JlZGVudGlhbDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBjb25zdCBjcmVkSWRUb0RldmljZSA9IG5ldyBNYXA8c3RyaW5nLCBXZWJhdXRobkRldmljZT4oKTtcblxuICBmb3IgKGNvbnN0IGRldmljZSBvZiBkZXZpY2VzKSB7XG4gICAgaWYgKCFkZXZpY2UucHJmU2FsdCkgY29udGludWU7XG4gICAgY29uc3QgeyBjcmVkSUQgfSA9IGRldmljZS5hdXRoZW50aWNhdG9ySW5mbztcbiAgICBldmFsQnlDcmVkZW50aWFsW2NyZWRJRF0gPSBkZXZpY2UucHJmU2FsdDtcbiAgICBjcmVkSWRUb0RldmljZS5zZXQoY3JlZElELCBkZXZpY2UpO1xuICB9XG5cbiAgcmV0dXJuIHsgZXZhbEJ5Q3JlZGVudGlhbCwgY3JlZElkVG9EZXZpY2UgfTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBXZWJhdXRobkRldmljZSBtYXRjaGluZyB0aGUgZ2l2ZW4gY3JlZGVudGlhbCBJRC5cbiAqIEB0aHJvd3MgaWYgbm8gbWF0Y2hpbmcgZGV2aWNlIGlzIGZvdW5kXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXRjaERldmljZUJ5Q3JlZGVudGlhbElkKGRldmljZXM6IFdlYmF1dGhuRGV2aWNlW10sIGNyZWRlbnRpYWxJZDogc3RyaW5nKTogV2ViYXV0aG5EZXZpY2Uge1xuICBjb25zdCBkZXZpY2UgPSBkZXZpY2VzLmZpbmQoKGQpID0+IGQuYXV0aGVudGljYXRvckluZm8uY3JlZElEID09PSBjcmVkZW50aWFsSWQpO1xuICBpZiAoIWRldmljZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ291bGQgbm90IGlkZW50aWZ5IHdoaWNoIHBhc3NrZXkgZGV2aWNlIHdhcyB1c2VkJyk7XG4gIH1cbiAgcmV0dXJuIGRldmljZTtcbn1cbiJdfQ==
47
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJmSGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wcmZIZWxwZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBT0Esc0RBNkJDO0FBTUQsOERBUUM7QUFqREQsbURBQW1EO0FBRW5EOzs7R0FHRztBQUNILFNBQWdCLHFCQUFxQixDQUFDLE9BQXlCO0lBSTdELE1BQU0sZ0JBQWdCLEdBQTJCLEVBQUUsQ0FBQztJQUNwRCxNQUFNLGNBQWMsR0FBRyxJQUFJLEdBQUcsRUFBMEIsQ0FBQztJQUV6RCxLQUFLLE1BQU0sTUFBTSxJQUFJLE9BQU8sRUFBRSxDQUFDO1FBQzdCLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTztZQUFFLFNBQVM7UUFDOUIsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQztRQUU1QywyRUFBMkU7UUFDM0UsNkVBQTZFO1FBQzdFLDRFQUE0RTtRQUM1RSwrRUFBK0U7UUFDL0UsZ0ZBQWdGO1FBQ2hGLDREQUE0RDtRQUM1RCxNQUFNLGVBQWUsR0FBRyxJQUFBLHNCQUFXLEVBQUMsTUFBTSxDQUFDLENBQUM7UUFFNUMsMkVBQTJFO1FBQzNFLHVFQUF1RTtRQUN2RSx3RUFBd0U7UUFDeEUsd0VBQXdFO1FBQ3hFLGtEQUFrRDtRQUNsRCxnQkFBZ0IsQ0FBQyxlQUFlLENBQUMsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDO1FBQ25ELGNBQWMsQ0FBQyxHQUFHLENBQUMsZUFBZSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQzlDLENBQUM7SUFFRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsY0FBYyxFQUFFLENBQUM7QUFDOUMsQ0FBQztBQUVEOzs7R0FHRztBQUNILFNBQWdCLHlCQUF5QixDQUFDLE9BQXlCLEVBQUUsWUFBb0I7SUFDdkYsc0ZBQXNGO0lBQ3RGLE1BQU0sTUFBTSxHQUFHLElBQUEsc0JBQVcsRUFBQyxZQUFZLENBQUMsQ0FBQztJQUN6QyxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFBLHNCQUFXLEVBQUMsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxLQUFLLE1BQU0sQ0FBQyxDQUFDO0lBQ3ZGLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNaLE1BQU0sSUFBSSxLQUFLLENBQUMsa0RBQWtELENBQUMsQ0FBQztJQUN0RSxDQUFDO0lBQ0QsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgV2ViYXV0aG5EZXZpY2UgfSBmcm9tICdAYml0Z28vcHVibGljLXR5cGVzJztcbmltcG9ydCB7IHRvQmFzZTY0VXJsIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuXG4vKipcbiAqIEJ1aWxkcyB0aGUgUFJGIGV2YWwgbWFwIGFuZCBjcmVkZW50aWFsLXRvLWRldmljZSBsb29rdXAgZnJvbSBhIHdhbGxldFxuICoga2V5Y2hhaW4ncyB3ZWJhdXRobiBkZXZpY2VzLiBEZXZpY2VzIHdpdGhvdXQgYSBwcmZTYWx0IGFyZSBza2lwcGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRFdmFsQnlDcmVkZW50aWFsKGRldmljZXM6IFdlYmF1dGhuRGV2aWNlW10pOiB7XG4gIGV2YWxCeUNyZWRlbnRpYWw6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIGNyZWRJZFRvRGV2aWNlOiBNYXA8c3RyaW5nLCBXZWJhdXRobkRldmljZT47XG59IHtcbiAgY29uc3QgZXZhbEJ5Q3JlZGVudGlhbDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBjb25zdCBjcmVkSWRUb0RldmljZSA9IG5ldyBNYXA8c3RyaW5nLCBXZWJhdXRobkRldmljZT4oKTtcblxuICBmb3IgKGNvbnN0IGRldmljZSBvZiBkZXZpY2VzKSB7XG4gICAgaWYgKCFkZXZpY2UucHJmU2FsdCkgY29udGludWU7XG4gICAgY29uc3QgeyBjcmVkSUQgfSA9IGRldmljZS5hdXRoZW50aWNhdG9ySW5mbztcblxuICAgIC8vIE5vcm1hbGlzZSBjcmVkSUQgdG8gYmFzZTY0dXJsIChubyBwYWRkaW5nLCBVUkwtc2FmZSBjaGFycykgc28gaXQgbWF0Y2hlc1xuICAgIC8vIHRoZSBrZXkgZm9ybWF0IHVzZWQgYnkgYXR0YWNoUGFzc2tleVRvV2FsbGV0IChkZXZpY2UuY3JlZGVudGlhbElkIGZyb20gdGhlXG4gICAgLy8gYnJvd3Nlciwgd2hpY2ggaXMgYWxyZWFkeSBiYXNlNjR1cmwpLiBUaGUgV2ViQXV0aG4gUFJGIGV4dGVuc2lvbiBsb29rcyB1cFxuICAgIC8vIHRoZSBzZWxlY3RlZCBjcmVkZW50aWFsJ3MgSUQgYWdhaW5zdCBldmFsQnlDcmVkZW50aWFsIGtleXMg4oCUIGlmIHRoZSBlbmNvZGluZ1xuICAgIC8vIGRpZmZlcnMgKGUuZy4gc3RhbmRhcmQgYmFzZTY0IHdpdGggcGFkZGluZy8rLyksIHRoZSBsb29rdXAgc2lsZW50bHkgZmFpbHMgYW5kXG4gICAgLy8gUFJGIGV2YWx1YXRlcyB3aXRoIG5vIHNhbHQsIHByb2R1Y2luZyBhIGRpZmZlcmVudCBvdXRwdXQuXG4gICAgY29uc3QgY3JlZElkQmFzZTY0dXJsID0gdG9CYXNlNjRVcmwoY3JlZElEKTtcblxuICAgIC8vIFBhc3MgcHJmU2FsdCB0aHJvdWdoIGFzLWlzIChiYXNlNjR1cmwpLiBhdHRhY2hQYXNza2V5VG9XYWxsZXQgd3JpdGVzIHRoZVxuICAgIC8vIHNlcnZlci1zdG9yZWQgc2FsdCBpbiB0aGUgc2FtZSBlbmNvZGluZyBhbmQgZmVlZHMgdGhlIHNhbWUgc3RyaW5nIHRvXG4gICAgLy8gdGhlIFBSRiBleHRlbnNpb24gYXQgYXR0YWNoIHRpbWUsIHNvIGJvdGggcGF0aHMgcHJvZHVjZSB0aGUgc2FtZSBzYWx0XG4gICAgLy8gYnl0ZXMg4oCUIHByb3ZpZGVkIHRoZSBXZWJBdXRobiBwcm92aWRlciBsYXllciBkZWNvZGVzIGJhc2U2NHVybCBiZWZvcmVcbiAgICAvLyBoYW5kaW5nIHRoZSBieXRlcyB0byBuYXZpZ2F0b3IuY3JlZGVudGlhbHMuZ2V0LlxuICAgIGV2YWxCeUNyZWRlbnRpYWxbY3JlZElkQmFzZTY0dXJsXSA9IGRldmljZS5wcmZTYWx0O1xuICAgIGNyZWRJZFRvRGV2aWNlLnNldChjcmVkSWRCYXNlNjR1cmwsIGRldmljZSk7XG4gIH1cblxuICByZXR1cm4geyBldmFsQnlDcmVkZW50aWFsLCBjcmVkSWRUb0RldmljZSB9O1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIFdlYmF1dGhuRGV2aWNlIG1hdGNoaW5nIHRoZSBnaXZlbiBjcmVkZW50aWFsIElELlxuICogQHRocm93cyBpZiBubyBtYXRjaGluZyBkZXZpY2UgaXMgZm91bmRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hdGNoRGV2aWNlQnlDcmVkZW50aWFsSWQoZGV2aWNlczogV2ViYXV0aG5EZXZpY2VbXSwgY3JlZGVudGlhbElkOiBzdHJpbmcpOiBXZWJhdXRobkRldmljZSB7XG4gIC8vIE5vcm1hbGlzZSBib3RoIHNpZGVzIHRvIGJhc2U2NHVybCBzbyBwYWRkaW5nL2NoYXIgZGlmZmVyZW5jZXMgZG9uJ3QgYnJlYWsgbWF0Y2hpbmcuXG4gIGNvbnN0IG5lZWRsZSA9IHRvQmFzZTY0VXJsKGNyZWRlbnRpYWxJZCk7XG4gIGNvbnN0IGRldmljZSA9IGRldmljZXMuZmluZCgoZCkgPT4gdG9CYXNlNjRVcmwoZC5hdXRoZW50aWNhdG9ySW5mby5jcmVkSUQpID09PSBuZWVkbGUpO1xuICBpZiAoIWRldmljZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ291bGQgbm90IGlkZW50aWZ5IHdoaWNoIHBhc3NrZXkgZGV2aWNlIHdhcyB1c2VkJyk7XG4gIH1cbiAgcmV0dXJuIGRldmljZTtcbn1cbiJdfQ==
@@ -0,0 +1,9 @@
1
+ import { BitGoBase, type WebAuthnOtpDevice, type WebAuthnProvider } from '@bitgo-beta/sdk-core';
2
+ export declare function registerPasskey(params: {
3
+ bitgo: BitGoBase;
4
+ provider: WebAuthnProvider;
5
+ label: string;
6
+ }): Promise<WebAuthnOtpDevice & {
7
+ prfSupported: boolean;
8
+ }>;
9
+ //# sourceMappingURL=registerPasskey.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registerPasskey.d.ts","sourceRoot":"","sources":["../../src/registerPasskey.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAqB,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAoEnH,wBAAsB,eAAe,CAAC,MAAM,EAAE;IAC5C,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,OAAO,CAAC,iBAAiB,GAAG;IAAE,YAAY,EAAE,OAAO,CAAA;CAAE,CAAC,CA8DzD"}
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerPasskey = registerPasskey;
4
+ const sdk_core_1 = require("@bitgo-beta/sdk-core");
5
+ /**
6
+ * Recursively converts a PublicKeyCredential (or any value it contains) to a
7
+ * JSON-serialisable representation, encoding ArrayBuffers as base64url strings.
8
+ */
9
+ function publicKeyCredentialToJSON(value) {
10
+ if (Array.isArray(value)) {
11
+ return value.map(publicKeyCredentialToJSON);
12
+ }
13
+ if (value instanceof ArrayBuffer) {
14
+ return (0, sdk_core_1.bufferToBase64Url)(value);
15
+ }
16
+ if (ArrayBuffer.isView(value)) {
17
+ return (0, sdk_core_1.bufferToBase64Url)(value.buffer);
18
+ }
19
+ if (value instanceof Object) {
20
+ const result = {};
21
+ // Use for...in to enumerate DOM object properties (non-enumerable own + inherited)
22
+ for (const key in value) {
23
+ result[key] = publicKeyCredentialToJSON(value[key]);
24
+ }
25
+ return result;
26
+ }
27
+ return value;
28
+ }
29
+ /**
30
+ * Decodes excluded credential IDs from base64 strings to ArrayBuffers.
31
+ * The WebAuthn API requires BufferSource values, not base64 strings.
32
+ */
33
+ function preformatExcludedCredentials(excludeCredentials) {
34
+ if (!excludeCredentials)
35
+ return [];
36
+ return excludeCredentials.map((cred) => ({
37
+ ...cred,
38
+ id: Buffer.from(cred.id, 'base64'),
39
+ }));
40
+ }
41
+ async function registerPasskey(params) {
42
+ const { bitgo, provider, label } = params;
43
+ // Step 1: Fetch server challenge (contains baseSalt)
44
+ const challenge = (await bitgo
45
+ .get(bitgo.url('/user/otp/webauthn/register', 2))
46
+ .result());
47
+ // Step 2: Pass formatted challenge to provider.create() — browser returns attestation
48
+ const attestation = await provider.create({
49
+ challenge: Buffer.from(challenge.challenge, 'base64'),
50
+ rp: challenge.rp,
51
+ user: challenge.user,
52
+ pubKeyCredParams: challenge.pubKeyCredParams,
53
+ timeout: challenge.timeout,
54
+ excludeCredentials: preformatExcludedCredentials(challenge.excludeCredentials),
55
+ authenticatorSelection: challenge.authenticatorSelection,
56
+ attestation: challenge.attestation,
57
+ extensions: challenge.extensions,
58
+ });
59
+ // Step 3: Check if PRF is supported — `prf.enabled` is set during registration
60
+ // (not `prf.results.first`, which is only present during authentication assertions)
61
+ const clientExtensionResults = attestation.getClientExtensionResults();
62
+ const prfEnabled = clientExtensionResults.prf;
63
+ const prfSupported = typeof prfEnabled === 'object' && prfEnabled !== null && prfEnabled.enabled === true;
64
+ // Step 4: Serialize the full credential using recursive base64url encoding
65
+ const otp = JSON.stringify(publicKeyCredentialToJSON(attestation));
66
+ const putBody = {
67
+ otp,
68
+ type: 'webauthn',
69
+ label,
70
+ };
71
+ if (prfSupported) {
72
+ putBody.extensions = ['prf'];
73
+ putBody.scopes = ['wallet_hot'];
74
+ }
75
+ // Step 5: PUT /api/v2/user/otp
76
+ const response = (await bitgo.put(bitgo.url('/user/otp', 2)).send(putBody).result());
77
+ // Step 6: Find the newly registered device by matching credentialId
78
+ const device = response.user.otpDevices.find((d) => d.credentialId === attestation.id);
79
+ if (!device) {
80
+ const available = response.user.otpDevices.map((d) => d.credentialId).join(', ');
81
+ throw new Error(`Registered device not found in response (credentialId: ${attestation.id}). Available: [${available}]`);
82
+ }
83
+ // Step 7: Return WebAuthnOtpDevice + prfSupported
84
+ return {
85
+ id: device.id,
86
+ credentialId: device.credentialId,
87
+ prfSalt: device.prfSalt,
88
+ isPasskey: device.isPasskey,
89
+ extensions: device.extensions,
90
+ prfSupported,
91
+ };
92
+ }
93
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaXN0ZXJQYXNza2V5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3JlZ2lzdGVyUGFzc2tleS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQW9FQSwwQ0FrRUM7QUF0SUQsbURBQW1IO0FBNkJuSDs7O0dBR0c7QUFDSCxTQUFTLHlCQUF5QixDQUFDLEtBQWM7SUFDL0MsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDekIsT0FBTyxLQUFLLENBQUMsR0FBRyxDQUFDLHlCQUF5QixDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUNELElBQUksS0FBSyxZQUFZLFdBQVcsRUFBRSxDQUFDO1FBQ2pDLE9BQU8sSUFBQSw0QkFBaUIsRUFBQyxLQUFLLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBQ0QsSUFBSSxXQUFXLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDOUIsT0FBTyxJQUFBLDRCQUFpQixFQUFDLEtBQUssQ0FBQyxNQUFxQixDQUFDLENBQUM7SUFDeEQsQ0FBQztJQUNELElBQUksS0FBSyxZQUFZLE1BQU0sRUFBRSxDQUFDO1FBQzVCLE1BQU0sTUFBTSxHQUE0QixFQUFFLENBQUM7UUFDM0MsbUZBQW1GO1FBQ25GLEtBQUssTUFBTSxHQUFHLElBQUksS0FBSyxFQUFFLENBQUM7WUFDeEIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLHlCQUF5QixDQUFFLEtBQWlDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNuRixDQUFDO1FBQ0QsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQztBQUVEOzs7R0FHRztBQUNILFNBQVMsNEJBQTRCLENBQ25DLGtCQUErRDtJQUUvRCxJQUFJLENBQUMsa0JBQWtCO1FBQUUsT0FBTyxFQUFFLENBQUM7SUFDbkMsT0FBTyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDdkMsR0FBRyxJQUFJO1FBQ1AsRUFBRSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQXVCLEVBQUUsUUFBUSxDQUEyQjtLQUNsRixDQUFDLENBQUMsQ0FBQztBQUNOLENBQUM7QUFFTSxLQUFLLFVBQVUsZUFBZSxDQUFDLE1BSXJDO0lBQ0MsTUFBTSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLEdBQUcsTUFBTSxDQUFDO0lBRTFDLHFEQUFxRDtJQUNyRCxNQUFNLFNBQVMsR0FBRyxDQUFDLE1BQU0sS0FBSztTQUMzQixHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyw2QkFBNkIsRUFBRSxDQUFDLENBQUMsQ0FBQztTQUNoRCxNQUFNLEVBQUUsQ0FBOEIsQ0FBQztJQUUxQyxzRkFBc0Y7SUFDdEYsTUFBTSxXQUFXLEdBQUcsTUFBTSxRQUFRLENBQUMsTUFBTSxDQUFDO1FBQ3hDLFNBQVMsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDO1FBQ3JELEVBQUUsRUFBRSxTQUFTLENBQUMsRUFBRTtRQUNoQixJQUFJLEVBQUUsU0FBUyxDQUFDLElBQUk7UUFDcEIsZ0JBQWdCLEVBQUUsU0FBUyxDQUFDLGdCQUFnQjtRQUM1QyxPQUFPLEVBQUUsU0FBUyxDQUFDLE9BQU87UUFDMUIsa0JBQWtCLEVBQUUsNEJBQTRCLENBQUMsU0FBUyxDQUFDLGtCQUFrQixDQUFDO1FBQzlFLHNCQUFzQixFQUFFLFNBQVMsQ0FBQyxzQkFBc0I7UUFDeEQsV0FBVyxFQUFFLFNBQVMsQ0FBQyxXQUFXO1FBQ2xDLFVBQVUsRUFBRSxTQUFTLENBQUMsVUFBVTtLQUNqQyxDQUFDLENBQUM7SUFFSCwrRUFBK0U7SUFDL0Usb0ZBQW9GO0lBQ3BGLE1BQU0sc0JBQXNCLEdBQTBDLFdBQVcsQ0FBQyx5QkFBeUIsRUFBRSxDQUFDO0lBQzlHLE1BQU0sVUFBVSxHQUFHLHNCQUFzQixDQUFDLEdBQUcsQ0FBQztJQUM5QyxNQUFNLFlBQVksR0FBRyxPQUFPLFVBQVUsS0FBSyxRQUFRLElBQUksVUFBVSxLQUFLLElBQUksSUFBSSxVQUFVLENBQUMsT0FBTyxLQUFLLElBQUksQ0FBQztJQUUxRywyRUFBMkU7SUFDM0UsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyx5QkFBeUIsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO0lBRW5FLE1BQU0sT0FBTyxHQUE0QjtRQUN2QyxHQUFHO1FBQ0gsSUFBSSxFQUFFLFVBQVU7UUFDaEIsS0FBSztLQUNOLENBQUM7SUFFRixJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ2pCLE9BQU8sQ0FBQyxVQUFVLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM3QixPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDbEMsQ0FBQztJQUVELCtCQUErQjtJQUMvQixNQUFNLFFBQVEsR0FBRyxDQUFDLE1BQU0sS0FBSyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBd0IsQ0FBQztJQUU1RyxvRUFBb0U7SUFDcEUsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsWUFBWSxLQUFLLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUN2RixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDWixNQUFNLFNBQVMsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDakYsTUFBTSxJQUFJLEtBQUssQ0FDYiwwREFBMEQsV0FBVyxDQUFDLEVBQUUsa0JBQWtCLFNBQVMsR0FBRyxDQUN2RyxDQUFDO0lBQ0osQ0FBQztJQUVELGtEQUFrRDtJQUNsRCxPQUFPO1FBQ0wsRUFBRSxFQUFFLE1BQU0sQ0FBQyxFQUFFO1FBQ2IsWUFBWSxFQUFFLE1BQU0sQ0FBQyxZQUFZO1FBQ2pDLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTztRQUN2QixTQUFTLEVBQUUsTUFBTSxDQUFDLFNBQVM7UUFDM0IsVUFBVSxFQUFFLE1BQU0sQ0FBQyxVQUFVO1FBQzdCLFlBQVk7S0FDYixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEJpdEdvQmFzZSwgYnVmZmVyVG9CYXNlNjRVcmwsIHR5cGUgV2ViQXV0aG5PdHBEZXZpY2UsIHR5cGUgV2ViQXV0aG5Qcm92aWRlciB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcblxuaW50ZXJmYWNlIFJlZ2lzdGVyQ2hhbGxlbmdlUmVzcG9uc2Uge1xuICBjaGFsbGVuZ2U6IHN0cmluZztcbiAgYmFzZVNhbHQ6IHN0cmluZztcbiAgcnA6IFB1YmxpY0tleUNyZWRlbnRpYWxScEVudGl0eTtcbiAgdXNlcjogUHVibGljS2V5Q3JlZGVudGlhbFVzZXJFbnRpdHk7XG4gIHB1YktleUNyZWRQYXJhbXM6IFB1YmxpY0tleUNyZWRlbnRpYWxQYXJhbWV0ZXJzW107XG4gIHRpbWVvdXQ/OiBudW1iZXI7XG4gIGV4Y2x1ZGVDcmVkZW50aWFscz86IFB1YmxpY0tleUNyZWRlbnRpYWxEZXNjcmlwdG9yW107XG4gIGF1dGhlbnRpY2F0b3JTZWxlY3Rpb24/OiBBdXRoZW50aWNhdG9yU2VsZWN0aW9uQ3JpdGVyaWE7XG4gIGF0dGVzdGF0aW9uPzogQXR0ZXN0YXRpb25Db252ZXlhbmNlUHJlZmVyZW5jZTtcbiAgZXh0ZW5zaW9ucz86IEF1dGhlbnRpY2F0aW9uRXh0ZW5zaW9uc0NsaWVudElucHV0cztcbn1cblxuaW50ZXJmYWNlIE90cERldmljZSB7XG4gIGlkOiBzdHJpbmc7XG4gIGNyZWRlbnRpYWxJZDogc3RyaW5nO1xuICBwcmZTYWx0Pzogc3RyaW5nO1xuICBpc1Bhc3NrZXk/OiBib29sZWFuO1xuICBleHRlbnNpb25zPzogUmVjb3JkPHN0cmluZywgYm9vbGVhbj47XG59XG5cbmludGVyZmFjZSBSZWdpc3Rlck90cFJlc3BvbnNlIHtcbiAgdXNlcjoge1xuICAgIG90cERldmljZXM6IE90cERldmljZVtdO1xuICB9O1xufVxuXG4vKipcbiAqIFJlY3Vyc2l2ZWx5IGNvbnZlcnRzIGEgUHVibGljS2V5Q3JlZGVudGlhbCAob3IgYW55IHZhbHVlIGl0IGNvbnRhaW5zKSB0byBhXG4gKiBKU09OLXNlcmlhbGlzYWJsZSByZXByZXNlbnRhdGlvbiwgZW5jb2RpbmcgQXJyYXlCdWZmZXJzIGFzIGJhc2U2NHVybCBzdHJpbmdzLlxuICovXG5mdW5jdGlvbiBwdWJsaWNLZXlDcmVkZW50aWFsVG9KU09OKHZhbHVlOiB1bmtub3duKTogdW5rbm93biB7XG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgIHJldHVybiB2YWx1ZS5tYXAocHVibGljS2V5Q3JlZGVudGlhbFRvSlNPTik7XG4gIH1cbiAgaWYgKHZhbHVlIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICByZXR1cm4gYnVmZmVyVG9CYXNlNjRVcmwodmFsdWUpO1xuICB9XG4gIGlmIChBcnJheUJ1ZmZlci5pc1ZpZXcodmFsdWUpKSB7XG4gICAgcmV0dXJuIGJ1ZmZlclRvQmFzZTY0VXJsKHZhbHVlLmJ1ZmZlciBhcyBBcnJheUJ1ZmZlcik7XG4gIH1cbiAgaWYgKHZhbHVlIGluc3RhbmNlb2YgT2JqZWN0KSB7XG4gICAgY29uc3QgcmVzdWx0OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9O1xuICAgIC8vIFVzZSBmb3IuLi5pbiB0byBlbnVtZXJhdGUgRE9NIG9iamVjdCBwcm9wZXJ0aWVzIChub24tZW51bWVyYWJsZSBvd24gKyBpbmhlcml0ZWQpXG4gICAgZm9yIChjb25zdCBrZXkgaW4gdmFsdWUpIHtcbiAgICAgIHJlc3VsdFtrZXldID0gcHVibGljS2V5Q3JlZGVudGlhbFRvSlNPTigodmFsdWUgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pW2tleV0pO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIHJldHVybiB2YWx1ZTtcbn1cblxuLyoqXG4gKiBEZWNvZGVzIGV4Y2x1ZGVkIGNyZWRlbnRpYWwgSURzIGZyb20gYmFzZTY0IHN0cmluZ3MgdG8gQXJyYXlCdWZmZXJzLlxuICogVGhlIFdlYkF1dGhuIEFQSSByZXF1aXJlcyBCdWZmZXJTb3VyY2UgdmFsdWVzLCBub3QgYmFzZTY0IHN0cmluZ3MuXG4gKi9cbmZ1bmN0aW9uIHByZWZvcm1hdEV4Y2x1ZGVkQ3JlZGVudGlhbHMoXG4gIGV4Y2x1ZGVDcmVkZW50aWFsczogUHVibGljS2V5Q3JlZGVudGlhbERlc2NyaXB0b3JbXSB8IHVuZGVmaW5lZFxuKTogUHVibGljS2V5Q3JlZGVudGlhbERlc2NyaXB0b3JbXSB7XG4gIGlmICghZXhjbHVkZUNyZWRlbnRpYWxzKSByZXR1cm4gW107XG4gIHJldHVybiBleGNsdWRlQ3JlZGVudGlhbHMubWFwKChjcmVkKSA9PiAoe1xuICAgIC4uLmNyZWQsXG4gICAgaWQ6IEJ1ZmZlci5mcm9tKGNyZWQuaWQgYXMgdW5rbm93biBhcyBzdHJpbmcsICdiYXNlNjQnKSBhcyB1bmtub3duIGFzIEFycmF5QnVmZmVyLFxuICB9KSk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZWdpc3RlclBhc3NrZXkocGFyYW1zOiB7XG4gIGJpdGdvOiBCaXRHb0Jhc2U7XG4gIHByb3ZpZGVyOiBXZWJBdXRoblByb3ZpZGVyO1xuICBsYWJlbDogc3RyaW5nO1xufSk6IFByb21pc2U8V2ViQXV0aG5PdHBEZXZpY2UgJiB7IHByZlN1cHBvcnRlZDogYm9vbGVhbiB9PiB7XG4gIGNvbnN0IHsgYml0Z28sIHByb3ZpZGVyLCBsYWJlbCB9ID0gcGFyYW1zO1xuXG4gIC8vIFN0ZXAgMTogRmV0Y2ggc2VydmVyIGNoYWxsZW5nZSAoY29udGFpbnMgYmFzZVNhbHQpXG4gIGNvbnN0IGNoYWxsZW5nZSA9IChhd2FpdCBiaXRnb1xuICAgIC5nZXQoYml0Z28udXJsKCcvdXNlci9vdHAvd2ViYXV0aG4vcmVnaXN0ZXInLCAyKSlcbiAgICAucmVzdWx0KCkpIGFzIFJlZ2lzdGVyQ2hhbGxlbmdlUmVzcG9uc2U7XG5cbiAgLy8gU3RlcCAyOiBQYXNzIGZvcm1hdHRlZCBjaGFsbGVuZ2UgdG8gcHJvdmlkZXIuY3JlYXRlKCkg4oCUIGJyb3dzZXIgcmV0dXJucyBhdHRlc3RhdGlvblxuICBjb25zdCBhdHRlc3RhdGlvbiA9IGF3YWl0IHByb3ZpZGVyLmNyZWF0ZSh7XG4gICAgY2hhbGxlbmdlOiBCdWZmZXIuZnJvbShjaGFsbGVuZ2UuY2hhbGxlbmdlLCAnYmFzZTY0JyksXG4gICAgcnA6IGNoYWxsZW5nZS5ycCxcbiAgICB1c2VyOiBjaGFsbGVuZ2UudXNlcixcbiAgICBwdWJLZXlDcmVkUGFyYW1zOiBjaGFsbGVuZ2UucHViS2V5Q3JlZFBhcmFtcyxcbiAgICB0aW1lb3V0OiBjaGFsbGVuZ2UudGltZW91dCxcbiAgICBleGNsdWRlQ3JlZGVudGlhbHM6IHByZWZvcm1hdEV4Y2x1ZGVkQ3JlZGVudGlhbHMoY2hhbGxlbmdlLmV4Y2x1ZGVDcmVkZW50aWFscyksXG4gICAgYXV0aGVudGljYXRvclNlbGVjdGlvbjogY2hhbGxlbmdlLmF1dGhlbnRpY2F0b3JTZWxlY3Rpb24sXG4gICAgYXR0ZXN0YXRpb246IGNoYWxsZW5nZS5hdHRlc3RhdGlvbixcbiAgICBleHRlbnNpb25zOiBjaGFsbGVuZ2UuZXh0ZW5zaW9ucyxcbiAgfSk7XG5cbiAgLy8gU3RlcCAzOiBDaGVjayBpZiBQUkYgaXMgc3VwcG9ydGVkIOKAlCBgcHJmLmVuYWJsZWRgIGlzIHNldCBkdXJpbmcgcmVnaXN0cmF0aW9uXG4gIC8vIChub3QgYHByZi5yZXN1bHRzLmZpcnN0YCwgd2hpY2ggaXMgb25seSBwcmVzZW50IGR1cmluZyBhdXRoZW50aWNhdGlvbiBhc3NlcnRpb25zKVxuICBjb25zdCBjbGllbnRFeHRlbnNpb25SZXN1bHRzOiBBdXRoZW50aWNhdGlvbkV4dGVuc2lvbnNDbGllbnRPdXRwdXRzID0gYXR0ZXN0YXRpb24uZ2V0Q2xpZW50RXh0ZW5zaW9uUmVzdWx0cygpO1xuICBjb25zdCBwcmZFbmFibGVkID0gY2xpZW50RXh0ZW5zaW9uUmVzdWx0cy5wcmY7XG4gIGNvbnN0IHByZlN1cHBvcnRlZCA9IHR5cGVvZiBwcmZFbmFibGVkID09PSAnb2JqZWN0JyAmJiBwcmZFbmFibGVkICE9PSBudWxsICYmIHByZkVuYWJsZWQuZW5hYmxlZCA9PT0gdHJ1ZTtcblxuICAvLyBTdGVwIDQ6IFNlcmlhbGl6ZSB0aGUgZnVsbCBjcmVkZW50aWFsIHVzaW5nIHJlY3Vyc2l2ZSBiYXNlNjR1cmwgZW5jb2RpbmdcbiAgY29uc3Qgb3RwID0gSlNPTi5zdHJpbmdpZnkocHVibGljS2V5Q3JlZGVudGlhbFRvSlNPTihhdHRlc3RhdGlvbikpO1xuXG4gIGNvbnN0IHB1dEJvZHk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge1xuICAgIG90cCxcbiAgICB0eXBlOiAnd2ViYXV0aG4nLFxuICAgIGxhYmVsLFxuICB9O1xuXG4gIGlmIChwcmZTdXBwb3J0ZWQpIHtcbiAgICBwdXRCb2R5LmV4dGVuc2lvbnMgPSBbJ3ByZiddO1xuICAgIHB1dEJvZHkuc2NvcGVzID0gWyd3YWxsZXRfaG90J107XG4gIH1cblxuICAvLyBTdGVwIDU6IFBVVCAvYXBpL3YyL3VzZXIvb3RwXG4gIGNvbnN0IHJlc3BvbnNlID0gKGF3YWl0IGJpdGdvLnB1dChiaXRnby51cmwoJy91c2VyL290cCcsIDIpKS5zZW5kKHB1dEJvZHkpLnJlc3VsdCgpKSBhcyBSZWdpc3Rlck90cFJlc3BvbnNlO1xuXG4gIC8vIFN0ZXAgNjogRmluZCB0aGUgbmV3bHkgcmVnaXN0ZXJlZCBkZXZpY2UgYnkgbWF0Y2hpbmcgY3JlZGVudGlhbElkXG4gIGNvbnN0IGRldmljZSA9IHJlc3BvbnNlLnVzZXIub3RwRGV2aWNlcy5maW5kKChkKSA9PiBkLmNyZWRlbnRpYWxJZCA9PT0gYXR0ZXN0YXRpb24uaWQpO1xuICBpZiAoIWRldmljZSkge1xuICAgIGNvbnN0IGF2YWlsYWJsZSA9IHJlc3BvbnNlLnVzZXIub3RwRGV2aWNlcy5tYXAoKGQpID0+IGQuY3JlZGVudGlhbElkKS5qb2luKCcsICcpO1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBSZWdpc3RlcmVkIGRldmljZSBub3QgZm91bmQgaW4gcmVzcG9uc2UgKGNyZWRlbnRpYWxJZDogJHthdHRlc3RhdGlvbi5pZH0pLiBBdmFpbGFibGU6IFske2F2YWlsYWJsZX1dYFxuICAgICk7XG4gIH1cblxuICAvLyBTdGVwIDc6IFJldHVybiBXZWJBdXRobk90cERldmljZSArIHByZlN1cHBvcnRlZFxuICByZXR1cm4ge1xuICAgIGlkOiBkZXZpY2UuaWQsXG4gICAgY3JlZGVudGlhbElkOiBkZXZpY2UuY3JlZGVudGlhbElkLFxuICAgIHByZlNhbHQ6IGRldmljZS5wcmZTYWx0LFxuICAgIGlzUGFzc2tleTogZGV2aWNlLmlzUGFzc2tleSxcbiAgICBleHRlbnNpb25zOiBkZXZpY2UuZXh0ZW5zaW9ucyxcbiAgICBwcmZTdXBwb3J0ZWQsXG4gIH07XG59XG4iXX0=
@@ -0,0 +1,11 @@
1
+ import { BitGoBase } from '@bitgo-beta/sdk-core';
2
+ import type { WebAuthnOtpDevice } from '@bitgo/public-types';
3
+ /**
4
+ * Permanently removes a passkey credential from the user's account.
5
+ * Call removePasskeyFromWallet() for all affected wallets before calling this.
6
+ */
7
+ export declare function removePasskeyFromAccount(params: {
8
+ bitgo: BitGoBase;
9
+ device: WebAuthnOtpDevice;
10
+ }): Promise<void>;
11
+ //# sourceMappingURL=removePasskeyFromAccount.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"removePasskeyFromAccount.d.ts","sourceRoot":"","sources":["../../src/removePasskeyFromAccount.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D;;;GAGG;AACH,wBAAsB,wBAAwB,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,iBAAiB,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAMrH"}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.removePasskeyFromAccount = removePasskeyFromAccount;
4
+ /**
5
+ * Permanently removes a passkey credential from the user's account.
6
+ * Call removePasskeyFromWallet() for all affected wallets before calling this.
7
+ */
8
+ async function removePasskeyFromAccount(params) {
9
+ const { bitgo, device } = params;
10
+ if (!device.id) {
11
+ throw new Error('device.id is required to remove a passkey from the account');
12
+ }
13
+ await bitgo.del(bitgo.url(`/user/otp/${device.id}`)).result();
14
+ }
15
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVtb3ZlUGFzc2tleUZyb21BY2NvdW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3JlbW92ZVBhc3NrZXlGcm9tQWNjb3VudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQU9BLDREQU1DO0FBVkQ7OztHQUdHO0FBQ0ksS0FBSyxVQUFVLHdCQUF3QixDQUFDLE1BQXVEO0lBQ3BHLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLEdBQUcsTUFBTSxDQUFDO0lBQ2pDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDZixNQUFNLElBQUksS0FBSyxDQUFDLDREQUE0RCxDQUFDLENBQUM7SUFDaEYsQ0FBQztJQUNELE1BQU0sS0FBSyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLGFBQWEsTUFBTSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztBQUNoRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQml0R29CYXNlIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuaW1wb3J0IHR5cGUgeyBXZWJBdXRobk90cERldmljZSB9IGZyb20gJ0BiaXRnby9wdWJsaWMtdHlwZXMnO1xuXG4vKipcbiAqIFBlcm1hbmVudGx5IHJlbW92ZXMgYSBwYXNza2V5IGNyZWRlbnRpYWwgZnJvbSB0aGUgdXNlcidzIGFjY291bnQuXG4gKiBDYWxsIHJlbW92ZVBhc3NrZXlGcm9tV2FsbGV0KCkgZm9yIGFsbCBhZmZlY3RlZCB3YWxsZXRzIGJlZm9yZSBjYWxsaW5nIHRoaXMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZW1vdmVQYXNza2V5RnJvbUFjY291bnQocGFyYW1zOiB7IGJpdGdvOiBCaXRHb0Jhc2U7IGRldmljZTogV2ViQXV0aG5PdHBEZXZpY2UgfSk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCB7IGJpdGdvLCBkZXZpY2UgfSA9IHBhcmFtcztcbiAgaWYgKCFkZXZpY2UuaWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2RldmljZS5pZCBpcyByZXF1aXJlZCB0byByZW1vdmUgYSBwYXNza2V5IGZyb20gdGhlIGFjY291bnQnKTtcbiAgfVxuICBhd2FpdCBiaXRnby5kZWwoYml0Z28udXJsKGAvdXNlci9vdHAvJHtkZXZpY2UuaWR9YCkpLnJlc3VsdCgpO1xufVxuIl19
@@ -0,0 +1,9 @@
1
+ import { BitGoBase, type WebAuthnOtpDevice } from '@bitgo-beta/sdk-core';
2
+ export declare function removePasskeyFromWallet(params: {
3
+ bitgo: BitGoBase;
4
+ coin: string;
5
+ walletId: string;
6
+ device: WebAuthnOtpDevice;
7
+ walletPassphrase: string;
8
+ }): Promise<void>;
9
+ //# sourceMappingURL=removePasskeyFromWallet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"removePasskeyFromWallet.d.ts","sourceRoot":"","sources":["../../src/removePasskeyFromWallet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAA6B,KAAK,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEpG,wBAAsB,uBAAuB,CAAC,MAAM,EAAE;IACpD,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;CAC1B,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBhB"}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.removePasskeyFromWallet = removePasskeyFromWallet;
4
+ const sdk_core_1 = require("@bitgo-beta/sdk-core");
5
+ async function removePasskeyFromWallet(params) {
6
+ const { bitgo, coin: coinName, walletId, device, walletPassphrase } = params;
7
+ if (!device.id) {
8
+ throw new Error('device.id is required to remove a passkey from the wallet');
9
+ }
10
+ const baseCoin = bitgo.coin(coinName);
11
+ const wallet = await baseCoin.wallets().get({ id: walletId });
12
+ const keychainId = wallet.keyIds()[0];
13
+ const keychain = await baseCoin.keychains().get({ id: keychainId });
14
+ // Verify passphrase before any mutation
15
+ const decrypted = await (0, sdk_core_1.decryptKeychainPrivateKey)(bitgo, keychain, walletPassphrase);
16
+ if (!decrypted) {
17
+ throw new Error('Incorrect wallet passphrase. Passkey removal aborted to prevent lockout.');
18
+ }
19
+ // No sdk-core abstraction for this endpoint; raw DELETE is required
20
+ await bitgo.del(bitgo.url(`/key/${keychainId}/webauthndevice/${device.id}`, 2)).result();
21
+ }
22
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVtb3ZlUGFzc2tleUZyb21XYWxsZXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcmVtb3ZlUGFzc2tleUZyb21XYWxsZXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFFQSwwREEwQkM7QUE1QkQsbURBQW9HO0FBRTdGLEtBQUssVUFBVSx1QkFBdUIsQ0FBQyxNQU03QztJQUNDLE1BQU0sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLGdCQUFnQixFQUFFLEdBQUcsTUFBTSxDQUFDO0lBRTdFLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDZixNQUFNLElBQUksS0FBSyxDQUFDLDJEQUEyRCxDQUFDLENBQUM7SUFDL0UsQ0FBQztJQUVELE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDdEMsTUFBTSxNQUFNLEdBQUcsTUFBTSxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7SUFDOUQsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3RDLE1BQU0sUUFBUSxHQUFHLE1BQU0sUUFBUSxDQUFDLFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsRUFBRSxVQUFVLEVBQUUsQ0FBQyxDQUFDO0lBRXBFLHdDQUF3QztJQUN4QyxNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUEsb0NBQXlCLEVBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO0lBQ3JGLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNmLE1BQU0sSUFBSSxLQUFLLENBQUMsMEVBQTBFLENBQUMsQ0FBQztJQUM5RixDQUFDO0lBRUQsb0VBQW9FO0lBQ3BFLE1BQU0sS0FBSyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLFFBQVEsVUFBVSxtQkFBbUIsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7QUFDM0YsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEJpdEdvQmFzZSwgZGVjcnlwdEtleWNoYWluUHJpdmF0ZUtleSwgdHlwZSBXZWJBdXRobk90cERldmljZSB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlbW92ZVBhc3NrZXlGcm9tV2FsbGV0KHBhcmFtczoge1xuICBiaXRnbzogQml0R29CYXNlO1xuICBjb2luOiBzdHJpbmc7XG4gIHdhbGxldElkOiBzdHJpbmc7XG4gIGRldmljZTogV2ViQXV0aG5PdHBEZXZpY2U7XG4gIHdhbGxldFBhc3NwaHJhc2U6IHN0cmluZztcbn0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgeyBiaXRnbywgY29pbjogY29pbk5hbWUsIHdhbGxldElkLCBkZXZpY2UsIHdhbGxldFBhc3NwaHJhc2UgfSA9IHBhcmFtcztcblxuICBpZiAoIWRldmljZS5pZCkge1xuICAgIHRocm93IG5ldyBFcnJvcignZGV2aWNlLmlkIGlzIHJlcXVpcmVkIHRvIHJlbW92ZSBhIHBhc3NrZXkgZnJvbSB0aGUgd2FsbGV0Jyk7XG4gIH1cblxuICBjb25zdCBiYXNlQ29pbiA9IGJpdGdvLmNvaW4oY29pbk5hbWUpO1xuICBjb25zdCB3YWxsZXQgPSBhd2FpdCBiYXNlQ29pbi53YWxsZXRzKCkuZ2V0KHsgaWQ6IHdhbGxldElkIH0pO1xuICBjb25zdCBrZXljaGFpbklkID0gd2FsbGV0LmtleUlkcygpWzBdO1xuICBjb25zdCBrZXljaGFpbiA9IGF3YWl0IGJhc2VDb2luLmtleWNoYWlucygpLmdldCh7IGlkOiBrZXljaGFpbklkIH0pO1xuXG4gIC8vIFZlcmlmeSBwYXNzcGhyYXNlIGJlZm9yZSBhbnkgbXV0YXRpb25cbiAgY29uc3QgZGVjcnlwdGVkID0gYXdhaXQgZGVjcnlwdEtleWNoYWluUHJpdmF0ZUtleShiaXRnbywga2V5Y2hhaW4sIHdhbGxldFBhc3NwaHJhc2UpO1xuICBpZiAoIWRlY3J5cHRlZCkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5jb3JyZWN0IHdhbGxldCBwYXNzcGhyYXNlLiBQYXNza2V5IHJlbW92YWwgYWJvcnRlZCB0byBwcmV2ZW50IGxvY2tvdXQuJyk7XG4gIH1cblxuICAvLyBObyBzZGstY29yZSBhYnN0cmFjdGlvbiBmb3IgdGhpcyBlbmRwb2ludDsgcmF3IERFTEVURSBpcyByZXF1aXJlZFxuICBhd2FpdCBiaXRnby5kZWwoYml0Z28udXJsKGAva2V5LyR7a2V5Y2hhaW5JZH0vd2ViYXV0aG5kZXZpY2UvJHtkZXZpY2UuaWR9YCwgMikpLnJlc3VsdCgpO1xufVxuIl19
@@ -0,0 +1,12 @@
1
+ export declare const ENTERPRISE_ID = "enterprise-abc";
2
+ export declare const WALLET_ID = "wallet-hot-123";
3
+ export declare const KEYCHAIN_ID = "key-user-001";
4
+ export declare const COIN = "tbtc";
5
+ export declare const EXISTING_PASSPHRASE = "my-existing-passphrase";
6
+ export declare const PRF_OUTPUT: ArrayBuffer;
7
+ export declare const CREDENTIAL_ID = "Y3JlZC1pZC00NTY";
8
+ export declare const DEVICE_MONGO_ID = "device-mongo-id-1";
9
+ export declare const BASE_SALT = "ZqJ64M2dL65zn2-Jxd58SMN2ILc9QjbCFxUTGHd_LC8";
10
+ export declare const REGISTER_CHALLENGE: string;
11
+ export declare const ASSERTION_CHALLENGE: string;
12
+ //# sourceMappingURL=fixtures.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../../../../test/integration/helpers/fixtures.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,mBAAmB,CAAC;AAC9C,eAAO,MAAM,SAAS,mBAAmB,CAAC;AAC1C,eAAO,MAAM,WAAW,iBAAiB,CAAC;AAC1C,eAAO,MAAM,IAAI,SAAS,CAAC;AAC3B,eAAO,MAAM,mBAAmB,2BAA2B,CAAC;AAC5D,eAAO,MAAM,UAAU,aAA0E,CAAC;AAClG,eAAO,MAAM,aAAa,oBAAoB,CAAC;AAC/C,eAAO,MAAM,eAAe,sBAAsB,CAAC;AACnD,eAAO,MAAM,SAAS,gDAAgD,CAAC;AACvE,eAAO,MAAM,kBAAkB,QAAqD,CAAC;AACrF,eAAO,MAAM,mBAAmB,QAAwD,CAAC"}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ASSERTION_CHALLENGE = exports.REGISTER_CHALLENGE = exports.BASE_SALT = exports.DEVICE_MONGO_ID = exports.CREDENTIAL_ID = exports.PRF_OUTPUT = exports.EXISTING_PASSPHRASE = exports.COIN = exports.KEYCHAIN_ID = exports.WALLET_ID = exports.ENTERPRISE_ID = void 0;
4
+ exports.ENTERPRISE_ID = 'enterprise-abc';
5
+ exports.WALLET_ID = 'wallet-hot-123';
6
+ exports.KEYCHAIN_ID = 'key-user-001';
7
+ exports.COIN = 'tbtc';
8
+ exports.EXISTING_PASSPHRASE = 'my-existing-passphrase';
9
+ exports.PRF_OUTPUT = new Uint8Array([0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x01, 0x02]).buffer;
10
+ exports.CREDENTIAL_ID = 'Y3JlZC1pZC00NTY';
11
+ exports.DEVICE_MONGO_ID = 'device-mongo-id-1';
12
+ exports.BASE_SALT = 'ZqJ64M2dL65zn2-Jxd58SMN2ILc9QjbCFxUTGHd_LC8';
13
+ exports.REGISTER_CHALLENGE = Buffer.from('random-challenge').toString('base64');
14
+ exports.ASSERTION_CHALLENGE = Buffer.from('assertion-challenge').toString('base64');
15
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZml4dHVyZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2ludGVncmF0aW9uL2hlbHBlcnMvZml4dHVyZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQWEsUUFBQSxhQUFhLEdBQUcsZ0JBQWdCLENBQUM7QUFDakMsUUFBQSxTQUFTLEdBQUcsZ0JBQWdCLENBQUM7QUFDN0IsUUFBQSxXQUFXLEdBQUcsY0FBYyxDQUFDO0FBQzdCLFFBQUEsSUFBSSxHQUFHLE1BQU0sQ0FBQztBQUNkLFFBQUEsbUJBQW1CLEdBQUcsd0JBQXdCLENBQUM7QUFDL0MsUUFBQSxVQUFVLEdBQUcsSUFBSSxVQUFVLENBQUMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7QUFDckYsUUFBQSxhQUFhLEdBQUcsaUJBQWlCLENBQUM7QUFDbEMsUUFBQSxlQUFlLEdBQUcsbUJBQW1CLENBQUM7QUFDdEMsUUFBQSxTQUFTLEdBQUcsNkNBQTZDLENBQUM7QUFDMUQsUUFBQSxrQkFBa0IsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ3hFLFFBQUEsbUJBQW1CLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBjb25zdCBFTlRFUlBSSVNFX0lEID0gJ2VudGVycHJpc2UtYWJjJztcbmV4cG9ydCBjb25zdCBXQUxMRVRfSUQgPSAnd2FsbGV0LWhvdC0xMjMnO1xuZXhwb3J0IGNvbnN0IEtFWUNIQUlOX0lEID0gJ2tleS11c2VyLTAwMSc7XG5leHBvcnQgY29uc3QgQ09JTiA9ICd0YnRjJztcbmV4cG9ydCBjb25zdCBFWElTVElOR19QQVNTUEhSQVNFID0gJ215LWV4aXN0aW5nLXBhc3NwaHJhc2UnO1xuZXhwb3J0IGNvbnN0IFBSRl9PVVRQVVQgPSBuZXcgVWludDhBcnJheShbMHhkZSwgMHhhZCwgMHhiZSwgMHhlZiwgMHhjYSwgMHhmZSwgMHgwMSwgMHgwMl0pLmJ1ZmZlcjtcbmV4cG9ydCBjb25zdCBDUkVERU5USUFMX0lEID0gJ1kzSmxaQzFwWkMwME5UWSc7XG5leHBvcnQgY29uc3QgREVWSUNFX01PTkdPX0lEID0gJ2RldmljZS1tb25nby1pZC0xJztcbmV4cG9ydCBjb25zdCBCQVNFX1NBTFQgPSAnWnFKNjRNMmRMNjV6bjItSnhkNThTTU4ySUxjOVFqYkNGeFVUR0hkX0xDOCc7XG5leHBvcnQgY29uc3QgUkVHSVNURVJfQ0hBTExFTkdFID0gQnVmZmVyLmZyb20oJ3JhbmRvbS1jaGFsbGVuZ2UnKS50b1N0cmluZygnYmFzZTY0Jyk7XG5leHBvcnQgY29uc3QgQVNTRVJUSU9OX0NIQUxMRU5HRSA9IEJ1ZmZlci5mcm9tKCdhc3NlcnRpb24tY2hhbGxlbmdlJykudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuIl19
@@ -0,0 +1,27 @@
1
+ export interface KeychainState {
2
+ id: string;
3
+ encryptedPrv: string;
4
+ webauthnDevices?: Array<{
5
+ authenticatorInfo: {
6
+ credID: string;
7
+ };
8
+ prfSalt: string;
9
+ id?: string;
10
+ encryptedPrv?: string;
11
+ }>;
12
+ }
13
+ export interface MockBitGo {
14
+ bitgo: any;
15
+ keychainState: KeychainState;
16
+ wallet: any;
17
+ encrypt: (params: {
18
+ password: string;
19
+ input: string;
20
+ }) => string;
21
+ decrypt: (params: {
22
+ password: string;
23
+ input: string;
24
+ }) => string;
25
+ }
26
+ export declare function makeMockBitGo(initialEncryptedPrv: string): MockBitGo;
27
+ //# sourceMappingURL=mockBitGo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mockBitGo.d.ts","sourceRoot":"","sources":["../../../../test/integration/helpers/mockBitGo.ts"],"names":[],"mappings":"AAsBA,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,KAAK,CAAC;QACtB,iBAAiB,EAAE;YAAE,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;QACtC,OAAO,EAAE,MAAM,CAAC;QAChB,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,GAAG,CAAC;IACX,aAAa,EAAE,aAAa,CAAC;IAC7B,MAAM,EAAE,GAAG,CAAC;IACZ,OAAO,EAAE,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM,CAAC;IACjE,OAAO,EAAE,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM,CAAC;CAClE;AAED,wBAAgB,aAAa,CAAC,mBAAmB,EAAE,MAAM,GAAG,SAAS,CA8GpE"}