@bitgo-beta/sdk-coin-sol 7.6.4-beta.782 → 7.6.4-beta.784

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
+ export {};
2
+ //# sourceMappingURL=solSafeRecovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solSafeRecovery.d.ts","sourceRoot":"","sources":["../../../../test/unit/solSafeRecovery.ts"],"names":[],"mappings":""}
@@ -0,0 +1,202 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const assert_1 = __importDefault(require("assert"));
40
+ const sinon_1 = __importDefault(require("sinon"));
41
+ const nacl = __importStar(require("tweetnacl"));
42
+ const base58 = __importStar(require("bs58"));
43
+ const sdk_test_1 = require("@bitgo-beta/sdk-test");
44
+ const sdk_api_1 = require("@bitgo-beta/sdk-api");
45
+ const sdk_lib_mpc_1 = require("@bitgo-beta/sdk-lib-mpc");
46
+ const sdk_core_1 = require("@bitgo-beta/sdk-core");
47
+ const src_1 = require("../../src");
48
+ const lib_1 = require("../../src/lib");
49
+ const statics_1 = require("@bitgo-beta/statics");
50
+ const testData = __importStar(require("../fixtures/sol"));
51
+ /**
52
+ * End-to-end Safe SOL recovery: real MPS DKG + VRF roots -> deriveSafeWalletKeys (slot-4 eddsaMpc
53
+ * child) -> buildSafeRecoverKeyParams -> Sol.recover() with the real MPS 2-of-2 signing path. Only
54
+ * chain queries are mocked.
55
+ *
56
+ * This proves the derived child keychain is accepted as `bitgoKey`, the re-encrypted child shares
57
+ * decrypt and sign, and the resulting signature verifies under the derived wallet address.
58
+ */
59
+ describe('Safe SOL recovery end-to-end', function () {
60
+ const sandbox = sinon_1.default.createSandbox();
61
+ let bitgo;
62
+ let basecoin;
63
+ let roots;
64
+ before(async function () {
65
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'mock' });
66
+ bitgo.safeRegister('tsol', src_1.Tsol.createInstance);
67
+ bitgo.initializeTestVars();
68
+ basecoin = bitgo.coin('tsol');
69
+ const [userDkg, backupDkg, bitgoDkg] = await sdk_lib_mpc_1.MPSUtil.generateEdDsaDKGKeyShares();
70
+ const [vrfUser, vrfBackup] = await sdk_lib_mpc_1.MpsVrfUtils.generateVrfDKGKeyShares();
71
+ roots = {
72
+ secp256k1Multisig: { user: 'u', backup: 'b', bitgo: 'g' },
73
+ ed25519Multisig: { user: 'u', backup: { prv: 'b', chainCode: 'c' }, bitgo: 'g' },
74
+ ecdsaMpc: {
75
+ user: { signing: Buffer.alloc(0), vrf: Buffer.alloc(0) },
76
+ backup: { signing: Buffer.alloc(0), vrf: Buffer.alloc(0) },
77
+ bitgo: 'g',
78
+ },
79
+ eddsaMpc: {
80
+ user: { signing: userDkg.getReducedKeyShare(), vrf: vrfUser.getKeyShare() },
81
+ backup: { signing: backupDkg.getReducedKeyShare(), vrf: vrfBackup.getKeyShare() },
82
+ bitgo: bitgoDkg.getCommonKeychain(),
83
+ },
84
+ };
85
+ });
86
+ afterEach(function () {
87
+ sandbox.restore();
88
+ });
89
+ async function deriveChild(account) {
90
+ const derived = await (0, sdk_core_1.deriveSafeWalletKeys)({ coin: 'tsol', slot: 'eddsaMpc', account, roots });
91
+ (0, assert_1.default)(derived.slot === 'eddsaMpc');
92
+ const mpc = await sdk_core_1.EDDSAMethods.getInitializedMpcInstance();
93
+ const publicKey = mpc.deriveUnhardened(derived.keys.commonKeychain, 'm/0').slice(0, 64);
94
+ return { derived, publicKey, address: new src_1.KeyPair({ pub: publicKey }).getAddress() };
95
+ }
96
+ function stubChain(walletAddress) {
97
+ const getDataFromNode = sandbox.stub(src_1.Sol.prototype, 'getDataFromNode');
98
+ getDataFromNode
99
+ .withArgs({
100
+ payload: { id: '1', jsonrpc: '2.0', method: 'getLatestBlockhash', params: [{ commitment: 'finalized' }] },
101
+ })
102
+ .resolves(testData.SolResponses.getBlockhashResponse);
103
+ getDataFromNode
104
+ .withArgs({ payload: { id: '1', jsonrpc: '2.0', method: 'getBalance', params: [walletAddress] } })
105
+ .resolves(testData.SolResponses.getAccountBalanceResponse);
106
+ getDataFromNode
107
+ .withArgs({
108
+ payload: {
109
+ id: '1',
110
+ jsonrpc: '2.0',
111
+ method: 'getFeeForMessage',
112
+ params: [sinon_1.default.match.string, { commitment: 'finalized' }],
113
+ },
114
+ })
115
+ .resolves(testData.SolResponses.getFeesForMessageResponse);
116
+ }
117
+ it('recovers a Safe SOL wallet offline: derive -> map -> sign, verifiable under the derived address', async function () {
118
+ const { derived, publicKey, address } = await deriveChild(0);
119
+ stubChain(address);
120
+ const keyParams = await (0, sdk_core_1.buildSafeRecoverKeyParams)({
121
+ bitgo,
122
+ coin: 'tsol',
123
+ slot: 'eddsaMpc',
124
+ keys: derived.keys,
125
+ mode: 'signed',
126
+ });
127
+ (0, assert_1.default)(keyParams.mode === 'signed');
128
+ assert_1.default.strictEqual(keyParams.isTss, true);
129
+ assert_1.default.strictEqual(keyParams.broadcast, false);
130
+ assert_1.default.strictEqual(keyParams.bitgoKey, derived.keys.commonKeychain);
131
+ const recovery = await basecoin.recover({
132
+ ...keyParams,
133
+ recoveryDestination: testData.keys.destinationPubKey,
134
+ });
135
+ (0, assert_1.default)('serializedTx' in recovery);
136
+ assert_1.default.strictEqual(recovery.scanIndex, 0);
137
+ // The signature on the recovered tx verifies under the derived child wallet key.
138
+ const tx = await new lib_1.TransactionBuilderFactory(statics_1.coins.get('tsol')).from(recovery.serializedTx).build();
139
+ assert_1.default.strictEqual(tx.signature.length, 1);
140
+ assert_1.default.strictEqual(nacl.sign.detached.verify(new Uint8Array(tx.signablePayload), new Uint8Array(base58.decode(tx.signature[0])), new Uint8Array(Buffer.from(publicKey, 'hex'))), true);
141
+ });
142
+ it('returns an unsigned sweep from the derived child address with no key material in the params', async function () {
143
+ const { derived, address } = await deriveChild(0);
144
+ stubChain(address);
145
+ const keyParams = await (0, sdk_core_1.buildSafeRecoverKeyParams)({
146
+ bitgo,
147
+ coin: 'tsol',
148
+ slot: 'eddsaMpc',
149
+ keys: derived.keys,
150
+ mode: 'unsigned',
151
+ });
152
+ (0, assert_1.default)(keyParams.mode === 'unsigned');
153
+ (0, assert_1.default)(!('userKey' in keyParams) && !('backupKey' in keyParams) && !('walletPassphrase' in keyParams));
154
+ const recovery = await basecoin.recover({
155
+ ...keyParams,
156
+ recoveryDestination: testData.keys.destinationPubKey,
157
+ });
158
+ (0, assert_1.default)('txRequests' in recovery);
159
+ const unsignedTx = recovery.txRequests[0].transactions[0].unsignedTx;
160
+ assert_1.default.strictEqual(unsignedTx.coinSpecific?.commonKeychain, derived.keys.commonKeychain);
161
+ assert_1.default.strictEqual(unsignedTx.derivationPath, 'm/0');
162
+ (0, assert_1.default)(unsignedTx.signableHex);
163
+ const tx = await new lib_1.TransactionBuilderFactory(statics_1.coins.get('tsol')).from(unsignedTx.serializedTx).build();
164
+ assert_1.default.strictEqual(tx.inputs[0].address, address);
165
+ });
166
+ it('fails closed when the signing shares belong to a different account than bitgoKey', async function () {
167
+ const account0 = await deriveChild(0);
168
+ const account1 = await deriveChild(1);
169
+ stubChain(account0.address);
170
+ const keyParams = await (0, sdk_core_1.buildSafeRecoverKeyParams)({
171
+ bitgo,
172
+ coin: 'tsol',
173
+ slot: 'eddsaMpc',
174
+ keys: account1.derived.keys,
175
+ mode: 'signed',
176
+ });
177
+ (0, assert_1.default)(keyParams.mode === 'signed');
178
+ await assert_1.default.rejects(basecoin.recover({
179
+ ...keyParams,
180
+ bitgoKey: account0.derived.keys.commonKeychain,
181
+ recoveryDestination: testData.keys.destinationPubKey,
182
+ }), /commonKeyChain from keycard does not match bitgoKey/);
183
+ });
184
+ it('fails closed when the wallet passphrase cannot decrypt the re-encrypted child shares', async function () {
185
+ const { derived, address } = await deriveChild(0);
186
+ stubChain(address);
187
+ const keyParams = await (0, sdk_core_1.buildSafeRecoverKeyParams)({
188
+ bitgo,
189
+ coin: 'tsol',
190
+ slot: 'eddsaMpc',
191
+ keys: derived.keys,
192
+ mode: 'signed',
193
+ });
194
+ (0, assert_1.default)(keyParams.mode === 'signed');
195
+ await assert_1.default.rejects(basecoin.recover({
196
+ ...keyParams,
197
+ walletPassphrase: 'not-the-ephemeral-passphrase',
198
+ recoveryDestination: testData.keys.destinationPubKey,
199
+ }), /Error decrypting user keychain/);
200
+ });
201
+ });
202
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29sU2FmZVJlY292ZXJ5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC91bml0L3NvbFNhZmVSZWNvdmVyeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLG9EQUE0QjtBQUM1QixrREFBMEI7QUFDMUIsZ0RBQWtDO0FBQ2xDLDZDQUErQjtBQUMvQixtREFBK0Q7QUFDL0QsaURBQStDO0FBQy9DLHlEQUErRDtBQUMvRCxtREFLOEI7QUFDOUIsbUNBQStDO0FBQy9DLHVDQUEwRDtBQUMxRCxpREFBNEM7QUFDNUMsMERBQTRDO0FBRTVDOzs7Ozs7O0dBT0c7QUFDSCxRQUFRLENBQUMsOEJBQThCLEVBQUU7SUFDdkMsTUFBTSxPQUFPLEdBQUcsZUFBSyxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ3RDLElBQUksS0FBbUIsQ0FBQztJQUN4QixJQUFJLFFBQWMsQ0FBQztJQUNuQixJQUFJLEtBQXlCLENBQUM7SUFFOUIsTUFBTSxDQUFDLEtBQUs7UUFDVixLQUFLLEdBQUcsb0JBQVMsQ0FBQyxRQUFRLENBQUMsa0JBQVEsRUFBRSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ3RELEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLFVBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUNoRCxLQUFLLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUMzQixRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQVMsQ0FBQztRQUV0QyxNQUFNLENBQUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxRQUFRLENBQUMsR0FBRyxNQUFNLHFCQUFPLENBQUMseUJBQXlCLEVBQUUsQ0FBQztRQUNqRixNQUFNLENBQUMsT0FBTyxFQUFFLFNBQVMsQ0FBQyxHQUFHLE1BQU0seUJBQVcsQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1FBQ3pFLEtBQUss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b0NBQXlCLEVBQUM7WUFDaEQsS0FBSztZQUNMLElBQUksRUFBRSxNQUFNO1lBQ1osSUFBSSxFQUFFLFVBQVU7WUFDaEIsSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJO1lBQ2xCLElBQUksRUFBRSxRQUFRO1NBQ2YsQ0FBQyxDQUFDO1FBQ0gsSUFBQSxnQkFBTSxFQUFDLFNBQVMsQ0FBQyxJQUFJLEtBQUssUUFBUSxDQUFDLENBQUM7UUFFcEMsTUFBTSxnQkFBTSxDQUFDLE9BQU8sQ0FDbEIsUUFBUSxDQUFDLE9BQU8sQ0FBQztZQUNmLEdBQUcsU0FBUztZQUNaLGdCQUFnQixFQUFFLDhCQUE4QjtZQUNoRCxtQkFBbUIsRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLGlCQUFpQjtTQUNyRCxDQUFDLEVBQ0YsZ0NBQWdDLENBQ2pDLENBQUM7SUFDSixDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IFNpbm9uIGZyb20gJ3Npbm9uJztcbmltcG9ydCAqIGFzIG5hY2wgZnJvbSAndHdlZXRuYWNsJztcbmltcG9ydCAqIGFzIGJhc2U1OCBmcm9tICdiczU4JztcbmltcG9ydCB7IFRlc3RCaXRHbywgVGVzdEJpdEdvQVBJIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLXRlc3QnO1xuaW1wb3J0IHsgQml0R29BUEkgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstYXBpJztcbmltcG9ydCB7IE1QU1V0aWwsIE1wc1ZyZlV0aWxzIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWxpYi1tcGMnO1xuaW1wb3J0IHtcbiAgYnVpbGRTYWZlUmVjb3ZlcktleVBhcmFtcyxcbiAgZGVyaXZlU2FmZVdhbGxldEtleXMsXG4gIEVERFNBTWV0aG9kcyxcbiAgdHlwZSBEZWNyeXB0ZWRTYWZlUm9vdHMsXG59IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcbmltcG9ydCB7IEtleVBhaXIsIFRzb2wsIFNvbCB9IGZyb20gJy4uLy4uL3NyYyc7XG5pbXBvcnQgeyBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5IH0gZnJvbSAnLi4vLi4vc3JjL2xpYic7XG5pbXBvcnQgeyBjb2lucyB9IGZyb20gJ0BiaXRnby1iZXRhL3N0YXRpY3MnO1xuaW1wb3J0ICogYXMgdGVzdERhdGEgZnJvbSAnLi4vZml4dHVyZXMvc29sJztcblxuLyoqXG4gKiBFbmQtdG8tZW5kIFNhZmUgU09MIHJlY292ZXJ5OiByZWFsIE1QUyBES0cgKyBWUkYgcm9vdHMgLT4gZGVyaXZlU2FmZVdhbGxldEtleXMgKHNsb3QtNCBlZGRzYU1wY1xuICogY2hpbGQpIC0+IGJ1aWxkU2FmZVJlY292ZXJLZXlQYXJhbXMgLT4gU29sLnJlY292ZXIoKSB3aXRoIHRoZSByZWFsIE1QUyAyLW9mLTIgc2lnbmluZyBwYXRoLiBPbmx5XG4gKiBjaGFpbiBxdWVyaWVzIGFyZSBtb2NrZWQuXG4gKlxuICogVGhpcyBwcm92ZXMgdGhlIGRlcml2ZWQgY2hpbGQga2V5Y2hhaW4gaXMgYWNjZXB0ZWQgYXMgYGJpdGdvS2V5YCwgdGhlIHJlLWVuY3J5cHRlZCBjaGlsZCBzaGFyZXNcbiAqIGRlY3J5cHQgYW5kIHNpZ24sIGFuZCB0aGUgcmVzdWx0aW5nIHNpZ25hdHVyZSB2ZXJpZmllcyB1bmRlciB0aGUgZGVyaXZlZCB3YWxsZXQgYWRkcmVzcy5cbiAqL1xuZGVzY3JpYmUoJ1NhZmUgU09MIHJlY292ZXJ5IGVuZC10by1lbmQnLCBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IHNhbmRib3ggPSBTaW5vbi5jcmVhdGVTYW5kYm94KCk7XG4gIGxldCBiaXRnbzogVGVzdEJpdEdvQVBJO1xuICBsZXQgYmFzZWNvaW46IFRzb2w7XG4gIGxldCByb290czogRGVjcnlwdGVkU2FmZVJvb3RzO1xuXG4gIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R29BUEksIHsgZW52OiAnbW9jaycgfSk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKCd0c29sJywgVHNvbC5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0c29sJykgYXMgVHNvbDtcblxuICAgIGNvbnN0IFt1c2VyRGtnLCBiYWNrdXBEa2csIGJpdGdvRGtnXSA9IGF3YWl0IE1QU1V0aWwuZ2VuZXJhdGVFZERzYURLR0tleVNoYXJlcygpO1xuICAgIGNvbnN0IFt2cmZVc2VyLCB2cmZCYWNrdXBdID0gYXdhaXQgTXBzVnJmVXRpbHMuZ2VuZXJhdGVWcmZES0dLZXlTaGFyZXMoKTtcbiAgICByb290cyA9IHtcbiAgICAgIHNlY3AyNTZrMU11bHRpc2lnOiB7IHVzZXI6ICd1JywgYmFja3VwOiAnYicsIGJpdGdvOiAnZycgfSxcbiAgICAgIGVkMjU1MTlNdWx0aXNpZzogeyB1c2VyOiAndScsIGJhY2t1cDogeyBwcnY6ICdiJywgY2hhaW5Db2RlOiAnYycgfSwgYml0Z286ICdnJyB9LFxuICAgICAgZWNkc2FNcGM6IHtcbiAgICAgICAgdXNlcjogeyBzaWduaW5nOiBCdWZmZXIuYWxsb2MoMCksIHZyZjogQnVmZmVyLmFsbG9jKDApIH0sXG4gICAgICAgIGJhY2t1cDogeyBzaWduaW5nOiBCdWZmZXIuYWxsb2MoMCksIHZyZjogQnVmZmVyLmFsbG9jKDApIH0sXG4gICAgICAgIGJpdGdvOiAnZycsXG4gICAgICB9LFxuICAgICAgZWRkc2FNcGM6IHtcbiAgICAgICAgdXNlcjogeyBzaWduaW5nOiB1c2VyRGtnLmdldFJlZHVjZWRLZXlTaGFyZSgpLCB2cmY6IHZyZlVzZXIuZ2V0S2V5U2hhcmUoKSB9LFxuICAgICAgICBiYWNrdXA6IHsgc2lnbmluZzogYmFja3VwRGtnLmdldFJlZHVjZWRLZXlTaGFyZSgpLCB2cmY6IHZyZkJhY2t1cC5nZXRLZXlTaGFyZSgpIH0sXG4gICAgICAgIGJpdGdvOiBiaXRnb0RrZy5nZXRDb21tb25LZXljaGFpbigpLFxuICAgICAgfSxcbiAgICB9O1xuICB9KTtcblxuICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgIHNhbmRib3gucmVzdG9yZSgpO1xuICB9KTtcblxuICBhc3luYyBmdW5jdGlvbiBkZXJpdmVDaGlsZChhY2NvdW50OiBudW1iZXIpIHtcbiAgICBjb25zdCBkZXJpdmVkID0gYXdhaXQgZGVyaXZlU2FmZVdhbGxldEtleXMoeyBjb2luOiAndHNvbCcsIHNsb3Q6ICdlZGRzYU1wYycsIGFjY291bnQsIHJvb3RzIH0pO1xuICAgIGFzc2VydChkZXJpdmVkLnNsb3QgPT09ICdlZGRzYU1wYycpO1xuICAgIGNvbnN0IG1wYyA9IGF3YWl0IEVERFNBTWV0aG9kcy5nZXRJbml0aWFsaXplZE1wY0luc3RhbmNlKCk7XG4gICAgY29uc3QgcHVibGljS2V5ID0gbXBjLmRlcml2ZVVuaGFyZGVuZWQoZGVyaXZlZC5rZXlzLmNvbW1vbktleWNoYWluLCAnbS8wJykuc2xpY2UoMCwgNjQpO1xuICAgIHJldHVybiB7IGRlcml2ZWQsIHB1YmxpY0tleSwgYWRkcmVzczogbmV3IEtleVBhaXIoeyBwdWI6IHB1YmxpY0tleSB9KS5nZXRBZGRyZXNzKCkgfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHN0dWJDaGFpbih3YWxsZXRBZGRyZXNzOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBnZXREYXRhRnJvbU5vZGUgPSBzYW5kYm94LnN0dWIoU29sLnByb3RvdHlwZSwgJ2dldERhdGFGcm9tTm9kZScgYXMga2V5b2YgU29sKTtcbiAgICBnZXREYXRhRnJvbU5vZGVcbiAgICAgIC53aXRoQXJncyh7XG4gICAgICAgIHBheWxvYWQ6IHsgaWQ6ICcxJywganNvbnJwYzogJzIuMCcsIG1ldGhvZDogJ2dldExhdGVzdEJsb2NraGFzaCcsIHBhcmFtczogW3sgY29tbWl0bWVudDogJ2ZpbmFsaXplZCcgfV0gfSxcbiAgICAgIH0pXG4gICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmdldEJsb2NraGFzaFJlc3BvbnNlKTtcbiAgICBnZXREYXRhRnJvbU5vZGVcbiAgICAgIC53aXRoQXJncyh7IHBheWxvYWQ6IHsgaWQ6ICcxJywganNvbnJwYzogJzIuMCcsIG1ldGhvZDogJ2dldEJhbGFuY2UnLCBwYXJhbXM6IFt3YWxsZXRBZGRyZXNzXSB9IH0pXG4gICAgICAucmVzb2x2ZXModGVzdERhdGEuU29sUmVzcG9uc2VzLmdldEFjY291bnRCYWxhbmNlUmVzcG9uc2UpO1xuICAgIGdldERhdGFGcm9tTm9kZVxuICAgICAgLndpdGhBcmdzKHtcbiAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAganNvbnJwYzogJzIuMCcsXG4gICAgICAgICAgbWV0aG9kOiAnZ2V0RmVlRm9yTWVzc2FnZScsXG4gICAgICAgICAgcGFyYW1zOiBbU2lub24ubWF0Y2guc3RyaW5nLCB7IGNvbW1pdG1lbnQ6ICdmaW5hbGl6ZWQnIH1dLFxuICAgICAgICB9LFxuICAgICAgfSlcbiAgICAgIC5yZXNvbHZlcyh0ZXN0RGF0YS5Tb2xSZXNwb25zZXMuZ2V0RmVlc0Zvck1lc3NhZ2VSZXNwb25zZSk7XG4gIH1cblxuICBpdCgncmVjb3ZlcnMgYSBTYWZlIFNPTCB3YWxsZXQgb2ZmbGluZTogZGVyaXZlIC0+IG1hcCAtPiBzaWduLCB2ZXJpZmlhYmxlIHVuZGVyIHRoZSBkZXJpdmVkIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgeyBkZXJpdmVkLCBwdWJsaWNLZXksIGFkZHJlc3MgfSA9IGF3YWl0IGRlcml2ZUNoaWxkKDApO1xuICAgIHN0dWJDaGFpbihhZGRyZXNzKTtcblxuICAgIGNvbnN0IGtleVBhcmFtcyA9IGF3YWl0IGJ1aWxkU2FmZVJlY292ZXJLZXlQYXJhbXMoe1xuICAgICAgYml0Z28sXG4gICAgICBjb2luOiAndHNvbCcsXG4gICAgICBzbG90OiAnZWRkc2FNcGMnLFxuICAgICAga2V5czogZGVyaXZlZC5rZXlzLFxuICAgICAgbW9kZTogJ3NpZ25lZCcsXG4gICAgfSk7XG4gICAgYXNzZXJ0KGtleVBhcmFtcy5tb2RlID09PSAnc2lnbmVkJyk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGtleVBhcmFtcy5pc1RzcywgdHJ1ZSk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKGtleVBhcmFtcy5icm9hZGNhc3QsIGZhbHNlKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoa2V5UGFyYW1zLmJpdGdvS2V5LCBkZXJpdmVkLmtleXMuY29tbW9uS2V5Y2hhaW4pO1xuXG4gICAgY29uc3QgcmVjb3ZlcnkgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgIC4uLmtleVBhcmFtcyxcbiAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IHRlc3REYXRhLmtleXMuZGVzdGluYXRpb25QdWJLZXksXG4gICAgfSk7XG5cbiAgICBhc3NlcnQoJ3NlcmlhbGl6ZWRUeCcgaW4gcmVjb3ZlcnkpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZWNvdmVyeS5zY2FuSW5kZXgsIDApO1xuXG4gICAgLy8gVGhlIHNpZ25hdHVyZSBvbiB0aGUgcmVjb3ZlcmVkIHR4IHZlcmlmaWVzIHVuZGVyIHRoZSBkZXJpdmVkIGNoaWxkIHdhbGxldCBrZXkuXG4gICAgY29uc3QgdHggPSBhd2FpdCBuZXcgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeShjb2lucy5nZXQoJ3Rzb2wnKSkuZnJvbShyZWNvdmVyeS5zZXJpYWxpemVkVHgpLmJ1aWxkKCk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHR4LnNpZ25hdHVyZS5sZW5ndGgsIDEpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbChcbiAgICAgIG5hY2wuc2lnbi5kZXRhY2hlZC52ZXJpZnkoXG4gICAgICAgIG5ldyBVaW50OEFycmF5KHR4LnNpZ25hYmxlUGF5bG9hZCksXG4gICAgICAgIG5ldyBVaW50OEFycmF5KGJhc2U1OC5kZWNvZGUodHguc2lnbmF0dXJlWzBdKSksXG4gICAgICAgIG5ldyBVaW50OEFycmF5KEJ1ZmZlci5mcm9tKHB1YmxpY0tleSwgJ2hleCcpKVxuICAgICAgKSxcbiAgICAgIHRydWVcbiAgICApO1xuICB9KTtcblxuICBpdCgncmV0dXJucyBhbiB1bnNpZ25lZCBzd2VlcCBmcm9tIHRoZSBkZXJpdmVkIGNoaWxkIGFkZHJlc3Mgd2l0aCBubyBrZXkgbWF0ZXJpYWwgaW4gdGhlIHBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCB7IGRlcml2ZWQsIGFkZHJlc3MgfSA9IGF3YWl0IGRlcml2ZUNoaWxkKDApO1xuICAgIHN0dWJDaGFpbihhZGRyZXNzKTtcblxuICAgIGNvbnN0IGtleVBhcmFtcyA9IGF3YWl0IGJ1aWxkU2FmZVJlY292ZXJLZXlQYXJhbXMoe1xuICAgICAgYml0Z28sXG4gICAgICBjb2luOiAndHNvbCcsXG4gICAgICBzbG90OiAnZWRkc2FNcGMnLFxuICAgICAga2V5czogZGVyaXZlZC5rZXlzLFxuICAgICAgbW9kZTogJ3Vuc2lnbmVkJyxcbiAgICB9KTtcbiAgICBhc3NlcnQoa2V5UGFyYW1zLm1vZGUgPT09ICd1bnNpZ25lZCcpO1xuICAgIGFzc2VydCghKCd1c2VyS2V5JyBpbiBrZXlQYXJhbXMpICYmICEoJ2JhY2t1cEtleScgaW4ga2V5UGFyYW1zKSAmJiAhKCd3YWxsZXRQYXNzcGhyYXNlJyBpbiBrZXlQYXJhbXMpKTtcblxuICAgIGNvbnN0IHJlY292ZXJ5ID0gYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAuLi5rZXlQYXJhbXMsXG4gICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiB0ZXN0RGF0YS5rZXlzLmRlc3RpbmF0aW9uUHViS2V5LFxuICAgIH0pO1xuICAgIGFzc2VydCgndHhSZXF1ZXN0cycgaW4gcmVjb3ZlcnkpO1xuXG4gICAgY29uc3QgdW5zaWduZWRUeCA9IHJlY292ZXJ5LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHg7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKHVuc2lnbmVkVHguY29pblNwZWNpZmljPy5jb21tb25LZXljaGFpbiwgZGVyaXZlZC5rZXlzLmNvbW1vbktleWNoYWluKTtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwodW5zaWduZWRUeC5kZXJpdmF0aW9uUGF0aCwgJ20vMCcpO1xuICAgIGFzc2VydCh1bnNpZ25lZFR4LnNpZ25hYmxlSGV4KTtcbiAgICBjb25zdCB0eCA9IGF3YWl0IG5ldyBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5KGNvaW5zLmdldCgndHNvbCcpKS5mcm9tKHVuc2lnbmVkVHguc2VyaWFsaXplZFR4KS5idWlsZCgpO1xuICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0eC5pbnB1dHNbMF0uYWRkcmVzcywgYWRkcmVzcyk7XG4gIH0pO1xuXG4gIGl0KCdmYWlscyBjbG9zZWQgd2hlbiB0aGUgc2lnbmluZyBzaGFyZXMgYmVsb25nIHRvIGEgZGlmZmVyZW50IGFjY291bnQgdGhhbiBiaXRnb0tleScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBhY2NvdW50MCA9IGF3YWl0IGRlcml2ZUNoaWxkKDApO1xuICAgIGNvbnN0IGFjY291bnQxID0gYXdhaXQgZGVyaXZlQ2hpbGQoMSk7XG4gICAgc3R1YkNoYWluKGFjY291bnQwLmFkZHJlc3MpO1xuXG4gICAgY29uc3Qga2V5UGFyYW1zID0gYXdhaXQgYnVpbGRTYWZlUmVjb3ZlcktleVBhcmFtcyh7XG4gICAgICBiaXRnbyxcbiAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgIHNsb3Q6ICdlZGRzYU1wYycsXG4gICAgICBrZXlzOiBhY2NvdW50MS5kZXJpdmVkLmtleXMsXG4gICAgICBtb2RlOiAnc2lnbmVkJyxcbiAgICB9KTtcbiAgICBhc3NlcnQoa2V5UGFyYW1zLm1vZGUgPT09ICdzaWduZWQnKTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIC4uLmtleVBhcmFtcyxcbiAgICAgICAgYml0Z29LZXk6IGFjY291bnQwLmRlcml2ZWQua2V5cy5jb21tb25LZXljaGFpbixcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogdGVzdERhdGEua2V5cy5kZXN0aW5hdGlvblB1YktleSxcbiAgICAgIH0pLFxuICAgICAgL2NvbW1vbktleUNoYWluIGZyb20ga2V5Y2FyZCBkb2VzIG5vdCBtYXRjaCBiaXRnb0tleS9cbiAgICApO1xuICB9KTtcblxuICBpdCgnZmFpbHMgY2xvc2VkIHdoZW4gdGhlIHdhbGxldCBwYXNzcGhyYXNlIGNhbm5vdCBkZWNyeXB0IHRoZSByZS1lbmNyeXB0ZWQgY2hpbGQgc2hhcmVzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHsgZGVyaXZlZCwgYWRkcmVzcyB9ID0gYXdhaXQgZGVyaXZlQ2hpbGQoMCk7XG4gICAgc3R1YkNoYWluKGFkZHJlc3MpO1xuXG4gICAgY29uc3Qga2V5UGFyYW1zID0gYXdhaXQgYnVpbGRTYWZlUmVjb3ZlcktleVBhcmFtcyh7XG4gICAgICBiaXRnbyxcbiAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgIHNsb3Q6ICdlZGRzYU1wYycsXG4gICAgICBrZXlzOiBkZXJpdmVkLmtleXMsXG4gICAgICBtb2RlOiAnc2lnbmVkJyxcbiAgICB9KTtcbiAgICBhc3NlcnQoa2V5UGFyYW1zLm1vZGUgPT09ICdzaWduZWQnKTtcblxuICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIC4uLmtleVBhcmFtcyxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ25vdC10aGUtZXBoZW1lcmFsLXBhc3NwaHJhc2UnLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiB0ZXN0RGF0YS5rZXlzLmRlc3RpbmF0aW9uUHViS2V5LFxuICAgICAgfSksXG4gICAgICAvRXJyb3IgZGVjcnlwdGluZyB1c2VyIGtleWNoYWluL1xuICAgICk7XG4gIH0pO1xufSk7XG4iXX0=