@bitgo/abstract-utxo 1.0.1-rc.0
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/.eslintignore +5 -0
- package/CHANGELOG.md +11 -0
- package/LICENSE +191 -0
- package/README.md +1 -0
- package/dist/src/abstractUtxoCoin.d.ts +388 -0
- package/dist/src/abstractUtxoCoin.d.ts.map +1 -0
- package/dist/src/abstractUtxoCoin.js +955 -0
- package/dist/src/config.d.ts +7 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/config.js +12 -0
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +18 -0
- package/dist/src/parseOutput.d.ts +22 -0
- package/dist/src/parseOutput.d.ts.map +1 -0
- package/dist/src/parseOutput.js +169 -0
- package/dist/src/recovery/RecoveryProvider.d.ts +18 -0
- package/dist/src/recovery/RecoveryProvider.d.ts.map +1 -0
- package/dist/src/recovery/RecoveryProvider.js +23 -0
- package/dist/src/recovery/backupKeyRecovery.d.ts +56 -0
- package/dist/src/recovery/backupKeyRecovery.d.ts.map +1 -0
- package/dist/src/recovery/backupKeyRecovery.js +273 -0
- package/dist/src/recovery/baseApi.d.ts +27 -0
- package/dist/src/recovery/baseApi.d.ts.map +1 -0
- package/dist/src/recovery/baseApi.js +73 -0
- package/dist/src/recovery/coingeckoApi.d.ts +9 -0
- package/dist/src/recovery/coingeckoApi.d.ts.map +1 -0
- package/dist/src/recovery/coingeckoApi.js +47 -0
- package/dist/src/recovery/crossChainRecovery.d.ts +95 -0
- package/dist/src/recovery/crossChainRecovery.d.ts.map +1 -0
- package/dist/src/recovery/crossChainRecovery.js +318 -0
- package/dist/src/recovery/index.d.ts +8 -0
- package/dist/src/recovery/index.d.ts.map +1 -0
- package/dist/src/recovery/index.js +20 -0
- package/dist/src/recovery/mempoolApi.d.ts +7 -0
- package/dist/src/recovery/mempoolApi.d.ts.map +1 -0
- package/dist/src/recovery/mempoolApi.js +33 -0
- package/dist/src/recovery/smartbitApi.d.ts +11 -0
- package/dist/src/recovery/smartbitApi.d.ts.map +1 -0
- package/dist/src/recovery/smartbitApi.js +36 -0
- package/dist/src/replayProtection.d.ts +5 -0
- package/dist/src/replayProtection.d.ts.map +1 -0
- package/dist/src/replayProtection.js +21 -0
- package/dist/src/sign.d.ts +29 -0
- package/dist/src/sign.d.ts.map +1 -0
- package/dist/src/sign.js +104 -0
- package/dist/tsconfig.tsbuildinfo +7371 -0
- package/package.json +55 -0
package/dist/src/sign.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.signAndVerifyWalletTransaction = exports.TransactionSigningError = exports.InputSigningError = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* @prettier
|
|
6
|
+
*/
|
|
7
|
+
const utxolib = require("@bitgo/utxo-lib");
|
|
8
|
+
const bitgo_1 = require("@bitgo/utxo-lib/dist/src/bitgo");
|
|
9
|
+
const debugLib = require("debug");
|
|
10
|
+
const replayProtection_1 = require("./replayProtection");
|
|
11
|
+
const debug = debugLib('bitgo:v2:utxo');
|
|
12
|
+
class InputSigningError extends Error {
|
|
13
|
+
constructor(inputIndex, unspent, reason) {
|
|
14
|
+
super(`signing error at input ${inputIndex}: unspentId=${unspent.id}: ${reason}`);
|
|
15
|
+
this.inputIndex = inputIndex;
|
|
16
|
+
this.unspent = unspent;
|
|
17
|
+
this.reason = reason;
|
|
18
|
+
}
|
|
19
|
+
static expectedWalletUnspent(inputIndex, unspent) {
|
|
20
|
+
return new InputSigningError(inputIndex, unspent, `not a wallet unspent, not a replay protection unspent`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.InputSigningError = InputSigningError;
|
|
24
|
+
class TransactionSigningError extends Error {
|
|
25
|
+
constructor(signErrors, verifyError) {
|
|
26
|
+
super(`sign errors at inputs: [${signErrors.join(',')}], ` +
|
|
27
|
+
`verify errors at inputs: [${verifyError.join(',')}], see log for details`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.TransactionSigningError = TransactionSigningError;
|
|
31
|
+
/**
|
|
32
|
+
* Sign all inputs of a wallet transaction and verify signatures after signing.
|
|
33
|
+
* Collects and logs signing errors and verification errors, throws error in the end if any of them
|
|
34
|
+
* failed.
|
|
35
|
+
*
|
|
36
|
+
* @param transaction - wallet transaction (builder) to be signed
|
|
37
|
+
* @param unspents - transaction unspents
|
|
38
|
+
* @param walletSigner - signing parameters
|
|
39
|
+
* @param isLastSignature - Returns full-signed transaction when true. Builds half-signed when false.
|
|
40
|
+
*/
|
|
41
|
+
function signAndVerifyWalletTransaction(transaction, unspents, walletSigner, { isLastSignature }) {
|
|
42
|
+
const network = transaction.network;
|
|
43
|
+
const prevOutputs = unspents.map((u) => bitgo_1.toOutput(u, network));
|
|
44
|
+
let txBuilder;
|
|
45
|
+
if (transaction instanceof utxolib.bitgo.UtxoTransaction) {
|
|
46
|
+
txBuilder = utxolib.bitgo.createTransactionBuilderFromTransaction(transaction, prevOutputs);
|
|
47
|
+
if (transaction.ins.length !== unspents.length) {
|
|
48
|
+
throw new Error(`transaction inputs must match unspents`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else if (transaction instanceof utxolib.bitgo.UtxoTransactionBuilder) {
|
|
52
|
+
txBuilder = transaction;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
throw new Error(`must pass UtxoTransaction or UtxoTransactionBuilder`);
|
|
56
|
+
}
|
|
57
|
+
const signErrors = unspents
|
|
58
|
+
.map((unspent, inputIndex) => {
|
|
59
|
+
if (replayProtection_1.isReplayProtectionUnspent(unspent, network)) {
|
|
60
|
+
debug('Skipping signature for input %d of %d (RP input?)', inputIndex + 1, unspents.length);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (!bitgo_1.isWalletUnspent(unspent)) {
|
|
64
|
+
return InputSigningError.expectedWalletUnspent(inputIndex, unspent);
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
bitgo_1.signInputWithUnspent(txBuilder, inputIndex, unspent, walletSigner);
|
|
68
|
+
debug('Successfully signed input %d of %d', inputIndex + 1, unspents.length);
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
return new InputSigningError(inputIndex, unspent, e);
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
.filter((e) => e !== undefined);
|
|
75
|
+
const signedTransaction = isLastSignature ? txBuilder.build() : txBuilder.buildIncomplete();
|
|
76
|
+
const verifyErrors = signedTransaction.ins
|
|
77
|
+
.map((input, inputIndex) => {
|
|
78
|
+
const unspent = unspents[inputIndex];
|
|
79
|
+
if (replayProtection_1.isReplayProtectionUnspent(unspent, network)) {
|
|
80
|
+
debug('Skipping input signature %d of %d (unspent from replay protection address which is platform signed only)', inputIndex + 1, unspents.length);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (!bitgo_1.isWalletUnspent(unspent)) {
|
|
84
|
+
return InputSigningError.expectedWalletUnspent(inputIndex, unspent);
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
const publicKey = walletSigner.deriveForChainAndIndex(unspent.chain, unspent.index).signer.publicKey;
|
|
88
|
+
if (!utxolib.bitgo.verifySignatureWithPublicKey(signedTransaction, inputIndex, prevOutputs, publicKey)) {
|
|
89
|
+
return new InputSigningError(inputIndex, unspent, new Error(`invalid signature`));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch (e) {
|
|
93
|
+
debug('Invalid signature');
|
|
94
|
+
return new InputSigningError(inputIndex, unspent, e);
|
|
95
|
+
}
|
|
96
|
+
})
|
|
97
|
+
.filter((e) => e !== undefined);
|
|
98
|
+
if (signErrors.length || verifyErrors.length) {
|
|
99
|
+
throw new TransactionSigningError(signErrors, verifyErrors);
|
|
100
|
+
}
|
|
101
|
+
return signedTransaction;
|
|
102
|
+
}
|
|
103
|
+
exports.signAndVerifyWalletTransaction = signAndVerifyWalletTransaction;
|
|
104
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zaWduLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBOztHQUVHO0FBQ0gsMkNBQTJDO0FBQzNDLDBEQU93QztBQUN4QyxrQ0FBa0M7QUFFbEMseURBQStEO0FBRS9ELE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxlQUFlLENBQUMsQ0FBQztBQUV4QyxNQUFhLGlCQUFrQixTQUFRLEtBQUs7SUFLMUMsWUFBbUIsVUFBa0IsRUFBUyxPQUFnQixFQUFTLE1BQXNCO1FBQzNGLEtBQUssQ0FBQywwQkFBMEIsVUFBVSxlQUFlLE9BQU8sQ0FBQyxFQUFFLEtBQUssTUFBTSxFQUFFLENBQUMsQ0FBQztRQURqRSxlQUFVLEdBQVYsVUFBVSxDQUFRO1FBQVMsWUFBTyxHQUFQLE9BQU8sQ0FBUztRQUFTLFdBQU0sR0FBTixNQUFNLENBQWdCO0lBRTdGLENBQUM7SUFORCxNQUFNLENBQUMscUJBQXFCLENBQUMsVUFBa0IsRUFBRSxPQUFnQjtRQUMvRCxPQUFPLElBQUksaUJBQWlCLENBQUMsVUFBVSxFQUFFLE9BQU8sRUFBRSx1REFBdUQsQ0FBQyxDQUFDO0lBQzdHLENBQUM7Q0FLRjtBQVJELDhDQVFDO0FBRUQsTUFBYSx1QkFBd0IsU0FBUSxLQUFLO0lBQ2hELFlBQVksVUFBK0IsRUFBRSxXQUFnQztRQUMzRSxLQUFLLENBQ0gsMkJBQTJCLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUs7WUFDbEQsNkJBQTZCLFdBQVcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLHdCQUF3QixDQUM3RSxDQUFDO0lBQ0osQ0FBQztDQUNGO0FBUEQsMERBT0M7QUFFRDs7Ozs7Ozs7O0dBU0c7QUFDSCxTQUFnQiw4QkFBOEIsQ0FDNUMsV0FBaUYsRUFDakYsUUFBbUIsRUFDbkIsWUFBaUQsRUFDakQsRUFBRSxlQUFlLEVBQWdDO0lBRWpELE1BQU0sT0FBTyxHQUFHLFdBQVcsQ0FB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aUJBQWlCLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxTQUFTLENBQUMsRUFBRTtnQkFDdEcsT0FBTyxJQUFJLGlCQUFpQixDQUFDLFVBQVUsRUFBRSxPQUFPLEVBQUUsSUFBSSxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDO2FBQ25GO1NBQ0Y7UUFBQyxPQUFPLENBQUMsRUFBRTtZQUNWLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1lBQzNCLE9BQU8sSUFBSSxpQkFBaUIsQ0FBQyxVQUFVLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO1NBQ3REO0lBQ0gsQ0FBQyxDQUFDO1NBQ0QsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUEwQixFQUFFLENBQUMsQ0FBQyxLQUFLLFNBQVMsQ0FBQyxDQUFDO0lBRTFELElBQUksVUFBVSxDQUFDLE1BQU0sSUFBSSxZQUFZLENBQUMsTUFBTSxFQUFFO1FBQzVDLE1BQU0sSUFBSSx1QkFBdUIsQ0FBQyxVQUFVLEVBQUUsWUFBWSxDQUFDLENBQUM7S0FDN0Q7SUFFRCxPQUFPLGlCQUFpQixDQUFDO0FBQzNCLENBQUM7QUF4RUQsd0VBd0VDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAcHJldHRpZXJcbiAqL1xuaW1wb3J0ICogYXMgdXR4b2xpYiBmcm9tICdAYml0Z28vdXR4by1saWInO1xuaW1wb3J0IHtcbiAgaXNXYWxsZXRVbnNwZW50LFxuICBSb290V2FsbGV0S2V5cyxcbiAgc2lnbklucHV0V2l0aFVuc3BlbnQsXG4gIHRvT3V0cHV0LFxuICBVbnNwZW50LFxuICBXYWxsZXRVbnNwZW50U2lnbmVyLFxufSBmcm9tICdAYml0Z28vdXR4by1saWIvZGlzdC9zcmMvYml0Z28nO1xuaW1wb3J0ICogYXMgZGVidWdMaWIgZnJvbSAnZGVidWcnO1xuXG5pbXBvcnQgeyBpc1JlcGxheVByb3RlY3Rpb25VbnNwZW50IH0gZnJvbSAnLi9yZXBsYXlQcm90ZWN0aW9uJztcblxuY29uc3QgZGVidWcgPSBkZWJ1Z0xpYignYml0Z286djI6dXR4bycpO1xuXG5leHBvcnQgY2xhc3MgSW5wdXRTaWduaW5nRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIHN0YXRpYyBleHBlY3RlZFdhbGxldFVuc3BlbnQoaW5wdXRJbmRleDogbnVtYmVyLCB1bnNwZW50OiBVbnNwZW50KTogSW5wdXRTaWduaW5nRXJyb3Ige1xuICAgIHJldHVybiBuZXcgSW5wdXRTaWduaW5nRXJyb3IoaW5wdXRJbmRleCwgdW5zcGVudCwgYG5vdCBhIHdhbGxldCB1bnNwZW50LCBub3QgYSByZXBsYXkgcHJvdGVjdGlvbiB1bnNwZW50YCk7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihwdWJsaWMgaW5wdXRJbmRleDogbnVtYmVyLCBwdWJsaWMgdW5zcGVudDogVW5zcGVudCwgcHVibGljIHJlYXNvbjogRXJyb3IgfCBzdHJpbmcpIHtcbiAgICBzdXBlcihgc2lnbmluZyBlcnJvciBhdCBpbnB1dCAke2lucHV0SW5kZXh9OiB1bnNwZW50SWQ9JHt1bnNwZW50LmlkfTogJHtyZWFzb259YCk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFRyYW5zYWN0aW9uU2lnbmluZ0Vycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihzaWduRXJyb3JzOiBJbnB1dFNpZ25pbmdFcnJvcltdLCB2ZXJpZnlFcnJvcjogSW5wdXRTaWduaW5nRXJyb3JbXSkge1xuICAgIHN1cGVyKFxuICAgICAgYHNpZ24gZXJyb3JzIGF0IGlucHV0czogWyR7c2lnbkVycm9ycy5qb2luKCcsJyl9XSwgYCArXG4gICAgICAgIGB2ZXJpZnkgZXJyb3JzIGF0IGlucHV0czogWyR7dmVyaWZ5RXJyb3Iuam9pbignLCcpfV0sIHNlZSBsb2cgZm9yIGRldGFpbHNgXG4gICAgKTtcbiAgfVxufVxuXG4vKipcbiAqIFNpZ24gYWxsIGlucHV0cyBvZiBhIHdhbGxldCB0cmFuc2FjdGlvbiBhbmQgdmVyaWZ5IHNpZ25hdHVyZXMgYWZ0ZXIgc2lnbmluZy5cbiAqIENvbGxlY3RzIGFuZCBsb2dzIHNpZ25pbmcgZXJyb3JzIGFuZCB2ZXJpZmljYXRpb24gZXJyb3JzLCB0aHJvd3MgZXJyb3IgaW4gdGhlIGVuZCBpZiBhbnkgb2YgdGhlbVxuICogZmFpbGVkLlxuICpcbiAqIEBwYXJhbSB0cmFuc2FjdGlvbiAtIHdhbGxldCB0cmFuc2FjdGlvbiAoYnVpbGRlcikgdG8gYmUgc2lnbmVkXG4gKiBAcGFyYW0gdW5zcGVudHMgLSB0cmFuc2FjdGlvbiB1bnNwZW50c1xuICogQHBhcmFtIHdhbGxldFNpZ25lciAtIHNpZ25pbmcgcGFyYW1ldGVyc1xuICogQHBhcmFtIGlzTGFzdFNpZ25hdHVyZSAtIFJldHVybnMgZnVsbC1zaWduZWQgdHJhbnNhY3Rpb24gd2hlbiB0cnVlLiBCdWlsZHMgaGFsZi1zaWduZWQgd2hlbiBmYWxzZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNpZ25BbmRWZXJpZnlXYWxsZXRUcmFuc2FjdGlvbihcbiAgdHJhbnNhY3Rpb246IHV0eG9saWIuYml0Z28uVXR4b1RyYW5zYWN0aW9uIHwgdXR4b2xpYi5iaXRnby5VdHhvVHJhbnNhY3Rpb25CdWlsZGVyLFxuICB1bnNwZW50czogVW5zcGVudFtdLFxuICB3YWxsZXRTaWduZXI6IFdhbGxldFVuc3BlbnRTaWduZXI8Um9vdFdhbGxldEtleXM+LFxuICB7IGlzTGFzdFNpZ25hdHVyZSB9OiB7IGlzTGFzdFNpZ25hdHVyZTogYm9vbGVhbiB9XG4pOiB1dHhvbGliLmJpdGdvLlV0eG9UcmFuc2FjdGlvbiB7XG4gIGNvbnN0IG5ldHdvcmsgPSB0cmFuc2FjdGlvbi5uZXR3b3JrIGFzIHV0eG9saWIuTmV0d29yaztcbiAgY29uc3QgcHJldk91dHB1dHMgPSB1bnNwZW50cy5tYXAoKHUpID0+IHRvT3V0cHV0KHUsIG5ldHdvcmspKTtcblxuICBsZXQgdHhCdWlsZGVyOiB1dHhvbGliLmJpdGdvLlV0eG9UcmFuc2FjdGlvbkJ1aWxkZXI7XG4gIGlmICh0cmFuc2FjdGlvbiBpbnN0YW5jZW9mIHV0eG9saWIuYml0Z28uVXR4b1RyYW5zYWN0aW9uKSB7XG4gICAgdHhCdWlsZGVyID0gdXR4b2xpYi5iaXRnby5jcmVhdGVUcmFuc2FjdGlvbkJ1aWxkZXJGcm9tVHJhbnNhY3Rpb24odHJhbnNhY3Rpb24sIHByZXZPdXRwdXRzKTtcbiAgICBpZiAodHJhbnNhY3Rpb24uaW5zLmxlbmd0aCAhPT0gdW5zcGVudHMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHRyYW5zYWN0aW9uIGlucHV0cyBtdXN0IG1hdGNoIHVuc3BlbnRzYCk7XG4gICAgfVxuICB9IGVsc2UgaWYgKHRyYW5zYWN0aW9uIGluc3RhbmNlb2YgdXR4b2xpYi5iaXRnby5VdHhvVHJhbnNhY3Rpb25CdWlsZGVyKSB7XG4gICAgdHhCdWlsZGVyID0gdHJhbnNhY3Rpb247XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBtdXN0IHBhc3MgVXR4b1RyYW5zYWN0aW9uIG9yIFV0eG9UcmFuc2FjdGlvbkJ1aWxkZXJgKTtcbiAgfVxuXG4gIGNvbnN0IHNpZ25FcnJvcnM6IElucHV0U2lnbmluZ0Vycm9yW10gPSB1bnNwZW50c1xuICAgIC5tYXAoKHVuc3BlbnQ6IFVuc3BlbnQsIGlucHV0SW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgaWYgKGlzUmVwbGF5UHJvdGVjdGlvblVuc3BlbnQodW5zcGVudCwgbmV0d29yaykpIHtcbiAgICAgICAgZGVidWcoJ1NraXBwaW5nIHNpZ25hdHVyZSBmb3IgaW5wdXQgJWQgb2YgJWQgKFJQIGlucHV0PyknLCBpbnB1dEluZGV4ICsgMSwgdW5zcGVudHMubGVuZ3RoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKCFpc1dhbGxldFVuc3BlbnQodW5zcGVudCkpIHtcbiAgICAgICAgcmV0dXJuIElucHV0U2lnbmluZ0Vycm9yLmV4cGVjdGVkV2FsbGV0VW5zcGVudChpbnB1dEluZGV4LCB1bnNwZW50KTtcbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIHNpZ25JbnB1dFdpdGhVbnNwZW50KHR4QnVpbGRlciwgaW5wdXRJbmRleCwgdW5zcGVudCwgd2FsbGV0U2lnbmVyKTtcbiAgICAgICAgZGVidWcoJ1N1Y2Nlc3NmdWxseSBzaWduZWQgaW5wdXQgJWQgb2YgJWQnLCBpbnB1dEluZGV4ICsgMSwgdW5zcGVudHMubGVuZ3RoKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBJbnB1dFNpZ25pbmdFcnJvcihpbnB1dEluZGV4LCB1bnNwZW50LCBlKTtcbiAgICAgIH1cbiAgICB9KVxuICAgIC5maWx0ZXIoKGUpOiBlIGlzIElucHV0U2lnbmluZ0Vycm9yID0+IGUgIT09IHVuZGVmaW5lZCk7XG5cbiAgY29uc3Qgc2lnbmVkVHJhbnNhY3Rpb24gPSBpc0xhc3RTaWduYXR1cmUgPyB0eEJ1aWxkZXIuYnVpbGQoKSA6IHR4QnVpbGRlci5idWlsZEluY29tcGxldGUoKTtcblxuICBjb25zdCB2ZXJpZnlFcnJvcnM6IElucHV0U2lnbmluZ0Vycm9yW10gPSBzaWduZWRUcmFuc2FjdGlvbi5pbnNcbiAgICAubWFwKChpbnB1dCwgaW5wdXRJbmRleCkgPT4ge1xuICAgICAgY29uc3QgdW5zcGVudCA9IHVuc3BlbnRzW2lucHV0SW5kZXhdIGFzIFVuc3BlbnQ7XG4gICAgICBpZiAoaXNSZXBsYXlQcm90ZWN0aW9uVW5zcGVudCh1bnNwZW50LCBuZXR3b3JrKSkge1xuICAgICAgICBkZWJ1ZyhcbiAgICAgICAgICAnU2tpcHBpbmcgaW5wdXQgc2lnbmF0dXJlICVkIG9mICVkICh1bnNwZW50IGZyb20gcmVwbGF5IHByb3RlY3Rpb24gYWRkcmVzcyB3aGljaCBpcyBwbGF0Zm9ybSBzaWduZWQgb25seSknLFxuICAgICAgICAgIGlucHV0SW5kZXggKyAxLFxuICAgICAgICAgIHVuc3BlbnRzLmxlbmd0aFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoIWlzV2FsbGV0VW5zcGVudCh1bnNwZW50KSkge1xuICAgICAgICByZXR1cm4gSW5wdXRTaWduaW5nRXJyb3IuZXhwZWN0ZWRXYWxsZXRVbnNwZW50KGlucHV0SW5kZXgsIHVuc3BlbnQpO1xuICAgICAgfVxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcHVibGljS2V5ID0gd2FsbGV0U2lnbmVyLmRlcml2ZUZvckNoYWluQW5kSW5kZXgodW5zcGVudC5jaGFpbiwgdW5zcGVudC5pbmRleCkuc2lnbmVyLnB1YmxpY0tleTtcbiAgICAgICAgaWYgKCF1dHhvbGliLmJpdGdvLnZlcmlmeVNpZ25hdHVyZVdpdGhQdWJsaWNLZXkoc2lnbmVkVHJhbnNhY3Rpb24sIGlucHV0SW5kZXgsIHByZXZPdXRwdXRzLCBwdWJsaWNLZXkpKSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBJbnB1dFNpZ25pbmdFcnJvcihpbnB1dEluZGV4LCB1bnNwZW50LCBuZXcgRXJyb3IoYGludmFsaWQgc2lnbmF0dXJlYCkpO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGRlYnVnKCdJbnZhbGlkIHNpZ25hdHVyZScpO1xuICAgICAgICByZXR1cm4gbmV3IElucHV0U2lnbmluZ0Vycm9yKGlucHV0SW5kZXgsIHVuc3BlbnQsIGUpO1xuICAgICAgfVxuICAgIH0pXG4gICAgLmZpbHRlcigoZSk6IGUgaXMgSW5wdXRTaWduaW5nRXJyb3IgPT4gZSAhPT0gdW5kZWZpbmVkKTtcblxuICBpZiAoc2lnbkVycm9ycy5sZW5ndGggfHwgdmVyaWZ5RXJyb3JzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBUcmFuc2FjdGlvblNpZ25pbmdFcnJvcihzaWduRXJyb3JzLCB2ZXJpZnlFcnJvcnMpO1xuICB9XG5cbiAgcmV0dXJuIHNpZ25lZFRyYW5zYWN0aW9uO1xufVxuIl19
|