@bitgo-beta/sdk-core 8.2.1-beta.1690 → 8.2.1-beta.1692

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.
@@ -0,0 +1,2 @@
1
+ import 'should';
2
+ //# sourceMappingURL=walletsWebauthn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"walletsWebauthn.d.ts","sourceRoot":"","sources":["../../../../../test/unit/bitgo/wallet/walletsWebauthn.ts"],"names":[],"mappings":"AAEA,OAAO,QAAQ,CAAC"}
@@ -0,0 +1,197 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const assert = __importStar(require("assert"));
37
+ const sinon = __importStar(require("sinon"));
38
+ require("should");
39
+ const wallets_1 = require("../../../../src/bitgo/wallet/wallets");
40
+ describe('Wallets - WebAuthn wallet creation', function () {
41
+ let wallets;
42
+ let mockBitGo;
43
+ let mockBaseCoin;
44
+ let mockKeychains;
45
+ const userPrv = 'xprvSomeUserPrivateKey';
46
+ const userPub = 'xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8';
47
+ const backupPub = 'xpub661MyMwAqRbcGczjuMoRm6dXaLDEhW1u34gKenbeYqAix21mdUKJyuyu5F1rzYGVxyL6tmgBUAEPrEz92mBXjByMRiJdba9wpnN37RLLAXa';
48
+ const bitgoPub = 'xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6LBpB85b3D2yc8sfvZU521AAwdZafEz7mnzBBsz4wKY5fTtTQBm';
49
+ beforeEach(function () {
50
+ mockKeychains = {
51
+ create: sinon.stub().returns({ pub: userPub, prv: userPrv }),
52
+ add: sinon.stub().resolves({ id: 'user-key-id', pub: userPub, encryptedPrv: 'encrypted-prv' }),
53
+ createBackup: sinon.stub().resolves({ id: 'backup-key-id', pub: backupPub }),
54
+ createBitGo: sinon.stub().resolves({ id: 'bitgo-key-id', pub: bitgoPub }),
55
+ };
56
+ const mockWalletData = { id: 'wallet-id', keys: ['user-key-id', 'backup-key-id', 'bitgo-key-id'] };
57
+ mockBitGo = {
58
+ post: sinon.stub().returns({
59
+ send: sinon.stub().returns({
60
+ result: sinon.stub().resolves(mockWalletData),
61
+ }),
62
+ }),
63
+ encrypt: sinon
64
+ .stub()
65
+ .callsFake(({ password, input }) => `encrypted:${password}:${input}`),
66
+ setRequestTracer: sinon.stub(),
67
+ };
68
+ mockBaseCoin = {
69
+ isEVM: sinon.stub().returns(false),
70
+ supportsTss: sinon.stub().returns(false),
71
+ getFamily: sinon.stub().returns('btc'),
72
+ getDefaultMultisigType: sinon.stub().returns('onchain'),
73
+ keychains: sinon.stub().returns(mockKeychains),
74
+ url: sinon.stub().returns('/test/url'),
75
+ isValidMofNSetup: sinon.stub().returns(true),
76
+ getConfig: sinon.stub().returns({ features: [] }),
77
+ supplementGenerateWallet: sinon.stub().callsFake((params) => Promise.resolve(params)),
78
+ signMessage: sinon.stub().resolves(Buffer.from('aabbcc', 'hex')),
79
+ };
80
+ wallets = new wallets_1.Wallets(mockBitGo, mockBaseCoin);
81
+ });
82
+ afterEach(function () {
83
+ sinon.restore();
84
+ });
85
+ describe('generateWallet with webauthnInfo', function () {
86
+ it('should add webauthnDevices to keychain params when webauthnInfo is provided', async function () {
87
+ const webauthnInfo = {
88
+ otpDeviceId: 'device-123',
89
+ prfSalt: 'salt-abc',
90
+ passphrase: 'prf-derived-passphrase',
91
+ };
92
+ await wallets.generateWallet({
93
+ label: 'Test Wallet',
94
+ passphrase: 'wallet-passphrase',
95
+ webauthnInfo,
96
+ });
97
+ assert.strictEqual(mockKeychains.add.calledOnce, true);
98
+ const addParams = mockKeychains.add.firstCall.args[0];
99
+ addParams.should.have.property('webauthnDevices');
100
+ addParams.webauthnDevices.should.have.length(1);
101
+ addParams.webauthnDevices[0].should.have.property('otpDeviceId', webauthnInfo.otpDeviceId);
102
+ addParams.webauthnDevices[0].should.have.property('prfSalt', webauthnInfo.prfSalt);
103
+ addParams.webauthnDevices[0].should.have.property('encryptedPrv');
104
+ });
105
+ it('should encrypt user private key with the webauthn passphrase', async function () {
106
+ const webauthnPassphrase = 'prf-derived-passphrase';
107
+ await wallets.generateWallet({
108
+ label: 'Test Wallet',
109
+ passphrase: 'wallet-passphrase',
110
+ webauthnInfo: {
111
+ otpDeviceId: 'device-123',
112
+ prfSalt: 'salt-abc',
113
+ passphrase: webauthnPassphrase,
114
+ },
115
+ });
116
+ const addParams = mockKeychains.add.firstCall.args[0];
117
+ const expectedEncryptedPrv = `encrypted:${webauthnPassphrase}:${userPrv}`;
118
+ addParams.webauthnDevices[0].should.have.property('encryptedPrv', expectedEncryptedPrv);
119
+ });
120
+ it('should also encrypt user private key with wallet passphrase when webauthnInfo is provided', async function () {
121
+ const walletPassphrase = 'wallet-passphrase';
122
+ await wallets.generateWallet({
123
+ label: 'Test Wallet',
124
+ passphrase: walletPassphrase,
125
+ webauthnInfo: {
126
+ otpDeviceId: 'device-123',
127
+ prfSalt: 'salt-abc',
128
+ passphrase: 'prf-derived-passphrase',
129
+ },
130
+ });
131
+ const addParams = mockKeychains.add.firstCall.args[0];
132
+ const expectedEncryptedPrv = `encrypted:${walletPassphrase}:${userPrv}`;
133
+ addParams.should.have.property('encryptedPrv', expectedEncryptedPrv);
134
+ });
135
+ it('should use separate encrypt calls for wallet passphrase and webauthn passphrase', async function () {
136
+ const walletPassphrase = 'wallet-passphrase';
137
+ const webauthnPassphrase = 'prf-derived-passphrase';
138
+ await wallets.generateWallet({
139
+ label: 'Test Wallet',
140
+ passphrase: walletPassphrase,
141
+ webauthnInfo: {
142
+ otpDeviceId: 'device-123',
143
+ prfSalt: 'salt-abc',
144
+ passphrase: webauthnPassphrase,
145
+ },
146
+ });
147
+ const encryptCalls = mockBitGo.encrypt.getCalls();
148
+ const passwordsUsed = encryptCalls.map((call) => call.args[0].password);
149
+ passwordsUsed.should.containEql(walletPassphrase);
150
+ passwordsUsed.should.containEql(webauthnPassphrase);
151
+ });
152
+ it('should not add webauthnDevices when webauthnInfo is not provided', async function () {
153
+ await wallets.generateWallet({
154
+ label: 'Test Wallet',
155
+ passphrase: 'wallet-passphrase',
156
+ });
157
+ assert.strictEqual(mockKeychains.add.calledOnce, true);
158
+ const addParams = mockKeychains.add.firstCall.args[0];
159
+ addParams.should.not.have.property('webauthnDevices');
160
+ });
161
+ it('should not add webauthnDevices when userKey is explicitly provided (no prv available)', async function () {
162
+ // When a user-provided public key is used, there is no private key to encrypt, so webauthnDevices is skipped
163
+ await wallets.generateWallet({
164
+ label: 'Test Wallet',
165
+ userKey: userPub,
166
+ backupXpub: backupPub,
167
+ webauthnInfo: {
168
+ otpDeviceId: 'device-123',
169
+ prfSalt: 'salt-abc',
170
+ passphrase: 'prf-derived-passphrase',
171
+ },
172
+ });
173
+ // add is called for both user keychain (pub-only) and backup keychain - neither should have webauthnDevices
174
+ const allAddCalls = mockKeychains.add.getCalls();
175
+ assert.ok(allAddCalls.length > 0, 'expected keychains().add to be called at least once');
176
+ for (const call of allAddCalls) {
177
+ call.args[0].should.not.have.property('webauthnDevices');
178
+ }
179
+ });
180
+ it('should return wallet with keychains when webauthnInfo is provided', async function () {
181
+ const result = await wallets.generateWallet({
182
+ label: 'Test Wallet',
183
+ passphrase: 'wallet-passphrase',
184
+ webauthnInfo: {
185
+ otpDeviceId: 'device-123',
186
+ prfSalt: 'salt-abc',
187
+ passphrase: 'prf-derived-passphrase',
188
+ },
189
+ });
190
+ result.should.have.property('wallet');
191
+ result.should.have.property('userKeychain');
192
+ result.should.have.property('backupKeychain');
193
+ result.should.have.property('bitgoKeychain');
194
+ });
195
+ });
196
+ });
197
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FsbGV0c1dlYmF1dGhuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vdGVzdC91bml0L2JpdGdvL3dhbGxldC93YWxsZXRzV2ViYXV0aG4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwrQ0FBaUM7QUFDakMsNkNBQStCO0FBQy9CLGtCQUFnQjtBQUNoQixrRUFBK0Q7QUFFL0QsUUFBUSxDQUFDLG9DQUFvQyxFQUFFO0lBQzdDLElBQUksT0FBZ0IsQ0FBQztJQUNyQixJQUFJLFNBQWMsQ0FBQztJQUNuQixJQUFJLFlBQWlCLENBQUM7SUFDdEIsSUFBSSxhQUFrQixDQUFDO0lBRXZCLE1BQU0sT0FBTyxHQUFHLHdCQUF3QixDQUFDO0lBQ3pDLE1BQU0sT0FBTyxHQUNYLGlIQUFpSCxDQUFDO0lBQ3BILE1BQU0sU0FBUyxHQUNiLGlIQUFpSCxDQUFDO0lBQ3BILE1BQU0sUUFBUSxHQUNaLGlIQUFpSCxDQUFDO0lBRXBILFVBQVUsQ0FBQztRQUNULGFBQWEsR0FBRztZQUNkLE1BQU0sRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLENBQUM7WUFDNUQsR0FBRyxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLEVBQUUsYUFBYSxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFLGVBQWUsRUFBRSxDQUFDO1lBQzlGLFlBQVksRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxFQUFFLGVBQWUsRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLENBQUM7WUFDNUUsV0FBVyxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLEVB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QyxRQUFRLEVBQUUsQ0FBQztZQUNqRCxNQUFNLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLHFEQUFxRCxDQUFDLENBQUM7WUFDekYsS0FBSyxNQUFNLElBQUksSUFBSSxXQUFXLEVBQUUsQ0FBQztnQkFDL0IsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsaUJBQWlCLENBQUMsQ0FBQztZQUMzRCxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsbUVBQW1FLEVBQUUsS0FBSztZQUMzRSxNQUFNLE1BQU0sR0FBRyxNQUFNLE9BQU8sQ0FBQyxjQUFjLENBQUM7Z0JBQzFDLEtBQUssRUFBRSxhQUFhO2dCQUNwQixVQUFVLEVBQUUsbUJBQW1CO2dCQUMvQixZQUFZLEVBQUU7b0JBQ1osV0FBVyxFQUFFLFlBQVk7b0JBQ3pCLE9BQU8sRUFBRSxVQUFVO29CQUNuQixVQUFVLEVBQUUsd0JBQXdCO2lCQUNyQzthQUNGLENBQUMsQ0FBQztZQUVILE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUN0QyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLENBQUM7WUFDNUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDOUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQy9DLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0ICogYXMgc2lub24gZnJvbSAnc2lub24nO1xuaW1wb3J0ICdzaG91bGQnO1xuaW1wb3J0IHsgV2FsbGV0cyB9IGZyb20gJy4uLy4uLy4uLy4uL3NyYy9iaXRnby93YWxsZXQvd2FsbGV0cyc7XG5cbmRlc2NyaWJlKCdXYWxsZXRzIC0gV2ViQXV0aG4gd2FsbGV0IGNyZWF0aW9uJywgZnVuY3Rpb24gKCkge1xuICBsZXQgd2FsbGV0czogV2FsbGV0cztcbiAgbGV0IG1vY2tCaXRHbzogYW55O1xuICBsZXQgbW9ja0Jhc2VDb2luOiBhbnk7XG4gIGxldCBtb2NrS2V5Y2hhaW5zOiBhbnk7XG5cbiAgY29uc3QgdXNlclBydiA9ICd4cHJ2U29tZVVzZXJQcml2YXRlS2V5JztcbiAgY29uc3QgdXNlclB1YiA9XG4gICAgJ3hwdWI2NjFNeU13QXFSYmNGdFhnUzVzWUpBQnFxRzlZTG1DNFExUmRhcDlnU0U4TnF0d3liR2hlUFkyZ1oyOUVTRmpxSm9DdTFSdXBqZThZdEdxc2VmRDI2NVRNZzd1c1VERmRwNlcxRUdNY2V0OCc7XG4gIGNvbnN0IGJhY2t1cFB1YiA9XG4gICAgJ3hwdWI2NjFNeU13QXFSYmNHY3pqdU1vUm02ZFhhTERFaFcxdTM0Z0tlbmJlWXFBaXgyMW1kVUtKeXV5dTVGMXJ6WUdWeHlMNnRtZ0JVQUVQckV6OTJtQlhqQnlNUmlKZGJhOXdwbk4zN1JMTEFYYSc7XG4gIGNvbnN0IGJpdGdvUHViID1cbiAgICAneHB1YjY2MU15TXdBcVJiY0VZUzh3N1hMU1ZlRXNCWHk3OXpTekgxSjh2Q2R4QVpuaW5nV0xkTjN6Z3RVNkxCcEI4NWIzRDJ5YzhzZnZaVTUyMUFBd2RaYWZFejdtbnpCQnN6NHdLWTVmVHRUUUJtJztcblxuICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICBtb2NrS2V5Y2hhaW5zID0ge1xuICAgICAgY3JlYXRlOiBzaW5vbi5zdHViKCkucmV0dXJucyh7IHB1YjogdXNlclB1YiwgcHJ2OiB1c2VyUHJ2IH0pLFxuICAgICAgYWRkOiBzaW5vbi5zdHViKCkucmVzb2x2ZXMoeyBpZDogJ3VzZXIta2V5LWlkJywgcHViOiB1c2VyUHViLCBlbmNyeXB0ZWRQcnY6ICdlbmNyeXB0ZWQtcHJ2JyB9KSxcbiAgICAgIGNyZWF0ZUJhY2t1cDogc2lub24uc3R1YigpLnJlc29sdmVzKHsgaWQ6ICdiYWNrdXAta2V5LWlkJywgcHViOiBiYWNrdXBQdWIgfSksXG4gICAgICBjcmVhdGVCaXRHbzogc2lub24uc3R1YigpLnJlc29sdmVzKHsgaWQ6ICdiaXRnby1rZXktaWQnLCBwdWI6IGJpdGdvUHViIH0pLFxuICAgIH07XG5cbiAgICBjb25zdCBtb2NrV2FsbGV0RGF0YSA9IHsgaWQ6ICd3YWxsZXQtaWQnLCBrZXlzOiBbJ3VzZXIta2V5LWlkJywgJ2JhY2t1cC1rZXktaWQnLCAnYml0Z28ta2V5LWlkJ10gfTtcblxuICAgIG1vY2tCaXRHbyA9IHtcbiAgICAgIHBvc3Q6IHNpbm9uLnN0dWIoKS5yZXR1cm5zKHtcbiAgICAgICAgc2VuZDogc2lub24uc3R1YigpLnJldHVybnMoe1xuICAgICAgICAgIHJlc3VsdDogc2lub24uc3R1YigpLnJlc29sdmVzKG1vY2tXYWxsZXREYXRhKSxcbiAgICAgICAgfSksXG4gICAgICB9KSxcbiAgICAgIGVuY3J5cHQ6IHNpbm9uXG4gICAgICAgIC5zdHViKClcbiAgICAgICAgLmNhbGxzRmFrZSgoeyBwYXNzd29yZCwgaW5wdXQgfTogeyBwYXNzd29yZDogc3RyaW5nOyBpbnB1dDogc3RyaW5nIH0pID0+IGBlbmNyeXB0ZWQ6JHtwYXNzd29yZH06JHtpbnB1dH1gKSxcbiAgICAgIHNldFJlcXVlc3RUcmFjZXI6IHNpbm9uLnN0dWIoKSxcbiAgICB9O1xuXG4gICAgbW9ja0Jhc2VDb2luID0ge1xuICAgICAgaXNFVk06IHNpbm9uLnN0dWIoKS5yZXR1cm5zKGZhbHNlKSxcbiAgICAgIHN1cHBvcnRzVHNzOiBzaW5vbi5zdHViKCkucmV0dXJucyhmYWxzZSksXG4gICAgICBnZXRGYW1pbHk6IHNpbm9uLnN0dWIoKS5yZXR1cm5zKCdidGMnKSxcbiAgICAgIGdldERlZmF1bHRNdWx0aXNpZ1R5cGU6IHNpbm9uLnN0dWIoKS5yZXR1cm5zKCdvbmNoYWluJyksXG4gICAgICBrZXljaGFpbnM6IHNpbm9uLnN0dWIoKS5yZXR1cm5zKG1vY2tLZXljaGFpbnMpLFxuICAgICAgdXJsOiBzaW5vbi5zdHViKCkucmV0dXJucygnL3Rlc3QvdXJsJyksXG4gICAgICBpc1ZhbGlkTW9mTlNldHVwOiBzaW5vbi5zdHViKCkucmV0dXJucyh0cnVlKSxcbiAgICAgIGdldENvbmZpZzogc2lub24uc3R1YigpLnJldHVybnMoeyBmZWF0dXJlczogW10gfSksXG4gICAgICBzdXBwbGVtZW50R2VuZXJhdGVXYWxsZXQ6IHNpbm9uLnN0dWIoKS5jYWxsc0Zha2UoKHBhcmFtczogYW55KSA9PiBQcm9taXNlLnJlc29sdmUocGFyYW1zKSksXG4gICAgICBzaWduTWVzc2FnZTogc2lub24uc3R1YigpLnJlc29sdmVzKEJ1ZmZlci5mcm9tKCdhYWJiY2MnLCAnaGV4JykpLFxuICAgIH07XG5cbiAgICB3YWxsZXRzID0gbmV3IFdhbGxldHMobW9ja0JpdEdvLCBtb2NrQmFzZUNvaW4pO1xuICB9KTtcblxuICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgIHNpbm9uLnJlc3RvcmUoKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2dlbmVyYXRlV2FsbGV0IHdpdGggd2ViYXV0aG5JbmZvJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgYWRkIHdlYmF1dGhuRGV2aWNlcyB0byBrZXljaGFpbiBwYXJhbXMgd2hlbiB3ZWJhdXRobkluZm8gaXMgcHJvdmlkZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3ZWJhdXRobkluZm8gPSB7XG4gICAgICAgIG90cERldmljZUlkOiAnZGV2aWNlLTEyMycsXG4gICAgICAgIHByZlNhbHQ6ICdzYWx0LWFiYycsXG4gICAgICAgIHBhc3NwaHJhc2U6ICdwcmYtZGVyaXZlZC1wYXNzcGhyYXNlJyxcbiAgICAgIH07XG5cbiAgICAgIGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQoe1xuICAgICAgICBsYWJlbDogJ1Rlc3QgV2FsbGV0JyxcbiAgICAgICAgcGFzc3BocmFzZTogJ3dhbGxldC1wYXNzcGhyYXNlJyxcbiAgICAgICAgd2ViYXV0aG5JbmZvLFxuICAgICAgfSk7XG5cbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChtb2NrS2V5Y2hhaW5zLmFkZC5jYWxsZWRPbmNlLCB0cnVlKTtcbiAgICAgIGNvbnN0IGFkZFBhcmFtcyA9IG1vY2tLZXljaGFpbnMuYWRkLmZpcnN0Q2FsbC5hcmdzWzBdO1xuICAgICAgYWRkUGFyYW1zLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3ZWJhdXRobkRldmljZXMnKTtcbiAgICAgIGFkZFBhcmFtcy53ZWJhdXRobkRldmljZXMuc2hvdWxkLmhhdmUubGVuZ3RoKDEpO1xuICAgICAgYWRkUGFyYW1zLndlYmF1dGhuRGV2aWNlc1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnb3RwRGV2aWNlSWQnLCB3ZWJhdXRobkluZm8ub3RwRGV2aWNlSWQpO1xuICAgICAgYWRkUGFyYW1zLndlYmF1dGhuRGV2aWNlc1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncHJmU2FsdCcsIHdlYmF1dGhuSW5mby5wcmZTYWx0KTtcbiAgICAgIGFkZFBhcmFtcy53ZWJhdXRobkRldmljZXNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2VuY3J5cHRlZFBydicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBlbmNyeXB0IHVzZXIgcHJpdmF0ZSBrZXkgd2l0aCB0aGUgd2ViYXV0aG4gcGFzc3BocmFzZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdlYmF1dGhuUGFzc3BocmFzZSA9ICdwcmYtZGVyaXZlZC1wYXNzcGhyYXNlJztcblxuICAgICAgYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldCh7XG4gICAgICAgIGxhYmVsOiAnVGVzdCBXYWxsZXQnLFxuICAgICAgICBwYXNzcGhyYXNlOiAnd2FsbGV0LXBhc3NwaHJhc2UnLFxuICAgICAgICB3ZWJhdXRobkluZm86IHtcbiAgICAgICAgICBvdHBEZXZpY2VJZDogJ2RldmljZS0xMjMnLFxuICAgICAgICAgIHByZlNhbHQ6ICdzYWx0LWFiYycsXG4gICAgICAgICAgcGFzc3BocmFzZTogd2ViYXV0aG5QYXNzcGhyYXNlLFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGFkZFBhcmFtcyA9IG1vY2tLZXljaGFpbnMuYWRkLmZpcnN0Q2FsbC5hcmdzWzBdO1xuICAgICAgY29uc3QgZXhwZWN0ZWRFbmNyeXB0ZWRQcnYgPSBgZW5jcnlwdGVkOiR7d2ViYXV0aG5QYXNzcGhyYXNlfToke3VzZXJQcnZ9YDtcbiAgICAgIGFkZFBhcmFtcy53ZWJhdXRobkRldmljZXNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2VuY3J5cHRlZFBydicsIGV4cGVjdGVkRW5jcnlwdGVkUHJ2KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYWxzbyBlbmNyeXB0IHVzZXIgcHJpdmF0ZSBrZXkgd2l0aCB3YWxsZXQgcGFzc3BocmFzZSB3aGVuIHdlYmF1dGhuSW5mbyBpcyBwcm92aWRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAnd2FsbGV0LXBhc3NwaHJhc2UnO1xuXG4gICAgICBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHtcbiAgICAgICAgbGFiZWw6ICdUZXN0IFdhbGxldCcsXG4gICAgICAgIHBhc3NwaHJhc2U6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIHdlYmF1dGhuSW5mbzoge1xuICAgICAgICAgIG90cERldmljZUlkOiAnZGV2aWNlLTEyMycsXG4gICAgICAgICAgcHJmU2FsdDogJ3NhbHQtYWJjJyxcbiAgICAgICAgICBwYXNzcGhyYXNlOiAncHJmLWRlcml2ZWQtcGFzc3BocmFzZScsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgYWRkUGFyYW1zID0gbW9ja0tleWNoYWlucy5hZGQuZmlyc3RDYWxsLmFyZ3NbMF07XG4gICAgICBjb25zdCBleHBlY3RlZEVuY3J5cHRlZFBydiA9IGBlbmNyeXB0ZWQ6JHt3YWxsZXRQYXNzcGhyYXNlfToke3VzZXJQcnZ9YDtcbiAgICAgIGFkZFBhcmFtcy5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZW5jcnlwdGVkUHJ2JywgZXhwZWN0ZWRFbmNyeXB0ZWRQcnYpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB1c2Ugc2VwYXJhdGUgZW5jcnlwdCBjYWxscyBmb3Igd2FsbGV0IHBhc3NwaHJhc2UgYW5kIHdlYmF1dGhuIHBhc3NwaHJhc2UnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ3dhbGxldC1wYXNzcGhyYXNlJztcbiAgICAgIGNvbnN0IHdlYmF1dGhuUGFzc3BocmFzZSA9ICdwcmYtZGVyaXZlZC1wYXNzcGhyYXNlJztcblxuICAgICAgYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldCh7XG4gICAgICAgIGxhYmVsOiAnVGVzdCBXYWxsZXQnLFxuICAgICAgICBwYXNzcGhyYXNlOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB3ZWJhdXRobkluZm86IHtcbiAgICAgICAgICBvdHBEZXZpY2VJZDogJ2RldmljZS0xMjMnLFxuICAgICAgICAgIHByZlNhbHQ6ICdzYWx0LWFiYycsXG4gICAgICAgICAgcGFzc3BocmFzZTogd2ViYXV0aG5QYXNzcGhyYXNlLFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGVuY3J5cHRDYWxscyA9IG1vY2tCaXRHby5lbmNyeXB0LmdldENhbGxzKCk7XG4gICAgICBjb25zdCBwYXNzd29yZHNVc2VkID0gZW5jcnlwdENhbGxzLm1hcCgoY2FsbDogc2lub24uU2lub25TcHlDYWxsKSA9PiBjYWxsLmFyZ3NbMF0ucGFzc3dvcmQpO1xuICAgICAgcGFzc3dvcmRzVXNlZC5zaG91bGQuY29udGFpbkVxbCh3YWxsZXRQYXNzcGhyYXNlKTtcbiAgICAgIHBhc3N3b3Jkc1VzZWQuc2hvdWxkLmNvbnRhaW5FcWwod2ViYXV0aG5QYXNzcGhyYXNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbm90IGFkZCB3ZWJhdXRobkRldmljZXMgd2hlbiB3ZWJhdXRobkluZm8gaXMgbm90IHByb3ZpZGVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldCh7XG4gICAgICAgIGxhYmVsOiAnVGVzdCBXYWxsZXQnLFxuICAgICAgICBwYXNzcGhyYXNlOiAnd2FsbGV0LXBhc3NwaHJhc2UnLFxuICAgICAgfSk7XG5cbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChtb2NrS2V5Y2hhaW5zLmFkZC5jYWxsZWRPbmNlLCB0cnVlKTtcbiAgICAgIGNvbnN0IGFkZFBhcmFtcyA9IG1vY2tLZXljaGFpbnMuYWRkLmZpcnN0Q2FsbC5hcmdzWzBdO1xuICAgICAgYWRkUGFyYW1zLnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSgnd2ViYXV0aG5EZXZpY2VzJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG5vdCBhZGQgd2ViYXV0aG5EZXZpY2VzIHdoZW4gdXNlcktleSBpcyBleHBsaWNpdGx5IHByb3ZpZGVkIChubyBwcnYgYXZhaWxhYmxlKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIFdoZW4gYSB1c2VyLXByb3ZpZGVkIHB1YmxpYyBrZXkgaXMgdXNlZCwgdGhlcmUgaXMgbm8gcHJpdmF0ZSBrZXkgdG8gZW5jcnlwdCwgc28gd2ViYXV0aG5EZXZpY2VzIGlzIHNraXBwZWRcbiAgICAgIGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQoe1xuICAgICAgICBsYWJlbDogJ1Rlc3QgV2FsbGV0JyxcbiAgICAgICAgdXNlcktleTogdXNlclB1YixcbiAgICAgICAgYmFja3VwWHB1YjogYmFja3VwUHViLFxuICAgICAgICB3ZWJhdXRobkluZm86IHtcbiAgICAgICAgICBvdHBEZXZpY2VJZDogJ2RldmljZS0xMjMnLFxuICAgICAgICAgIHByZlNhbHQ6ICdzYWx0LWFiYycsXG4gICAgICAgICAgcGFzc3BocmFzZTogJ3ByZi1kZXJpdmVkLXBhc3NwaHJhc2UnLFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIC8vIGFkZCBpcyBjYWxsZWQgZm9yIGJvdGggdXNlciBrZXljaGFpbiAocHViLW9ubHkpIGFuZCBiYWNrdXAga2V5Y2hhaW4gLSBuZWl0aGVyIHNob3VsZCBoYXZlIHdlYmF1dGhuRGV2aWNlc1xuICAgICAgY29uc3QgYWxsQWRkQ2FsbHMgPSBtb2NrS2V5Y2hhaW5zLmFkZC5nZXRDYWxscygpO1xuICAgICAgYXNzZXJ0Lm9rKGFsbEFkZENhbGxzLmxlbmd0aCA+IDAsICdleHBlY3RlZCBrZXljaGFpbnMoKS5hZGQgdG8gYmUgY2FsbGVkIGF0IGxlYXN0IG9uY2UnKTtcbiAgICAgIGZvciAoY29uc3QgY2FsbCBvZiBhbGxBZGRDYWxscykge1xuICAgICAgICBjYWxsLmFyZ3NbMF0uc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5KCd3ZWJhdXRobkRldmljZXMnKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHdhbGxldCB3aXRoIGtleWNoYWlucyB3aGVuIHdlYmF1dGhuSW5mbyBpcyBwcm92aWRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQoe1xuICAgICAgICBsYWJlbDogJ1Rlc3QgV2FsbGV0JyxcbiAgICAgICAgcGFzc3BocmFzZTogJ3dhbGxldC1wYXNzcGhyYXNlJyxcbiAgICAgICAgd2ViYXV0aG5JbmZvOiB7XG4gICAgICAgICAgb3RwRGV2aWNlSWQ6ICdkZXZpY2UtMTIzJyxcbiAgICAgICAgICBwcmZTYWx0OiAnc2FsdC1hYmMnLFxuICAgICAgICAgIHBhc3NwaHJhc2U6ICdwcmYtZGVyaXZlZC1wYXNzcGhyYXNlJyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICByZXN1bHQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldCcpO1xuICAgICAgcmVzdWx0LnNob3VsZC5oYXZlLnByb3BlcnR5KCd1c2VyS2V5Y2hhaW4nKTtcbiAgICAgIHJlc3VsdC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnYmFja3VwS2V5Y2hhaW4nKTtcbiAgICAgIHJlc3VsdC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnYml0Z29LZXljaGFpbicpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19