PHP WebShell

Текущая директория: /opt/BitGoJS/modules/abstract-utxo/dist/src/transaction/fixedScript

Просмотр файла: signTransaction.js

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.signTransaction = signTransaction;
const assert_1 = __importDefault(require("assert"));
const lodash_1 = __importDefault(require("lodash"));
const utxo_lib_1 = require("@bitgo/utxo-lib");
const utxolib = __importStar(require("@bitgo/utxo-lib"));
const sdk_core_1 = require("@bitgo/sdk-core");
const sign_1 = require("../../sign");
/**
 * Key Value: Unsigned tx id => PSBT
 * It is used to cache PSBTs with taproot key path (MuSig2) inputs during external express signer is activated.
 * Reason: MuSig2 signer secure nonce is cached in the UtxoPsbt object. It will be required during the signing step.
 * For more info, check SignTransactionOptions.signingStep
 *
 * TODO BTC-276: This cache may need to be done with LRU like memory safe caching if memory issues comes up.
 */
const PSBT_CACHE = new Map();
async function signTransaction(coin, tx, signerKeychain, params) {
    const isTxWithKeyPathSpendInput = tx instanceof utxo_lib_1.bitgo.UtxoPsbt && utxo_lib_1.bitgo.isTransactionWithKeyPathSpendInput(tx);
    let isLastSignature = false;
    if (lodash_1.default.isBoolean(params.isLastSignature)) {
        // We can only be the first signature on a transaction with taproot key path spend inputs because
        // we require the secret nonce in the cache of the first signer, which is impossible to retrieve if
        // deserialized from a hex.
        if (params.isLastSignature && isTxWithKeyPathSpendInput) {
            throw new Error('Cannot be last signature on a transaction with key path spend inputs');
        }
        // if build is called instead of buildIncomplete, no signature placeholders are left in the sig script
        isLastSignature = params.isLastSignature;
    }
    const setSignerMusigNonceWithOverride = (psbt, signerKeychain, nonSegwitOverride) => {
        utxolib.bitgo.withUnsafeNonSegwit(psbt, () => psbt.setAllInputsMusig2NonceHD(signerKeychain), nonSegwitOverride);
    };
    if (tx instanceof utxo_lib_1.bitgo.UtxoPsbt && isTxWithKeyPathSpendInput) {
        switch (params.signingStep) {
            case 'signerNonce':
                (0, assert_1.default)(signerKeychain);
                setSignerMusigNonceWithOverride(tx, signerKeychain, params.allowNonSegwitSigningWithoutPrevTx);
                PSBT_CACHE.set(tx.getUnsignedTx().getId(), tx);
                return { txHex: tx.toHex() };
            case 'cosignerNonce':
                (0, assert_1.default)(params.walletId, 'walletId is required for MuSig2 bitgo nonce');
                return { txHex: (await coin.signPsbt(tx.toHex(), params.walletId)).psbt };
            case 'signerSignature':
                const txId = tx.getUnsignedTx().getId();
                const psbt = PSBT_CACHE.get(txId);
                (0, assert_1.default)(psbt, `Psbt is missing from txCache (cache size ${PSBT_CACHE.size}).
            This may be due to the request being routed to a different BitGo-Express instance that for signing step 'signerNonce'.`);
                PSBT_CACHE.delete(txId);
                tx = psbt.combine(tx);
                break;
            default:
                // this instance is not an external signer
                (0, assert_1.default)(params.walletId, 'walletId is required for MuSig2 bitgo nonce');
                (0, assert_1.default)(signerKeychain);
                setSignerMusigNonceWithOverride(tx, signerKeychain, params.allowNonSegwitSigningWithoutPrevTx);
                const response = await coin.signPsbt(tx.toHex(), params.walletId);
                tx.combine(utxo_lib_1.bitgo.createPsbtFromHex(response.psbt, coin.network));
                break;
        }
    }
    else {
        switch (params.signingStep) {
            case 'signerNonce':
            case 'cosignerNonce':
                /**
                 * In certain cases, the caller of this method may not know whether the txHex contains a psbt with taproot key path spend input(s).
                 * Instead of throwing error, no-op and return the txHex. So that the caller can call this method in the same sequence.
                 */
                return { txHex: tx.toHex() };
        }
    }
    let signedTransaction;
    if (tx instanceof utxo_lib_1.bitgo.UtxoPsbt) {
        (0, assert_1.default)(signerKeychain);
        signedTransaction = (0, sign_1.signAndVerifyPsbt)(tx, signerKeychain, {
            isLastSignature,
            allowNonSegwitSigningWithoutPrevTx: params.allowNonSegwitSigningWithoutPrevTx,
        });
    }
    else {
        if (tx.ins.length !== params.txInfo?.unspents?.length) {
            throw new Error('length of unspents array should equal to the number of transaction inputs');
        }
        if (!params.pubs || !(0, sdk_core_1.isTriple)(params.pubs)) {
            throw new Error(`must provide xpub array`);
        }
        const keychains = params.pubs.map((pub) => utxo_lib_1.bip32.fromBase58(pub));
        const cosignerPub = params.cosignerPub ?? params.pubs[2];
        const cosignerKeychain = utxo_lib_1.bip32.fromBase58(cosignerPub);
        (0, assert_1.default)(signerKeychain);
        const walletSigner = new utxo_lib_1.bitgo.WalletUnspentSigner(keychains, signerKeychain, cosignerKeychain);
        signedTransaction = (0, sign_1.signAndVerifyWalletTransaction)(tx, params.txInfo.unspents, walletSigner, {
            isLastSignature,
        });
    }
    return {
        txHex: signedTransaction.toBuffer().toString('hex'),
    };
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnblRyYW5zYWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3RyYW5zYWN0aW9uL2ZpeGVkU2NyaXB0L3NpZ25UcmFuc2FjdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW9CQSwwQ0E2R0M7QUFqSUQsb0RBQTRCO0FBRTVCLG9EQUF1QjtBQUN2Qiw4Q0FBK0Q7QUFDL0QseURBQTJDO0FBQzNDLDhDQUFtRDtBQUVuRCxxQ0FBK0U7QUFHL0U7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxHQUFHLElBQUksR0FBRyxFQUFrQyxDQUFDO0FBRXRELEtBQUssVUFBVSxlQUFlLENBQ25DLElBQXNCLEVBQ3RCLEVBQStCLEVBQy9CLGNBQTBDLEVBQzFDLE1BUUM7SUFFRCxNQUFNLHlCQUF5QixHQUFHLEVBQUUsWUFBWSxnQkFBSyxDQUFDLFFBQVEsSUFBSSxnQkFBSyxDQUFDLGtDQUFrQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBRS9HLElBQUksZUFBZSxHQUFHLEtBQUssQ0FBQztJQUM1QixJQUFJLGdCQUFDLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDO1FBQ3hDLGlHQUFpRztRQUNqRyxtR0FBbUc7UUFDbkcsMkJBQTJCO1FBQzNCLElBQUksTUFBTSxDQUFDLGVBQWUsSUFBSSx5QkFBeUIsRUFBRSxDQUFDO1lBQ3hELE1BQU0sSUFBSSxLQUFLLENBQUMsc0VBQXNFLENBQUMsQ0FBQztRQUMxRixDQUFDO1FBRUQsc0dBQXNHO1FBQ3RHLGVBQWUsR0FBRyxNQUFNLENBQUMsZUFBZSxDQUFDO0lBQzNDLENBQUM7SUFFRCxNQUFNLCtCQUErQixHQUFHLENBQ3RDLElBQTRCLEVBQzVCLGNBQXNDLEVBQ3RDLGlCQUEwQixFQUMxQixFQUFFO1FBQ0YsT0FBTyxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxJ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b20gJ2Fzc2VydCc7XG5cbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyBiaXAzMiwgQklQMzJJbnRlcmZhY2UsIGJpdGdvIH0gZnJvbSAnQGJpdGdvL3V0eG8tbGliJztcbmltcG9ydCAqIGFzIHV0eG9saWIgZnJvbSAnQGJpdGdvL3V0eG8tbGliJztcbmltcG9ydCB7IGlzVHJpcGxlLCBUcmlwbGUgfSBmcm9tICdAYml0Z28vc2RrLWNvcmUnO1xuXG5pbXBvcnQgeyBzaWduQW5kVmVyaWZ5UHNidCwgc2lnbkFuZFZlcmlmeVdhbGxldFRyYW5zYWN0aW9uIH0gZnJvbSAnLi4vLi4vc2lnbic7XG5pbXBvcnQgeyBBYnN0cmFjdFV0eG9Db2luLCBEZWNvZGVkVHJhbnNhY3Rpb24sIFJvb3RXYWxsZXRLZXlzIH0gZnJvbSAnLi4vLi4vYWJzdHJhY3RVdHhvQ29pbic7XG5cbi8qKlxuICogS2V5IFZhbHVlOiBVbnNpZ25lZCB0eCBpZCA9PiBQU0JUXG4gKiBJdCBpcyB1c2VkIHRvIGNhY2hlIFBTQlRzIHdpdGggdGFwcm9vdCBrZXkgcGF0aCAoTXVTaWcyKSBpbnB1dHMgZHVyaW5nIGV4dGVybmFsIGV4cHJlc3Mgc2lnbmVyIGlzIGFjdGl2YXRlZC5cbiAqIFJlYXNvbjogTXVTaWcyIHNpZ25lciBzZWN1cmUgbm9uY2UgaXMgY2FjaGVkIGluIHRoZSBVdHhvUHNidCBvYmplY3QuIEl0IHdpbGwgYmUgcmVxdWlyZWQgZHVyaW5nIHRoZSBzaWduaW5nIHN0ZXAuXG4gKiBGb3IgbW9yZSBpbmZvLCBjaGVjayBTaWduVHJhbnNhY3Rpb25PcHRpb25zLnNpZ25pbmdTdGVwXG4gKlxuICogVE9ETyBCVEMtMjc2OiBUaGlzIGNhY2hlIG1heSBuZWVkIHRvIGJlIGRvbmUgd2l0aCBMUlUgbGlrZSBtZW1vcnkgc2FmZSBjYWNoaW5nIGlmIG1lbW9yeSBpc3N1ZXMgY29tZXMgdXAuXG4gKi9cbmNvbnN0IFBTQlRfQ0FDSEUgPSBuZXcgTWFwPHN0cmluZywgdXR4b2xpYi5iaXRnby5VdHhvUHNidD4oKTtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNpZ25UcmFuc2FjdGlvbjxUTnVtYmVyIGV4dGVuZHMgbnVtYmVyIHwgYmlnaW50PihcbiAgY29pbjogQWJzdHJhY3RVdHhvQ29pbixcbiAgdHg6IERlY29kZWRUcmFuc2FjdGlvbjxUTnVtYmVyPixcbiAgc2lnbmVyS2V5Y2hhaW46IEJJUDMySW50ZXJmYWNlIHwgdW5kZWZpbmVkLFxuICBwYXJhbXM6IHtcbiAgICB3YWxsZXRJZDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIHR4SW5mbzogeyB1bnNwZW50cz86IHV0eG9saWIuYml0Z28uVW5zcGVudDxUTnVtYmVyPltdIH0gfCB1bmRlZmluZWQ7XG4gICAgaXNMYXN0U2lnbmF0dXJlOiBib29sZWFuO1xuICAgIHNpZ25pbmdTdGVwOiAnc2lnbmVyTm9uY2UnIHwgJ2Nvc2lnbmVyTm9uY2UnIHwgJ3NpZ25lclNpZ25hdHVyZScgfCB1bmRlZmluZWQ7XG4gICAgYWxsb3dOb25TZWd3aXRTaWduaW5nV2l0aG91dFByZXZUeDogYm9vbGVhbjtcbiAgICBwdWJzOiBzdHJpbmdbXSB8IHVuZGVmaW5lZDtcbiAgICBjb3NpZ25lclB1Yjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICB9XG4pOiBQcm9taXNlPHsgdHhIZXg6IHN0cmluZyB9PiB7XG4gIGNvbnN0IGlzVHhXaXRoS2V5UGF0aFNwZW5kSW5wdXQgPSB0eCBpbnN0YW5jZW9mIGJpdGdvLlV0eG9Qc2J0ICYmIGJpdGdvLmlzVHJhbnNhY3Rpb25XaXRoS2V5UGF0aFNwZW5kSW5wdXQodHgpO1xuXG4gIGxldCBpc0xhc3RTaWduYXR1cmUgPSBmYWxzZTtcbiAgaWYgKF8uaXNCb29sZWFuKHBhcmFtcy5pc0xhc3RTaWduYXR1cmUpKSB7XG4gICAgLy8gV2UgY2FuIG9ubHkgYmUgdGhlIGZpcnN0IHNpZ25hdHVyZSBvbiBhIHRyYW5zYWN0aW9uIHdpdGggdGFwcm9vdCBrZXkgcGF0aCBzcGVuZCBpbnB1dHMgYmVjYXVzZVxuICAgIC8vIHdlIHJlcXVpcmUgdGhlIHNlY3JldCBub25jZSBpbiB0aGUgY2FjaGUgb2YgdGhlIGZpcnN0IHNpZ25lciwgd2hpY2ggaXMgaW1wb3NzaWJsZSB0byByZXRyaWV2ZSBpZlxuICAgIC8vIGRlc2VyaWFsaXplZCBmcm9tIGEgaGV4LlxuICAgIGlmIChwYXJhbXMuaXNMYXN0U2lnbmF0dXJlICYmIGlzVHhXaXRoS2V5UGF0aFNwZW5kSW5wdXQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGJlIGxhc3Qgc2lnbmF0dXJlIG9uIGEgdHJhbnNhY3Rpb24gd2l0aCBrZXkgcGF0aCBzcGVuZCBpbnB1dHMnKTtcbiAgICB9XG5cbiAgICAvLyBpZiBidWlsZCBpcyBjYWxsZWQgaW5zdGVhZCBvZiBidWlsZEluY29tcGxldGUsIG5vIHNpZ25hdHVyZSBwbGFjZWhvbGRlcnMgYXJlIGxlZnQgaW4gdGhlIHNpZyBzY3JpcHRcbiAgICBpc0xhc3RTaWduYXR1cmUgPSBwYXJhbXMuaXNMYXN0U2lnbmF0dXJlO1xuICB9XG5cbiAgY29uc3Qgc2V0U2lnbmVyTXVzaWdOb25jZVdpdGhPdmVycmlkZSA9IChcbiAgICBwc2J0OiB1dHhvbGliLmJpdGdvLlV0eG9Qc2J0LFxuICAgIHNpZ25lcktleWNoYWluOiB1dHhvbGliLkJJUDMySW50ZXJmYWNlLFxuICAgIG5vblNlZ3dpdE92ZXJyaWRlOiBib29sZWFuXG4gICkgPT4ge1xuICAgIHV0eG9saWIuYml0Z28ud2l0aFVuc2FmZU5vblNlZ3dpdChwc2J0LCAoKSA9PiBwc2J0LnNldEFsbElucHV0c011c2lnMk5vbmNlSEQoc2lnbmVyS2V5Y2hhaW4pLCBub25TZWd3aXRPdmVycmlkZSk7XG4gIH07XG5cbiAgaWYgKHR4IGluc3RhbmNlb2YgYml0Z28uVXR4b1BzYnQgJiYgaXNUeFdpdGhLZXlQYXRoU3BlbmRJbnB1dCkge1xuICAgIHN3aXRjaCAocGFyYW1zLnNpZ25pbmdTdGVwKSB7XG4gICAgICBjYXNlICdzaWduZXJOb25jZSc6XG4gICAgICAgIGFzc2VydChzaWduZXJLZXljaGFpbik7XG4gICAgICAgIHNldFNpZ25lck11c2lnTm9uY2VXaXRoT3ZlcnJpZGUodHgsIHNpZ25lcktleWNoYWluLCBwYXJhbXMuYWxsb3dOb25TZWd3aXRTaWduaW5nV2l0aG91dFByZXZUeCk7XG4gICAgICAgIFBTQlRfQ0FDSEUuc2V0KHR4LmdldFVuc2lnbmVkVHgoKS5nZXRJZCgpLCB0eCk7XG4gICAgICAgIHJldHVybiB7IHR4SGV4OiB0eC50b0hleCgpIH07XG4gICAgICBjYXNlICdjb3NpZ25lck5vbmNlJzpcbiAgICAgICAgYXNzZXJ0KHBhcmFtcy53YWxsZXRJZCwgJ3dhbGxldElkIGlzIHJlcXVpcmVkIGZvciBNdVNpZzIgYml0Z28gbm9uY2UnKTtcbiAgICAgICAgcmV0dXJuIHsgdHhIZXg6IChhd2FpdCBjb2luLnNpZ25Qc2J0KHR4LnRvSGV4KCksIHBhcmFtcy53YWxsZXRJZCkpLnBzYnQgfTtcbiAgICAgIGNhc2UgJ3NpZ25lclNpZ25hdHVyZSc6XG4gICAgICAgIGNvbnN0IHR4SWQgPSB0eC5nZXRVbnNpZ25lZFR4KCkuZ2V0SWQoKTtcbiAgICAgICAgY29uc3QgcHNidCA9IFBTQlRfQ0FDSEUuZ2V0KHR4SWQpO1xuICAgICAgICBhc3NlcnQoXG4gICAgICAgICAgcHNidCxcbiAgICAgICAgICBgUHNidCBpcyBtaXNzaW5nIGZyb20gdHhDYWNoZSAoY2FjaGUgc2l6ZSAke1BTQlRfQ0FDSEUuc2l6ZX0pLlxuICAgICAgICAgICAgVGhpcyBtYXkgYmUgZHVlIHRvIHRoZSByZXF1ZXN0IGJlaW5nIHJvdXRlZCB0byBhIGRpZmZlcmVudCBCaXRHby1FeHByZXNzIGluc3RhbmNlIHRoYXQgZm9yIHNpZ25pbmcgc3RlcCAnc2lnbmVyTm9uY2UnLmBcbiAgICAgICAgKTtcbiAgICAgICAgUFNCVF9DQUNIRS5kZWxldGUodHhJZCk7XG4gICAgICAgIHR4ID0gcHNidC5jb21iaW5lKHR4KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICAvLyB0aGlzIGluc3RhbmNlIGlzIG5vdCBhbiBleHRlcm5hbCBzaWduZXJcbiAgICAgICAgYXNzZXJ0KHBhcmFtcy53YWxsZXRJZCwgJ3dhbGxldElkIGlzIHJlcXVpcmVkIGZvciBNdVNpZzIgYml0Z28gbm9uY2UnKTtcbiAgICAgICAgYXNzZXJ0KHNpZ25lcktleWNoYWluKTtcbiAgICAgICAgc2V0U2lnbmVyTXVzaWdOb25jZVdpdGhPdmVycmlkZSh0eCwgc2lnbmVyS2V5Y2hhaW4sIHBhcmFtcy5hbGxvd05vblNlZ3dpdFNpZ25pbmdXaXRob3V0UHJldlR4KTtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBjb2luLnNpZ25Qc2J0KHR4LnRvSGV4KCksIHBhcmFtcy53YWxsZXRJZCk7XG4gICAgICAgIHR4LmNvbWJpbmUoYml0Z28uY3JlYXRlUHNidEZyb21IZXgocmVzcG9uc2UucHNidCwgY29pbi5uZXR3b3JrKSk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBzd2l0Y2ggKHBhcmFtcy5zaWduaW5nU3RlcCkge1xuICAgICAgY2FzZSAnc2lnbmVyTm9uY2UnOlxuICAgICAgY2FzZSAnY29zaWduZXJOb25jZSc6XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJbiBjZXJ0YWluIGNhc2VzLCB0aGUgY2FsbGVyIG9mIHRoaXMgbWV0aG9kIG1heSBub3Qga25vdyB3aGV0aGVyIHRoZSB0eEhleCBjb250YWlucyBhIHBzYnQgd2l0aCB0YXByb290IGtleSBwYXRoIHNwZW5kIGlucHV0KHMpLlxuICAgICAgICAgKiBJbnN0ZWFkIG9mIHRocm93aW5nIGVycm9yLCBuby1vcCBhbmQgcmV0dXJuIHRoZSB0eEhleC4gU28gdGhhdCB0aGUgY2FsbGVyIGNhbiBjYWxsIHRoaXMgbWV0aG9kIGluIHRoZSBzYW1lIHNlcXVlbmNlLlxuICAgICAgICAgKi9cbiAgICAgICAgcmV0dXJuIHsgdHhIZXg6IHR4LnRvSGV4KCkgfTtcbiAgICB9XG4gIH1cblxuICBsZXQgc2lnbmVkVHJhbnNhY3Rpb246IGJpdGdvLlV0eG9UcmFuc2FjdGlvbjxiaWdpbnQ+IHwgYml0Z28uVXR4b1BzYnQ7XG4gIGlmICh0eCBpbnN0YW5jZW9mIGJpdGdvLlV0eG9Qc2J0KSB7XG4gICAgYXNzZXJ0KHNpZ25lcktleWNoYWluKTtcbiAgICBzaWduZWRUcmFuc2FjdGlvbiA9IHNpZ25BbmRWZXJpZnlQc2J0KHR4LCBzaWduZXJLZXljaGFpbiwge1xuICAgICAgaXNMYXN0U2lnbmF0dXJlLFxuICAgICAgYWxsb3dOb25TZWd3aXRTaWduaW5nV2l0aG91dFByZXZUeDogcGFyYW1zLmFsbG93Tm9uU2Vnd2l0U2lnbmluZ1dpdGhvdXRQcmV2VHgsXG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgaWYgKHR4Lmlucy5sZW5ndGggIT09IHBhcmFtcy50eEluZm8/LnVuc3BlbnRzPy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbGVuZ3RoIG9mIHVuc3BlbnRzIGFycmF5IHNob3VsZCBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIHRyYW5zYWN0aW9uIGlucHV0cycpO1xuICAgIH1cblxuICAgIGlmICghcGFyYW1zLnB1YnMgfHwgIWlzVHJpcGxlKHBhcmFtcy5wdWJzKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBtdXN0IHByb3ZpZGUgeHB1YiBhcnJheWApO1xuICAgIH1cblxuICAgIGNvbnN0IGtleWNoYWlucyA9IHBhcmFtcy5wdWJzLm1hcCgocHViKSA9PiBiaXAzMi5mcm9tQmFzZTU4KHB1YikpIGFzIFRyaXBsZTxCSVAzMkludGVyZmFjZT47XG4gICAgY29uc3QgY29zaWduZXJQdWIgPSBwYXJhbXMuY29zaWduZXJQdWIgPz8gcGFyYW1zLnB1YnNbMl07XG4gICAgY29uc3QgY29zaWduZXJLZXljaGFpbiA9IGJpcDMyLmZyb21CYXNlNTgoY29zaWduZXJQdWIpO1xuXG4gICAgYXNzZXJ0KHNpZ25lcktleWNoYWluKTtcbiAgICBjb25zdCB3YWxsZXRTaWduZXIgPSBuZXcgYml0Z28uV2FsbGV0VW5zcGVudFNpZ25lcjxSb290V2FsbGV0S2V5cz4oa2V5Y2hhaW5zLCBzaWduZXJLZXljaGFpbiwgY29zaWduZXJLZXljaGFpbik7XG4gICAgc2lnbmVkVHJhbnNhY3Rpb24gPSBzaWduQW5kVmVyaWZ5V2FsbGV0VHJhbnNhY3Rpb24odHgsIHBhcmFtcy50eEluZm8udW5zcGVudHMsIHdhbGxldFNpZ25lciwge1xuICAgICAgaXNMYXN0U2lnbmF0dXJlLFxuICAgIH0pIGFzIGJpdGdvLlV0eG9UcmFuc2FjdGlvbjxiaWdpbnQ+O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB0eEhleDogc2lnbmVkVHJhbnNhY3Rpb24udG9CdWZmZXIoKS50b1N0cmluZygnaGV4JyksXG4gIH07XG59XG4iXX0=

Выполнить команду


Для локальной разработки. Не используйте в интернете!