@bitgo-beta/passkey-crypto 0.0.1-beta.7 → 0.0.1-beta.9

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 (39) 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 +67 -0
  4. package/dist/src/deriveEnterpriseSalt.d.ts +1 -1
  5. package/dist/src/deriveEnterpriseSalt.d.ts.map +1 -1
  6. package/dist/src/deriveEnterpriseSalt.js +5 -42
  7. package/dist/src/derivePasskeyPrfKey.d.ts +15 -0
  8. package/dist/src/derivePasskeyPrfKey.d.ts.map +1 -0
  9. package/dist/src/derivePasskeyPrfKey.js +45 -0
  10. package/dist/src/index.d.ts +3 -0
  11. package/dist/src/index.d.ts.map +1 -1
  12. package/dist/src/index.js +8 -2
  13. package/dist/src/registerPasskey.d.ts +10 -0
  14. package/dist/src/registerPasskey.d.ts.map +1 -0
  15. package/dist/src/registerPasskey.js +96 -0
  16. package/dist/src/removePasskeyFromAccount.d.ts +11 -0
  17. package/dist/src/removePasskeyFromAccount.d.ts.map +1 -0
  18. package/dist/src/removePasskeyFromAccount.js +15 -0
  19. package/dist/src/removePasskeyFromWallet.d.ts +10 -0
  20. package/dist/src/removePasskeyFromWallet.d.ts.map +1 -0
  21. package/dist/src/removePasskeyFromWallet.js +22 -0
  22. package/dist/test/unit/attachPasskeyToWallet.test.d.ts +2 -0
  23. package/dist/test/unit/attachPasskeyToWallet.test.d.ts.map +1 -0
  24. package/dist/test/unit/attachPasskeyToWallet.test.js +205 -0
  25. package/dist/test/unit/deriveEnterpriseSalt.test.js +4 -4
  26. package/dist/test/unit/derivePasskeyPrfKey.test.d.ts +2 -0
  27. package/dist/test/unit/derivePasskeyPrfKey.test.d.ts.map +1 -0
  28. package/dist/test/unit/derivePasskeyPrfKey.test.js +152 -0
  29. package/dist/test/unit/registerPasskey.test.d.ts +2 -0
  30. package/dist/test/unit/registerPasskey.test.d.ts.map +1 -0
  31. package/dist/test/unit/registerPasskey.test.js +155 -0
  32. package/dist/test/unit/removePasskeyFromAccount.test.d.ts +2 -0
  33. package/dist/test/unit/removePasskeyFromAccount.test.d.ts.map +1 -0
  34. package/dist/test/unit/removePasskeyFromAccount.test.js +88 -0
  35. package/dist/test/unit/removePasskeyFromWallet.test.d.ts +2 -0
  36. package/dist/test/unit/removePasskeyFromWallet.test.d.ts.map +1 -0
  37. package/dist/test/unit/removePasskeyFromWallet.test.js +170 -0
  38. package/dist/tsconfig.tsbuildinfo +1 -1
  39. package/package.json +3 -3
@@ -0,0 +1,11 @@
1
+ import { BitGoBase, Keychain } from '@bitgo-beta/sdk-core';
2
+ import { WebAuthnOtpDevice, WebAuthnProvider } from './webAuthnTypes';
3
+ export declare function attachPasskeyToWallet(params: {
4
+ bitgo: BitGoBase;
5
+ coin: string;
6
+ walletId: string;
7
+ device: WebAuthnOtpDevice;
8
+ existingPassphrase: string;
9
+ provider: WebAuthnProvider;
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,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAG3D,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEtE,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;CAC5B,GAAG,OAAO,CAAC,QAAQ,CAAC,CA2EpB"}
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.attachPasskeyToWallet = attachPasskeyToWallet;
4
+ const deriveEnterpriseSalt_1 = require("./deriveEnterpriseSalt");
5
+ const derivePassword_1 = require("./derivePassword");
6
+ async function attachPasskeyToWallet(params) {
7
+ const { bitgo, coin, walletId, device, existingPassphrase, provider } = params;
8
+ // Throw early if PRF extension is not supported
9
+ if (!device.prfSalt) {
10
+ throw new Error('PRF extension not supported by this device. Please use a different passkey.');
11
+ }
12
+ const baseCoin = bitgo.coin(coin);
13
+ // Fetch wallet and validate it is a hot wallet
14
+ const wallet = await baseCoin.wallets().get({ id: walletId });
15
+ if (wallet.type() !== 'hot') {
16
+ throw new Error(`Wallet ${walletId} is not a hot wallet. Only hot wallets support passkey attachment.`);
17
+ }
18
+ const walletData = wallet.toJSON();
19
+ const enterpriseId = walletData.enterprise;
20
+ if (!enterpriseId) {
21
+ throw new Error(`Wallet ${walletId} has no enterprise.`);
22
+ }
23
+ // Fetch the user keychain — iterates keys until it finds one with encryptedPrv
24
+ const keychain = await wallet.getEncryptedUserKeychain();
25
+ const keychainId = keychain.id;
26
+ // Derive enterprise-scoped salt
27
+ const enterpriseSalt = (0, deriveEnterpriseSalt_1.deriveEnterpriseSalt)(device.prfSalt, enterpriseId);
28
+ // Decrypt private key with existing passphrase
29
+ const privateKey = bitgo.decrypt({ password: existingPassphrase, input: keychain.encryptedPrv });
30
+ // Decode credentialId from base64url to ArrayBuffer for allowCredentials.
31
+ // The WebAuthn spec requires allowCredentials to be non-empty when using evalByCredential,
32
+ // and each entry must correspond to a key in the evalByCredential map.
33
+ const credentialIdBuffer = Buffer.from(device.credentialId.replace(/-/g, '+').replace(/_/g, '/'), 'base64').buffer;
34
+ // PRF assertion — evalByCredential maps this device's credentialId to its enterprise salt
35
+ const authResult = await provider.get({
36
+ publicKey: {
37
+ allowCredentials: [{ type: 'public-key', id: credentialIdBuffer }],
38
+ },
39
+ evalByCredential: { [device.credentialId]: enterpriseSalt },
40
+ });
41
+ if (!authResult.prfResult) {
42
+ throw new Error('PRF assertion did not return a result.');
43
+ }
44
+ // Derive password from PRF output and re-encrypt
45
+ const prfPassword = (0, derivePassword_1.derivePassword)(authResult.prfResult);
46
+ const encryptedPrv = bitgo.encrypt({ password: prfPassword, input: privateKey });
47
+ // Convert enterpriseSalt from hex to base64url (URL-safe, no padding)
48
+ // as required by the server's prfSalt validation.
49
+ const prfSaltBase64url = Buffer.from(enterpriseSalt, 'hex')
50
+ .toString('base64')
51
+ .replace(/\+/g, '-')
52
+ .replace(/\//g, '_')
53
+ .replace(/=+$/, '');
54
+ // PUT webauthnInfo to keychain endpoint
55
+ const updatedKeychain = await bitgo
56
+ .put(bitgo.url(`/${coin}/key/${keychainId}`, 2))
57
+ .send({
58
+ webauthnInfo: {
59
+ prfSalt: prfSaltBase64url,
60
+ otpDeviceId: device.id,
61
+ encryptedPrv,
62
+ },
63
+ })
64
+ .result();
65
+ return updatedKeychain;
66
+ }
67
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXR0YWNoUGFzc2tleVRvV2FsbGV0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2F0dGFjaFBhc3NrZXlUb1dhbGxldC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUtBLHNEQWtGQztBQXRGRCxpRUFBOEQ7QUFDOUQscURBQWtEO0FBRzNDLEtBQUssVUFBVSxxQkFBcUIsQ0FBQyxNQU8zQztJQUNDLE1BQU0sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsa0JBQWtCLEVBQUUsUUFBUSxFQUFFLEdBQUcsTUFBTSxDQUFDO0lBRS9FLGdEQUFnRDtJQUNoRCxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3BCLE1BQU0sSUFBSSxLQUFLLENBQUMsNkVBQTZFLENBQUMsQ0FBQztJQUNqRyxDQUFDO0lBRUQsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUVsQywrQ0FBK0M7SUFDL0MsTUFBTSxNQUFNLEdBQUcsTUFBTSxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7SUFFOUQsSUFBSSxNQUFNLENBQUMsSUFBSSxFQUFFLEtBQUssS0FBSyxFQUFFLENBQUM7UUFDNUIsTUFBTSxJQUFJLEtBQUssQ0FBQyxVQUFVLFFBQVEsb0VBQW9FLENBQUMsQ0FBQztJQUMxRyxDQUFDO0lBRUQsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ25DLE1BQU0sWUFBWSxHQUFHLFVBQVUsQ0FBQyxVQUFVLENBQUM7SUFDM0MsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ2xCLE1BQU0sSUFBSSxLQUFLLENBQUMsVUFBVSxRQUFRLHFCQUFxQixDQUFDLENBQUM7SUFDM0QsQ0FBQztJQUVELCtFQUErRTtJQUMvRSxNQUFNLFFBQVEsR0FBRyxNQUFNLE1BQU0sQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO0lBQ3pELE1BQU0sVUFBVSxHQUFHLFFBQVEsQ0FBQyxFQUFFLENBQUM7SUFFL0IsZ0NBQWdDO0lBQ2hDLE1BQU0sY0FBYyxHQUFHLElBQUEsMkNBQW9CLEVBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxZQUFZLENBQUMsQ0FBQztJQUUxRSwrQ0FBK0M7SUFDL0MsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFLFFBQVEsRUFBRSxrQkFBa0IsRUFBRSxLQUFLLEVBQUUsUUFBUSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUM7SUFFakcsMEVBQTBFO0lBQzFFLDJGQUEyRjtJQUMzRix1RUFBdUU7SUFDdkUsTUFBTSxrQkFBa0IsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUVuSCwwRkFBMEY7SUFDMUYsTUFBTSxVQUFVLEdBQUcsTUFBTSxRQUFRLENBQUMsR0FBRyxDQUFDO1FBQ3BDLFNBQVMsRUFBRTtZQUNULGdCQUFnQixFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLEVBQUUsRUFBRSxrQkFBa0IsRUFBRSxDQUFDO1NBQzlCO1FBQ3RDLGdCQUFnQixFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLEVBQUUsY0FBYyxFQUFFO0tBQzVELENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxVQUFVLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDMUIsTUFBTSxJQUFJLEtBQUssQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO0lBQzVELENBQUM7SUFFRCxpREFBaUQ7SUFDakQsTUFBTSxXQUFXLEdBQUcsSUFBQSwrQkFBYyxFQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN6RCxNQUFNLFlBQVksR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLENBQUMsQ0FBQztJQUVqRixzRUFBc0U7SUFDdEUsa0RBQWtEO0lBQ2xELE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsS0FBSyxDQUFDO1NBQ3hELFFBQVEsQ0FBQyxRQUFRLENBQUM7U0FDbEIsT0FBTyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUM7U0FDbkIsT0FBTyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUM7U0FDbkIsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztJQUV0Qix3Q0FBd0M7SUFDeEMsTUFBTSxlQUFlLEdBQUcsTUFBTSxLQUFLO1NBQ2hDLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxRQUFRLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1NBQy9DLElBQUksQ0FBQztRQUNKLFlBQVksRUFBRTtZQUNaLE9BQU8sRUFBRSxnQkFBZ0I7WUFDekIsV0FBVyxFQUFFLE1BQU0sQ0FBQyxFQUFFO1lBQ3RCLFlBQVk7U0FDYjtLQUNGLENBQUM7U0FDRCxNQUFNLEVBQUUsQ0FBQztJQUVaLE9BQU8sZUFBMkIsQ0FBQztBQUNyQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQml0R29CYXNlLCBLZXljaGFpbiB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcbmltcG9ydCB7IGRlcml2ZUVudGVycHJpc2VTYWx0IH0gZnJvbSAnLi9kZXJpdmVFbnRlcnByaXNlU2FsdCc7XG5pbXBvcnQgeyBkZXJpdmVQYXNzd29yZCB9IGZyb20gJy4vZGVyaXZlUGFzc3dvcmQnO1xuaW1wb3J0IHsgV2ViQXV0aG5PdHBEZXZpY2UsIFdlYkF1dGhuUHJvdmlkZXIgfSBmcm9tICcuL3dlYkF1dGhuVHlwZXMnO1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYXR0YWNoUGFzc2tleVRvV2FsbGV0KHBhcmFtczoge1xuICBiaXRnbzogQml0R29CYXNlO1xuICBjb2luOiBzdHJpbmc7XG4gIHdhbGxldElkOiBzdHJpbmc7XG4gIGRldmljZTogV2ViQXV0aG5PdHBEZXZpY2U7XG4gIGV4aXN0aW5nUGFzc3BocmFzZTogc3RyaW5nO1xuICBwcm92aWRlcjogV2ViQXV0aG5Qcm92aWRlcjtcbn0pOiBQcm9taXNlPEtleWNoYWluPiB7XG4gIGNvbnN0IHsgYml0Z28sIGNvaW4sIHdhbGxldElkLCBkZXZpY2UsIGV4aXN0aW5nUGFzc3BocmFzZSwgcHJvdmlkZXIgfSA9IHBhcmFtcztcblxuICAvLyBUaHJvdyBlYXJseSBpZiBQUkYgZXh0ZW5zaW9uIGlzIG5vdCBzdXBwb3J0ZWRcbiAgaWYgKCFkZXZpY2UucHJmU2FsdCkge1xuICAgIHRocm93IG5ldyBFcnJvcignUFJGIGV4dGVuc2lvbiBub3Qgc3VwcG9ydGVkIGJ5IHRoaXMgZGV2aWNlLiBQbGVhc2UgdXNlIGEgZGlmZmVyZW50IHBhc3NrZXkuJyk7XG4gIH1cblxuICBjb25zdCBiYXNlQ29pbiA9IGJpdGdvLmNvaW4oY29pbik7XG5cbiAgLy8gRmV0Y2ggd2FsbGV0IGFuZCB2YWxpZGF0ZSBpdCBpcyBhIGhvdCB3YWxsZXRcbiAgY29uc3Qgd2FsbGV0ID0gYXdhaXQgYmFzZUNvaW4ud2FsbGV0cygpLmdldCh7IGlkOiB3YWxsZXRJZCB9KTtcblxuICBpZiAod2FsbGV0LnR5cGUoKSAhPT0gJ2hvdCcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFdhbGxldCAke3dhbGxldElkfSBpcyBub3QgYSBob3Qgd2FsbGV0LiBPbmx5IGhvdCB3YWxsZXRzIHN1cHBvcnQgcGFzc2tleSBhdHRhY2htZW50LmApO1xuICB9XG5cbiAgY29uc3Qgd2FsbGV0RGF0YSA9IHdhbGxldC50b0pTT04oKTtcbiAgY29uc3QgZW50ZXJwcmlzZUlkID0gd2FsbGV0RGF0YS5lbnRlcnByaXNlO1xuICBpZiAoIWVudGVycHJpc2VJZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgV2FsbGV0ICR7d2FsbGV0SWR9IGhhcyBubyBlbnRlcnByaXNlLmApO1xuICB9XG5cbiAgLy8gRmV0Y2ggdGhlIHVzZXIga2V5Y2hhaW4g4oCUIGl0ZXJhdGVzIGtleXMgdW50aWwgaXQgZmluZHMgb25lIHdpdGggZW5jcnlwdGVkUHJ2XG4gIGNvbnN0IGtleWNoYWluID0gYXdhaXQgd2FsbGV0LmdldEVuY3J5cHRlZFVzZXJLZXljaGFpbigpO1xuICBjb25zdCBrZXljaGFpbklkID0ga2V5Y2hhaW4uaWQ7XG5cbiAgLy8gRGVyaXZlIGVudGVycHJpc2Utc2NvcGVkIHNhbHRcbiAgY29uc3QgZW50ZXJwcmlzZVNhbHQgPSBkZXJpdmVFbnRlcnByaXNlU2FsdChkZXZpY2UucHJmU2FsdCwgZW50ZXJwcmlzZUlkKTtcblxuICAvLyBEZWNyeXB0IHByaXZhdGUga2V5IHdpdGggZXhpc3RpbmcgcGFzc3BocmFzZVxuICBjb25zdCBwcml2YXRlS2V5ID0gYml0Z28uZGVjcnlwdCh7IHBhc3N3b3JkOiBleGlzdGluZ1Bhc3NwaHJhc2UsIGlucHV0OiBrZXljaGFpbi5lbmNyeXB0ZWRQcnYgfSk7XG5cbiAgLy8gRGVjb2RlIGNyZWRlbnRpYWxJZCBmcm9tIGJhc2U2NHVybCB0byBBcnJheUJ1ZmZlciBmb3IgYWxsb3dDcmVkZW50aWFscy5cbiAgLy8gVGhlIFdlYkF1dGhuIHNwZWMgcmVxdWlyZXMgYWxsb3dDcmVkZW50aWFscyB0byBiZSBub24tZW1wdHkgd2hlbiB1c2luZyBldmFsQnlDcmVkZW50aWFsLFxuICAvLyBhbmQgZWFjaCBlbnRyeSBtdXN0IGNvcnJlc3BvbmQgdG8gYSBrZXkgaW4gdGhlIGV2YWxCeUNyZWRlbnRpYWwgbWFwLlxuICBjb25zdCBjcmVkZW50aWFsSWRCdWZmZXIgPSBCdWZmZXIuZnJvbShkZXZpY2UuY3JlZGVudGlhbElkLnJlcGxhY2UoLy0vZywgJysnKS5yZXBsYWNlKC9fL2csICcvJyksICdiYXNlNjQnKS5idWZmZXI7XG5cbiAgLy8gUFJGIGFzc2VydGlvbiDigJQgZXZhbEJ5Q3JlZGVudGlhbCBtYXBzIHRoaXMgZGV2aWNlJ3MgY3JlZGVudGlhbElkIHRvIGl0cyBlbnRlcnByaXNlIHNhbHRcbiAgY29uc3QgYXV0aFJlc3VsdCA9IGF3YWl0IHByb3ZpZGVyLmdldCh7XG4gICAgcHVibGljS2V5OiB7XG4gICAgICBhbGxvd0NyZWRlbnRpYWxzOiBbeyB0eXBlOiAncHVibGljLWtleScsIGlkOiBjcmVkZW50aWFsSWRCdWZmZXIgfV0sXG4gICAgfSBhcyBQdWJsaWNLZXlDcmVkZW50aWFsUmVxdWVzdE9wdGlvbnMsXG4gICAgZXZhbEJ5Q3JlZGVudGlhbDogeyBbZGV2aWNlLmNyZWRlbnRpYWxJZF06IGVudGVycHJpc2VTYWx0IH0sXG4gIH0pO1xuXG4gIGlmICghYXV0aFJlc3VsdC5wcmZSZXN1bHQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1BSRiBhc3NlcnRpb24gZGlkIG5vdCByZXR1cm4gYSByZXN1bHQuJyk7XG4gIH1cblxuICAvLyBEZXJpdmUgcGFzc3dvcmQgZnJvbSBQUkYgb3V0cHV0IGFuZCByZS1lbmNyeXB0XG4gIGNvbnN0IHByZlBhc3N3b3JkID0gZGVyaXZlUGFzc3dvcmQoYXV0aFJlc3VsdC5wcmZSZXN1bHQpO1xuICBjb25zdCBlbmNyeXB0ZWRQcnYgPSBiaXRnby5lbmNyeXB0KHsgcGFzc3dvcmQ6IHByZlBhc3N3b3JkLCBpbnB1dDogcHJpdmF0ZUtleSB9KTtcblxuICAvLyBDb252ZXJ0IGVudGVycHJpc2VTYWx0IGZyb20gaGV4IHRvIGJhc2U2NHVybCAoVVJMLXNhZmUsIG5vIHBhZGRpbmcpXG4gIC8vIGFzIHJlcXVpcmVkIGJ5IHRoZSBzZXJ2ZXIncyBwcmZTYWx0IHZhbGlkYXRpb24uXG4gIGNvbnN0IHByZlNhbHRCYXNlNjR1cmwgPSBCdWZmZXIuZnJvbShlbnRlcnByaXNlU2FsdCwgJ2hleCcpXG4gICAgLnRvU3RyaW5nKCdiYXNlNjQnKVxuICAgIC5yZXBsYWNlKC9cXCsvZywgJy0nKVxuICAgIC5yZXBsYWNlKC9cXC8vZywgJ18nKVxuICAgIC5yZXBsYWNlKC89KyQvLCAnJyk7XG5cbiAgLy8gUFVUIHdlYmF1dGhuSW5mbyB0byBrZXljaGFpbiBlbmRwb2ludFxuICBjb25zdCB1cGRhdGVkS2V5Y2hhaW4gPSBhd2FpdCBiaXRnb1xuICAgIC5wdXQoYml0Z28udXJsKGAvJHtjb2lufS9rZXkvJHtrZXljaGFpbklkfWAsIDIpKVxuICAgIC5zZW5kKHtcbiAgICAgIHdlYmF1dGhuSW5mbzoge1xuICAgICAgICBwcmZTYWx0OiBwcmZTYWx0QmFzZTY0dXJsLFxuICAgICAgICBvdHBEZXZpY2VJZDogZGV2aWNlLmlkLFxuICAgICAgICBlbmNyeXB0ZWRQcnYsXG4gICAgICB9LFxuICAgIH0pXG4gICAgLnJlc3VsdCgpO1xuXG4gIHJldHVybiB1cGRhdGVkS2V5Y2hhaW4gYXMgS2V5Y2hhaW47XG59XG4iXX0=
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * @param baseSalt - Server-provided base64url-encoded PRF salt
8
8
  * @param enterpriseId - Enterprise identifier
9
- * @returns Base64-encoded HMAC-SHA256 digest
9
+ * @returns Hex-encoded HMAC-SHA256 digest
10
10
  */
11
11
  export declare function deriveEnterpriseSalt(baseSalt: string, enterpriseId: string): string;
12
12
  //# sourceMappingURL=deriveEnterpriseSalt.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"deriveEnterpriseSalt.d.ts","sourceRoot":"","sources":["../../src/deriveEnterpriseSalt.ts"],"names":[],"mappings":"AASA;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAUnF"}
1
+ {"version":3,"file":"deriveEnterpriseSalt.d.ts","sourceRoot":"","sources":["../../src/deriveEnterpriseSalt.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAGnF"}
@@ -1,40 +1,7 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
2
  Object.defineProperty(exports, "__esModule", { value: true });
36
3
  exports.deriveEnterpriseSalt = deriveEnterpriseSalt;
37
- const sjcl = __importStar(require("@bitgo-beta/sjcl"));
4
+ const crypto_1 = require("crypto");
38
5
  /**
39
6
  * Derives an enterprise-scoped PRF salt to prevent cross-enterprise key reuse.
40
7
  *
@@ -43,14 +10,10 @@ const sjcl = __importStar(require("@bitgo-beta/sjcl"));
43
10
  *
44
11
  * @param baseSalt - Server-provided base64url-encoded PRF salt
45
12
  * @param enterpriseId - Enterprise identifier
46
- * @returns Base64-encoded HMAC-SHA256 digest
13
+ * @returns Hex-encoded HMAC-SHA256 digest
47
14
  */
48
15
  function deriveEnterpriseSalt(baseSalt, enterpriseId) {
49
- const { misc, codec, hash } = sjcl;
50
- const keyBits = codec.base64url.toBits(baseSalt);
51
- const dataBits = codec.utf8String.toBits(enterpriseId);
52
- const hmacInstance = new misc.hmac(keyBits, hash.sha256);
53
- const resultBits = hmacInstance.mac(dataBits);
54
- return codec.base64.fromBits(resultBits);
16
+ const keyBytes = Buffer.from(baseSalt.replace(/-/g, '+').replace(/_/g, '/'), 'base64');
17
+ return (0, crypto_1.createHmac)('sha256', keyBytes).update(enterpriseId).digest('hex');
55
18
  }
56
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVyaXZlRW50ZXJwcmlzZVNhbHQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZGVyaXZlRW50ZXJwcmlzZVNhbHQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFtQkEsb0RBVUM7QUE3QkQsdURBQXlDO0FBU3pDOzs7Ozs7Ozs7R0FTRztBQUNILFNBQWdCLG9CQUFvQixDQUFDLFFBQWdCLEVBQUUsWUFBb0I7SUFDekUsTUFBTSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEdBQUcsSUFBMkIsQ0FBQztJQUUxRCxNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNqRCxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUV2RCxNQUFNLFlBQVksR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN6RCxNQUFNLFVBQVUsR0FBRyxZQUFZLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBRTlDLE9BQU8sS0FBSyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDM0MsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHNqY2wgZnJvbSAnQGJpdGdvLWJldGEvc2pjbCc7XG5pbXBvcnQgdHlwZSB7IFNqY2xDb2RlY3MsIFNqY2xIYXNoZXMsIFNqY2xNaXNjIH0gZnJvbSAnQGJpdGdvLWJldGEvc2pjbCc7XG5cbnR5cGUgU2pjbFR5cGUgPSB7XG4gIGhhc2g6IFNqY2xIYXNoZXM7XG4gIGNvZGVjOiBTamNsQ29kZWNzO1xuICBtaXNjOiBTamNsTWlzYztcbn07XG5cbi8qKlxuICogRGVyaXZlcyBhbiBlbnRlcnByaXNlLXNjb3BlZCBQUkYgc2FsdCB0byBwcmV2ZW50IGNyb3NzLWVudGVycHJpc2Uga2V5IHJldXNlLlxuICpcbiAqIENvbXB1dGVzIEhNQUMtU0hBMjU2KGtleT1wcmZTYWx0X2Jhc2U2NHVybF9kZWNvZGVkLCBkYXRhPWVudGVycHJpc2VJZF91dGY4KS5cbiAqIFRoZSBiYXNlU2FsdCBtdXN0IGFsd2F5cyBjb21lIGZyb20gdGhlIHNlcnZlciDigJQgbmV2ZXIgZ2VuZXJhdGUgaXQgY2xpZW50LXNpZGUuXG4gKlxuICogQHBhcmFtIGJhc2VTYWx0IC0gU2VydmVyLXByb3ZpZGVkIGJhc2U2NHVybC1lbmNvZGVkIFBSRiBzYWx0XG4gKiBAcGFyYW0gZW50ZXJwcmlzZUlkIC0gRW50ZXJwcmlzZSBpZGVudGlmaWVyXG4gKiBAcmV0dXJucyBCYXNlNjQtZW5jb2RlZCBITUFDLVNIQTI1NiBkaWdlc3RcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlcml2ZUVudGVycHJpc2VTYWx0KGJhc2VTYWx0OiBzdHJpbmcsIGVudGVycHJpc2VJZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgeyBtaXNjLCBjb2RlYywgaGFzaCB9ID0gc2pjbCBhcyB1bmtub3duIGFzIFNqY2xUeXBlO1xuXG4gIGNvbnN0IGtleUJpdHMgPSBjb2RlYy5iYXNlNjR1cmwudG9CaXRzKGJhc2VTYWx0KTtcbiAgY29uc3QgZGF0YUJpdHMgPSBjb2RlYy51dGY4U3RyaW5nLnRvQml0cyhlbnRlcnByaXNlSWQpO1xuXG4gIGNvbnN0IGhtYWNJbnN0YW5jZSA9IG5ldyBtaXNjLmhtYWMoa2V5Qml0cywgaGFzaC5zaGEyNTYpO1xuICBjb25zdCByZXN1bHRCaXRzID0gaG1hY0luc3RhbmNlLm1hYyhkYXRhQml0cyk7XG5cbiAgcmV0dXJuIGNvZGVjLmJhc2U2NC5mcm9tQml0cyhyZXN1bHRCaXRzKTtcbn1cbiJdfQ==
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVyaXZlRW50ZXJwcmlzZVNhbHQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZGVyaXZlRW50ZXJwcmlzZVNhbHQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFZQSxvREFHQztBQWZELG1DQUFvQztBQUVwQzs7Ozs7Ozs7O0dBU0c7QUFDSCxTQUFnQixvQkFBb0IsQ0FBQyxRQUFnQixFQUFFLFlBQW9CO0lBQ3pFLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUN2RixPQUFPLElBQUEsbUJBQVUsRUFBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUMzRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY3JlYXRlSG1hYyB9IGZyb20gJ2NyeXB0byc7XG5cbi8qKlxuICogRGVyaXZlcyBhbiBlbnRlcnByaXNlLXNjb3BlZCBQUkYgc2FsdCB0byBwcmV2ZW50IGNyb3NzLWVudGVycHJpc2Uga2V5IHJldXNlLlxuICpcbiAqIENvbXB1dGVzIEhNQUMtU0hBMjU2KGtleT1wcmZTYWx0X2Jhc2U2NHVybF9kZWNvZGVkLCBkYXRhPWVudGVycHJpc2VJZF91dGY4KS5cbiAqIFRoZSBiYXNlU2FsdCBtdXN0IGFsd2F5cyBjb21lIGZyb20gdGhlIHNlcnZlciDigJQgbmV2ZXIgZ2VuZXJhdGUgaXQgY2xpZW50LXNpZGUuXG4gKlxuICogQHBhcmFtIGJhc2VTYWx0IC0gU2VydmVyLXByb3ZpZGVkIGJhc2U2NHVybC1lbmNvZGVkIFBSRiBzYWx0XG4gKiBAcGFyYW0gZW50ZXJwcmlzZUlkIC0gRW50ZXJwcmlzZSBpZGVudGlmaWVyXG4gKiBAcmV0dXJucyBIZXgtZW5jb2RlZCBITUFDLVNIQTI1NiBkaWdlc3RcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlcml2ZUVudGVycHJpc2VTYWx0KGJhc2VTYWx0OiBzdHJpbmcsIGVudGVycHJpc2VJZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3Qga2V5Qnl0ZXMgPSBCdWZmZXIuZnJvbShiYXNlU2FsdC5yZXBsYWNlKC8tL2csICcrJykucmVwbGFjZSgvXy9nLCAnLycpLCAnYmFzZTY0Jyk7XG4gIHJldHVybiBjcmVhdGVIbWFjKCdzaGEyNTYnLCBrZXlCeXRlcykudXBkYXRlKGVudGVycHJpc2VJZCkuZGlnZXN0KCdoZXgnKTtcbn1cbiJdfQ==
@@ -0,0 +1,15 @@
1
+ import type { BitGoBase, IWallet } from '@bitgo-beta/sdk-core';
2
+ import type { WebAuthnProvider } from './webAuthnTypes';
3
+ /**
4
+ * Derives a wallet passphrase from a passkey PRF output.
5
+ *
6
+ * Fetches the wallet's user keychain, triggers a WebAuthn assertion with PRF
7
+ * evaluation, and returns a hex-encoded passphrase suitable for use as
8
+ * walletPassphrase in signing calls.
9
+ */
10
+ export declare function derivePasskeyPrfKey(params: {
11
+ bitgo: BitGoBase;
12
+ wallet: IWallet;
13
+ provider: WebAuthnProvider;
14
+ }): Promise<string>;
15
+ //# sourceMappingURL=derivePasskeyPrfKey.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"derivePasskeyPrfKey.d.ts","sourceRoot":"","sources":["../../src/derivePasskeyPrfKey.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAG/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAMxD;;;;;;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,CAwClB"}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.derivePasskeyPrfKey = derivePasskeyPrfKey;
4
+ const prfHelpers_1 = require("./prfHelpers");
5
+ const derivePassword_1 = require("./derivePassword");
6
+ /**
7
+ * Derives a wallet passphrase from a passkey PRF output.
8
+ *
9
+ * Fetches the wallet's user keychain, triggers a WebAuthn assertion with PRF
10
+ * evaluation, and returns a hex-encoded passphrase suitable for use as
11
+ * walletPassphrase in signing calls.
12
+ */
13
+ async function derivePasskeyPrfKey(params) {
14
+ const { bitgo, wallet, provider } = params;
15
+ // Fetch the wallet's user keychain to get webauthnDevices
16
+ const keychain = await wallet.getEncryptedUserKeychain();
17
+ const devices = keychain.webauthnDevices;
18
+ if (!devices || devices.length === 0) {
19
+ throw new Error('No passkey devices available');
20
+ }
21
+ // Build PRF eval map from devices
22
+ const { evalByCredential } = (0, prfHelpers_1.buildEvalByCredential)(devices);
23
+ if (Object.keys(evalByCredential).length === 0) {
24
+ throw new Error('No passkey devices available with a valid PRF salt');
25
+ }
26
+ // Fetch a server-issued assertion challenge
27
+ const { challenge } = (await bitgo
28
+ .get(bitgo.url('/user/otp/webauthn/assertion', 2))
29
+ .result());
30
+ // Trigger WebAuthn assertion with PRF evaluation via the provider (navigator layer)
31
+ const result = await provider.get({
32
+ publicKey: {
33
+ challenge: Buffer.from(challenge, 'base64'),
34
+ },
35
+ evalByCredential,
36
+ });
37
+ // Verify the credential matches a known device
38
+ (0, prfHelpers_1.matchDeviceByCredentialId)(devices, result.credentialId);
39
+ // Derive and return hex-encoded wallet passphrase
40
+ if (!result.prfResult) {
41
+ throw new Error('PRF output was not returned by the authenticator');
42
+ }
43
+ return (0, derivePassword_1.derivePassword)(result.prfResult);
44
+ }
45
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVyaXZlUGFzc2tleVByZktleS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kZXJpdmVQYXNza2V5UHJmS2V5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBZ0JBLGtEQTRDQztBQTNERCw2Q0FBZ0Y7QUFDaEYscURBQWtEO0FBT2xEOzs7Ozs7R0FNRztBQUNJLEtBQUssVUFBVSxtQkFBbUIsQ0FBQyxNQUl6QztJQUNDLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxHQUFHLE1BQU0sQ0FBQztJQUUzQywwREFBMEQ7SUFDMUQsTUFBTSxRQUFRLEdBQUcsTUFBTSxNQUFNLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztJQUN6RCxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsZUFBZSxDQUFDO0lBRXpDLElBQUksQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUNyQyxNQUFNLElBQUksS0FBSyxDQUFDLDhCQUE4QixDQUFDLENBQUM7SUFDbEQsQ0FBQztJQUVELGtDQUFrQztJQUNsQyxNQUFNLEVBQUUsZ0JBQWdCLEVBQUUsR0FBRyxJQUFBLGtDQUFxQixFQUFDLE9BQXNELENBQUMsQ0FBQztJQUUzRyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDL0MsTUFBTSxJQUFJLEtBQUssQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO0lBQ3hFLENBQUM7SUFFRCw0Q0FBNEM7SUFDNUMsTUFBTSxFQUFFLFNBQVMsRUFBRSxHQUFHLENBQUMsTUFBTSxLQUFLO1NBQy9CLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLDhCQUE4QixFQUFFLENBQUMsQ0FBQyxDQUFDO1NBQ2pELE1BQU0sRUFBRSxDQUErQixDQUFDO0lBRTNDLG9GQUFvRjtJQUNwRixNQUFNLE1BQU0sR0FBRyxNQUFNLFFBQVEsQ0FBQyxHQUFHLENBQUM7UUFDaEMsU0FBUyxFQUFFO1lBQ1QsU0FBUyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQztTQUNQO1FBQ3RDLGdCQUFnQjtLQUNqQixDQUFDLENBQUM7SUFFSCwrQ0FBK0M7SUFDL0MsSUFBQSxzQ0FBeUIsRUFBQyxPQUEwRCxFQUFFLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUUzRyxrREFBa0Q7SUFDbEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUN0QixNQUFNLElBQUksS0FBSyxDQUFDLGtEQUFrRCxDQUFDLENBQUM7SUFDdEUsQ0FBQztJQUVELE9BQU8sSUFBQSwrQkFBYyxFQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUMxQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBCaXRHb0Jhc2UsIElXYWxsZXQgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgeyBidWlsZEV2YWxCeUNyZWRlbnRpYWwsIG1hdGNoRGV2aWNlQnlDcmVkZW50aWFsSWQgfSBmcm9tICcuL3ByZkhlbHBlcnMnO1xuaW1wb3J0IHsgZGVyaXZlUGFzc3dvcmQgfSBmcm9tICcuL2Rlcml2ZVBhc3N3b3JkJztcbmltcG9ydCB0eXBlIHsgV2ViQXV0aG5Qcm92aWRlciB9IGZyb20gJy4vd2ViQXV0aG5UeXBlcyc7XG5cbmludGVyZmFjZSBBc3NlcnRpb25DaGFsbGVuZ2VSZXNwb25zZSB7XG4gIGNoYWxsZW5nZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIERlcml2ZXMgYSB3YWxsZXQgcGFzc3BocmFzZSBmcm9tIGEgcGFzc2tleSBQUkYgb3V0cHV0LlxuICpcbiAqIEZldGNoZXMgdGhlIHdhbGxldCdzIHVzZXIga2V5Y2hhaW4sIHRyaWdnZXJzIGEgV2ViQXV0aG4gYXNzZXJ0aW9uIHdpdGggUFJGXG4gKiBldmFsdWF0aW9uLCBhbmQgcmV0dXJucyBhIGhleC1lbmNvZGVkIHBhc3NwaHJhc2Ugc3VpdGFibGUgZm9yIHVzZSBhc1xuICogd2FsbGV0UGFzc3BocmFzZSBpbiBzaWduaW5nIGNhbGxzLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGVyaXZlUGFzc2tleVByZktleShwYXJhbXM6IHtcbiAgYml0Z286IEJpdEdvQmFzZTtcbiAgd2FsbGV0OiBJV2FsbGV0O1xuICBwcm92aWRlcjogV2ViQXV0aG5Qcm92aWRlcjtcbn0pOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCB7IGJpdGdvLCB3YWxsZXQsIHByb3ZpZGVyIH0gPSBwYXJhbXM7XG5cbiAgLy8gRmV0Y2ggdGhlIHdhbGxldCdzIHVzZXIga2V5Y2hhaW4gdG8gZ2V0IHdlYmF1dGhuRGV2aWNlc1xuICBjb25zdCBrZXljaGFpbiA9IGF3YWl0IHdhbGxldC5nZXRFbmNyeXB0ZWRVc2VyS2V5Y2hhaW4oKTtcbiAgY29uc3QgZGV2aWNlcyA9IGtleWNoYWluLndlYmF1dGhuRGV2aWNlcztcblxuICBpZiAoIWRldmljZXMgfHwgZGV2aWNlcy5sZW5ndGggPT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIHBhc3NrZXkgZGV2aWNlcyBhdmFpbGFibGUnKTtcbiAgfVxuXG4gIC8vIEJ1aWxkIFBSRiBldmFsIG1hcCBmcm9tIGRldmljZXNcbiAgY29uc3QgeyBldmFsQnlDcmVkZW50aWFsIH0gPSBidWlsZEV2YWxCeUNyZWRlbnRpYWwoZGV2aWNlcyBhcyBQYXJhbWV0ZXJzPHR5cGVvZiBidWlsZEV2YWxCeUNyZWRlbnRpYWw+WzBdKTtcblxuICBpZiAoT2JqZWN0LmtleXMoZXZhbEJ5Q3JlZGVudGlhbCkubGVuZ3RoID09PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdObyBwYXNza2V5IGRldmljZXMgYXZhaWxhYmxlIHdpdGggYSB2YWxpZCBQUkYgc2FsdCcpO1xuICB9XG5cbiAgLy8gRmV0Y2ggYSBzZXJ2ZXItaXNzdWVkIGFzc2VydGlvbiBjaGFsbGVuZ2VcbiAgY29uc3QgeyBjaGFsbGVuZ2UgfSA9IChhd2FpdCBiaXRnb1xuICAgIC5nZXQoYml0Z28udXJsKCcvdXNlci9vdHAvd2ViYXV0aG4vYXNzZXJ0aW9uJywgMikpXG4gICAgLnJlc3VsdCgpKSBhcyBBc3NlcnRpb25DaGFsbGVuZ2VSZXNwb25zZTtcblxuICAvLyBUcmlnZ2VyIFdlYkF1dGhuIGFzc2VydGlvbiB3aXRoIFBSRiBldmFsdWF0aW9uIHZpYSB0aGUgcHJvdmlkZXIgKG5hdmlnYXRvciBsYXllcilcbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcHJvdmlkZXIuZ2V0KHtcbiAgICBwdWJsaWNLZXk6IHtcbiAgICAgIGNoYWxsZW5nZTogQnVmZmVyLmZyb20oY2hhbGxlbmdlLCAnYmFzZTY0JyksXG4gICAgfSBhcyBQdWJsaWNLZXlDcmVkZW50aWFsUmVxdWVzdE9wdGlvbnMsXG4gICAgZXZhbEJ5Q3JlZGVudGlhbCxcbiAgfSk7XG5cbiAgLy8gVmVyaWZ5IHRoZSBjcmVkZW50aWFsIG1hdGNoZXMgYSBrbm93biBkZXZpY2VcbiAgbWF0Y2hEZXZpY2VCeUNyZWRlbnRpYWxJZChkZXZpY2VzIGFzIFBhcmFtZXRlcnM8dHlwZW9mIG1hdGNoRGV2aWNlQnlDcmVkZW50aWFsSWQ+WzBdLCByZXN1bHQuY3JlZGVudGlhbElkKTtcblxuICAvLyBEZXJpdmUgYW5kIHJldHVybiBoZXgtZW5jb2RlZCB3YWxsZXQgcGFzc3BocmFzZVxuICBpZiAoIXJlc3VsdC5wcmZSZXN1bHQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1BSRiBvdXRwdXQgd2FzIG5vdCByZXR1cm5lZCBieSB0aGUgYXV0aGVudGljYXRvcicpO1xuICB9XG5cbiAgcmV0dXJuIGRlcml2ZVBhc3N3b3JkKHJlc3VsdC5wcmZSZXN1bHQpO1xufVxuIl19
@@ -1,5 +1,8 @@
1
1
  export { derivePassword } from './derivePassword';
2
+ export { registerPasskey } from './registerPasskey';
2
3
  export { deriveEnterpriseSalt } from './deriveEnterpriseSalt';
3
4
  export { buildEvalByCredential, matchDeviceByCredentialId } from './prfHelpers';
5
+ export { removePasskeyFromAccount } from './removePasskeyFromAccount';
4
6
  export type { WebAuthnOtpDevice, PasskeyAuthResult, PasskeyGetOptions, WebAuthnProvider } from './webAuthnTypes';
7
+ export { removePasskeyFromWallet } from './removePasskeyFromWallet';
5
8
  //# 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,kBAAkB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,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,iBAAiB,CAAC;AACjH,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC"}
package/dist/src/index.js CHANGED
@@ -1,11 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.matchDeviceByCredentialId = exports.buildEvalByCredential = exports.deriveEnterpriseSalt = exports.derivePassword = void 0;
3
+ exports.removePasskeyFromWallet = exports.removePasskeyFromAccount = exports.matchDeviceByCredentialId = exports.buildEvalByCredential = exports.deriveEnterpriseSalt = exports.registerPasskey = exports.derivePassword = void 0;
4
4
  var derivePassword_1 = require("./derivePassword");
5
5
  Object.defineProperty(exports, "derivePassword", { enumerable: true, get: function () { return derivePassword_1.derivePassword; } });
6
+ var registerPasskey_1 = require("./registerPasskey");
7
+ Object.defineProperty(exports, "registerPasskey", { enumerable: true, get: function () { return registerPasskey_1.registerPasskey; } });
6
8
  var deriveEnterpriseSalt_1 = require("./deriveEnterpriseSalt");
7
9
  Object.defineProperty(exports, "deriveEnterpriseSalt", { enumerable: true, get: function () { return deriveEnterpriseSalt_1.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
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbURBQWtEO0FBQXpDLGdIQUFBLGNBQWMsT0FBQTtBQUN2QixxREFBb0Q7QUFBM0Msa0hBQUEsZUFBZSxPQUFBO0FBQ3hCLCtEQUE4RDtBQUFyRCw0SEFBQSxvQkFBb0IsT0FBQTtBQUM3QiwyQ0FBZ0Y7QUFBdkUsbUhBQUEscUJBQXFCLE9BQUE7QUFBRSx1SEFBQSx5QkFBeUIsT0FBQTtBQUN6RCx1RUFBc0U7QUFBN0Qsb0lBQUEsd0JBQXdCLE9BQUE7QUFFakMscUVBQW9FO0FBQTNELGtJQUFBLHVCQUF1QixPQUFBIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHsgZGVyaXZlUGFzc3dvcmQgfSBmcm9tICcuL2Rlcml2ZVBhc3N3b3JkJztcbmV4cG9ydCB7IHJlZ2lzdGVyUGFzc2tleSB9IGZyb20gJy4vcmVnaXN0ZXJQYXNza2V5JztcbmV4cG9ydCB7IGRlcml2ZUVudGVycHJpc2VTYWx0IH0gZnJvbSAnLi9kZXJpdmVFbnRlcnByaXNlU2FsdCc7XG5leHBvcnQgeyBidWlsZEV2YWxCeUNyZWRlbnRpYWwsIG1hdGNoRGV2aWNlQnlDcmVkZW50aWFsSWQgfSBmcm9tICcuL3ByZkhlbHBlcnMnO1xuZXhwb3J0IHsgcmVtb3ZlUGFzc2tleUZyb21BY2NvdW50IH0gZnJvbSAnLi9yZW1vdmVQYXNza2V5RnJvbUFjY291bnQnO1xuZXhwb3J0IHR5cGUgeyBXZWJBdXRobk90cERldmljZSwgUGFzc2tleUF1dGhSZXN1bHQsIFBhc3NrZXlHZXRPcHRpb25zLCBXZWJBdXRoblByb3ZpZGVyIH0gZnJvbSAnLi93ZWJBdXRoblR5cGVzJztcbmV4cG9ydCB7IHJlbW92ZVBhc3NrZXlGcm9tV2FsbGV0IH0gZnJvbSAnLi9yZW1vdmVQYXNza2V5RnJvbVdhbGxldCc7XG4iXX0=
@@ -0,0 +1,10 @@
1
+ import { BitGoBase } from '@bitgo-beta/sdk-core';
2
+ import { WebAuthnOtpDevice, WebAuthnProvider } from './webAuthnTypes';
3
+ export declare function registerPasskey(params: {
4
+ bitgo: BitGoBase;
5
+ provider: WebAuthnProvider;
6
+ label: string;
7
+ }): Promise<WebAuthnOtpDevice & {
8
+ prfSupported: boolean;
9
+ }>;
10
+ //# 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,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAyEtE,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,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerPasskey = registerPasskey;
4
+ /** Encodes an ArrayBuffer as a base64url string (no padding). */
5
+ function encodeBase64Url(buffer) {
6
+ return Buffer.from(buffer).toString('base64').replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
7
+ }
8
+ /**
9
+ * Recursively converts a PublicKeyCredential (or any value it contains) to a
10
+ * JSON-serialisable representation, encoding ArrayBuffers as base64url strings.
11
+ */
12
+ function publicKeyCredentialToJSON(value) {
13
+ if (Array.isArray(value)) {
14
+ return value.map(publicKeyCredentialToJSON);
15
+ }
16
+ if (value instanceof ArrayBuffer) {
17
+ return encodeBase64Url(value);
18
+ }
19
+ if (ArrayBuffer.isView(value)) {
20
+ return encodeBase64Url(value.buffer);
21
+ }
22
+ if (value instanceof Object) {
23
+ const result = {};
24
+ // Use for...in to enumerate DOM object properties (non-enumerable own + inherited)
25
+ for (const key in value) {
26
+ result[key] = publicKeyCredentialToJSON(value[key]);
27
+ }
28
+ return result;
29
+ }
30
+ return value;
31
+ }
32
+ /**
33
+ * Decodes excluded credential IDs from base64 strings to ArrayBuffers.
34
+ * The WebAuthn API requires BufferSource values, not base64 strings.
35
+ */
36
+ function preformatExcludedCredentials(excludeCredentials) {
37
+ if (!excludeCredentials)
38
+ return [];
39
+ return excludeCredentials.map((cred) => ({
40
+ ...cred,
41
+ id: Buffer.from(cred.id, 'base64'),
42
+ }));
43
+ }
44
+ async function registerPasskey(params) {
45
+ const { bitgo, provider, label } = params;
46
+ // Step 1: Fetch server challenge (contains baseSalt)
47
+ const challenge = (await bitgo
48
+ .get(bitgo.url('/user/otp/webauthn/register', 2))
49
+ .result());
50
+ // Step 2: Pass formatted challenge to provider.create() — browser returns attestation
51
+ const attestation = await provider.create({
52
+ challenge: Buffer.from(challenge.challenge, 'base64'),
53
+ rp: challenge.rp,
54
+ user: challenge.user,
55
+ pubKeyCredParams: challenge.pubKeyCredParams,
56
+ timeout: challenge.timeout,
57
+ excludeCredentials: preformatExcludedCredentials(challenge.excludeCredentials),
58
+ authenticatorSelection: challenge.authenticatorSelection,
59
+ attestation: challenge.attestation,
60
+ extensions: challenge.extensions,
61
+ });
62
+ // Step 3: Check if PRF is supported — `prf.enabled` is set during registration
63
+ // (not `prf.results.first`, which is only present during authentication assertions)
64
+ const clientExtensionResults = attestation.getClientExtensionResults();
65
+ const prfEnabled = clientExtensionResults.prf;
66
+ const prfSupported = typeof prfEnabled === 'object' && prfEnabled !== null && prfEnabled.enabled === true;
67
+ // Step 4: Serialize the full credential using recursive base64url encoding
68
+ const otp = JSON.stringify(publicKeyCredentialToJSON(attestation));
69
+ const putBody = {
70
+ otp,
71
+ type: 'webauthn',
72
+ label,
73
+ };
74
+ if (prfSupported) {
75
+ putBody.extensions = ['prf'];
76
+ putBody.scopes = ['wallet_hot'];
77
+ }
78
+ // Step 5: PUT /api/v2/user/otp
79
+ const response = (await bitgo.put(bitgo.url('/user/otp', 2)).send(putBody).result());
80
+ // Step 6: Find the newly registered device by matching credentialId
81
+ const device = response.user.otpDevices.find((d) => d.credentialId === attestation.id);
82
+ if (!device) {
83
+ const available = response.user.otpDevices.map((d) => d.credentialId).join(', ');
84
+ throw new Error(`Registered device not found in response (credentialId: ${attestation.id}). Available: [${available}]`);
85
+ }
86
+ // Step 7: Return WebAuthnOtpDevice + prfSupported
87
+ return {
88
+ id: device.id,
89
+ credentialId: device.credentialId,
90
+ prfSalt: device.prfSalt,
91
+ isPasskey: device.isPasskey,
92
+ extensions: device.extensions,
93
+ prfSupported,
94
+ };
95
+ }
96
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaXN0ZXJQYXNza2V5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3JlZ2lzdGVyUGFzc2tleS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQTBFQSwwQ0FrRUM7QUE5R0QsaUVBQWlFO0FBQ2pFLFNBQVMsZUFBZSxDQUFDLE1BQW1CO0lBQzFDLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDMUcsQ0FBQztBQUVEOzs7R0FHRztBQUNILFNBQVMseUJBQXlCLENBQUMsS0FBYztJQUMvQyxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUN6QixPQUFPLEtBQUssQ0FBQyxHQUFHLENBQUMseUJBQXlCLENBQUMsQ0FBQztJQUM5QyxDQUFDO0lBQ0QsSUFBSSxLQUFLLFlBQVksV0FBVyxFQUFFLENBQUM7UUFDakMsT0FBTyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDaEMsQ0FBQztJQUNELElBQUksV0FBVyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQzlCLE9BQU8sZUFBZSxDQUFDLEtBQUssQ0FBQyxNQUFxQixDQUFDLENBQUM7SUFDdEQsQ0FBQztJQUNELElBQUksS0FBSyxZQUFZLE1BQU0sRUFBRSxDQUFDO1FBQzVCLE1BQU0sTUFBTSxHQUE0QixFQUFFLENBQUM7UUFDM0MsbUZBQW1GO1FBQ25GLEtBQUssTUFBTSxHQUFHLElBQUksS0FBSyxFQUFFLENBQUM7WUFDeEIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLHlCQUF5QixDQUFFLEtBQWlDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztR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QUMsTUFBTSxFQUFFLENBQUM7UUFDWixNQUFNLFNBQVMsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDakYsTUFBTSxJQUFJLEtBQUssQ0FDYiwwREFBMEQsV0FBVyxDQUFDLEVBQUUsa0JBQWtCLFNBQVMsR0FBRyxDQUN2RyxDQUFDO0lBQ0osQ0FBQztJQUVELGtEQUFrRDtJQUNsRCxPQUFPO1FBQ0wsRUFBRSxFQUFFLE1BQU0sQ0FBQyxFQUFFO1FBQ2IsWUFBWSxFQUFFLE1BQU0sQ0FBQyxZQUFZO1FBQ2pDLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTztRQUN2QixTQUFTLEVBQUUsTUFBTSxDQUFDLFNBQVM7UUFDM0IsVUFBVSxFQUFFLE1BQU0sQ0FBQyxVQUFVO1FBQzdCLFlBQVk7S0FDYixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEJpdEdvQmFzZSB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcbmltcG9ydCB7IFdlYkF1dGhuT3RwRGV2aWNlLCBXZWJBdXRoblByb3ZpZGVyIH0gZnJvbSAnLi93ZWJBdXRoblR5cGVzJztcblxuaW50ZXJmYWNlIFJlZ2lzdGVyQ2hhbGxlbmdlUmVzcG9uc2Uge1xuICBjaGFsbGVuZ2U6IHN0cmluZztcbiAgYmFzZVNhbHQ6IHN0cmluZztcbiAgcnA6IFB1YmxpY0tleUNyZWRlbnRpYWxScEVudGl0eTtcbiAgdXNlcjogUHVibGljS2V5Q3JlZGVudGlhbFVzZXJFbnRpdHk7XG4gIHB1YktleUNyZWRQYXJhbXM6IFB1YmxpY0tleUNyZWRlbnRpYWxQYXJhbWV0ZXJzW107XG4gIHRpbWVvdXQ/OiBudW1iZXI7XG4gIGV4Y2x1ZGVDcmVkZW50aWFscz86IFB1YmxpY0tleUNyZWRlbnRpYWxEZXNjcmlwdG9yW107XG4gIGF1dGhlbnRpY2F0b3JTZWxlY3Rpb24/OiBBdXRoZW50aWNhdG9yU2VsZWN0aW9uQ3JpdGVyaWE7XG4gIGF0dGVzdGF0aW9uPzogQXR0ZXN0YXRpb25Db252ZXlhbmNlUHJlZmVyZW5jZTtcbiAgZXh0ZW5zaW9ucz86IEF1dGhlbnRpY2F0aW9uRXh0ZW5zaW9uc0NsaWVudElucHV0cztcbn1cblxuaW50ZXJmYWNlIE90cERldmljZSB7XG4gIGlkOiBzdHJpbmc7XG4gIGNyZWRlbnRpYWxJZDogc3RyaW5nO1xuICBwcmZTYWx0Pzogc3RyaW5nO1xuICBpc1Bhc3NrZXk/OiBib29sZWFuO1xuICBleHRlbnNpb25zPzogUmVjb3JkPHN0cmluZywgYm9vbGVhbj47XG59XG5cbmludGVyZmFjZSBSZWdpc3Rlck90cFJlc3BvbnNlIHtcbiAgdXNlcjoge1xuICAgIG90cERldmljZXM6IE90cERldmljZVtdO1xuICB9O1xufVxuXG4vKiogRW5jb2RlcyBhbiBBcnJheUJ1ZmZlciBhcyBhIGJhc2U2NHVybCBzdHJpbmcgKG5vIHBhZGRpbmcpLiAqL1xuZnVuY3Rpb24gZW5jb2RlQmFzZTY0VXJsKGJ1ZmZlcjogQXJyYXlCdWZmZXIpOiBzdHJpbmcge1xuICByZXR1cm4gQnVmZmVyLmZyb20oYnVmZmVyKS50b1N0cmluZygnYmFzZTY0JykucmVwbGFjZSgvPS9nLCAnJykucmVwbGFjZSgvXFwrL2csICctJykucmVwbGFjZSgvXFwvL2csICdfJyk7XG59XG5cbi8qKlxuICogUmVjdXJzaXZlbHkgY29udmVydHMgYSBQdWJsaWNLZXlDcmVkZW50aWFsIChvciBhbnkgdmFsdWUgaXQgY29udGFpbnMpIHRvIGFcbiAqIEpTT04tc2VyaWFsaXNhYmxlIHJlcHJlc2VudGF0aW9uLCBlbmNvZGluZyBBcnJheUJ1ZmZlcnMgYXMgYmFzZTY0dXJsIHN0cmluZ3MuXG4gKi9cbmZ1bmN0aW9uIHB1YmxpY0tleUNyZWRlbnRpYWxUb0pTT04odmFsdWU6IHVua25vd24pOiB1bmtub3duIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgcmV0dXJuIHZhbHVlLm1hcChwdWJsaWNLZXlDcmVkZW50aWFsVG9KU09OKTtcbiAgfVxuICBpZiAodmFsdWUgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikge1xuICAgIHJldHVybiBlbmNvZGVCYXNlNjRVcmwodmFsdWUpO1xuICB9XG4gIGlmIChBcnJheUJ1ZmZlci5pc1ZpZXcodmFsdWUpKSB7XG4gICAgcmV0dXJuIGVuY29kZUJhc2U2NFVybCh2YWx1ZS5idWZmZXIgYXMgQXJyYXlCdWZmZXIpO1xuICB9XG4gIGlmICh2YWx1ZSBpbnN0YW5jZW9mIE9iamVjdCkge1xuICAgIGNvbnN0IHJlc3VsdDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcbiAgICAvLyBVc2UgZm9yLi4uaW4gdG8gZW51bWVyYXRlIERPTSBvYmplY3QgcHJvcGVydGllcyAobm9uLWVudW1lcmFibGUgb3duICsgaW5oZXJpdGVkKVxuICAgIGZvciAoY29uc3Qga2V5IGluIHZhbHVlKSB7XG4gICAgICByZXN1bHRba2V5XSA9IHB1YmxpY0tleUNyZWRlbnRpYWxUb0pTT04oKHZhbHVlIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KVtrZXldKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59XG5cbi8qKlxuICogRGVjb2RlcyBleGNsdWRlZCBjcmVkZW50aWFsIElEcyBmcm9tIGJhc2U2NCBzdHJpbmdzIHRvIEFycmF5QnVmZmVycy5cbiAqIFRoZSBXZWJBdXRobiBBUEkgcmVxdWlyZXMgQnVmZmVyU291cmNlIHZhbHVlcywgbm90IGJhc2U2NCBzdHJpbmdzLlxuICovXG5mdW5jdGlvbiBwcmVmb3JtYXRFeGNsdWRlZENyZWRlbnRpYWxzKFxuICBleGNsdWRlQ3JlZGVudGlhbHM6IFB1YmxpY0tleUNyZWRlbnRpYWxEZXNjcmlwdG9yW10gfCB1bmRlZmluZWRcbik6IFB1YmxpY0tleUNyZWRlbnRpYWxEZXNjcmlwdG9yW10ge1xuICBpZiAoIWV4Y2x1ZGVDcmVkZW50aWFscykgcmV0dXJuIFtdO1xuICByZXR1cm4gZXhjbHVkZUNyZWRlbnRpYWxzLm1hcCgoY3JlZCkgPT4gKHtcbiAgICAuLi5jcmVkLFxuICAgIGlkOiBCdWZmZXIuZnJvbShjcmVkLmlkIGFzIHVua25vd24gYXMgc3RyaW5nLCAnYmFzZTY0JykgYXMgdW5rbm93biBhcyBBcnJheUJ1ZmZlcixcbiAgfSkpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVnaXN0ZXJQYXNza2V5KHBhcmFtczoge1xuICBiaXRnbzogQml0R29CYXNlO1xuICBwcm92aWRlcjogV2ViQXV0aG5Qcm92aWRlcjtcbiAgbGFiZWw6IHN0cmluZztcbn0pOiBQcm9taXNlPFdlYkF1dGhuT3RwRGV2aWNlICYgeyBwcmZTdXBwb3J0ZWQ6IGJvb2xlYW4gfT4ge1xuICBjb25zdCB7IGJpdGdvLCBwcm92aWRlciwgbGFiZWwgfSA9IHBhcmFtcztcblxuICAvLyBTdGVwIDE6IEZldGNoIHNlcnZlciBjaGFsbGVuZ2UgKGNvbnRhaW5zIGJhc2VTYWx0KVxuICBjb25zdCBjaGFsbGVuZ2UgPSAoYXdhaXQgYml0Z29cbiAgICAuZ2V0KGJpdGdvLnVybCgnL3VzZXIvb3RwL3dlYmF1dGhuL3JlZ2lzdGVyJywgMikpXG4gICAgLnJlc3VsdCgpKSBhcyBSZWdpc3RlckNoYWxsZW5nZVJlc3BvbnNlO1xuXG4gIC8vIFN0ZXAgMjogUGFzcyBmb3JtYXR0ZWQgY2hhbGxlbmdlIHRvIHByb3ZpZGVyLmNyZWF0ZSgpIOKAlCBicm93c2VyIHJldHVybnMgYXR0ZXN0YXRpb25cbiAgY29uc3QgYXR0ZXN0YXRpb24gPSBhd2FpdCBwcm92aWRlci5jcmVhdGUoe1xuICAgIGNoYWxsZW5nZTogQnVmZmVyLmZyb20oY2hhbGxlbmdlLmNoYWxsZW5nZSwgJ2Jhc2U2NCcpLFxuICAgIHJwOiBjaGFsbGVuZ2UucnAsXG4gICAgdXNlcjogY2hhbGxlbmdlLnVzZXIsXG4gICAgcHViS2V5Q3JlZFBhcmFtczogY2hhbGxlbmdlLnB1YktleUNyZWRQYXJhbXMsXG4gICAgdGltZW91dDogY2hhbGxlbmdlLnRpbWVvdXQsXG4gICAgZXhjbHVkZUNyZWRlbnRpYWxzOiBwcmVmb3JtYXRFeGNsdWRlZENyZWRlbnRpYWxzKGNoYWxsZW5nZS5leGNsdWRlQ3JlZGVudGlhbHMpLFxuICAgIGF1dGhlbnRpY2F0b3JTZWxlY3Rpb246IGNoYWxsZW5nZS5hdXRoZW50aWNhdG9yU2VsZWN0aW9uLFxuICAgIGF0dGVzdGF0aW9uOiBjaGFsbGVuZ2UuYXR0ZXN0YXRpb24sXG4gICAgZXh0ZW5zaW9uczogY2hhbGxlbmdlLmV4dGVuc2lvbnMsXG4gIH0pO1xuXG4gIC8vIFN0ZXAgMzogQ2hlY2sgaWYgUFJGIGlzIHN1cHBvcnRlZCDigJQgYHByZi5lbmFibGVkYCBpcyBzZXQgZHVyaW5nIHJlZ2lzdHJhdGlvblxuICAvLyAobm90IGBwcmYucmVzdWx0cy5maXJzdGAsIHdoaWNoIGlzIG9ubHkgcHJlc2VudCBkdXJpbmcgYXV0aGVudGljYXRpb24gYXNzZXJ0aW9ucylcbiAgY29uc3QgY2xpZW50RXh0ZW5zaW9uUmVzdWx0czogQXV0aGVudGljYXRpb25FeHRlbnNpb25zQ2xpZW50T3V0cHV0cyA9IGF0dGVzdGF0aW9uLmdldENsaWVudEV4dGVuc2lvblJlc3VsdHMoKTtcbiAgY29uc3QgcHJmRW5hYmxlZCA9IGNsaWVudEV4dGVuc2lvblJlc3VsdHMucHJmO1xuICBjb25zdCBwcmZTdXBwb3J0ZWQgPSB0eXBlb2YgcHJmRW5hYmxlZCA9PT0gJ29iamVjdCcgJiYgcHJmRW5hYmxlZCAhPT0gbnVsbCAmJiBwcmZFbmFibGVkLmVuYWJsZWQgPT09IHRydWU7XG5cbiAgLy8gU3RlcCA0OiBTZXJpYWxpemUgdGhlIGZ1bGwgY3JlZGVudGlhbCB1c2luZyByZWN1cnNpdmUgYmFzZTY0dXJsIGVuY29kaW5nXG4gIGNvbnN0IG90cCA9IEpTT04uc3RyaW5naWZ5KHB1YmxpY0tleUNyZWRlbnRpYWxUb0pTT04oYXR0ZXN0YXRpb24pKTtcblxuICBjb25zdCBwdXRCb2R5OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHtcbiAgICBvdHAsXG4gICAgdHlwZTogJ3dlYmF1dGhuJyxcbiAgICBsYWJlbCxcbiAgfTtcblxuICBpZiAocHJmU3VwcG9ydGVkKSB7XG4gICAgcHV0Qm9keS5leHRlbnNpb25zID0gWydwcmYnXTtcbiAgICBwdXRCb2R5LnNjb3BlcyA9IFsnd2FsbGV0X2hvdCddO1xuICB9XG5cbiAgLy8gU3RlcCA1OiBQVVQgL2FwaS92Mi91c2VyL290cFxuICBjb25zdCByZXNwb25zZSA9IChhd2FpdCBiaXRnby5wdXQoYml0Z28udXJsKCcvdXNlci9vdHAnLCAyKSkuc2VuZChwdXRCb2R5KS5yZXN1bHQoKSkgYXMgUmVnaXN0ZXJPdHBSZXNwb25zZTtcblxuICAvLyBTdGVwIDY6IEZpbmQgdGhlIG5ld2x5IHJlZ2lzdGVyZWQgZGV2aWNlIGJ5IG1hdGNoaW5nIGNyZWRlbnRpYWxJZFxuICBjb25zdCBkZXZpY2UgPSByZXNwb25zZS51c2VyLm90cERldmljZXMuZmluZCgoZCkgPT4gZC5jcmVkZW50aWFsSWQgPT09IGF0dGVzdGF0aW9uLmlkKTtcbiAgaWYgKCFkZXZpY2UpIHtcbiAgICBjb25zdCBhdmFpbGFibGUgPSByZXNwb25zZS51c2VyLm90cERldmljZXMubWFwKChkKSA9PiBkLmNyZWRlbnRpYWxJZCkuam9pbignLCAnKTtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgUmVnaXN0ZXJlZCBkZXZpY2Ugbm90IGZvdW5kIGluIHJlc3BvbnNlIChjcmVkZW50aWFsSWQ6ICR7YXR0ZXN0YXRpb24uaWR9KS4gQXZhaWxhYmxlOiBbJHthdmFpbGFibGV9XWBcbiAgICApO1xuICB9XG5cbiAgLy8gU3RlcCA3OiBSZXR1cm4gV2ViQXV0aG5PdHBEZXZpY2UgKyBwcmZTdXBwb3J0ZWRcbiAgcmV0dXJuIHtcbiAgICBpZDogZGV2aWNlLmlkLFxuICAgIGNyZWRlbnRpYWxJZDogZGV2aWNlLmNyZWRlbnRpYWxJZCxcbiAgICBwcmZTYWx0OiBkZXZpY2UucHJmU2FsdCxcbiAgICBpc1Bhc3NrZXk6IGRldmljZS5pc1Bhc3NrZXksXG4gICAgZXh0ZW5zaW9uczogZGV2aWNlLmV4dGVuc2lvbnMsXG4gICAgcHJmU3VwcG9ydGVkLFxuICB9O1xufVxuIl19
@@ -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,10 @@
1
+ import { BitGoBase } from '@bitgo-beta/sdk-core';
2
+ import { WebAuthnOtpDevice } from './webAuthnTypes';
3
+ export declare function removePasskeyFromWallet(params: {
4
+ bitgo: BitGoBase;
5
+ coin: string;
6
+ walletId: string;
7
+ device: WebAuthnOtpDevice;
8
+ walletPassphrase: string;
9
+ }): Promise<void>;
10
+ //# 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,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD,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 = (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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVtb3ZlUGFzc2tleUZyb21XYWxsZXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcmVtb3ZlUGFzc2tleUZyb21XYWxsZXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFHQSwwREEwQkM7QUE3QkQsbURBQTRFO0FBR3JFLEtBQUssVUFBVSx1QkFBdUIsQ0FBQyxNQU03QztJQUNDLE1BQU0sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLGdCQUFnQixFQUFFLEdBQUcsTUFBTSxDQUFDO0lBRTdFLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDZixNQUFNLElBQUksS0FBSyxDQUFDLDJEQUEyRCxDQUFDLENBQUM7SUFDL0UsQ0FBQztJQUVELE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDdEMsTUFBTSxNQUFNLEdBQUcsTUFBTSxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7SUFDOUQsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3RDLE1BQU0sUUFBUSxHQUFHLE1BQU0sUUFBUSxDQUFDLFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsRUFBRSxVQUFVLEVBQUUsQ0FBQyxDQUFDO0lBRXBFLHdDQUF3QztJQUN4QyxNQUFNLFNBQVMsR0FBRyxJQUFBLG9DQUF5QixFQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztJQUMvRSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDZixNQUFNLElBQUksS0FBSyxDQUFDLDBFQUEwRSxDQUFDLENBQUM7SUFDOUYsQ0FBQztJQUVELG9FQUFvRTtJQUNwRSxNQUFNLEtBQUssQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxRQUFRLFVBQVUsbUJBQW1CLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO0FBQzNGLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBCaXRHb0Jhc2UsIGRlY3J5cHRLZXljaGFpblByaXZhdGVLZXkgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgeyBXZWJBdXRobk90cERldmljZSB9IGZyb20gJy4vd2ViQXV0aG5UeXBlcyc7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZW1vdmVQYXNza2V5RnJvbVdhbGxldChwYXJhbXM6IHtcbiAgYml0Z286IEJpdEdvQmFzZTtcbiAgY29pbjogc3RyaW5nO1xuICB3YWxsZXRJZDogc3RyaW5nO1xuICBkZXZpY2U6IFdlYkF1dGhuT3RwRGV2aWNlO1xuICB3YWxsZXRQYXNzcGhyYXNlOiBzdHJpbmc7XG59KTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHsgYml0Z28sIGNvaW46IGNvaW5OYW1lLCB3YWxsZXRJZCwgZGV2aWNlLCB3YWxsZXRQYXNzcGhyYXNlIH0gPSBwYXJhbXM7XG5cbiAgaWYgKCFkZXZpY2UuaWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2RldmljZS5pZCBpcyByZXF1aXJlZCB0byByZW1vdmUgYSBwYXNza2V5IGZyb20gdGhlIHdhbGxldCcpO1xuICB9XG5cbiAgY29uc3QgYmFzZUNvaW4gPSBiaXRnby5jb2luKGNvaW5OYW1lKTtcbiAgY29uc3Qgd2FsbGV0ID0gYXdhaXQgYmFzZUNvaW4ud2FsbGV0cygpLmdldCh7IGlkOiB3YWxsZXRJZCB9KTtcbiAgY29uc3Qga2V5Y2hhaW5JZCA9IHdhbGxldC5rZXlJZHMoKVswXTtcbiAgY29uc3Qga2V5Y2hhaW4gPSBhd2FpdCBiYXNlQ29pbi5rZXljaGFpbnMoKS5nZXQoeyBpZDoga2V5Y2hhaW5JZCB9KTtcblxuICAvLyBWZXJpZnkgcGFzc3BocmFzZSBiZWZvcmUgYW55IG11dGF0aW9uXG4gIGNvbnN0IGRlY3J5cHRlZCA9IGRlY3J5cHRLZXljaGFpblByaXZhdGVLZXkoYml0Z28sIGtleWNoYWluLCB3YWxsZXRQYXNzcGhyYXNlKTtcbiAgaWYgKCFkZWNyeXB0ZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0luY29ycmVjdCB3YWxsZXQgcGFzc3BocmFzZS4gUGFzc2tleSByZW1vdmFsIGFib3J0ZWQgdG8gcHJldmVudCBsb2Nrb3V0LicpO1xuICB9XG5cbiAgLy8gTm8gc2RrLWNvcmUgYWJzdHJhY3Rpb24gZm9yIHRoaXMgZW5kcG9pbnQ7IHJhdyBERUxFVEUgaXMgcmVxdWlyZWRcbiAgYXdhaXQgYml0Z28uZGVsKGJpdGdvLnVybChgL2tleS8ke2tleWNoYWluSWR9L3dlYmF1dGhuZGV2aWNlLyR7ZGV2aWNlLmlkfWAsIDIpKS5yZXN1bHQoKTtcbn1cbiJdfQ==
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=attachPasskeyToWallet.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachPasskeyToWallet.test.d.ts","sourceRoot":"","sources":["../../../test/unit/attachPasskeyToWallet.test.ts"],"names":[],"mappings":""}