@bitgo-beta/abstract-lightning 1.0.1-beta.142 → 1.0.1-beta.1421
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/abstractLightningCoin.d.ts +11 -5
- package/dist/src/abstractLightningCoin.d.ts.map +1 -1
- package/dist/src/abstractLightningCoin.js +79 -8
- package/dist/src/codecs/api/backup.d.ts +15 -0
- package/dist/src/codecs/api/backup.d.ts.map +1 -0
- package/dist/src/codecs/api/backup.js +47 -0
- package/dist/src/codecs/api/balance.d.ts +156 -0
- package/dist/src/codecs/api/balance.d.ts.map +1 -0
- package/dist/src/codecs/api/balance.js +107 -0
- package/dist/src/codecs/api/index.d.ts +8 -0
- package/dist/src/codecs/api/index.d.ts.map +1 -0
- package/dist/src/codecs/api/index.js +24 -0
- package/dist/src/codecs/api/invoice.d.ts +68 -0
- package/dist/src/codecs/api/invoice.d.ts.map +1 -0
- package/dist/src/codecs/api/invoice.js +102 -0
- package/dist/src/codecs/api/payment.d.ts +107 -0
- package/dist/src/codecs/api/payment.d.ts.map +1 -0
- package/dist/src/codecs/api/payment.js +153 -0
- package/dist/src/codecs/api/transaction.d.ts +138 -0
- package/dist/src/codecs/api/transaction.d.ts.map +1 -0
- package/dist/src/codecs/api/transaction.js +122 -0
- package/dist/src/codecs/api/wallet.d.ts +100 -0
- package/dist/src/codecs/api/wallet.d.ts.map +1 -0
- package/dist/src/codecs/api/wallet.js +104 -0
- package/dist/src/codecs/api/withdraw.d.ts +92 -0
- package/dist/src/codecs/api/withdraw.d.ts.map +1 -0
- package/dist/src/codecs/api/withdraw.js +92 -0
- package/dist/src/codecs/index.d.ts +3 -0
- package/dist/src/codecs/index.d.ts.map +1 -0
- package/dist/src/codecs/index.js +19 -0
- package/dist/src/codecs/shared.d.ts +7 -0
- package/dist/src/codecs/shared.d.ts.map +1 -0
- package/dist/src/codecs/shared.js +42 -0
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -1
- package/dist/src/lightning/index.d.ts +5 -0
- package/dist/src/lightning/index.d.ts.map +1 -0
- package/dist/src/lightning/index.js +21 -0
- package/dist/src/lightning/lightningUtils.d.ts +90 -0
- package/dist/src/lightning/lightningUtils.d.ts.map +1 -0
- package/dist/src/lightning/lightningUtils.js +290 -0
- package/dist/src/lightning/parseWithdrawPsbt.d.ts +11 -0
- package/dist/src/lightning/parseWithdrawPsbt.d.ts.map +1 -0
- package/dist/src/lightning/parseWithdrawPsbt.js +163 -0
- package/dist/src/lightning/signableJson.d.ts +17 -0
- package/dist/src/lightning/signableJson.d.ts.map +1 -0
- package/dist/src/lightning/signableJson.js +29 -0
- package/dist/src/lightning/signature.d.ts +22 -0
- package/dist/src/lightning/signature.d.ts.map +1 -0
- package/dist/src/lightning/signature.js +69 -0
- package/dist/src/wallet/custodialLightning.d.ts +7 -0
- package/dist/src/wallet/custodialLightning.d.ts.map +1 -0
- package/dist/src/wallet/custodialLightning.js +14 -0
- package/dist/src/wallet/index.d.ts +5 -0
- package/dist/src/wallet/index.d.ts.map +1 -0
- package/dist/src/wallet/index.js +21 -0
- package/dist/src/wallet/lightning.d.ts +141 -0
- package/dist/src/wallet/lightning.d.ts.map +1 -0
- package/dist/src/wallet/lightning.js +288 -0
- package/dist/src/wallet/selfCustodialLightning.d.ts +32 -0
- package/dist/src/wallet/selfCustodialLightning.d.ts.map +1 -0
- package/dist/src/wallet/selfCustodialLightning.js +134 -0
- package/dist/src/wallet/wallet.d.ts +7 -0
- package/dist/src/wallet/wallet.d.ts.map +1 -0
- package/dist/src/wallet/wallet.js +22 -0
- package/dist/test/unit/lightning/codecs.d.ts +2 -0
- package/dist/test/unit/lightning/codecs.d.ts.map +1 -0
- package/dist/test/unit/lightning/codecs.js +151 -0
- package/dist/test/unit/lightning/createPsbt.d.ts +27 -0
- package/dist/test/unit/lightning/createPsbt.d.ts.map +1 -0
- package/dist/test/unit/lightning/createPsbt.js +162 -0
- package/dist/test/unit/lightning/createWatchOnlyFixture.d.ts +4 -0
- package/dist/test/unit/lightning/createWatchOnlyFixture.d.ts.map +1 -0
- package/dist/test/unit/lightning/createWatchOnlyFixture.js +1561 -0
- package/dist/test/unit/lightning/lightningUtils.d.ts +2 -0
- package/dist/test/unit/lightning/lightningUtils.d.ts.map +1 -0
- package/dist/test/unit/lightning/lightningUtils.js +123 -0
- package/dist/test/unit/lightning/parseWithdrawPsbt.d.ts +2 -0
- package/dist/test/unit/lightning/parseWithdrawPsbt.d.ts.map +1 -0
- package/dist/test/unit/lightning/parseWithdrawPsbt.js +478 -0
- package/dist/test/unit/lightning/signableJson.d.ts +2 -0
- package/dist/test/unit/lightning/signableJson.d.ts.map +1 -0
- package/dist/test/unit/lightning/signableJson.js +52 -0
- package/dist/test/unit/lightning/signature.d.ts +2 -0
- package/dist/test/unit/lightning/signature.d.ts.map +1 -0
- package/dist/test/unit/lightning/signature.js +91 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +19 -6
- package/.eslintignore +0 -5
- package/.mocharc.yml +0 -8
- package/CHANGELOG.md +0 -96
|
@@ -0,0 +1,478 @@
|
|
|
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 utxolib = __importStar(require("@bitgo-beta/utxo-lib"));
|
|
41
|
+
const src_1 = require("../../../src");
|
|
42
|
+
const createPsbt_1 = require("./createPsbt");
|
|
43
|
+
describe('parseWithdrawPsbt', () => {
|
|
44
|
+
const network = utxolib.networks.testnet;
|
|
45
|
+
describe('regression tests with hardcoded PSBT', () => {
|
|
46
|
+
// Keeping one regression test with real PSBT data to ensure backward compatibility
|
|
47
|
+
const unsignedPsbtHex = '70736274ff01007d02000000015e50b8d96cebdc3273d9a100eb68392d980d5b934b8170c80a23488b595268ca0100000000ffffffff02a086010000000000225120379bc88cc15d3605ed9de1b61ff8d65021b650db1151e751a30885ccfcc7d15affa80a000000000016001480a06f2e6b77e817fd5de6e41ea512c563c26cb800000000000100ea02000000000101a158d806735bb7c54e4c701d4f5821cd5342d48d5e1fcbed1169e6e45aa444be0100000000ffffffff02a086010000000000225120379bc88cc15d3605ed9de1b61ff8d65021b650db1151e751a30885ccfcc7d15a6a310c000000000016001478a5d98c7160484b9b00f1782803c58edfc49b9a024730440220407d9162f52371df246dcfa2943d40fbdcb0d4b6768f7682c65193378b2845a60220101c7bc460c93d2976961ac23400f0f10c145efb989a3addb7f03ebaaa2200950121037e17444c85c8b7da07f12fd53cb2ca142c2b4932d0f898649c4b5be0021da0980000000001030401000000220602e57146e5b4762a7ff374adf4072047b67ef115ad46a34189bdeb6a4f88db9b0818000000005400008000000080000000800100000006000000000022020379abbe44004ff7e527bdee3dd8d95e5cd250053f35ee92258b97aa83dfa93c621800000000540000800000008000000080010000005000000000';
|
|
48
|
+
const recipients = [
|
|
49
|
+
{
|
|
50
|
+
amountSat: 100000n,
|
|
51
|
+
address: 'tb1px7du3rxpt5mqtmvauxmpl7xk2qsmv5xmz9g7w5drpzzuelx869dqwape7k',
|
|
52
|
+
},
|
|
53
|
+
];
|
|
54
|
+
const accounts = [
|
|
55
|
+
{
|
|
56
|
+
xpub: 'tpubDCmiWMkTJrZ24t1Z6ECR3HyynCyZ9zGsWqhcLh6H4yFK2CDozSszD1pP2Li4Nx1YYtRcvmNbdb3nD1SzFejYtPFfTocTv2EaAgJCg4zpJpA',
|
|
57
|
+
purpose: 49,
|
|
58
|
+
coin_type: 0,
|
|
59
|
+
account: 0,
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
xpub: 'tpubDCFN7bsxR9UTKggdH2pmv5HeHGQNiDrJwa1EZFtP9sH5PF28i37FHpoYSYARQkKZ6Mi98pkp7oypDcxFmE4dQGq8jV8Gv3L6gmWBeRwPxkP',
|
|
63
|
+
purpose: 84,
|
|
64
|
+
coin_type: 0,
|
|
65
|
+
account: 0,
|
|
66
|
+
},
|
|
67
|
+
];
|
|
68
|
+
it('should parse a valid withdraw PSBT', () => {
|
|
69
|
+
(0, src_1.validatePsbtForWithdraw)(unsignedPsbtHex, network, recipients, accounts);
|
|
70
|
+
});
|
|
71
|
+
it('should throw for invalid PSBT hex', () => {
|
|
72
|
+
assert_1.default.throws(() => {
|
|
73
|
+
(0, src_1.validatePsbtForWithdraw)('asdasd', network, recipients, accounts);
|
|
74
|
+
}, /ERR_BUFFER_OUT_OF_BOUNDS/);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
describe('regression tests with created PSBT from LND (no `m/` prefix)', () => {
|
|
78
|
+
const unsignedPsbtHex = '70736274ff01007d0200000001814f07febb372cf9e303c40938d7f1372cf7f5bd3d43de763be10c1b2ac539200000000000ffffffff028813000000000000220020ac06117832f08e952b16c220dde35dd505b5c54fa45a4eb9f2b040efd27ecb12f86a040000000000160014f1f4753cf0f9171dd3724f17ea511baa49e3c22600000000000100fde70401000000000104e55600b7d0003c6b2be7dc105f6c3499b8d426e92fd56c3dca06728e060c80720000000000fdffffff366f5356038e883dd7dd621d0b340c526018329664ccbeb1a723b0a6f8f312a40000000023220020b4b69dea98d8d5fb32a22a0c9ad208fc28efb44943f8e576d5978d215d784d49fdffffff15978f903d63dac56026cec90fc568fbe6e8a5a8b53bf8b5a34eee3723e63eff0000000000fdffffff58a9e6be1da0f25e39af4c95ed102336a64baf9bc8eb7c1ffca97ff0d0d651ff0000000000fdffffff0145860400000000001600146b618e8d1d709711104f92a857032a8d66f1bf7d0400483045022100d85bc99bf6d610978630518f79eeee025c8ce40eb65f12360f0f47d5b30ca547022036d79384a55bbba00520d626c3ae05a5f341fd7d65f211fa64bfedad5e827c7301483045022100dacce37fbffeb2e9ee198ab3a78cfdf01e34655313482ff75376bb5e2152a05d02205a7d1b7072480368d274de0229bbb9e6f4e4cda202f6750b9a90f8517604413e0169522102dd6b15d5c483080aaeaf3be51c8ee6cd794dbfa65e5c8036fe2c67f0080929702103370c44e05dddfc29fdb418ae583652b4fb7ee62d07562fc1e5b1696caaf3908f2103c6d980811cb03048a7b48f639bbb0575444af1f670af8462bb1c93112af2080a53ae040048304502210094646e8c1c25368ed9cdf5ba10b54a88ce20bb9b452877d0d2f27823897ab9d40220183c80560c1860d22d7ae8aaeee712d930e427252345bddece1a333d345c6d9801483045022100d123c1f5a79d32905f9d725b590160afc8e14bb01cb1a5d258304c6b6673113c0220722003050f57366b3f3486c1fdd5559579f1c67c3d644d31ac6f20bb8022f7d201695221034a2c8e0891e30698aa7015f1210451f1e5336be96bf846cd43528c15b0645b032103e6305f797838299f4188595b1b01bd9fe60db0e4bb9331d957750248d055f299210383c028341d5d273afca5f5265e2c2ee9619c0f1b328956ef3000ab09eccaed3b53ae0400473044022044a43ae38b86c375aa57b3d96386fca52f74a5bc4fb37c77738efa4c0566662202200d1af93d2022c48f3f3cc134d3d75bbcfce30615e53d9246c200c5349a7d978c0147304402207ce3043211d9344dad8f4e2bf848bf1ca151310a188e707663b28475e12099d0022060d2b3533e7c362d39b041102edf17e0486b1aee55a01c7895485b8630daa39c0169522103c71a350e2b06ec9d0710a13f608bb76f35a35fed491fbb5b97280caed4c9590f2103692ea685162a1da7e86e0beeb1ed0331e8d0fbbf2e05f002071b15044c402b782102960087d0d5b8e1a449ed562553ef3149885a930f60c40324165221a7fc7627ea53ae0400483045022100a8382cfa2582abdc77417f9aa53e5ce0e2d31eb5e14b7836961da8c045de3a500220398555b93816ef7ec417bb7555bc51e0477b3c65f83d0951cff2a5040457314e0147304402204f66fd4507bd54cc25028b5660c00fdcfe15ce6121eabff7911e7307d24c7f1102200591e969897109a2372a6b22e41d158d4e0ae53ca0963166ffd8a23e06522ac9016952210282aaf28d528e6b6326880b1539a14a96dcee5d9a0920a31f3581e5ac21a9de462103f84e26e78f2c587821b581761b134f7721e33b1ad97bd1599125ee23369ea1202103da6eddca9c0eaaa08b179c035ed0adb516a592ba1321ffc5cb11dcae8c3a704f53ae0000000001011f45860400000000001600146b618e8d1d709711104f92a857032a8d66f1bf7d010304010000002206038361bfad9b6896c938690df1e67c669ecd7a021b117382bbfa81ff6de8ec153718000000005400008000000080000000800000000000000000000022020376cb4ac899d130e2d655fca6d362fe7c745cc15486849e401f7c21b3d3df37c81800000000540000800000008000000080010000000800000000';
|
|
79
|
+
const recipients = [
|
|
80
|
+
{
|
|
81
|
+
amountSat: 5000n,
|
|
82
|
+
address: 'tb1q4srpz7pj7z8f22ckcgsdmc6a65zmt32053dyaw0jkpqwl5n7evfqhc07u4',
|
|
83
|
+
},
|
|
84
|
+
];
|
|
85
|
+
const accounts = [
|
|
86
|
+
{
|
|
87
|
+
purpose: 49,
|
|
88
|
+
coin_type: 0,
|
|
89
|
+
account: 0,
|
|
90
|
+
xpub: 'upub5EW2cim2FSeBDqote8jcKnBSohtZjPRbw9HsXNototipVVj31AzWjgXUSonbvi7RNALY73rkgXTQY4YUpovrG1WV4ATKXyQpMa1sMnJdCbm',
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
purpose: 84,
|
|
94
|
+
coin_type: 0,
|
|
95
|
+
account: 0,
|
|
96
|
+
xpub: 'vpub5Z8kVs9L6fSK4qc1G36VqKdTiSdfCGSzrcz4EYGkywkWX43EJiLcSBEd1XE4fxgXir7Wkwaia4eTwbakngVDHHnToc9qQMBcxerr2U5MHnN',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
purpose: 86,
|
|
100
|
+
coin_type: 0,
|
|
101
|
+
account: 0,
|
|
102
|
+
xpub: 'tpubDCyXDnLqhmTxjcGV2KexrojfJPBept2gWs2mg9V46y6HAp9nLzg3idmESEJ1RDtfaLyVL6x2MoJsv66hQPWrCxoR2jYQbGbHd5FmEa6BfW3',
|
|
103
|
+
},
|
|
104
|
+
];
|
|
105
|
+
it('should parse a valid withdraw PSBT', () => {
|
|
106
|
+
(0, src_1.validatePsbtForWithdraw)(unsignedPsbtHex, network, recipients, accounts);
|
|
107
|
+
});
|
|
108
|
+
it('should throw for invalid PSBT hex', () => {
|
|
109
|
+
assert_1.default.throws(() => {
|
|
110
|
+
(0, src_1.validatePsbtForWithdraw)('asdasd', network, recipients, accounts);
|
|
111
|
+
}, /ERR_BUFFER_OUT_OF_BOUNDS/);
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
describe('test cases with creating psbt on the go', () => {
|
|
115
|
+
it('should validate PSBT with P2WPKH (purpose 84) change address', () => {
|
|
116
|
+
const { psbt, masterKey } = (0, createPsbt_1.createTestPsbt)({
|
|
117
|
+
network,
|
|
118
|
+
inputValue: 500000,
|
|
119
|
+
outputValue: 100000,
|
|
120
|
+
changeValue: 390000,
|
|
121
|
+
changePurpose: 84,
|
|
122
|
+
changeDerivationPath: "m/84'/0'/0'/1/6",
|
|
123
|
+
});
|
|
124
|
+
const recipientAddress = utxolib.address.fromOutputScript(psbt.txOutputs[0].script, network);
|
|
125
|
+
const recipients = [
|
|
126
|
+
{
|
|
127
|
+
amountSat: BigInt(100000),
|
|
128
|
+
address: recipientAddress,
|
|
129
|
+
},
|
|
130
|
+
];
|
|
131
|
+
const accounts = [
|
|
132
|
+
{
|
|
133
|
+
xpub: masterKey.neutered().toBase58(),
|
|
134
|
+
purpose: 84,
|
|
135
|
+
coin_type: 0,
|
|
136
|
+
account: 0,
|
|
137
|
+
},
|
|
138
|
+
];
|
|
139
|
+
(0, src_1.validatePsbtForWithdraw)(psbt.toHex(), network, recipients, accounts);
|
|
140
|
+
});
|
|
141
|
+
it('should validate PSBT with P2SH-P2WPKH (purpose 49) change address', () => {
|
|
142
|
+
const { psbt, masterKey } = (0, createPsbt_1.createTestPsbt)({
|
|
143
|
+
network,
|
|
144
|
+
inputValue: 500000,
|
|
145
|
+
outputValue: 100000,
|
|
146
|
+
changeValue: 390000,
|
|
147
|
+
changePurpose: 49,
|
|
148
|
+
changeDerivationPath: "m/49'/0'/0'/1/6",
|
|
149
|
+
});
|
|
150
|
+
const recipientAddress = utxolib.address.fromOutputScript(psbt.txOutputs[0].script, network);
|
|
151
|
+
const recipients = [
|
|
152
|
+
{
|
|
153
|
+
amountSat: BigInt(100000),
|
|
154
|
+
address: recipientAddress,
|
|
155
|
+
},
|
|
156
|
+
];
|
|
157
|
+
const accounts = [
|
|
158
|
+
{
|
|
159
|
+
xpub: masterKey.neutered().toBase58(),
|
|
160
|
+
purpose: 49,
|
|
161
|
+
coin_type: 0,
|
|
162
|
+
account: 0,
|
|
163
|
+
},
|
|
164
|
+
];
|
|
165
|
+
(0, src_1.validatePsbtForWithdraw)(psbt.toHex(), network, recipients, accounts);
|
|
166
|
+
});
|
|
167
|
+
it('should validate PSBT with P2TR (purpose 86) change address', () => {
|
|
168
|
+
const { psbt, masterKey } = (0, createPsbt_1.createTestPsbt)({
|
|
169
|
+
network,
|
|
170
|
+
inputValue: 500000,
|
|
171
|
+
outputValue: 100000,
|
|
172
|
+
changeValue: 390000,
|
|
173
|
+
changePurpose: 86,
|
|
174
|
+
changeDerivationPath: "m/86'/0'/0'/1/6",
|
|
175
|
+
});
|
|
176
|
+
const recipientAddress = utxolib.address.fromOutputScript(psbt.txOutputs[0].script, network);
|
|
177
|
+
const recipients = [
|
|
178
|
+
{
|
|
179
|
+
amountSat: BigInt(100000),
|
|
180
|
+
address: recipientAddress,
|
|
181
|
+
},
|
|
182
|
+
];
|
|
183
|
+
const accounts = [
|
|
184
|
+
{
|
|
185
|
+
xpub: masterKey.neutered().toBase58(),
|
|
186
|
+
purpose: 86,
|
|
187
|
+
coin_type: 0,
|
|
188
|
+
account: 0,
|
|
189
|
+
},
|
|
190
|
+
];
|
|
191
|
+
(0, src_1.validatePsbtForWithdraw)(psbt.toHex(), network, recipients, accounts);
|
|
192
|
+
});
|
|
193
|
+
it('should throw for missing bip32Derivation path on change output', () => {
|
|
194
|
+
const { psbt, masterKey } = (0, createPsbt_1.createTestPsbt)({
|
|
195
|
+
network,
|
|
196
|
+
inputValue: 500000,
|
|
197
|
+
outputValue: 100000,
|
|
198
|
+
changeValue: 390000,
|
|
199
|
+
changePurpose: 84,
|
|
200
|
+
});
|
|
201
|
+
// Remove the bip32Derivation from the change output
|
|
202
|
+
// This will cause the output to be treated as a regular recipient output, not a change output
|
|
203
|
+
delete psbt.data.outputs[1].bip32Derivation;
|
|
204
|
+
const recipientAddress = utxolib.address.fromOutputScript(psbt.txOutputs[0].script, network);
|
|
205
|
+
const recipients = [
|
|
206
|
+
{
|
|
207
|
+
amountSat: BigInt(100000),
|
|
208
|
+
address: recipientAddress,
|
|
209
|
+
},
|
|
210
|
+
];
|
|
211
|
+
const accounts = [
|
|
212
|
+
{
|
|
213
|
+
xpub: masterKey.neutered().toBase58(),
|
|
214
|
+
purpose: 84,
|
|
215
|
+
coin_type: 0,
|
|
216
|
+
account: 0,
|
|
217
|
+
},
|
|
218
|
+
];
|
|
219
|
+
// The output without bip32Derivation is treated as a recipient output,
|
|
220
|
+
// and since it's not in the recipients list, it should fail with "does not match any recipient"
|
|
221
|
+
assert_1.default.throws(() => {
|
|
222
|
+
(0, src_1.validatePsbtForWithdraw)(psbt.toHex(), network, recipients, accounts);
|
|
223
|
+
}, /does not match any recipient/);
|
|
224
|
+
});
|
|
225
|
+
it('should throw for invalid change address (derived address mismatch)', () => {
|
|
226
|
+
const { psbt } = (0, createPsbt_1.createTestPsbt)({
|
|
227
|
+
network,
|
|
228
|
+
inputValue: 500000,
|
|
229
|
+
outputValue: 100000,
|
|
230
|
+
changeValue: 390000,
|
|
231
|
+
changePurpose: 84,
|
|
232
|
+
changeDerivationPath: "m/84'/0'/0'/1/6",
|
|
233
|
+
});
|
|
234
|
+
const recipientAddress = utxolib.address.fromOutputScript(psbt.txOutputs[0].script, network);
|
|
235
|
+
const recipients = [
|
|
236
|
+
{
|
|
237
|
+
amountSat: BigInt(100000),
|
|
238
|
+
address: recipientAddress,
|
|
239
|
+
},
|
|
240
|
+
];
|
|
241
|
+
// Use a different xpub that won't match the change address
|
|
242
|
+
const differentMasterKey = utxolib.bip32.fromSeed(Buffer.alloc(32, 2), network);
|
|
243
|
+
const accounts = [
|
|
244
|
+
{
|
|
245
|
+
xpub: differentMasterKey.neutered().toBase58(),
|
|
246
|
+
purpose: 84,
|
|
247
|
+
coin_type: 0,
|
|
248
|
+
account: 0,
|
|
249
|
+
},
|
|
250
|
+
];
|
|
251
|
+
assert_1.default.throws(() => {
|
|
252
|
+
(0, src_1.validatePsbtForWithdraw)(psbt.toHex(), network, recipients, accounts);
|
|
253
|
+
}, /Derived pubkey does not match for address/);
|
|
254
|
+
});
|
|
255
|
+
it('should validate PSBT with upub prefix (P2SH-P2WPKH testnet)', () => {
|
|
256
|
+
const { psbt } = (0, createPsbt_1.createTestPsbt)({
|
|
257
|
+
network,
|
|
258
|
+
inputValue: 500000,
|
|
259
|
+
outputValue: 100000,
|
|
260
|
+
changeValue: 390000,
|
|
261
|
+
changePurpose: 49,
|
|
262
|
+
changeDerivationPath: "m/49'/0'/0'/1/6",
|
|
263
|
+
});
|
|
264
|
+
const recipientAddress = utxolib.address.fromOutputScript(psbt.txOutputs[0].script, network);
|
|
265
|
+
const recipients = [
|
|
266
|
+
{
|
|
267
|
+
amountSat: BigInt(100000),
|
|
268
|
+
address: recipientAddress,
|
|
269
|
+
},
|
|
270
|
+
];
|
|
271
|
+
// Use upub prefix (testnet P2SH-P2WPKH) instead of standard tpub
|
|
272
|
+
// This tests that revertXpubPrefix correctly converts upub -> tpub
|
|
273
|
+
const accounts = [
|
|
274
|
+
{
|
|
275
|
+
xpub: 'upub5Eep7H5q39PzQZLVEYLBytDyBNeV74E8mQsyeL6UozFq9Y3MsZ52G7YGuqrJPgoyAqF7TBeJdnkrHrVrB5pkWkPJ9cJGAePMU6F1Gyw6aFH',
|
|
276
|
+
purpose: 49,
|
|
277
|
+
coin_type: 0,
|
|
278
|
+
account: 0,
|
|
279
|
+
},
|
|
280
|
+
];
|
|
281
|
+
// This should work because revertXpubPrefix will convert upub back to tpub
|
|
282
|
+
// However, the master key we used is different, so it should fail with pubkey mismatch
|
|
283
|
+
assert_1.default.throws(() => {
|
|
284
|
+
(0, src_1.validatePsbtForWithdraw)(psbt.toHex(), network, recipients, accounts);
|
|
285
|
+
}, /Derived pubkey does not match for address/);
|
|
286
|
+
});
|
|
287
|
+
it('should validate PSBT with vpub prefix (P2WPKH testnet)', () => {
|
|
288
|
+
const { psbt } = (0, createPsbt_1.createTestPsbt)({
|
|
289
|
+
network,
|
|
290
|
+
inputValue: 500000,
|
|
291
|
+
outputValue: 100000,
|
|
292
|
+
changeValue: 390000,
|
|
293
|
+
changePurpose: 84,
|
|
294
|
+
changeDerivationPath: "m/84'/0'/0'/1/6",
|
|
295
|
+
});
|
|
296
|
+
const recipientAddress = utxolib.address.fromOutputScript(psbt.txOutputs[0].script, network);
|
|
297
|
+
const recipients = [
|
|
298
|
+
{
|
|
299
|
+
amountSat: BigInt(100000),
|
|
300
|
+
address: recipientAddress,
|
|
301
|
+
},
|
|
302
|
+
];
|
|
303
|
+
// Use vpub prefix (testnet P2WPKH) instead of standard tpub
|
|
304
|
+
// This tests that revertXpubPrefix correctly converts vpub -> tpub
|
|
305
|
+
const accounts = [
|
|
306
|
+
{
|
|
307
|
+
xpub: 'vpub5ZU1PHGpQoDSHckYico4nsvwsD3mTh6UjqL5zyGWXZXzBjTYMNKot7t9eRPQY71hJcnNN9r1ss25g3xA9rmoJ5nWPg8jEWavrttnsVa1qw1',
|
|
308
|
+
purpose: 84,
|
|
309
|
+
coin_type: 0,
|
|
310
|
+
account: 0,
|
|
311
|
+
},
|
|
312
|
+
];
|
|
313
|
+
// This should work because revertXpubPrefix will convert vpub back to tpub
|
|
314
|
+
// However, the master key we used is different, so it should fail with pubkey mismatch
|
|
315
|
+
assert_1.default.throws(() => {
|
|
316
|
+
(0, src_1.validatePsbtForWithdraw)(psbt.toHex(), network, recipients, accounts);
|
|
317
|
+
}, /Derived pubkey does not match for address/);
|
|
318
|
+
});
|
|
319
|
+
it('should validate PSBT with matching upub prefix and correct key', () => {
|
|
320
|
+
// Import the signer root key from the fixture which corresponds to the upub/vpub accounts
|
|
321
|
+
const signerRootKey = 'tprv8ZgxMBicQKsPe6jS4vDm2n7s42Q6MpvghUQqMmSKG7bTZvGKtjrcU3PGzMNG37yzxywrcdvgkwrr8eYXJmbwdvUNVT4Ucv7ris4jvA7BUmg';
|
|
322
|
+
const masterHDNode = utxolib.bip32.fromBase58(signerRootKey, network);
|
|
323
|
+
// Derive the account key for purpose 49
|
|
324
|
+
const accountKey = masterHDNode.derivePath("m/49'/0'/0'");
|
|
325
|
+
const { psbt } = (0, createPsbt_1.createTestPsbt)({
|
|
326
|
+
network,
|
|
327
|
+
inputValue: 500000,
|
|
328
|
+
outputValue: 100000,
|
|
329
|
+
changeValue: 390000,
|
|
330
|
+
changePurpose: 49,
|
|
331
|
+
changeDerivationPath: "m/49'/0'/0'/1/6",
|
|
332
|
+
masterKey: accountKey,
|
|
333
|
+
});
|
|
334
|
+
const recipientAddress = utxolib.address.fromOutputScript(psbt.txOutputs[0].script, network);
|
|
335
|
+
const recipients = [
|
|
336
|
+
{
|
|
337
|
+
amountSat: BigInt(100000),
|
|
338
|
+
address: recipientAddress,
|
|
339
|
+
},
|
|
340
|
+
];
|
|
341
|
+
// Use the upub from the fixture - this should work because the keys match
|
|
342
|
+
const accounts = [
|
|
343
|
+
{
|
|
344
|
+
xpub: 'upub5Eep7H5q39PzQZLVEYLBytDyBNeV74E8mQsyeL6UozFq9Y3MsZ52G7YGuqrJPgoyAqF7TBeJdnkrHrVrB5pkWkPJ9cJGAePMU6F1Gyw6aFH',
|
|
345
|
+
purpose: 49,
|
|
346
|
+
coin_type: 0,
|
|
347
|
+
account: 0,
|
|
348
|
+
},
|
|
349
|
+
];
|
|
350
|
+
// This should pass - revertXpubPrefix converts upub -> tpub, and the key matches
|
|
351
|
+
(0, src_1.validatePsbtForWithdraw)(psbt.toHex(), network, recipients, accounts);
|
|
352
|
+
});
|
|
353
|
+
it('should validate PSBT with matching vpub prefix and correct key', () => {
|
|
354
|
+
// Import the signer root key from the fixture which corresponds to the upub/vpub accounts
|
|
355
|
+
const signerRootKey = 'tprv8ZgxMBicQKsPe6jS4vDm2n7s42Q6MpvghUQqMmSKG7bTZvGKtjrcU3PGzMNG37yzxywrcdvgkwrr8eYXJmbwdvUNVT4Ucv7ris4jvA7BUmg';
|
|
356
|
+
const masterHDNode = utxolib.bip32.fromBase58(signerRootKey, network);
|
|
357
|
+
// Derive the account key for purpose 84
|
|
358
|
+
const accountKey = masterHDNode.derivePath("m/84'/0'/0'");
|
|
359
|
+
const { psbt } = (0, createPsbt_1.createTestPsbt)({
|
|
360
|
+
network,
|
|
361
|
+
inputValue: 500000,
|
|
362
|
+
outputValue: 100000,
|
|
363
|
+
changeValue: 390000,
|
|
364
|
+
changePurpose: 84,
|
|
365
|
+
changeDerivationPath: "m/84'/0'/0'/1/6",
|
|
366
|
+
masterKey: accountKey,
|
|
367
|
+
});
|
|
368
|
+
const recipientAddress = utxolib.address.fromOutputScript(psbt.txOutputs[0].script, network);
|
|
369
|
+
const recipients = [
|
|
370
|
+
{
|
|
371
|
+
amountSat: BigInt(100000),
|
|
372
|
+
address: recipientAddress,
|
|
373
|
+
},
|
|
374
|
+
];
|
|
375
|
+
// Use the vpub from the fixture - this should work because the keys match
|
|
376
|
+
const accounts = [
|
|
377
|
+
{
|
|
378
|
+
xpub: 'vpub5ZU1PHGpQoDSHckYico4nsvwsD3mTh6UjqL5zyGWXZXzBjTYMNKot7t9eRPQY71hJcnNN9r1ss25g3xA9rmoJ5nWPg8jEWavrttnsVa1qw1',
|
|
379
|
+
purpose: 84,
|
|
380
|
+
coin_type: 0,
|
|
381
|
+
account: 0,
|
|
382
|
+
},
|
|
383
|
+
];
|
|
384
|
+
// This should pass - revertXpubPrefix converts vpub -> tpub, and the key matches
|
|
385
|
+
(0, src_1.validatePsbtForWithdraw)(psbt.toHex(), network, recipients, accounts);
|
|
386
|
+
});
|
|
387
|
+
it('should validate PSBT with multiple recipients', () => {
|
|
388
|
+
// Create a PSBT manually with 2 recipient outputs and 1 change output
|
|
389
|
+
const masterKey = utxolib.bip32.fromSeed(Buffer.alloc(32, 1), network);
|
|
390
|
+
const inputKeyPair = utxolib.ECPair.makeRandom({ network });
|
|
391
|
+
const p2wpkhInput = utxolib.payments.p2wpkh({
|
|
392
|
+
pubkey: Buffer.from(inputKeyPair.publicKey),
|
|
393
|
+
network,
|
|
394
|
+
});
|
|
395
|
+
const psbt = new utxolib.Psbt({ network });
|
|
396
|
+
// Add input
|
|
397
|
+
psbt.addInput({
|
|
398
|
+
hash: 'ca6852598b48230ac870814b935b0d982d3968eb00a1d97332dceb6cd9b8505e',
|
|
399
|
+
index: 1,
|
|
400
|
+
witnessUtxo: {
|
|
401
|
+
script: p2wpkhInput.output,
|
|
402
|
+
value: BigInt(500000),
|
|
403
|
+
},
|
|
404
|
+
bip32Derivation: [
|
|
405
|
+
{
|
|
406
|
+
masterFingerprint: Buffer.alloc(4, 0),
|
|
407
|
+
path: "m/84'/0'/0'/0/0",
|
|
408
|
+
pubkey: Buffer.from(inputKeyPair.publicKey),
|
|
409
|
+
},
|
|
410
|
+
],
|
|
411
|
+
});
|
|
412
|
+
// Create first recipient
|
|
413
|
+
const recipient1KeyPair = utxolib.ECPair.makeRandom({ network });
|
|
414
|
+
const recipient1Payment = utxolib.payments.p2wpkh({
|
|
415
|
+
pubkey: Buffer.from(recipient1KeyPair.publicKey),
|
|
416
|
+
network,
|
|
417
|
+
});
|
|
418
|
+
const recipient1Address = recipient1Payment.address;
|
|
419
|
+
// Create second recipient
|
|
420
|
+
const recipient2KeyPair = utxolib.ECPair.makeRandom({ network });
|
|
421
|
+
const recipient2Payment = utxolib.payments.p2wpkh({
|
|
422
|
+
pubkey: Buffer.from(recipient2KeyPair.publicKey),
|
|
423
|
+
network,
|
|
424
|
+
});
|
|
425
|
+
const recipient2Address = recipient2Payment.address;
|
|
426
|
+
// Derive change address from master key
|
|
427
|
+
const changeNode = masterKey.derive(1).derive(6); // m/1/6
|
|
428
|
+
const changePayment = utxolib.payments.p2wpkh({
|
|
429
|
+
pubkey: changeNode.publicKey,
|
|
430
|
+
network,
|
|
431
|
+
});
|
|
432
|
+
const changeAddress = changePayment.address;
|
|
433
|
+
// Add outputs: recipient1, recipient2, change
|
|
434
|
+
psbt.addOutput({
|
|
435
|
+
address: recipient1Address,
|
|
436
|
+
value: BigInt(100000),
|
|
437
|
+
});
|
|
438
|
+
psbt.addOutput({
|
|
439
|
+
address: recipient2Address,
|
|
440
|
+
value: BigInt(50000),
|
|
441
|
+
});
|
|
442
|
+
psbt.addOutput({
|
|
443
|
+
address: changeAddress,
|
|
444
|
+
value: BigInt(340000), // 500000 - 100000 - 50000 - 10000 (fee)
|
|
445
|
+
});
|
|
446
|
+
// Add bip32Derivation to the change output (index 2)
|
|
447
|
+
psbt.updateOutput(2, {
|
|
448
|
+
bip32Derivation: [
|
|
449
|
+
{
|
|
450
|
+
masterFingerprint: Buffer.alloc(4, 0),
|
|
451
|
+
path: "m/84'/0'/0'/1/6",
|
|
452
|
+
pubkey: changeNode.publicKey,
|
|
453
|
+
},
|
|
454
|
+
],
|
|
455
|
+
});
|
|
456
|
+
const recipients = [
|
|
457
|
+
{
|
|
458
|
+
amountSat: BigInt(100000),
|
|
459
|
+
address: recipient1Address,
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
amountSat: BigInt(50000),
|
|
463
|
+
address: recipient2Address,
|
|
464
|
+
},
|
|
465
|
+
];
|
|
466
|
+
const accounts = [
|
|
467
|
+
{
|
|
468
|
+
xpub: masterKey.neutered().toBase58(),
|
|
469
|
+
purpose: 84,
|
|
470
|
+
coin_type: 0,
|
|
471
|
+
account: 0,
|
|
472
|
+
},
|
|
473
|
+
];
|
|
474
|
+
(0, src_1.validatePsbtForWithdraw)(psbt.toHex(), network, recipients, accounts);
|
|
475
|
+
});
|
|
476
|
+
});
|
|
477
|
+
});
|
|
478
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2VXaXRoZHJhd1BzYnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L3VuaXQvbGlnaHRuaW5nL3BhcnNlV2l0aGRyYXdQc2J0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsb0RBQTRCO0FBRTVCLDhEQUFnRDtBQUVoRCxzQ0FBdUQ7QUFDdkQsNkNBQThDO0FBRTlDLFFBQVEsQ0FBQyxtQkFBbUIsRUFBRSxHQUFHLEVBQUU7SUFDakMsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUM7SUFFekMsUUFBUSxDQUFDLHNDQUFzQyxFQUFFLEdBQUcsRUFBRTtRQUNwRCxtRkFBbUY7UUFDbkYsTUFBTSxlQUFlLEdBQ25CLDQrQkFBNCtCLENBQUM7UUFDLytCLE1BQU0sVUFBVSxHQUFHO1lBQ2pCO2dCQUNFLFNBQVMsRUFBRSxPQUFPO2dCQUNsQixPQUFPLEVBQUUsZ0VBQWdFO2FBQzFFO1NBQ0YsQ0FBQztRQUNGLE1BQU0sUUFBUSxHQUFHO1lBQ2Y7Z0JBQ0UsSUFBSSxFQUFFLGlIQUFpSDtnQkFDdkgsT0FBTyxFQUFFLEVBQUU7Z0JBQ1gsU0FBUyxFQUFFLENBQUM7Z0JBQ1osT0FBTyxFQUFFLENBQUM7YUFDWDtZQUNEO2dCQUNFLElBQUksRUFBRSxpSEFBaUg7Z0JBQ3ZILE9BQU8sRUFBRSxFQUFFO2dCQUNYLFNBQVMsRUFBRSxDQUFDO2dCQUNaLE9BQU8sRUFBRSxDQUFDO2FBQ1g7U0FDRixDQUFDO1FBRUYsRUFBRSxDQUFDLG9DQUFvQyxFQUFFLEdBQUcsRUFBRTtZQUM1QyxJQUFBLDZCQUF1QixFQUFDLGVBQWUsRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzFFLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLG1DQUFtQyxFQUFFLEdBQUcsRUFBRTtZQUMzQyxnQkFB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LEVBQUU7b0JBQ1gsU0FBUyxFQUFFLENBQUM7b0JBQ1osT0FBTyxFQUFFLENBQUM7aUJBQ1g7YUFDRixDQUFDO1lBRUYsSUFBQSw2QkFBdUIsRUFBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUN2RSxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5cbmltcG9ydCAqIGFzIHV0eG9saWIgZnJvbSAnQGJpdGdvLWJldGEvdXR4by1saWInO1xuXG5pbXBvcnQgeyB2YWxpZGF0ZVBzYnRGb3JXaXRoZHJhdyB9IGZyb20gJy4uLy4uLy4uL3NyYyc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0UHNidCB9IGZyb20gJy4vY3JlYXRlUHNidCc7XG5cbmRlc2NyaWJlKCdwYXJzZVdpdGhkcmF3UHNidCcsICgpID0+IHtcbiAgY29uc3QgbmV0d29yayA9IHV0eG9saWIubmV0d29ya3MudGVzdG5ldDtcblxuICBkZXNjcmliZSgncmVncmVzc2lvbiB0ZXN0cyB3aXRoIGhhcmRjb2RlZCBQU0JUJywgKCkgPT4ge1xuICAgIC8vIEtlZXBpbmcgb25lIHJlZ3Jlc3Npb24gdGVzdCB3aXRoIHJlYWwgUFNCVCBkYXRhIHRvIGVuc3VyZSBiYWNrd2FyZCBjb21wYXRpYmlsaXR5XG4gICAgY29uc3QgdW5zaWduZWRQc2J0SGV4ID1cbiAgICAgICc3MDczNjI3NGZmMDEwMDdkMDIwMDAwMDAwMTVlNTBiOGQ5NmNlYmRjMzI3M2Q5YTEwMGViNjgzOTJkOTgwZDViOTM0YjgxNzBjODBhMjM0ODhiNTk1MjY4Y2EwMTAwMDAwMDAwZmZmZmZmZmYwMmEwODYwMTAwMDAwMDAwMDAyMjUxMjAzNzliYzg4Y2MxNWQzNjA1ZWQ5ZGUxYjYxZmY4ZDY1MDIxYjY1MGRiMTE1MWU3NTFhMzA4ODVjY2ZjYzdkMTVhZmZhODBhMDAwMDAwMDAwMDE2MDAxNDgwYTA2ZjJlNmI3N2U4MTdmZDVkZTZlNDFlYTUxMmM1NjNjMjZjYjgwMDAwMDAwMDAwMDEwMGVhMDIwMDAwMDAwMDAxMDFhMTU4ZDgwNjczNWJiN2M1NGU0YzcwMWQ0ZjU4MjFjZDUzNDJkNDhkNWUxZmNiZWQxMTY5ZTZlNDVhYTQ0NGJlMDEwMDAwMDAwMGZmZmZmZmZmMDJhMDg2MDEwMDAwMDAwMDAwMjI1MTIwMzc5YmM4OGNjMTVkMzYwNWVkOWRlMWI2MWZmOGQ2NTAyMWI2NTBkYjExNTFlNzUxYTMwODg1Y2NmY2M3ZDE1YTZhMzEwYzAwMDAwMDAwMDAxNjAwMTQ3OGE1ZDk4YzcxNjA0ODRiOWIwMGYxNzgyODAzYzU4ZWRmYzQ5YjlhMDI0NzMwNDQwMjIwNDA3ZDkxNjJmNTIzNzFkZjI0NmRjZmEyOTQzZDQwZmJkY2IwZDRiNjc2OGY3NjgyYzY1MTkzMzc4YjI4NDVhNjAyMjAxMDFjN2JjNDYwYzkzZDI5NzY5NjFhYzIzNDAwZjBmMTBjMTQ1ZWZiOTg5YTNhZGRiN2YwM2ViYWFhMjIwMDk1MDEyMTAzN2UxNzQ0NGM4NWM4YjdkYTA3ZjEyZmQ1M2NiMmNhMTQyYzJiNDkzMmQwZjg5ODY0OWM0YjViZTAwMjFkYTA5ODAwMDAwMDAwMDEwMzA0MDEwMDAwMDAyMjA2MDJlNTcxNDZlNWI0NzYyYTdmZjM3NGFkZjQwNzIwNDdiNjdlZjExNWFkNDZhMzQxODliZGViNmE0Zjg4ZGI5YjA4MTgwMDAwMDAwMDU0MDAwMDgwMDAwMDAwODAwMDAwMDA4MDAxMDAwMDAwMDYwMDAwMDAwMDAwMjIwMjAzNzlhYmJlNDQwMDRmZjdlNTI3YmRlZTNkZDhkOTVlNWNkMjUwMDUzZjM1ZWU5MjI1OGI5N2FhODNkZmE5M2M2MjE4MDAwMDAwMDA1NDAwMDA4MDAwMDAwMDgwMDAwMDAwODAwMTAwMDAwMDUwMDAwMDAwMDAnO1xuICAgIGNvbnN0IHJlY2lwaWVudHMgPSBbXG4gICAgICB7XG4gICAgICAgIGFtb3VudFNhdDogMTAwMDAwbixcbiAgICAgICAgYWRkcmVzczogJ3RiMXB4N2R1M3J4cHQ1bXF0bXZhdXhtcGw3eGsycXNtdjV4bXo5Zzd3NWRycHp6dWVseDg2OWRxd2FwZTdrJyxcbiAgICAgIH0sXG4gICAgXTtcbiAgICBjb25zdCBhY2NvdW50cyA9IFtcbiAgICAgIHtcbiAgICAgICAgeHB1YjogJ3RwdWJEQ21pV01rVEpyWjI0dDFaNkVDUjNIeXluQ3laOXpHc1dxaGNMaDZINHlGSzJDRG96U3N6RDFwUDJMaTROeDFZWXRSY3ZtTmJkYjNuRDFTekZlall0UEZmVG9jVHYyRWFBZ0pDZzR6cEpwQScsXG4gICAgICAgIHB1cnBvc2U6IDQ5LFxuICAgICAgICBjb2luX3R5cGU6IDAsXG4gICAgICAgIGFjY291bnQ6IDAsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB4cHViOiAndHB1YkRDRk43YnN4UjlVVEtnZ2RIMnBtdjVIZUhHUU5pRHJKd2ExRVpGdFA5c0g1UEYyOGkzN0ZIcG9ZU1lBUlFrS1o2TWk5OHBrcDdveXBEY3hGbUU0ZFFHcThqVjhHdjNMNmdtV0JlUndQeGtQJyxcbiAgICAgICAgcHVycG9zZTogODQsXG4gICAgICAgIGNvaW5fdHlwZTogMCxcbiAgICAgICAgYWNjb3VudDogMCxcbiAgICAgIH0sXG4gICAgXTtcblxuICAgIGl0KCdzaG91bGQgcGFyc2UgYSB2YWxpZCB3aXRoZHJhdyBQU0JUJywgKCkgPT4ge1xuICAgICAgdmFsaWRhdGVQc2J0Rm9yV2l0aGRyYXcodW5zaWduZWRQc2J0SGV4LCBuZXR3b3JrLCByZWNpcGllbnRzLCBhY2NvdW50cyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGZvciBpbnZhbGlkIFBTQlQgaGV4JywgKCkgPT4ge1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiB7XG4gICAgICAgIHZhbGlkYXRlUHNidEZvcldpdGhkcmF3KCdhc2Rhc2QnLCBuZXR3b3JrLCByZWNpcGllbnRzLCBhY2NvdW50cyk7XG4gICAgICB9LCAvRVJSX0JVRkZFUl9PVVRfT0ZfQk9VTkRTLyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdyZWdyZXNzaW9uIHRlc3RzIHdpdGggY3JlYXRlZCBQU0JUIGZyb20gTE5EIChubyBgbS9gIHByZWZpeCknLCAoKSA9PiB7XG4gICAgY29uc3QgdW5zaWduZWRQc2J0SGV4ID1cbiAgICAgICc3MDczNjI3NGZmMDEwMDdkMDIwMDAwMDAwMTgxNGYwN2ZlYmIzNzJjZjllMzAzYzQwOTM4ZDdmMTM3MmNmN2Y1YmQzZDQzZGU3NjNiZTEwYzFiMmFjNTM5MjAwMDAwMDAwMDAwZmZmZmZmZmYwMjg4MTMwMDAwMDAwMDAwMDAyMjAwMjBhYzA2MTE3ODMyZjA4ZTk1MmIxNmMyMjBkZGUzNWRkNTA1YjVjNTRmYTQ1YTRlYjlmMmIwNDBlZmQyN2VjYjEyZjg2YTA0MDAwMDAwMDAwMDE2MDAxNGYxZjQ3NTNjZjBmOTE3MWRkMzcyNGYxN2VhNTExYmFhNDllM2MyMjYwMDAwMDAwMDAwMDEwMGZkZTcwNDAxMDAwMDAwMDAwMTA0ZTU1NjAwYjdkMDAwM2M2YjJiZTdkYzEwNWY2YzM0OTliOGQ0MjZlOTJmZDU2YzNkY2EwNjcyOGUwNjBjODA3MjAwMDAwMDAwMDBmZGZmZmZmZjM2NmY1MzU2MDM4ZTg4M2RkN2RkNjIxZDBiMzQwYzUyNjAxODMyOTY2NGNjYmViMWE3MjNiMGE2ZjhmMzEyYTQwMDAwMDAwMDIzMjIwMDIwYjRiNjlkZWE5OGQ4ZDVmYjMyYTIyYTBjOWFkMjA4ZmMyOGVmYjQ0OTQzZjhlNTc2ZDU5NzhkMjE1ZDc4NGQ0OWZkZmZmZmZmMTU5NzhmOTAzZDYzZGFjNTYwMjZjZWM5MGZjNTY4ZmJlNmU4YTVhOGI1M2JmOGI1YTM0ZWVlMzcyM2U2M2VmZjAwMDAwMDAwMDBmZGZmZmZmZjU4YTllNmJlMWRhMGYyNWUzOWFmNGM5NWVkMTAyMzM2YTY0YmFmOWJjOGViN2MxZmZjYTk3ZmYwZDBkNjUxZmYwMDAwMDAwMDAwZmRmZmZmZmYwMTQ1ODYwNDAwMDAwMDAwMDAxNjAwMTQ2YjYxOGU4ZDFkNzA5NzExMTA0ZjkyYTg1NzAzMmE4ZDY2ZjFiZjdkMDQwMDQ4MzA0NTAyMjEwMGQ4NWJjOTliZjZkNjEwOTc4NjMwNTE4Zjc5ZWVlZTAyNWM4Y2U0MGViNjVmMTIzNjBmMGY0N2Q1YjMwY2E1NDcwMjIwMzZkNzkzODRhNTViYmJhMDA1MjBkNjI2YzNhZTA1YTVmMzQxZmQ3ZDY1ZjIxMWZhNjRiZmVkYWQ1ZTgyN2M3MzAxNDgzMDQ1MDIyMTAwZGFjY2UzN2ZiZmZlYjJlOWVlMTk4YWIzYTc4Y2ZkZjAxZTM0NjU1MzEzNDgyZmY3NTM3NmJiNWUyMTUyYTA1ZDAyMjA1YTdkMWI3MDcyNDgwMzY4ZDI3NGRlMDIyOWJiYjllNmY0ZTRjZGEyMDJmNjc1MGI5YTkwZjg1MTc2MDQ0MTNlMDE2OTUyMjEwMmRkNmIxNWQ1YzQ4MzA4MGFhZWFmM2JlNTFjOGVlNmNkNzk0ZGJmYTY1ZTVjODAzNmZlMmM2N2YwMDgwOTI5NzAyMTAzMzcwYzQ0ZTA1ZGRkZmMyOWZkYjQxOGFlNTgzNjUyYjRmYjdlZTYyZDA3NTYyZmMxZTViMTY5NmNhYWYzOTA4ZjIxMDNjNmQ5ODA4MTFjYjAzMDQ4YTdiNDhmNjM5YmJiMDU3NTQ0NGFmMWY2NzBhZjg0NjJiYjFjOTMxMTJhZjIwODBhNTNhZTA0MDA0ODMwNDUwMjIxMDA5NDY0NmU4YzFjMjUzNjhlZDljZGY1YmExMGI1NGE4OGNlMjBiYjliNDUyODc3ZDBkMmYyNzgyMzg5N2FiOWQ0MDIyMDE4M2M4MDU2MGMxODYwZDIyZDdhZThhYWVlZTcxMmQ5MzBlNDI3MjUyMzQ1YmRkZWNlMWEzMzNkMzQ1YzZkOTgwMTQ4MzA0NTAyMjEwMGQxMjNjMWY1YTc5ZDMyOTA1ZjlkNzI1YjU5MDE2MGFmYzhlMTRiYjAxY2IxYTVkMjU4MzA0YzZiNjY3MzExM2MwMjIwNzIyMDAzMDUwZjU3MzY2YjNmMzQ4NmMxZmRkNTU1OTU3OWYxYzY3YzNkNjQ0ZDMxYWM2ZjIwYmI4MDIyZjdkMjAxNjk1MjIxMDM0YTJjOGUwODkxZTMwNjk4YWE3MDE1ZjEyMTA0NTFmMWU1MzM2YmU5NmJmODQ2Y2Q0MzUyOGMxNWIwNjQ1YjAzMjEwM2U2MzA1Zjc5NzgzODI5OWY0MTg4NTk1YjFiMDFiZDlmZTYwZGIwZTRiYjkzMzFkOTU3NzUwMjQ4ZDA1NWYyOTkyMTAzODNjMDI4MzQxZDVkMjczYWZjYTVmNTI2NWUyYzJlZTk2MTljMGYxYjMyODk1NmVmMzAwMGFiMDllY2NhZWQzYjUzYWUwNDAwNDczMDQ0MDIyMDQ0YTQzYWUzOGI4NmMzNzVhYTU3YjNkOTYzODZmY2E1MmY3NGE1YmM0ZmIzN2M3NzczOGVmYTRjMDU2NjY2MjIwMjIwMGQxYWY5M2QyMDIyYzQ4ZjNmM2NjMTM0ZDNkNzViYmNmY2UzMDYxNWU1M2Q5MjQ2YzIwMGM1MzQ5YTdkOTc4YzAxNDczMDQ0MDIyMDdjZTMwNDMyMTFkOTM0NGRhZDhmNGUyYmY4NDhiZjFjYTE1MTMxMGExODhlNzA3NjYzYjI4NDc1ZTEyMDk5ZDAwMjIwNjBkMmIzNTMzZTdjMzYyZDM5YjA0MTEwMmVkZjE3ZTA0ODZiMWFlZTU1YTAxYzc4OTU0ODViODYzMGRhYTM5YzAxNjk1MjIxMDNjNzFhMzUwZTJiMDZlYzlkMDcxMGExM2Y2MDhiYjc2ZjM1YTM1ZmVkNDkxZmJiNWI5NzI4MGNhZWQ0Yzk1OTBmMjEwMzY5MmVhNjg1MTYyYTFkYTdlODZlMGJlZWIxZWQwMzMxZThkMGZiYmYyZTA1ZjAwMjA3MWIxNTA0NGM0MDJiNzgyMTAyOTYwMDg3ZDBkNWI4ZTFhNDQ5ZWQ1NjI1NTNlZjMxNDk4ODVhOTMwZjYwYzQwMzI0MTY1MjIxYTdmYzc2MjdlYTUzYWUwNDAwNDgzMDQ1MDIyMTAwYTgzODJjZmEyNTgyYWJkYzc3NDE3ZjlhYTUzZTVjZTBlMmQzMWViNWUxNGI3ODM2OTYxZGE4YzA0NWRlM2E1MDAyMjAzOTg1NTViOTM4MTZlZjdlYzQxN2JiNzU1NWJjNTFlMDQ3N2IzYzY1ZjgzZDA5NTFjZmYyYTUwNDA0NTczMTRlMDE0NzMwNDQwMjIwNGY2NmZkNDUwN2JkNTRjYzI1MDI4YjU2NjBjMDBmZGNmZTE1Y2U2MTIxZWFiZmY3OTExZTczMDdkMjRjN2YxMTAyMjAwNTkxZTk2OTg5NzEwOWEyMzcyYTZiMjJlNDFkMTU4ZDRlMGFlNTNjYTA5NjMxNjZmZmQ4YTIzZTA2NTIyYWM5MDE2OTUyMjEwMjgyYWFmMjhkNTI4ZTZiNjMyNjg4MGIxNTM5YTE0YTk2ZGNlZTVkOWEwOTIwYTMxZjM1ODFlNWFjMjFhOWRlNDYyMTAzZjg0ZTI2ZTc4ZjJjNTg3ODIxYjU4MTc2MWIxMzRmNzcyMWUzM2IxYWQ5N2JkMTU5OTEyNWVlMjMzNjllYTEyMDIxMDNkYTZlZGRjYTljMGVhYWEwOGIxNzljMDM1ZWQwYWRiNTE2YTU5MmJhMTMyMWZmYzVjYjExZGNhZThjM2E3MDRmNTNhZTAwMDAwMDAwMDEwMTFmNDU4NjA0MDAwMDAwMDAwMDE2MDAxNDZiNjE4ZThkMWQ3MDk3MTExMDRmOTJhODU3MDMyYThkNjZmMWJmN2QwMTAzMDQwMTAwMDAwMDIyMDYwMzgzNjFiZmFkOWI2ODk2YzkzODY5MGRmMWU2N2M2NjllY2Q3YTAyMWIxMTczODJiYmZhODFmZjZkZThlYzE1MzcxODAwMDAwMDAwNTQwMDAwODAwMDAwMDA4MDAwMDAwMDgwMDAwMDAwMDAwMDAwMDAwMDAwMDAyMjAyMDM3NmNiNGFjODk5ZDEzMGUyZDY1NWZjYTZkMzYyZmU3Yzc0NWNjMTU0ODY4NDllNDAxZjdjMjFiM2QzZGYzN2M4MTgwMDAwMDAwMDU0MDAwMDgwMDAwMDAwODAwMDAwMDA4MDAxMDAwMDAwMDgwMDAwMDAwMCc7XG4gICAgY29uc3QgcmVjaXBpZW50cyA9IFtcbiAgICAgIHtcbiAgICAgICAgYW1vdW50U2F0OiA1MDAwbixcbiAgICAgICAgYWRkcmVzczogJ3RiMXE0c3Jwejdwajd6OGYyMmNrY2dzZG1jNmE2NXptdDMyMDUzZHlhdzBqa3Bxd2w1bjdldmZxaGMwN3U0JyxcbiAgICAgIH0sXG4gICAgXTtcbiAgICBjb25zdCBhY2NvdW50cyA9IFtcbiAgICAgIHtcbiAgICAgICAgcHVycG9zZTogNDksXG4gICAgICAgIGNvaW5fdHlwZTogMCxcbiAgICAgICAgYWNjb3VudDogMCxcbiAgICAgICAgeHB1YjogJ3VwdWI1RVcyY2ltMkZTZUJEcW90ZThqY0tuQlNvaHRaalBSYnc5SHNYTm90b3RpcFZWajMxQXpXamdYVVNvbmJ2aTdSTkFMWTczcmtnWFRRWTRZVXBvdnJHMVdWNEFUS1h5UXBNYTFzTW5KZENibScsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBwdXJwb3NlOiA4NCxcbiAgICAgICAgY29pbl90eXBlOiAwLFxuICAgICAgICBhY2NvdW50OiAwLFxuICAgICAgICB4cHViOiAndnB1YjVaOGtWczlMNmZTSzRxYzFHMzZWcUtkVGlTZGZDR1N6cmN6NEVZR2t5d2tXWDQzRUppTGNTQkVkMVhFNGZ4Z1hpcjdXa3dhaWE0ZVR3YmFrbmdWREhIblRvYzlxUU1CY3hlcnIyVTVNSG5OJyxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIHB1cnBvc2U6IDg2LFxuICAgICAgICBjb2luX3R5cGU6IDAsXG4gICAgICAgIGFjY291bnQ6IDAsXG4gICAgICAgIHhwdWI6ICd0cHViREN5WERuTHFobVR4amNHVjJLZXhyb2pmSlBCZXB0MmdXczJtZzlWNDZ5NkhBcDluTHpnM2lkbUVTRUoxUkR0ZmFMeVZMNngyTW9Kc3Y2NmhRUFdyQ3hvUjJqWVFiR2JIZDVGbUVhNkJmVzMnLFxuICAgICAgfSxcbiAgICBdO1xuXG4gICAgaXQoJ3Nob3VsZCBwYXJzZSBhIHZhbGlkIHdpdGhkcmF3IFBTQlQnLCAoKSA9PiB7XG4gICAgICB2YWxpZGF0ZVBzYnRGb3JXaXRoZHJhdyh1bnNpZ25lZFBzYnRIZXgsIG5ldHdvcmssIHJlY2lwaWVudHMsIGFjY291bnRzKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZm9yIGludmFsaWQgUFNCVCBoZXgnLCAoKSA9PiB7XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHtcbiAgICAgICAgdmFsaWRhdGVQc2J0Rm9yV2l0aGRyYXcoJ2FzZGFzZCcsIG5ldHdvcmssIHJlY2lwaWVudHMsIGFjY291bnRzKTtcbiAgICAgIH0sIC9FUlJfQlVGRkVSX09VVF9PRl9CT1VORFMvKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3Rlc3QgY2FzZXMgd2l0aCBjcmVhdGluZyBwc2J0IG9uIHRoZSBnbycsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIFBTQlQgd2l0aCBQMldQS0ggKHB1cnBvc2UgODQpIGNoYW5nZSBhZGRyZXNzJywgKCkgPT4ge1xuICAgICAgY29uc3QgeyBwc2J0LCBtYXN0ZXJLZXkgfSA9IGNyZWF0ZVRlc3RQc2J0KHtcbiAgICAgICAgbmV0d29yayxcbiAgICAgICAgaW5wdXRWYWx1ZTogNTAwMDAwLFxuICAgICAgICBvdXRwdXRWYWx1ZTogMTAwMDAwLFxuICAgICAgICBjaGFuZ2VWYWx1ZTogMzkwMDAwLFxuICAgICAgICBjaGFuZ2VQdXJwb3NlOiA4NCxcbiAgICAgICAgY2hhbmdlRGVyaXZhdGlvblBhdGg6IFwibS84NCcvMCcvMCcvMS82XCIsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcmVjaXBpZW50QWRkcmVzcyA9IHV0eG9saWIuYWRkcmVzcy5mcm9tT3V0cHV0U2NyaXB0KHBzYnQudHhPdXRwdXRzWzBdLnNjcmlwdCwgbmV0d29yayk7XG5cbiAgICAgIGNvbnN0IHJlY2lwaWVudHMgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICBhbW91bnRTYXQ6IEJpZ0ludCgxMDAwMDApLFxuICAgICAgICAgIGFkZHJlc3M6IHJlY2lwaWVudEFkZHJlc3MsXG4gICAgICAgIH0sXG4gICAgICBdO1xuXG4gICAgICBjb25zdCBhY2NvdW50cyA9IFtcbiAgICAgICAge1xuICAgICAgICAgIHhwdWI6IG1hc3RlcktleS5uZXV0ZXJlZCgpLnRvQmFzZTU4KCksXG4gICAgICAgICAgcHVycG9zZTogODQsXG4gICAgICAgICAgY29pbl90eXBlOiAwLFxuICAgICAgICAgIGFjY291bnQ6IDAsXG4gICAgICAgIH0sXG4gICAgICBdO1xuXG4gICAgICB2YWxpZGF0ZVBzYnRGb3JXaXRoZHJhdyhwc2J0LnRvSGV4KCksIG5ldHdvcmssIHJlY2lwaWVudHMsIGFjY291bnRzKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgUFNCVCB3aXRoIFAyU0gtUDJXUEtIIChwdXJwb3NlIDQ5KSBjaGFuZ2UgYWRkcmVzcycsICgpID0+IHtcbiAgICAgIGNvbnN0IHsgcHNidCwgbWFzdGVyS2V5IH0gPSBjcmVhdGVUZXN0UHNidCh7XG4gICAgICAgIG5ldHdvcmssXG4gICAgICAgIGlucHV0VmFsdWU6IDUwMDAwMCxcbiAgICAgICAgb3V0cHV0VmFsdWU6IDEwMDAwMCxcbiAgICAgICAgY2hhbmdlVmFsdWU6IDM5MDAwMCxcbiAgICAgICAgY2hhbmdlUHVycG9zZTogNDksXG4gICAgICAgIGNoYW5nZURlcml2YXRpb25QYXRoOiBcIm0vNDknLzAnLzAnLzEvNlwiLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHJlY2lwaWVudEFkZHJlc3MgPSB1dHhvbGliLmFkZHJlc3MuZnJvbU91dHB1dFNjcmlwdChwc2J0LnR4T3V0cHV0c1swXS5zY3JpcHQsIG5ldHdvcmspO1xuXG4gICAgICBjb25zdCByZWNpcGllbnRzID0gW1xuICAgICAgICB7XG4gICAgICAgICAgYW1vdW50U2F0OiBCaWdJbnQoMTAwMDAwKSxcbiAgICAgICAgICBhZGRyZXNzOiByZWNpcGllbnRBZGRyZXNzLFxuICAgICAgICB9LFxuICAgICAgXTtcblxuICAgICAgY29uc3QgYWNjb3VudHMgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICB4cHViOiBtYXN0ZXJLZXkubmV1dGVyZWQoKS50b0Jhc2U1OCgpLFxuICAgICAgICAgIHB1cnBvc2U6IDQ5LFxuICAgICAgICAgIGNvaW5fdHlwZTogMCxcbiAgICAgICAgICBhY2NvdW50OiAwLFxuICAgICAgICB9LFxuICAgICAgXTtcblxuICAgICAgdmFsaWRhdGVQc2J0Rm9yV2l0aGRyYXcocHNidC50b0hleCgpLCBuZXR3b3JrLCByZWNpcGllbnRzLCBhY2NvdW50cyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIFBTQlQgd2l0aCBQMlRSIChwdXJwb3NlIDg2KSBjaGFuZ2UgYWRkcmVzcycsICgpID0+IHtcbiAgICAgIGNvbnN0IHsgcHNidCwgbWFzdGVyS2V5IH0gPSBjcmVhdGVUZXN0UHNidCh7XG4gICAgICAgIG5ldHdvcmssXG4gICAgICAgIGlucHV0VmFsdWU6IDUwMDAwMCxcbiAgICAgICAgb3V0cHV0VmFsdWU6IDEwMDAwMCxcbiAgICAgICAgY2hhbmdlVmFsdWU6IDM5MDAwMCxcbiAgICAgICAgY2hhbmdlUHVycG9zZTogODYsXG4gICAgICAgIGNoYW5nZURlcml2YXRpb25QYXRoOiBcIm0vODYnLzAnLzAnLzEvNlwiLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHJlY2lwaWVudEFkZHJlc3MgPSB1dHhvbGliLmFkZHJlc3MuZnJvbU91dHB1dFNjcmlwdChwc2J0LnR4T3V0cHV0c1swXS5zY3JpcHQsIG5ldHdvcmspO1xuXG4gICAgICBjb25zdCByZWNpcGllbnRzID0gW1xuICAgICAgICB7XG4gICAgICAgICAgYW1vdW50U2F0OiBCaWdJbnQoMTAwMDAwKSxcbiAgICAgICAgICBhZGRyZXNzOiByZWNpcGllbnRBZGRyZXNzLFxuICAgICAgICB9LFxuICAgICAgXTtcblxuICAgICAgY29uc3QgYWNjb3VudHMgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICB4cHViOiBtYXN0ZXJLZXkubmV1dGVyZWQoKS50b0Jhc2U1OCgpLFxuICAgICAgICAgIHB1cnBvc2U6IDg2LFxuICAgICAgICAgIGNvaW5fdHlwZTogMCxcbiAgICAgICAgICBhY2NvdW50OiAwLFxuICAgICAgICB9LFxuICAgICAgXTtcblxuICAgICAgdmFsaWRhdGVQc2J0Rm9yV2l0aGRyYXcocHNidC50b0hleCgpLCBuZXR3b3JrLCByZWNpcGllbnRzLCBhY2NvdW50cyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGZvciBtaXNzaW5nIGJpcDMyRGVyaXZhdGlvbiBwYXRoIG9uIGNoYW5nZSBvdXRwdXQnLCAoKSA9PiB7XG4gICAgICBjb25zdCB7IHBzYnQsIG1hc3RlcktleSB9ID0gY3JlYXRlVGVzdFBzYnQoe1xuICAgICAgICBuZXR3b3JrLFxuICAgICAgICBpbnB1dFZhbHVlOiA1MDAwMDAsXG4gICAgICAgIG91dHB1dFZhbHVlOiAxMDAwMDAsXG4gICAgICAgIGNoYW5nZVZhbHVlOiAzOTAwMDAsXG4gICAgICAgIGNoYW5nZVB1cnBvc2U6IDg0LFxuICAgICAgfSk7XG5cbiAgICAgIC8vIFJlbW92ZSB0aGUgYmlwMzJEZXJpdmF0aW9uIGZyb20gdGhlIGNoYW5nZSBvdXRwdXRcbiAgICAgIC8vIFRoaXMgd2lsbCBjYXVzZSB0aGUgb3V0cHV0IHRvIGJlIHRyZWF0ZWQgYXMgYSByZWd1bGFyIHJlY2lwaWVudCBvdXRwdXQsIG5vdCBhIGNoYW5nZSBvdXRwdXRcbiAgICAgIGRlbGV0ZSBwc2J0LmRhdGEub3V0cHV0c1sxXS5iaXAzMkRlcml2YXRpb247XG5cbiAgICAgIGNvbnN0IHJlY2lwaWVudEFkZHJlc3MgPSB1dHhvbGliLmFkZHJlc3MuZnJvbU91dHB1dFNjcmlwdChwc2J0LnR4T3V0cHV0c1swXS5zY3JpcHQsIG5ldHdvcmspO1xuXG4gICAgICBjb25zdCByZWNpcGllbnRzID0gW1xuICAgICAgICB7XG4gICAgICAgICAgYW1vdW50U2F0OiBCaWdJbnQoMTAwMDAwKSxcbiAgICAgICAgICBhZGRyZXNzOiByZWNpcGllbnRBZGRyZXNzLFxuICAgICAgICB9LFxuICAgICAgXTtcblxuICAgICAgY29uc3QgYWNjb3VudHMgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICB4cHViOiBtYXN0ZXJLZXkubmV1dGVyZWQoKS50b0Jhc2U1OCgpLFxuICAgICAgICAgIHB1cnBvc2U6IDg0LFxuICAgICAgICAgIGNvaW5fdHlwZTogMCxcbiAgICAgICAgICBhY2NvdW50OiAwLFxuICAgICAgICB9LFxuICAgICAgXTtcblxuICAgICAgLy8gVGhlIG91dHB1dCB3aXRob3V0IGJpcDMyRGVyaXZhdGlvbiBpcyB0cmVhdGVkIGFzIGEgcmVjaXBpZW50IG91dHB1dCxcbiAgICAgIC8vIGFuZCBzaW5jZSBpdCdzIG5vdCBpbiB0aGUgcmVjaXBpZW50cyBsaXN0LCBpdCBzaG91bGQgZmFpbCB3aXRoIFwiZG9lcyBub3QgbWF0Y2ggYW55IHJlY2lwaWVudFwiXG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHtcbiAgICAgICAgdmFsaWRhdGVQc2J0Rm9yV2l0aGRyYXcocHNidC50b0hleCgpLCBuZXR3b3JrLCByZWNpcGllbnRzLCBhY2NvdW50cyk7XG4gICAgICB9LCAvZG9lcyBub3QgbWF0Y2ggYW55IHJlY2lwaWVudC8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBmb3IgaW52YWxpZCBjaGFuZ2UgYWRkcmVzcyAoZGVyaXZlZCBhZGRyZXNzIG1pc21hdGNoKScsICgpID0+IHtcbiAgICAgIGNvbnN0IHsgcHNidCB9ID0gY3JlYXRlVGVzdFBzYnQoe1xuICAgICAgICBuZXR3b3JrLFxuICAgICAgICBpbnB1dFZhbHVlOiA1MDAwMDAsXG4gICAgICAgIG91dHB1dFZhbHVlOiAxMDAwMDAsXG4gICAgICAgIGNoYW5nZVZhbHVlOiAzOTAwMDAsXG4gICAgICAgIGNoYW5nZVB1cnBvc2U6IDg0LFxuICAgICAgICBjaGFuZ2VEZXJpdmF0aW9uUGF0aDogXCJtLzg0Jy8wJy8wJy8xLzZcIixcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCByZWNpcGllbnRBZGRyZXNzID0gdXR4b2xpYi5hZGRyZXNzLmZyb21PdXRwdXRTY3JpcHQocHNidC50eE91dHB1dHNbMF0uc2NyaXB0LCBuZXR3b3JrKTtcblxuICAgICAgY29uc3QgcmVjaXBpZW50cyA9IFtcbiAgICAgICAge1xuICAgICAgICAgIGFtb3VudFNhdDogQmlnSW50KDEwMDAwMCksXG4gICAgICAgICAgYWRkcmVzczogcmVjaXBpZW50QWRkcmVzcyxcbiAgICAgICAgfSxcbiAgICAgIF07XG5cbiAgICAgIC8vIFVzZSBhIGRpZmZlcmVudCB4cHViIHRoYXQgd29uJ3QgbWF0Y2ggdGhlIGNoYW5nZSBhZGRyZXNzXG4gICAgICBjb25zdCBkaWZmZXJlbnRNYXN0ZXJLZXkgPSB1dHhvbGliLmJpcDMyLmZyb21TZWVkKEJ1ZmZlci5hbGxvYygzMiwgMiksIG5ldHdvcmspO1xuICAgICAgY29uc3QgYWNjb3VudHMgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICB4cHViOiBkaWZmZXJlbnRNYXN0ZXJLZXkubmV1dGVyZWQoKS50b0Jhc2U1OCgpLFxuICAgICAgICAgIHB1cnBvc2U6IDg0LFxuICAgICAgICAgIGNvaW5fdHlwZTogMCxcbiAgICAgICAgICBhY2NvdW50OiAwLFxuICAgICAgICB9LFxuICAgICAgXTtcblxuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiB7XG4gICAgICAgIHZhbGlkYXRlUHNidEZvcldpdGhkcmF3KHBzYnQudG9IZXgoKSwgbmV0d29yaywgcmVjaXBpZW50cywgYWNjb3VudHMpO1xuICAgICAgfSwgL0Rlcml2ZWQgcHVia2V5IGRvZXMgbm90IG1hdGNoIGZvciBhZGRyZXNzLyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIFBTQlQgd2l0aCB1cHViIHByZWZpeCAoUDJTSC1QMldQS0ggdGVzdG5ldCknLCAoKSA9PiB7XG4gICAgICBjb25zdCB7IHBzYnQgfSA9IGNyZWF0ZVRlc3RQc2J0KHtcbiAgICAgICAgbmV0d29yayxcbiAgICAgICAgaW5wdXRWYWx1ZTogNTAwMDAwLFxuICAgICAgICBvdXRwdXRWYWx1ZTogMTAwMDAwLFxuICAgICAgICBjaGFuZ2VWYWx1ZTogMzkwMDAwLFxuICAgICAgICBjaGFuZ2VQdXJwb3NlOiA0OSxcbiAgICAgICAgY2hhbmdlRGVyaXZhdGlvblBhdGg6IFwibS80OScvMCcvMCcvMS82XCIsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcmVjaXBpZW50QWRkcmVzcyA9IHV0eG9saWIuYWRkcmVzcy5mcm9tT3V0cHV0U2NyaXB0KHBzYnQudHhPdXRwdXRzWzBdLnNjcmlwdCwgbmV0d29yayk7XG5cbiAgICAgIGNvbnN0IHJlY2lwaWVudHMgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICBhbW91bnRTYXQ6IEJpZ0ludCgxMDAwMDApLFxuICAgICAgICAgIGFkZHJlc3M6IHJlY2lwaWVudEFkZHJlc3MsXG4gICAgICAgIH0sXG4gICAgICBdO1xuXG4gICAgICAvLyBVc2UgdXB1YiBwcmVmaXggKHRlc3RuZXQgUDJTSC1QMldQS0gpIGluc3RlYWQgb2Ygc3RhbmRhcmQgdHB1YlxuICAgICAgLy8gVGhpcyB0ZXN0cyB0aGF0IHJldmVydFhwdWJQcmVmaXggY29ycmVjdGx5IGNvbnZlcnRzIHVwdWIgLT4gdHB1YlxuICAgICAgY29uc3QgYWNjb3VudHMgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICB4cHViOiAndXB1YjVFZXA3SDVxMzlQelFaTFZFWUxCeXREeUJOZVY3NEU4bVFzeWVMNlVvekZxOVkzTXNaNTJHN1lHdXFySlBnb3lBcUY3VEJlSmRua3JIclZyQjVwa1drUEo5Y0pHQWVQTVU2RjFHeXc2YUZIJyxcbiAgICAgICAgICBwdXJwb3NlOiA0OSxcbiAgICAgICAgICBjb2luX3R5cGU6IDAsXG4gICAgICAgICAgYWNjb3VudDogMCxcbiAgICAgICAgfSxcbiAgICAgIF07XG5cbiAgICAgIC8vIFRoaXMgc2hvdWxkIHdvcmsgYmVjYXVzZSByZXZlcnRYcHViUHJlZml4IHdpbGwgY29udmVydCB1cHViIGJhY2sgdG8gdHB1YlxuICAgICAgLy8gSG93ZXZlciwgdGhlIG1hc3RlciBrZXkgd2UgdXNlZCBpcyBkaWZmZXJlbnQsIHNvIGl0IHNob3VsZCBmYWlsIHdpdGggcHVia2V5IG1pc21hdGNoXG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHtcbiAgICAgICAgdmFsaWRhdGVQc2J0Rm9yV2l0aGRyYXcocHNidC50b0hleCgpLCBuZXR3b3JrLCByZWNpcGllbnRzLCBhY2NvdW50cyk7XG4gICAgICB9LCAvRGVyaXZlZCBwdWJrZXkgZG9lcyBub3QgbWF0Y2ggZm9yIGFkZHJlc3MvKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgUFNCVCB3aXRoIHZwdWIgcHJlZml4IChQMldQS0ggdGVzdG5ldCknLCAoKSA9PiB7XG4gICAgICBjb25zdCB7IHBzYnQgfSA9IGNyZWF0ZVRlc3RQc2J0KHtcbiAgICAgICAgbmV0d29yayxcbiAgICAgICAgaW5wdXRWYWx1ZTogNTAwMDAwLFxuICAgICAgICBvdXRwdXRWYWx1ZTogMTAwMDAwLFxuICAgICAgICBjaGFuZ2VWYWx1ZTogMzkwMDAwLFxuICAgICAgICBjaGFuZ2VQdXJwb3NlOiA4NCxcbiAgICAgICAgY2hhbmdlRGVyaXZhdGlvblBhdGg6IFwibS84NCcvMCcvMCcvMS82XCIsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcmVjaXBpZW50QWRkcmVzcyA9IHV0eG9saWIuYWRkcmVzcy5mcm9tT3V0cHV0U2NyaXB0KHBzYnQudHhPdXRwdXRzWzBdLnNjcmlwdCwgbmV0d29yayk7XG5cbiAgICAgIGNvbnN0IHJlY2lwaWVudHMgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICBhbW91bnRTYXQ6IEJpZ0ludCgxMDAwMDApLFxuICAgICAgICAgIGFkZHJlc3M6IHJlY2lwaWVudEFkZHJlc3MsXG4gICAgICAgIH0sXG4gICAgICBdO1xuXG4gICAgICAvLyBVc2UgdnB1YiBwcmVmaXggKHRlc3RuZXQgUDJXUEtIKSBpbnN0ZWFkIG9mIHN0YW5kYXJkIHRwdWJcbiAgICAgIC8vIFRoaXMgdGVzdHMgdGhhdCByZXZlcnRYcHViUHJlZml4IGNvcnJlY3RseSBjb252ZXJ0cyB2cHViIC0+IHRwdWJcbiAgICAgIGNvbnN0IGFjY291bnRzID0gW1xuICAgICAgICB7XG4gICAgICAgICAgeHB1YjogJ3ZwdWI1WlUxUEhHcFFvRFNIY2tZaWNvNG5zdndzRDNtVGg2VWpxTDV6eUdXWFpYekJqVFlNTktvdDd0OWVSUFFZNzFoSmNuTk45cjFzczI1ZzN4QTlybW9KNW5XUGc4akVXYXZydHRuc1ZhMXF3MScsXG4gICAgICAgICAgcHVycG9zZTogODQsXG4gICAgICAgICAgY29pbl90eXBlOiAwLFxuICAgICAgICAgIGFjY291bnQ6IDAsXG4gICAgICAgIH0sXG4gICAgICBdO1xuXG4gICAgICAvLyBUaGlzIHNob3VsZCB3b3JrIGJlY2F1c2UgcmV2ZXJ0WHB1YlByZWZpeCB3aWxsIGNvbnZlcnQgdnB1YiBiYWNrIHRvIHRwdWJcbiAgICAgIC8vIEhvd2V2ZXIsIHRoZSBtYXN0ZXIga2V5IHdlIHVzZWQgaXMgZGlmZmVyZW50LCBzbyBpdCBzaG91bGQgZmFpbCB3aXRoIHB1YmtleSBtaXNtYXRjaFxuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiB7XG4gICAgICAgIHZhbGlkYXRlUHNidEZvcldpdGhkcmF3KHBzYnQudG9IZXgoKSwgbmV0d29yaywgcmVjaXBpZW50cywgYWNjb3VudHMpO1xuICAgICAgfSwgL0Rlcml2ZWQgcHVia2V5IGRvZXMgbm90IG1hdGNoIGZvciBhZGRyZXNzLyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIFBTQlQgd2l0aCBtYXRjaGluZyB1cHViIHByZWZpeCBhbmQgY29ycmVjdCBrZXknLCAoKSA9PiB7XG4gICAgICAvLyBJbXBvcnQgdGhlIHNpZ25lciByb290IGtleSBmcm9tIHRoZSBmaXh0dXJlIHdoaWNoIGNvcnJlc3BvbmRzIHRvIHRoZSB1cHViL3ZwdWIgYWNjb3VudHNcbiAgICAgIGNvbnN0IHNpZ25lclJvb3RLZXkgPVxuICAgICAgICAndHBydjhaZ3hNQmljUUtzUGU2alM0dkRtMm43czQyUTZNcHZnaFVRcU1tU0tHN2JUWnZHS3RqcmNVM1BHek1ORzM3eXp4eXdyY2R2Z2t3cnI4ZVlYSm1id2R2VU5WVDRVY3Y3cmlzNGp2QTdCVW1nJztcbiAgICAgIGNvbnN0IG1hc3RlckhETm9kZSA9IHV0eG9saWIuYmlwMzIuZnJvbUJhc2U1OChzaWduZXJSb290S2V5LCBuZXR3b3JrKTtcblxuICAgICAgLy8gRGVyaXZlIHRoZSBhY2NvdW50IGtleSBmb3IgcHVycG9zZSA0OVxuICAgICAgY29uc3QgYWNjb3VudEtleSA9IG1hc3RlckhETm9kZS5kZXJpdmVQYXRoKFwibS80OScvMCcvMCdcIik7XG5cbiAgICAgIGNvbnN0IHsgcHNidCB9ID0gY3JlYXRlVGVzdFBzYnQoe1xuICAgICAgICBuZXR3b3JrLFxuICAgICAgICBpbnB1dFZhbHVlOiA1MDAwMDAsXG4gICAgICAgIG91dHB1dFZhbHVlOiAxMDAwMDAsXG4gICAgICAgIGNoYW5nZVZhbHVlOiAzOTAwMDAsXG4gICAgICAgIGNoYW5nZVB1cnBvc2U6IDQ5LFxuICAgICAgICBjaGFuZ2VEZXJpdmF0aW9uUGF0aDogXCJtLzQ5Jy8wJy8wJy8xLzZcIixcbiAgICAgICAgbWFzdGVyS2V5OiBhY2NvdW50S2V5LFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHJlY2lwaWVudEFkZHJlc3MgPSB1dHhvbGliLmFkZHJlc3MuZnJvbU91dHB1dFNjcmlwdChwc2J0LnR4T3V0cHV0c1swXS5zY3JpcHQsIG5ldHdvcmspO1xuXG4gICAgICBjb25zdCByZWNpcGllbnRzID0gW1xuICAgICAgICB7XG4gICAgICAgICAgYW1vdW50U2F0OiBCaWdJbnQoMTAwMDAwKSxcbiAgICAgICAgICBhZGRyZXNzOiByZWNpcGllbnRBZGRyZXNzLFxuICAgICAgICB9LFxuICAgICAgXTtcblxuICAgICAgLy8gVXNlIHRoZSB1cHViIGZyb20gdGhlIGZpeHR1cmUgLSB0aGlzIHNob3VsZCB3b3JrIGJlY2F1c2UgdGhlIGtleXMgbWF0Y2hcbiAgICAgIGNvbnN0IGFjY291bnRzID0gW1xuICAgICAgICB7XG4gICAgICAgICAgeHB1YjogJ3VwdWI1RWVwN0g1cTM5UHpRWkxWRVlMQnl0RHlCTmVWNzRFOG1Rc3llTDZVb3pGcTlZM01zWjUyRzdZR3VxckpQZ295QXFGN1RCZUpkbmtySHJWckI1cGtXa1BKOWNKR0FlUE1VNkYxR3l3NmFGSCcsXG4gICAgICAgICAgcHVycG9zZTogNDksXG4gICAgICAgICAgY29pbl90eXBlOiAwLFxuICAgICAgICAgIGFjY291bnQ6IDAsXG4gICAgICAgIH0sXG4gICAgICBdO1xuXG4gICAgICAvLyBUaGlzIHNob3VsZCBwYXNzIC0gcmV2ZXJ0WHB1YlByZWZpeCBjb252ZXJ0cyB1cHViIC0+IHRwdWIsIGFuZCB0aGUga2V5IG1hdGNoZXNcbiAgICAgIHZhbGlkYXRlUHNidEZvcldpdGhkcmF3KHBzYnQudG9IZXgoKSwgbmV0d29yaywgcmVjaXBpZW50cywgYWNjb3VudHMpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2YWxpZGF0ZSBQU0JUIHdpdGggbWF0Y2hpbmcgdnB1YiBwcmVmaXggYW5kIGNvcnJlY3Qga2V5JywgKCkgPT4ge1xuICAgICAgLy8gSW1wb3J0IHRoZSBzaWduZXIgcm9vdCBrZXkgZnJvbSB0aGUgZml4dHVyZSB3aGljaCBjb3JyZXNwb25kcyB0byB0aGUgdXB1Yi92cHViIGFjY291bnRzXG4gICAgICBjb25zdCBzaWduZXJSb290S2V5ID1cbiAgICAgICAgJ3RwcnY4Wmd4TUJpY1FLc1BlNmpTNHZEbTJuN3M0MlE2TXB2Z2hVUXFNbVNLRzdiVFp2R0t0anJjVTNQR3pNTkczN3l6eHl3cmNkdmdrd3JyOGVZWEptYndkdlVOVlQ0VWN2N3JpczRqdkE3QlVtZyc7XG4gICAgICBjb25zdCBtYXN0ZXJIRE5vZGUgPSB1dHhvbGliLmJpcDMyLmZyb21CYXNlNTgoc2lnbmVyUm9vdEtleSwgbmV0d29yayk7XG5cbiAgICAgIC8vIERlcml2ZSB0aGUgYWNjb3VudCBrZXkgZm9yIHB1cnBvc2UgODRcbiAgICAgIGNvbnN0IGFjY291bnRLZXkgPSBtYXN0ZXJIRE5vZGUuZGVyaXZlUGF0aChcIm0vODQnLzAnLzAnXCIpO1xuXG4gICAgICBjb25zdCB7IHBzYnQgfSA9IGNyZWF0ZVRlc3RQc2J0KHtcbiAgICAgICAgbmV0d29yayxcbiAgICAgICAgaW5wdXRWYWx1ZTogNTAwMDAwLFxuICAgICAgICBvdXRwdXRWYWx1ZTogMTAwMDAwLFxuICAgICAgICBjaGFuZ2VWYWx1ZTogMzkwMDAwLFxuICAgICAgICBjaGFuZ2VQdXJwb3NlOiA4NCxcbiAgICAgICAgY2hhbmdlRGVyaXZhdGlvblBhdGg6IFwibS84NCcvMCcvMCcvMS82XCIsXG4gICAgICAgIG1hc3RlcktleTogYWNjb3VudEtleSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCByZWNpcGllbnRBZGRyZXNzID0gdXR4b2xpYi5hZGRyZXNzLmZyb21PdXRwdXRTY3JpcHQocHNidC50eE91dHB1dHNbMF0uc2NyaXB0LCBuZXR3b3JrKTtcblxuICAgICAgY29uc3QgcmVjaXBpZW50cyA9IFtcbiAgICAgICAge1xuICAgICAgICAgIGFtb3VudFNhdDogQmlnSW50KDEwMDAwMCksXG4gICAgICAgICAgYWRkcmVzczogcmVjaXBpZW50QWRkcmVzcyxcbiAgICAgICAgfSxcbiAgICAgIF07XG5cbiAgICAgIC8vIFVzZSB0aGUgdnB1YiBmcm9tIHRoZSBmaXh0dXJlIC0gdGhpcyBzaG91bGQgd29yayBiZWNhdXNlIHRoZSBrZXlzIG1hdGNoXG4gICAgICBjb25zdCBhY2NvdW50cyA9IFtcbiAgICAgICAge1xuICAgICAgICAgIHhwdWI6ICd2cHViNVpVMVBIR3BRb0RTSGNrWWljbzRuc3Z3c0QzbVRoNlVqcUw1enlHV1haWHpCalRZTU5Lb3Q3dDllUlBRWTcxaEpjbk5OOXIxc3MyNWczeEE5cm1vSjVuV1BnOGpFV2F2cnR0bnNWYTFxdzEnLFxuICAgICAgICAgIHB1cnBvc2U6IDg0LFxuICAgICAgICAgIGNvaW5fdHlwZTogMCxcbiAgICAgICAgICBhY2NvdW50OiAwLFxuICAgICAgICB9LFxuICAgICAgXTtcblxuICAgICAgLy8gVGhpcyBzaG91bGQgcGFzcyAtIHJldmVydFhwdWJQcmVmaXggY29udmVydHMgdnB1YiAtPiB0cHViLCBhbmQgdGhlIGtleSBtYXRjaGVzXG4gICAgICB2YWxpZGF0ZVBzYnRGb3JXaXRoZHJhdyhwc2J0LnRvSGV4KCksIG5ldHdvcmssIHJlY2lwaWVudHMsIGFjY291bnRzKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgUFNCVCB3aXRoIG11bHRpcGxlIHJlY2lwaWVudHMnLCAoKSA9PiB7XG4gICAgICAvLyBDcmVhdGUgYSBQU0JUIG1hbnVhbGx5IHdpdGggMiByZWNpcGllbnQgb3V0cHV0cyBhbmQgMSBjaGFuZ2Ugb3V0cHV0XG4gICAgICBjb25zdCBtYXN0ZXJLZXkgPSB1dHhvbGliLmJpcDMyLmZyb21TZWVkKEJ1ZmZlci5hbGxvYygzMiwgMSksIG5ldHdvcmspO1xuXG4gICAgICBjb25zdCBpbnB1dEtleVBhaXIgPSB1dHhvbGliLkVDUGFpci5tYWtlUmFuZG9tKHsgbmV0d29yayB9KTtcbiAgICAgIGNvbnN0IHAyd3BraElucHV0ID0gdXR4b2xpYi5wYXltZW50cy5wMndwa2goe1xuICAgICAgICBwdWJrZXk6IEJ1ZmZlci5mcm9tKGlucHV0S2V5UGFpci5wdWJsaWNLZXkpLFxuICAgICAgICBuZXR3b3JrLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHBzYnQgPSBuZXcgdXR4b2xpYi5Qc2J0KHsgbmV0d29yayB9KTtcblxuICAgICAgLy8gQWRkIGlucHV0XG4gICAgICBwc2J0LmFkZElucHV0KHtcbiAgICAgICAgaGFzaDogJ2NhNjg1MjU5OGI0ODIzMGFjODcwODE0YjkzNWIwZDk4MmQzOTY4ZWIwMGExZDk3MzMyZGNlYjZjZDliODUwNWUnLFxuICAgICAgICBpbmRleDogMSxcbiAgICAgICAgd2l0bmVzc1V0eG86IHtcbiAgICAgICAgICBzY3JpcHQ6IHAyd3BraElucHV0Lm91dHB1dCEsXG4gICAgICAgICAgdmFsdWU6IEJpZ0ludCg1MDAwMDApLFxuICAgICAgICB9LFxuICAgICAgICBiaXAzMkRlcml2YXRpb246IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBtYXN0ZXJGaW5nZXJwcmludDogQnVmZmVyLmFsbG9jKDQsIDApLFxuICAgICAgICAgICAgcGF0aDogXCJtLzg0Jy8wJy8wJy8wLzBcIixcbiAgICAgICAgICAgIHB1YmtleTogQnVmZmVyLmZyb20oaW5wdXRLZXlQYWlyLnB1YmxpY0tleSksXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBDcmVhdGUgZmlyc3QgcmVjaXBpZW50XG4gICAgICBjb25zdCByZWNpcGllbnQxS2V5UGFpciA9IHV0eG9saWIuRUNQYWlyLm1ha2VSYW5kb20oeyBuZXR3b3JrIH0pO1xuICAgICAgY29uc3QgcmVjaXBpZW50MVBheW1lbnQgPSB1dHhvbGliLnBheW1lbnRzLnAyd3BraCh7XG4gICAgICAgIHB1YmtleTogQnVmZmVyLmZyb20ocmVjaXBpZW50MUtleVBhaXIucHVibGljS2V5KSxcbiAgICAgICAgbmV0d29yayxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgcmVjaXBpZW50MUFkZHJlc3MgPSByZWNpcGllbnQxUGF5bWVudC5hZGRyZXNzITtcblxuICAgICAgLy8gQ3JlYXRlIHNlY29uZCByZWNpcGllbnRcbiAgICAgIGNvbnN0IHJlY2lwaWVudDJLZXlQYWlyID0gdXR4b2xpYi5FQ1BhaXIubWFrZVJhbmRvbSh7IG5ldHdvcmsgfSk7XG4gICAgICBjb25zdCByZWNpcGllbnQyUGF5bWVudCA9IHV0eG9saWIucGF5bWVudHMucDJ3cGtoKHtcbiAgICAgICAgcHVia2V5OiBCdWZmZXIuZnJvbShyZWNpcGllbnQyS2V5UGFpci5wdWJsaWNLZXkpLFxuICAgICAgICBuZXR3b3JrLFxuICAgICAgfSk7XG4gICAgICBjb25zdCByZWNpcGllbnQyQWRkcmVzcyA9IHJlY2lwaWVudDJQYXltZW50LmFkZHJlc3MhO1xuXG4gICAgICAvLyBEZXJpdmUgY2hhbmdlIGFkZHJlc3MgZnJvbSBtYXN0ZXIga2V5XG4gICAgICBjb25zdCBjaGFuZ2VOb2RlID0gbWFzdGVyS2V5LmRlcml2ZSgxKS5kZXJpdmUoNik7IC8vIG0vMS82XG4gICAgICBjb25zdCBjaGFuZ2VQYXltZW50ID0gdXR4b2xpYi5wYXltZW50cy5wMndwa2goe1xuICAgICAgICBwdWJrZXk6IGNoYW5nZU5vZGUucHVibGljS2V5LFxuICAgICAgICBuZXR3b3JrLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBjaGFuZ2VBZGRyZXNzID0gY2hhbmdlUGF5bWVudC5hZGRyZXNzITtcblxuICAgICAgLy8gQWRkIG91dHB1dHM6IHJlY2lwaWVudDEsIHJlY2lwaWVudDIsIGNoYW5nZVxuICAgICAgcHNidC5hZGRPdXRwdXQoe1xuICAgICAgICBhZGRyZXNzOiByZWNpcGllbnQxQWRkcmVzcyxcbiAgICAgICAgdmFsdWU6IEJpZ0ludCgxMDAwMDApLFxuICAgICAgfSk7XG5cbiAgICAgIHBzYnQuYWRkT3V0cHV0KHtcbiAgICAgICAgYWRkcmVzczogcmVjaXBpZW50MkFkZHJlc3MsXG4gICAgICAgIHZhbHVlOiBCaWdJbnQoNTAwMDApLFxuICAgICAgfSk7XG5cbiAgICAgIHBzYnQuYWRkT3V0cHV0KHtcbiAgICAgICAgYWRkcmVzczogY2hhbmdlQWRkcmVzcyxcbiAgICAgICAgdmFsdWU6IEJpZ0ludCgzNDAwMDApLCAvLyA1MDAwMDAgLSAxMDAwMDAgLSA1MDAwMCAtIDEwMDAwIChmZWUpXG4gICAgICB9KTtcblxuICAgICAgLy8gQWRkIGJpcDMyRGVyaXZhdGlvbiB0byB0aGUgY2hhbmdlIG91dHB1dCAoaW5kZXggMilcbiAgICAgIHBzYnQudXBkYXRlT3V0cHV0KDIsIHtcbiAgICAgICAgYmlwMzJEZXJpdmF0aW9uOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgbWFzdGVyRmluZ2VycHJpbnQ6IEJ1ZmZlci5hbGxvYyg0LCAwKSxcbiAgICAgICAgICAgIHBhdGg6IFwibS84NCcvMCcvMCcvMS82XCIsXG4gICAgICAgICAgICBwdWJrZXk6IGNoYW5nZU5vZGUucHVibGljS2V5LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcmVjaXBpZW50cyA9IFtcbiAgICAgICAge1xuICAgICAgICAgIGFtb3VudFNhdDogQmlnSW50KDEwMDAwMCksXG4gICAgICAgICAgYWRkcmVzczogcmVjaXBpZW50MUFkZHJlc3MsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBhbW91bnRTYXQ6IEJpZ0ludCg1MDAwMCksXG4gICAgICAgICAgYWRkcmVzczogcmVjaXBpZW50MkFkZHJlc3MsXG4gICAgICAgIH0sXG4gICAgICBdO1xuXG4gICAgICBjb25zdCBhY2NvdW50cyA9IFtcbiAgICAgICAge1xuICAgICAgICAgIHhwdWI6IG1hc3RlcktleS5uZXV0ZXJlZCgpLnRvQmFzZTU4KCksXG4gICAgICAgICAgcHVycG9zZTogODQsXG4gICAgICAgICAgY29pbl90eXBlOiAwLFxuICAgICAgICAgIGFjY291bnQ6IDAsXG4gICAgICAgIH0sXG4gICAgICBdO1xuXG4gICAgICB2YWxpZGF0ZVBzYnRGb3JXaXRoZHJhdyhwc2J0LnRvSGV4KCksIG5ldHdvcmssIHJlY2lwaWVudHMsIGFjY291bnRzKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signableJson.d.ts","sourceRoot":"","sources":["../../../../test/unit/lightning/signableJson.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const lightning_1 = require("../../../src/lightning");
|
|
7
|
+
const assert_1 = __importDefault(require("assert"));
|
|
8
|
+
describe('canonicalizeObject', function () {
|
|
9
|
+
it('should return the canonicalized object with sorted keys', function () {
|
|
10
|
+
const input = { b: 1, a: 2 };
|
|
11
|
+
const expected = { a: 2, b: 1 };
|
|
12
|
+
const result = (0, lightning_1.canonicalizeObject)(input);
|
|
13
|
+
assert_1.default.notDeepStrictEqual(JSON.stringify(input), JSON.stringify(expected));
|
|
14
|
+
assert_1.default.deepStrictEqual(JSON.stringify(result), JSON.stringify(expected));
|
|
15
|
+
});
|
|
16
|
+
it('should handle nested objects and sort their keys', function () {
|
|
17
|
+
const input = { b: { d: 4, c: 3 }, a: 2 };
|
|
18
|
+
const expected = { a: 2, b: { c: 3, d: 4 } };
|
|
19
|
+
const result = (0, lightning_1.canonicalizeObject)(input);
|
|
20
|
+
assert_1.default.notDeepStrictEqual(JSON.stringify(input), JSON.stringify(expected));
|
|
21
|
+
assert_1.default.deepStrictEqual(JSON.stringify(result), JSON.stringify(expected));
|
|
22
|
+
});
|
|
23
|
+
it('should handle arrays within objects', function () {
|
|
24
|
+
const input = { b: [3, 2, 1], a: 2 };
|
|
25
|
+
const expected = { a: 2, b: [3, 2, 1] };
|
|
26
|
+
const result = (0, lightning_1.canonicalizeObject)(input);
|
|
27
|
+
assert_1.default.notDeepStrictEqual(JSON.stringify(input), JSON.stringify(expected));
|
|
28
|
+
assert_1.default.deepStrictEqual(JSON.stringify(result), JSON.stringify(expected));
|
|
29
|
+
});
|
|
30
|
+
it('should handle arrays of objects and sort their keys', function () {
|
|
31
|
+
const input = [
|
|
32
|
+
{ b: 2, a: 1 },
|
|
33
|
+
{ d: 4, c: 3 },
|
|
34
|
+
];
|
|
35
|
+
const expected = [
|
|
36
|
+
{ a: 1, b: 2 },
|
|
37
|
+
{ c: 3, d: 4 },
|
|
38
|
+
];
|
|
39
|
+
const result = (0, lightning_1.canonicalizeObject)(input);
|
|
40
|
+
assert_1.default.notDeepStrictEqual(JSON.stringify(input), JSON.stringify(expected));
|
|
41
|
+
assert_1.default.deepStrictEqual(JSON.stringify(result), JSON.stringify(expected));
|
|
42
|
+
});
|
|
43
|
+
it('should return primitive values as is', function () {
|
|
44
|
+
assert_1.default.strictEqual(JSON.stringify((0, lightning_1.canonicalizeObject)(42)), JSON.stringify(42));
|
|
45
|
+
assert_1.default.strictEqual(JSON.stringify((0, lightning_1.canonicalizeObject)('string')), JSON.stringify('string'));
|
|
46
|
+
});
|
|
47
|
+
it('should throw an error for invalid object types', function () {
|
|
48
|
+
assert_1.default.throws(() => (0, lightning_1.canonicalizeObject)(null), /Invalid object type/);
|
|
49
|
+
assert_1.default.throws(() => (0, lightning_1.canonicalizeObject)(undefined), /Invalid object type/);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbmFibGVKc29uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC91bml0L2xpZ2h0bmluZy9zaWduYWJsZUpzb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxzREFBNEQ7QUFDNUQsb0RBQTRCO0FBRTVCLFFBQVEsQ0FBQyxvQkFBb0IsRUFBRTtJQUM3QixFQUFFLENBQUMseURBQXlELEVBQUU7UUFDNUQsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztRQUM3QixNQUFNLFFBQVEsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO1FBQ2hDLE1BQU0sTUFBTSxHQUFHLElBQUEsOEJBQWtCLEVBQUMsS0FBSyxDQUFDLENBQUM7UUFDekMsZ0JBQU0sQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUMzRSxnQkFBTSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztJQUMzRSxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxrREFBa0QsRUFBRTtRQUNyRCxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztRQUMxQyxNQUFNLFFBQVEsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUM3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QUUsQ0FBQyxJQUFBLDhCQUFrQixFQUFDLFNBQWtCLENBQUMsRUFBRSxxQkFBcUIsQ0FBQyxDQUFDO0lBQ3JGLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjYW5vbmljYWxpemVPYmplY3QgfSBmcm9tICcuLi8uLi8uLi9zcmMvbGlnaHRuaW5nJztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcblxuZGVzY3JpYmUoJ2Nhbm9uaWNhbGl6ZU9iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgaXQoJ3Nob3VsZCByZXR1cm4gdGhlIGNhbm9uaWNhbGl6ZWQgb2JqZWN0IHdpdGggc29ydGVkIGtleXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgaW5wdXQgPSB7IGI6IDEsIGE6IDIgfTtcbiAgICBjb25zdCBleHBlY3RlZCA9IHsgYTogMiwgYjogMSB9O1xuICAgIGNvbnN0IHJlc3VsdCA9IGNhbm9uaWNhbGl6ZU9iamVjdChpbnB1dCk7XG4gICAgYXNzZXJ0Lm5vdERlZXBTdHJpY3RFcXVhbChKU09OLnN0cmluZ2lmeShpbnB1dCksIEpTT04uc3RyaW5naWZ5KGV4cGVjdGVkKSk7XG4gICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChKU09OLnN0cmluZ2lmeShyZXN1bHQpLCBKU09OLnN0cmluZ2lmeShleHBlY3RlZCkpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGhhbmRsZSBuZXN0ZWQgb2JqZWN0cyBhbmQgc29ydCB0aGVpciBrZXlzJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGlucHV0ID0geyBiOiB7IGQ6IDQsIGM6IDMgfSwgYTogMiB9O1xuICAgIGNvbnN0IGV4cGVjdGVkID0geyBhOiAyLCBiOiB7IGM6IDMsIGQ6IDQgfSB9O1xuICAgIGNvbnN0IHJlc3VsdCA9IGNhbm9uaWNhbGl6ZU9iamVjdChpbnB1dCk7XG4gICAgYXNzZXJ0Lm5vdERlZXBTdHJpY3RFcXVhbChKU09OLnN0cmluZ2lmeShpbnB1dCksIEpTT04uc3RyaW5naWZ5KGV4cGVjdGVkKSk7XG4gICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChKU09OLnN0cmluZ2lmeShyZXN1bHQpLCBKU09OLnN0cmluZ2lmeShleHBlY3RlZCkpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGhhbmRsZSBhcnJheXMgd2l0aGluIG9iamVjdHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgaW5wdXQgPSB7IGI6IFszLCAyLCAxXSwgYTogMiB9O1xuICAgIGNvbnN0IGV4cGVjdGVkID0geyBhOiAyLCBiOiBbMywgMiwgMV0gfTtcbiAgICBjb25zdCByZXN1bHQgPSBjYW5vbmljYWxpemVPYmplY3QoaW5wdXQpO1xuICAgIGFzc2VydC5ub3REZWVwU3RyaWN0RXF1YWwoSlNPTi5zdHJpbmdpZnkoaW5wdXQpLCBKU09OLnN0cmluZ2lmeShleHBlY3RlZCkpO1xuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoSlNPTi5zdHJpbmdpZnkocmVzdWx0KSwgSlNPTi5zdHJpbmdpZnkoZXhwZWN0ZWQpKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBoYW5kbGUgYXJyYXlzIG9mIG9iamVjdHMgYW5kIHNvcnQgdGhlaXIga2V5cycsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBpbnB1dCA9IFtcbiAgICAgIHsgYjogMiwgYTogMSB9LFxuICAgICAgeyBkOiA0LCBjOiAzIH0sXG4gICAgXTtcbiAgICBjb25zdCBleHBlY3RlZCA9IFtcbiAgICAgIHsgYTogMSwgYjogMiB9LFxuICAgICAgeyBjOiAzLCBkOiA0IH0sXG4gICAgXTtcbiAgICBjb25zdCByZXN1bHQgPSBjYW5vbmljYWxpemVPYmplY3QoaW5wdXQpO1xuICAgIGFzc2VydC5ub3REZWVwU3RyaWN0RXF1YWwoSlNPTi5zdHJpbmdpZnkoaW5wdXQpLCBKU09OLnN0cmluZ2lmeShleHBlY3RlZCkpO1xuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoSlNPTi5zdHJpbmdpZnkocmVzdWx0KSwgSlNPTi5zdHJpbmdpZnkoZXhwZWN0ZWQpKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZXR1cm4gcHJpbWl0aXZlIHZhbHVlcyBhcyBpcycsIGZ1bmN0aW9uICgpIHtcbiAgICBhc3NlcnQuc3RyaWN0RXF1YWwoSlNPTi5zdHJpbmdpZnkoY2Fub25pY2FsaXplT2JqZWN0KDQyKSksIEpTT04uc3RyaW5naWZ5KDQyKSk7XG4gICAgYXNzZXJ0LnN0cmljdEVxdWFsKEpTT04uc3RyaW5naWZ5KGNhbm9uaWNhbGl6ZU9iamVjdCgnc3RyaW5nJykpLCBKU09OLnN0cmluZ2lmeSgnc3RyaW5nJykpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHRocm93IGFuIGVycm9yIGZvciBpbnZhbGlkIG9iamVjdCB0eXBlcycsIGZ1bmN0aW9uICgpIHtcbiAgICBhc3NlcnQudGhyb3dzKCgpID0+IGNhbm9uaWNhbGl6ZU9iamVjdChudWxsIGFzIG5ldmVyKSwgL0ludmFsaWQgb2JqZWN0IHR5cGUvKTtcbiAgICBhc3NlcnQudGhyb3dzKCgpID0+IGNhbm9uaWNhbGl6ZU9iamVjdCh1bmRlZmluZWQgYXMgbmV2ZXIpLCAvSW52YWxpZCBvYmplY3QgdHlwZS8pO1xuICB9KTtcbn0pO1xuIl19
|