PHP WebShell
Текущая директория: /opt/BitGoJS/modules/utxo-lib/dist/test/bitgo/psbt
Просмотр файла: PsbtOutputs.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const assert = require("assert");
const bs58check = require("bs58check");
const address_1 = require("../../../src/address");
const outputScripts_1 = require("../../../src/bitgo/outputScripts");
const testutil_1 = require("../../../src/testutil");
const src_1 = require("../../../src");
const bitgo_1 = require("../../../src/bitgo");
const PsbtOutputs_1 = require("../../../src/bitgo/wallet/psbt/PsbtOutputs");
const network = src_1.networks.bitcoin;
const rootWalletKeys = (0, testutil_1.getDefaultWalletKeys)();
describe('psbt internal and wallet outputs', function () {
const value = BigInt(1e8);
const fee = BigInt(1000);
const externalAddress = (0, address_1.fromOutputScript)((0, outputScripts_1.createOutputScriptP2shP2pk)(testutil_1.replayProtectionKeyPair.publicKey).scriptPubKey, src_1.networks.bitcoin);
describe('success', function () {
it(`Find indices of psbt wallet & internal outputs`, function () {
const psbt = src_1.testutil.constructPsbt([
{ scriptType: 'p2wsh', value: BigInt(value + value) },
{ scriptType: 'p2shP2wsh', value: BigInt(value) },
{ scriptType: 'p2trMusig2', value: BigInt(value) },
{ scriptType: 'p2tr', value: BigInt(value) },
{ scriptType: 'p2sh', value: BigInt(value) },
], [
{ scriptType: 'p2sh', value: BigInt(value) },
{ scriptType: 'p2shP2wsh', value: BigInt(value) },
{ scriptType: 'p2wsh', value: BigInt(value) },
{
address: externalAddress,
value: BigInt(value - fee),
},
{ scriptType: 'p2tr', value: BigInt(value), isInternalAddress: true },
{ scriptType: 'p2trMusig2', value: BigInt(value), isInternalAddress: true },
], network, rootWalletKeys, 'unsigned');
const expected = [0, 1, 2, 4, 5];
assert.deepEqual((0, PsbtOutputs_1.findWalletOutputIndices)(psbt, rootWalletKeys.triple), expected);
(0, bitgo_1.addXpubsToPsbt)(psbt, rootWalletKeys);
assert.deepEqual((0, PsbtOutputs_1.findInternalOutputIndices)(psbt), expected);
});
outputScripts_1.scriptTypes2Of3.forEach((scriptType) => {
const psbt = src_1.testutil.constructPsbt([
{ scriptType: scriptType, value: BigInt(value) },
{ scriptType: 'p2wsh', value: BigInt(value) },
{ scriptType: 'p2shP2wsh', value: BigInt(value) },
{ scriptType: 'p2trMusig2', value: BigInt(value) },
{ scriptType: 'p2tr', value: BigInt(value) },
{ scriptType: 'p2sh', value: BigInt(value) },
], [
{ scriptType: 'p2sh', value: BigInt(value) },
{ scriptType: 'p2shP2wsh', value: BigInt(value) },
{ scriptType: 'p2wsh', value: BigInt(value) },
{
address: externalAddress,
value: BigInt(value - fee),
},
{ scriptType: 'p2tr', value: BigInt(value), isInternalAddress: true },
{ scriptType: 'p2trMusig2', value: BigInt(value), isInternalAddress: true },
], network, rootWalletKeys, 'unsigned');
(0, bitgo_1.addXpubsToPsbt)(psbt, rootWalletKeys);
const totalInternalAmount = value * BigInt(psbt.inputCount - 1);
it(`PSBT with ${scriptType} input and globalXpub`, function () {
assert.strictEqual((0, PsbtOutputs_1.getTotalAmountOfInternalOutputs)(psbt), totalInternalAmount);
});
it(`Cloned PSBT with ${scriptType} input and globalXpub`, function () {
assert.strictEqual((0, PsbtOutputs_1.getTotalAmountOfInternalOutputs)(psbt.clone()), totalInternalAmount);
});
it(`PSBT with ${scriptType} input and ordered rootNodes`, function () {
assert.strictEqual((0, PsbtOutputs_1.getTotalAmountOfWalletOutputs)(psbt, rootWalletKeys.triple), totalInternalAmount);
});
});
it(`PSBT with p2shP2pk as first input`, function () {
const psbt = src_1.testutil.constructPsbt([
{ scriptType: 'p2shP2pk', value: BigInt(value) },
{ scriptType: 'p2wsh', value: BigInt(value) },
], [
{ scriptType: 'p2sh', value: BigInt(value) },
{
address: externalAddress,
value: BigInt(value - fee),
},
], network, rootWalletKeys, 'unsigned');
(0, bitgo_1.addXpubsToPsbt)(psbt, rootWalletKeys);
assert.strictEqual((0, PsbtOutputs_1.getTotalAmountOfInternalOutputs)(psbt), value);
});
it(`PSBT with outputs of external wallet root nodes`, function () {
const psbt = src_1.testutil.constructPsbt([{ scriptType: 'p2wsh', value: BigInt(value) }], [{ scriptType: 'p2sh', value: BigInt(value) }], network, rootWalletKeys, 'unsigned');
const externalAmount = BigInt(8888);
const externalRootWalletKeys = new bitgo_1.RootWalletKeys((0, testutil_1.getKeyTriple)('dummy'));
const indices = [0, 1];
indices.forEach((index) => (0, bitgo_1.addWalletOutputToPsbt)(psbt, externalRootWalletKeys, (0, bitgo_1.getExternalChainCode)('p2wsh'), index, externalAmount));
assert.strictEqual((0, PsbtOutputs_1.getTotalAmountOfWalletOutputs)(psbt, externalRootWalletKeys.triple), externalAmount * BigInt(indices.length));
});
it(`PSBT with no outputs of external wallet root nodes`, function () {
const psbt = src_1.testutil.constructPsbt([{ scriptType: 'p2wsh', value: BigInt(value) }], [{ scriptType: 'p2sh', value: BigInt(value) }], network, rootWalletKeys, 'unsigned');
assert.strictEqual((0, PsbtOutputs_1.getTotalAmountOfWalletOutputs)(psbt, new bitgo_1.RootWalletKeys((0, testutil_1.getKeyTriple)('dummy')).triple), BigInt(0));
});
it(`PSBT with no internal output`, function () {
const psbt = src_1.testutil.constructPsbt([{ scriptType: 'p2wsh', value: BigInt(value) }], [
{
address: externalAddress,
value: BigInt(value - fee),
},
], network, rootWalletKeys, 'unsigned');
(0, bitgo_1.addXpubsToPsbt)(psbt, rootWalletKeys);
assert.strictEqual((0, PsbtOutputs_1.getTotalAmountOfInternalOutputs)(psbt), BigInt(0));
});
});
describe('failure', function () {
it('PSBT without globalXpub', function () {
const psbt = src_1.testutil.constructPsbt([], [], network, rootWalletKeys, 'unsigned');
assert.throws(() => (0, PsbtOutputs_1.getTotalAmountOfInternalOutputs)(psbt), (e) => e.message === 'Could not find root nodes in PSBT');
});
it('PSBT with invalid number of globalXpub', function () {
const psbt = src_1.testutil.constructPsbt([], [], network, rootWalletKeys, 'unsigned');
const globalXpub = [
{
extendedPubkey: bs58check.decode(rootWalletKeys.triple[0].neutered().toBase58()),
masterFingerprint: rootWalletKeys.triple[0].fingerprint,
path: 'm',
},
];
psbt.updateGlobal({ globalXpub });
assert.throws(() => (0, PsbtOutputs_1.getTotalAmountOfInternalOutputs)(psbt), (e) => e.message === 'Invalid globalXpubs in PSBT. Expected 3 or none. Got 1');
});
it('PSBT without input scriptPubKey', function () {
const psbt = src_1.testutil.constructPsbt([{ scriptType: 'p2wsh', value: BigInt(value) }], [
{
address: externalAddress,
value: BigInt(value - fee),
},
], network, rootWalletKeys, 'unsigned');
psbt.data.inputs[0].witnessUtxo = undefined;
(0, bitgo_1.addXpubsToPsbt)(psbt, rootWalletKeys);
assert.throws(() => (0, PsbtOutputs_1.getTotalAmountOfInternalOutputs)(psbt), (e) => e.message === 'Input scriptPubKey can not be found');
});
it('PSBT without input Bip32Derivation', function () {
const psbt = src_1.testutil.constructPsbt([{ scriptType: 'p2wsh', value: BigInt(value) }], [
{
address: externalAddress,
value: BigInt(value - fee),
},
], network, rootWalletKeys, 'unsigned');
psbt.data.inputs[0].bip32Derivation = undefined;
(0, bitgo_1.addXpubsToPsbt)(psbt, rootWalletKeys);
assert.throws(() => (0, PsbtOutputs_1.getTotalAmountOfInternalOutputs)(psbt), (e) => e.message === 'Input Bip32Derivation can not be found');
});
it('PSBT woth an OP_RETURN output', function () {
const opReturnScript = '6a4c505341542b01045bde60b7d0e6b758ca5dd8c61d377a2c5f1af51ec1a9e209f5ea0036c8c2f41078a3cebee57d8a47d501041f5e0e66b17576a914c4b8ae927ff2b9ce218e20bf06d425d6b68424fd88ac';
const psbt = src_1.testutil.constructPsbt([{ scriptType: 'p2wsh', value: BigInt(value) }], [
{
address: externalAddress,
value: BigInt(value - fee),
},
{
script: opReturnScript,
value: BigInt(0),
},
], network, rootWalletKeys, 'unsigned');
const tx = psbt.getUnsignedTx();
assert.strictEqual(tx.outs.length, 2);
const out = tx.outs[1];
assert.strictEqual(out.value, BigInt(0));
assert.strictEqual(out.script.toString('hex'), opReturnScript);
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUHNidE91dHB1dHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L2JpdGdvL3BzYnQvUHNidE91dHB1dHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxpQ0FBaUM7QUFFakMsdUNBQXVDO0FBRXZDLGtEQUF3RDtBQUN4RCxvRUFBK0Y7QUFDL0Ysb0RBQW9HO0FBQ3BHLHNDQUFrRDtBQUNsRCw4Q0FBaUg7QUFDakgsNEVBS29EO0FBR3BELE1BQU0sT0FBTyxHQUFHLGNBQVEsQ0FBQyxPQUFPLENBQUM7QUFDakMsTUFBTSxjQUFjLEdBQUcsSUFBQSwrQkFBb0IsR0FBRSxDQUFDO0FBRTlDLFFBQVEsQ0FBQyxrQ0FBa0MsRUFBRTtJQUMzQyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDMUIsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3pCLE1BQU0sZUFBZSxHQUFHLElBQUEsMEJBQWdCLEVBQ3RDLElBQUEsMENBQTBCLEVBQUMsa0NBQXVCLENBQUMsU0FBUyxDQUFDLENBQUMsWUFBWSxFQUMxRSxjQUFRLENBQUMsT0FBTyxDQUNqQixDQUFDO0lBRUYsUUFBUSxDQUFDLFNBQVMsRUFBRTtRQUNsQixFQUFFLENBQUMsZ0RBQWdELEVBQUU7WUFDbkQsTUFBTSxJQUFJLEdBQUcsY0FBUSxDQUFDLGFBQWEsQ0FDakM7Z0JBQ0UsRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxFQUFFO2dCQUNyRCxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRTtnQkFDakQsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUU7Z0JBQ2xELEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxL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QUFHLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3pDLE1BQU0sQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsY0FBYyxDQUFDLENBQUM7UUFDakUsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5cbmltcG9ydCAqIGFzIGJzNThjaGVjayBmcm9tICdiczU4Y2hlY2snO1xuXG5pbXBvcnQgeyBmcm9tT3V0cHV0U2NyaXB0IH0gZnJvbSAnLi4vLi4vLi4vc3JjL2FkZHJlc3MnO1xuaW1wb3J0IHsgY3JlYXRlT3V0cHV0U2NyaXB0UDJzaFAycGssIHNjcmlwdFR5cGVzMk9mMyB9IGZyb20gJy4uLy4uLy4uL3NyYy9iaXRnby9vdXRwdXRTY3JpcHRzJztcbmltcG9ydCB7IGdldERlZmF1bHRXYWxsZXRLZXlzLCBnZXRLZXlUcmlwbGUsIHJlcGxheVByb3RlY3Rpb25LZXlQYWlyIH0gZnJvbSAnLi4vLi4vLi4vc3JjL3Rlc3R1dGlsJztcbmltcG9ydCB7IG5ldHdvcmtzLCB0ZXN0dXRpbCB9IGZyb20gJy4uLy4uLy4uL3NyYyc7XG5pbXBvcnQgeyBhZGRXYWxsZXRPdXRwdXRUb1BzYnQsIGFkZFhwdWJzVG9Qc2J0LCBnZXRFeHRlcm5hbENoYWluQ29kZSwgUm9vdFdhbGxldEtleXMgfSBmcm9tICcuLi8uLi8uLi9zcmMvYml0Z28nO1xuaW1wb3J0IHtcbiAgZmluZEludGVybmFsT3V0cHV0SW5kaWNlcyxcbiAgZmluZFdhbGxldE91dHB1dEluZGljZXMsXG4gIGdldFRvdGFsQW1vdW50T2ZJbnRlcm5hbE91dHB1dHMsXG4gIGdldFRvdGFsQW1vdW50T2ZXYWxsZXRPdXRwdXRzLFxufSBmcm9tICcuLi8uLi8uLi9zcmMvYml0Z28vd2FsbGV0L3BzYnQvUHNidE91dHB1dHMnO1xuaW1wb3J0IHsgR2xvYmFsWHB1YiB9IGZyb20gJ2JpcDE3NC9zcmMvbGliL2ludGVyZmFjZXMnO1xuXG5jb25zdCBuZXR3b3JrID0gbmV0d29ya3MuYml0Y29pbjtcbmNvbnN0IHJvb3RXYWxsZXRLZXlzID0gZ2V0RGVmYXVsdFdhbGxldEtleXMoKTtcblxuZGVzY3JpYmUoJ3BzYnQgaW50ZXJuYWwgYW5kIHdhbGxldCBvdXRwdXRzJywgZnVuY3Rpb24gKCkge1xuICBjb25zdCB2YWx1ZSA9IEJpZ0ludCgxZTgpO1xuICBjb25zdCBmZWUgPSBCaWdJbnQoMTAwMCk7XG4gIGNvbnN0IGV4dGVybmFsQWRkcmVzcyA9IGZyb21PdXRwdXRTY3JpcHQoXG4gICAgY3JlYXRlT3V0cHV0U2NyaXB0UDJzaFAycGsocmVwbGF5UHJvdGVjdGlvbktleVBhaXIucHVibGljS2V5KS5zY3JpcHRQdWJLZXksXG4gICAgbmV0d29ya3MuYml0Y29pblxuICApO1xuXG4gIGRlc2NyaWJlKCdzdWNjZXNzJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KGBGaW5kIGluZGljZXMgb2YgcHNidCB3YWxsZXQgJiBpbnRlcm5hbCBvdXRwdXRzYCwgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcHNidCA9IHRlc3R1dGlsLmNvbnN0cnVjdFBzYnQoXG4gICAgICAgIFtcbiAgICAgICAgICB7IHNjcmlwdFR5cGU6ICdwMndzaCcsIHZhbHVlOiBCaWdJbnQodmFsdWUgKyB2YWx1ZSkgfSxcbiAgICAgICAgICB7IHNjcmlwdFR5cGU6ICdwMnNoUDJ3c2gnLCB2YWx1ZTogQmlnSW50KHZhbHVlKSB9LFxuICAgICAgICAgIHsgc2NyaXB0VHlwZTogJ3AydHJNdXNpZzInLCB2YWx1ZTogQmlnSW50KHZhbHVlKSB9LFxuICAgICAgICAgIHsgc2NyaXB0VHlwZTogJ3AydHInLCB2YWx1ZTogQmlnSW50KHZhbHVlKSB9LFxuICAgICAgICAgIHsgc2NyaXB0VHlwZTogJ3Ayc2gnLCB2YWx1ZTogQmlnSW50KHZhbHVlKSB9LFxuICAgICAgICBdLFxuICAgICAgICBbXG4gICAgICAgICAgeyBzY3JpcHRUeXBlOiAncDJzaCcsIHZhbHVlOiBCaWdJbnQodmFsdWUpIH0sXG4gICAgICAgICAgeyBzY3JpcHRUeXBlOiAncDJzaFAyd3NoJywgdmFsdWU6IEJpZ0ludCh2YWx1ZSkgfSxcbiAgICAgICAgICB7IHNjcmlwdFR5cGU6ICdwMndzaCcsIHZhbHVlOiBCaWdJbnQodmFsdWUpIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogZXh0ZXJuYWxBZGRyZXNzLFxuICAgICAgICAgICAgdmFsdWU6IEJpZ0ludCh2YWx1ZSAtIGZlZSksXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7IHNjcmlwdFR5cGU6ICdwMnRyJywgdmFsdWU6IEJpZ0ludCh2YWx1ZSksIGlzSW50ZXJuYWxBZGRyZXNzOiB0cnVlIH0sXG4gICAgICAgICAgeyBzY3JpcHRUeXBlOiAncDJ0ck11c2lnMicsIHZhbHVlOiBCaWdJbnQodmFsdWUpLCBpc0ludGVybmFsQWRkcmVzczogdHJ1ZSB9LFxuICAgICAgICBdLFxuICAgICAgICBuZXR3b3JrLFxuICAgICAgICByb290V2FsbGV0S2V5cyxcbiAgICAgICAgJ3Vuc2lnbmVkJ1xuICAgICAgKTtcbiAgICAgIGNvbnN0IGV4cGVjdGVkID0gWzAsIDEsIDIsIDQsIDVdO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbChmaW5kV2FsbGV0T3V0cHV0SW5kaWNlcyhwc2J0LCByb290V2FsbGV0S2V5cy50cmlwbGUpLCBleHBlY3RlZCk7XG4gICAgICBhZGRYcHVic1RvUHNidChwc2J0LCByb290V2FsbGV0S2V5cyk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKGZpbmRJbnRlcm5hbE91dHB1dEluZGljZXMocHNidCksIGV4cGVjdGVkKTtcbiAgICB9KTtcblxuICAgIHNjcmlwdFR5cGVzMk9mMy5mb3JFYWNoKChzY3JpcHRUeXBlKSA9PiB7XG4gICAgICBjb25zdCBwc2J0ID0gdGVzdHV0aWwuY29uc3RydWN0UHNidChcbiAgICAgICAgW1xuICAgICAgICAgIHsgc2NyaXB0VHlwZTogc2NyaXB0VHlwZSwgdmFsdWU6IEJpZ0ludCh2YWx1ZSkgfSxcbiAgICAgICAgICB7IHNjcmlwdFR5cGU6ICdwMndzaCcsIHZhbHVlOiBCaWdJbnQodmFsdWUpIH0sXG4gICAgICAgICAgeyBzY3JpcHRUeXBlOiAncDJzaFAyd3NoJywgdmFsdWU6IEJpZ0ludCh2YWx1ZSkgfSxcbiAgICAgICAgICB7IHNjcmlwdFR5cGU6ICdwMnRyTXVzaWcyJywgdmFsdWU6IEJpZ0ludCh2YWx1ZSkgfSxcbiAgICAgICAgICB7IHNjcmlwdFR5cGU6ICdwMnRyJywgdmFsdWU6IEJpZ0ludCh2YWx1ZSkgfSxcbiAgICAgICAgICB7IHNjcmlwdFR5cGU6ICdwMnNoJywgdmFsdWU6IEJpZ0ludCh2YWx1ZSkgfSxcbiAgICAgICAgXSxcbiAgICAgICAgW1xuICAgICAgICAgIHsgc2NyaXB0VHlwZTogJ3Ayc2gnLCB2YWx1ZTogQmlnSW50KHZhbHVlKSB9LFxuICAgICAgICAgIHsgc2NyaXB0VHlwZTogJ3Ayc2hQMndzaCcsIHZhbHVlOiBCaWdJbnQodmFsdWUpIH0sXG4gICAgICAgICAgeyBzY3JpcHRUeXBlOiAncDJ3c2gnLCB2YWx1ZTogQmlnSW50KHZhbHVlKSB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6IGV4dGVybmFsQWRkcmVzcyxcbiAgICAgICAgICAgIHZhbHVlOiBCaWdJbnQodmFsdWUgLSBmZWUpLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgeyBzY3JpcHRUeXBlOiAncDJ0cicsIHZhbHVlOiBCaWdJbnQodmFsdWUpLCBpc0ludGVybmFsQWRkcmVzczogdHJ1ZSB9LFxuICAgICAgICAgIHsgc2NyaXB0VHlwZTogJ3AydHJNdXNpZzInLCB2YWx1ZTogQmlnSW50KHZhbHVlKSwgaXNJbnRlcm5hbEFkZHJlc3M6IHRydWUgfSxcbiAgICAgICAgXSxcbiAgICAgICAgbmV0d29yayxcbiAgICAgICAgcm9vdFdhbGxldEtleXMsXG4gICAgICAgICd1bnNpZ25lZCdcbiAgICAgICk7XG5cbiAgICAgIGFkZFhwdWJzVG9Qc2J0KHBzYnQsIHJvb3RXYWxsZXRLZXlzKTtcblxuICAgICAgY29uc3QgdG90YWxJbnRlcm5hbEFtb3VudCA9IHZhbHVlICogQmlnSW50KHBzYnQuaW5wdXRDb3VudCAtIDEpO1xuXG4gICAgICBpdChgUFNCVCB3aXRoICR7c2NyaXB0VHlwZX0gaW5wdXQgYW5kIGdsb2JhbFhwdWJgLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChnZXRUb3RhbEFtb3VudE9mSW50ZXJuYWxPdXRwdXRzKHBzYnQpLCB0b3RhbEludGVybmFsQW1vdW50KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdChgQ2xvbmVkIFBTQlQgd2l0aCAke3NjcmlwdFR5cGV9IGlucHV0IGFuZCBnbG9iYWxYcHViYCwgZnVuY3Rpb24gKCkge1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZ2V0VG90YWxBbW91bnRPZkludGVybmFsT3V0cHV0cyhwc2J0LmNsb25lKCkpLCB0b3RhbEludGVybmFsQW1vdW50KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdChgUFNCVCB3aXRoICR7c2NyaXB0VHlwZX0gaW5wdXQgYW5kIG9yZGVyZWQgcm9vdE5vZGVzYCwgZnVuY3Rpb24gKCkge1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZ2V0VG90YWxBbW91bnRPZldhbGxldE91dHB1dHMocHNidCwgcm9vdFdhbGxldEtleXMudHJpcGxlKSwgdG90YWxJbnRlcm5hbEFtb3VudCk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KGBQU0JUIHdpdGggcDJzaFAycGsgYXMgZmlyc3QgaW5wdXRgLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwc2J0ID0gdGVzdHV0aWwuY29uc3RydWN0UHNidChcbiAgICAgICAgW1xuICAgICAgICAgIHsgc2NyaXB0VHlwZTogJ3Ayc2hQMnBrJywgdmFsdWU6IEJpZ0ludCh2YWx1ZSkgfSxcbiAgICAgICAgICB7IHNjcmlwdFR5cGU6ICdwMndzaCcsIHZhbHVlOiBCaWdJbnQodmFsdWUpIH0sXG4gICAgICAgIF0sXG4gICAgICAgIFtcbiAgICAgICAgICB7IHNjcmlwdFR5cGU6ICdwMnNoJywgdmFsdWU6IEJpZ0ludCh2YWx1ZSkgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiBleHRlcm5hbEFkZHJlc3MsXG4gICAgICAgICAgICB2YWx1ZTogQmlnSW50KHZhbHVlIC0gZmVlKSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBuZXR3b3JrLFxuICAgICAgICByb290V2FsbGV0S2V5cyxcbiAgICAgICAgJ3Vuc2lnbmVkJ1xuICAgICAgKTtcbiAgICAgIGFkZFhwdWJzVG9Qc2J0KHBzYnQsIHJvb3RXYWxsZXRLZXlzKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChnZXRUb3RhbEFtb3VudE9mSW50ZXJuYWxPdXRwdXRzKHBzYnQpLCB2YWx1ZSk7XG4gICAgfSk7XG5cbiAgICBpdChgUFNCVCB3aXRoIG91dHB1dHMgb2YgZXh0ZXJuYWwgd2FsbGV0IHJvb3Qgbm9kZXNgLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwc2J0ID0gdGVzdHV0aWwuY29uc3RydWN0UHNidChcbiAgICAgICAgW3sgc2NyaXB0VHlwZTogJ3Ayd3NoJywgdmFsdWU6IEJpZ0ludCh2YWx1ZSkgfV0sXG4gICAgICAgIFt7IHNjcmlwdFR5cGU6ICdwMnNoJywgdmFsdWU6IEJpZ0ludCh2YWx1ZSkgfV0sXG4gICAgICAgIG5ldHdvcmssXG4gICAgICAgIHJvb3RXYWxsZXRLZXlzLFxuICAgICAgICAndW5zaWduZWQnXG4gICAgICApO1xuICAgICAgY29uc3QgZXh0ZXJuYWxBbW91bnQgPSBCaWdJbnQoODg4OCk7XG4gICAgICBjb25zdCBleHRlcm5hbFJvb3RXYWxsZXRLZXlzID0gbmV3IFJvb3RXYWxsZXRLZXlzKGdldEtleVRyaXBsZSgnZHVtbXknKSk7XG4gICAgICBjb25zdCBpbmRpY2VzID0gWzAsIDFdO1xuICAgICAgaW5kaWNlcy5mb3JFYWNoKChpbmRleCkgPT5cbiAgICAgICAgYWRkV2FsbGV0T3V0cHV0VG9Qc2J0KHBzYnQsIGV4dGVybmFsUm9vdFdhbGxldEtleXMsIGdldEV4dGVybmFsQ2hhaW5Db2RlKCdwMndzaCcpLCBpbmRleCwgZXh0ZXJuYWxBbW91bnQpXG4gICAgICApO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKFxuICAgICAgICBnZXRUb3RhbEFtb3VudE9mV2FsbGV0T3V0cHV0cyhwc2J0LCBleHRlcm5hbFJvb3RXYWxsZXRLZXlzLnRyaXBsZSksXG4gICAgICAgIGV4dGVybmFsQW1vdW50ICogQmlnSW50KGluZGljZXMubGVuZ3RoKVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KGBQU0JUIHdpdGggbm8gb3V0cHV0cyBvZiBleHRlcm5hbCB3YWxsZXQgcm9vdCBub2Rlc2AsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBzYnQgPSB0ZXN0dXRpbC5jb25zdHJ1Y3RQc2J0KFxuICAgICAgICBbeyBzY3JpcHRUeXBlOiAncDJ3c2gnLCB2YWx1ZTogQmlnSW50KHZhbHVlKSB9XSxcbiAgICAgICAgW3sgc2NyaXB0VHlwZTogJ3Ayc2gnLCB2YWx1ZTogQmlnSW50KHZhbHVlKSB9XSxcbiAgICAgICAgbmV0d29yayxcbiAgICAgICAgcm9vdFdhbGxldEtleXMsXG4gICAgICAgICd1bnNpZ25lZCdcbiAgICAgICk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoXG4gICAgICAgIGdldFRvdGFsQW1vdW50T2ZXYWxsZXRPdXRwdXRzKHBzYnQsIG5ldyBSb290V2FsbGV0S2V5cyhnZXRLZXlUcmlwbGUoJ2R1bW15JykpLnRyaXBsZSksXG4gICAgICAgIEJpZ0ludCgwKVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KGBQU0JUIHdpdGggbm8gaW50ZXJuYWwgb3V0cHV0YCwgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcHNidCA9IHRlc3R1dGlsLmNvbnN0cnVjdFBzYnQoXG4gICAgICAgIFt7IHNjcmlwdFR5cGU6ICdwMndzaCcsIHZhbHVlOiBCaWdJbnQodmFsdWUpIH1dLFxuICAgICAgICBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogZXh0ZXJuYWxBZGRyZXNzLFxuICAgICAgICAgICAgdmFsdWU6IEJpZ0ludCh2YWx1ZSAtIGZlZSksXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgbmV0d29yayxcbiAgICAgICAgcm9vdFdhbGxldEtleXMsXG4gICAgICAgICd1bnNpZ25lZCdcbiAgICAgICk7XG4gICAgICBhZGRYcHVic1RvUHNidChwc2J0LCByb290V2FsbGV0S2V5cyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZ2V0VG90YWxBbW91bnRPZkludGVybmFsT3V0cHV0cyhwc2J0KSwgQmlnSW50KDApKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2ZhaWx1cmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ1BTQlQgd2l0aG91dCBnbG9iYWxYcHViJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcHNidCA9IHRlc3R1dGlsLmNvbnN0cnVjdFBzYnQoW10sIFtdLCBuZXR3b3JrLCByb290V2FsbGV0S2V5cywgJ3Vuc2lnbmVkJyk7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiBnZXRUb3RhbEFtb3VudE9mSW50ZXJuYWxPdXRwdXRzKHBzYnQpLFxuICAgICAgICAoZTogYW55KSA9PiBlLm1lc3NhZ2UgPT09ICdDb3VsZCBub3QgZmluZCByb290IG5vZGVzIGluIFBTQlQnXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ1BTQlQgd2l0aCBpbnZhbGlkIG51bWJlciBvZiBnbG9iYWxYcHViJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcHNidCA9IHRlc3R1dGlsLmNvbnN0cnVjdFBzYnQoW10sIFtdLCBuZXR3b3JrLCByb290V2FsbGV0S2V5cywgJ3Vuc2lnbmVkJyk7XG4gICAgICBjb25zdCBnbG9iYWxYcHViOiBHbG9iYWxYcHViW10gPSBbXG4gICAgICAgIHtcbiAgICAgICAgICBleHRlbmRlZFB1YmtleTogYnM1OGNoZWNrLmRlY29kZShyb290V2FsbGV0S2V5cy50cmlwbGVbMF0ubmV1dGVyZWQoKS50b0Jhc2U1OCgpKSxcbiAgICAgICAgICBtYXN0ZXJGaW5nZXJwcmludDogcm9vdFdhbGxldEtleXMudHJpcGxlWzBdLmZpbmdlcnByaW50LFxuICAgICAgICAgIHBhdGg6ICdtJyxcbiAgICAgICAgfSxcbiAgICAgIF07XG4gICAgICBwc2J0LnVwZGF0ZUdsb2JhbCh7IGdsb2JhbFhwdWIgfSk7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiBnZXRUb3RhbEFtb3VudE9mSW50ZXJuYWxPdXRwdXRzKHBzYnQpLFxuICAgICAgICAoZTogYW55KSA9PiBlLm1lc3NhZ2UgPT09ICdJbnZhbGlkIGdsb2JhbFhwdWJzIGluIFBTQlQuIEV4cGVjdGVkIDMgb3Igbm9uZS4gR290IDEnXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ1BTQlQgd2l0aG91dCBpbnB1dCBzY3JpcHRQdWJLZXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwc2J0ID0gdGVzdHV0aWwuY29uc3RydWN0UHNidChcbiAgICAgICAgW3sgc2NyaXB0VHlwZTogJ3Ayd3NoJywgdmFsdWU6IEJpZ0ludCh2YWx1ZSkgfV0sXG4gICAgICAgIFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiBleHRlcm5hbEFkZHJlc3MsXG4gICAgICAgICAgICB2YWx1ZTogQmlnSW50KHZhbHVlIC0gZmVlKSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBuZXR3b3JrLFxuICAgICAgICByb290V2FsbGV0S2V5cyxcbiAgICAgICAgJ3Vuc2lnbmVkJ1xuICAgICAgKTtcbiAgICAgIHBzYnQuZGF0YS5pbnB1dHNbMF0ud2l0bmVzc1V0eG8gPSB1bmRlZmluZWQ7XG4gICAgICBhZGRYcHVic1RvUHNidChwc2J0LCByb290V2FsbGV0S2V5cyk7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiBnZXRUb3RhbEFtb3VudE9mSW50ZXJuYWxPdXRwdXRzKHBzYnQpLFxuICAgICAgICAoZTogYW55KSA9PiBlLm1lc3NhZ2UgPT09ICdJbnB1dCBzY3JpcHRQdWJLZXkgY2FuIG5vdCBiZSBmb3VuZCdcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnUFNCVCB3aXRob3V0IGlucHV0IEJpcDMyRGVyaXZhdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBzYnQgPSB0ZXN0dXRpbC5jb25zdHJ1Y3RQc2J0KFxuICAgICAgICBbeyBzY3JpcHRUeXBlOiAncDJ3c2gnLCB2YWx1ZTogQmlnSW50KHZhbHVlKSB9XSxcbiAgICAgICAgW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6IGV4dGVybmFsQWRkcmVzcyxcbiAgICAgICAgICAgIHZhbHVlOiBCaWdJbnQodmFsdWUgLSBmZWUpLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIG5ldHdvcmssXG4gICAgICAgIHJvb3RXYWxsZXRLZXlzLFxuICAgICAgICAndW5zaWduZWQnXG4gICAgICApO1xuICAgICAgcHNidC5kYXRhLmlucHV0c1swXS5iaXAzMkRlcml2YXRpb24gPSB1bmRlZmluZWQ7XG4gICAgICBhZGRYcHVic1RvUHNidChwc2J0LCByb290V2FsbGV0S2V5cyk7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiBnZXRUb3RhbEFtb3VudE9mSW50ZXJuYWxPdXRwdXRzKHBzYnQpLFxuICAgICAgICAoZTogYW55KSA9PiBlLm1lc3NhZ2UgPT09ICdJbnB1dCBCaXAzMkRlcml2YXRpb24gY2FuIG5vdCBiZSBmb3VuZCdcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnUFNCVCB3b3RoIGFuIE9QX1JFVFVSTiBvdXRwdXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBvcFJldHVyblNjcmlwdCA9XG4gICAgICAgICc2YTRjNTA1MzQxNTQyYjAxMDQ1YmRlNjBiN2QwZTZiNzU4Y2E1ZGQ4YzYxZDM3N2EyYzVmMWFmNTFlYzFhOWUyMDlmNWVhMDAzNmM4YzJmNDEwNzhhM2NlYmVlNTdkOGE0N2Q1MDEwNDFmNWUwZTY2YjE3NTc2YTkxNGM0YjhhZTkyN2ZmMmI5Y2UyMThlMjBiZjA2ZDQyNWQ2YjY4NDI0ZmQ4OGFjJztcbiAgICAgIGNvbnN0IHBzYnQgPSB0ZXN0dXRpbC5jb25zdHJ1Y3RQc2J0KFxuICAgICAgICBbeyBzY3JpcHRUeXBlOiAncDJ3c2gnLCB2YWx1ZTogQmlnSW50KHZhbHVlKSB9XSxcbiAgICAgICAgW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6IGV4dGVybmFsQWRkcmVzcyxcbiAgICAgICAgICAgIHZhbHVlOiBCaWdJbnQodmFsdWUgLSBmZWUpLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgc2NyaXB0OiBvcFJldHVyblNjcmlwdCxcbiAgICAgICAgICAgIHZhbHVlOiBCaWdJbnQoMCksXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgbmV0d29yayxcbiAgICAgICAgcm9vdFdhbGxldEtleXMsXG4gICAgICAgICd1bnNpZ25lZCdcbiAgICAgICk7XG4gICAgICBjb25zdCB0eCA9IHBzYnQuZ2V0VW5zaWduZWRUeCgpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHR4Lm91dHMubGVuZ3RoLCAyKTtcbiAgICAgIGNvbnN0IG91dCA9IHR4Lm91dHNbMV07XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwob3V0LnZhbHVlLCBCaWdJbnQoMCkpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKG91dC5zY3JpcHQudG9TdHJpbmcoJ2hleCcpLCBvcFJldHVyblNjcmlwdCk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=Выполнить команду
Для локальной разработки. Не используйте в интернете!