PHP WebShell
Текущая директория: /usr/lib/node_modules/bitgo/node_modules/@bitgo/sdk-coin-stx/dist/src/lib
Просмотр файла: transactionBuilder.js
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TransactionBuilder = void 0;
const bignumber_js_1 = __importDefault(require("bignumber.js"));
const bn_js_1 = __importDefault(require("bn.js"));
const statics_1 = require("@bitgo/statics");
const transactions_1 = require("@stacks/transactions");
const network_1 = require("@stacks/network");
const sdk_core_1 = require("@bitgo/sdk-core");
const transaction_1 = require("./transaction");
const keyPair_1 = require("./keyPair");
const utils_1 = require("./utils");
const constants_1 = require("./constants");
class TransactionBuilder extends sdk_core_1.BaseTransactionBuilder {
constructor(_coinConfig) {
super(_coinConfig);
this.getSignature = (_, index) => this._signatures.find((s) => s.index === index);
this.getPrivateKey = (pubKey, _) => this._multiSignerKeyPairs.find((kp) => kp.getKeys(true).pub === pubKey || kp.getKeys().pub === pubKey);
this._anchorMode = constants_1.ANCHOR_MODE;
this._multiSignerKeyPairs = [];
this._fromPubKeys = [];
this._signatures = [];
this._numberSignatures = constants_1.DEFAULT_MULTISIG_SIG_NUMBER;
this._network = _coinConfig.network.type === statics_1.NetworkType.MAINNET ? new network_1.StacksMainnet() : new network_1.StacksTestnet();
this._transaction = new transaction_1.Transaction(_coinConfig);
}
/**
* Initialize the transaction builder fields using the decoded transaction data
*
* @param {Transaction} tx the transaction data
*/
initBuilder(tx) {
this.transaction = tx;
// check if it is signed or unsigned tx
if (tx.stxTransaction.auth.spendingCondition === undefined) {
throw new sdk_core_1.InvalidTransactionError('spending condition cannot be undefined');
}
const txData = tx.toJson();
this.fee({ fee: txData.fee.toString() });
this.nonce(txData.nonce);
let sigHash = tx.stxTransaction.verifyBegin();
const authType = tx.stxTransaction.auth.authType ? tx.stxTransaction.auth.authType : transactions_1.AuthType.Standard;
if ((0, transactions_1.isSingleSig)(tx.stxTransaction.auth.spendingCondition)) {
this._numberSignatures = 1;
if (tx.stxTransaction.auth.spendingCondition.signature.data !== (0, transactions_1.emptyMessageSignature)().data) {
const signature = tx.stxTransaction.auth.spendingCondition.signature;
sigHash = (0, transactions_1.makeSigHashPreSign)(sigHash, authType, new bn_js_1.default(this._fee.fee), new bn_js_1.default(this._nonce));
this._signatures.push({ ...signature, index: 0, sigHash });
this._fromPubKeys = [(0, transactions_1.publicKeyFromSignature)(sigHash, signature)];
}
}
else {
this._numberSignatures = tx.stxTransaction.auth.spendingCondition.signaturesRequired;
tx.stxTransaction.auth.spendingCondition.fields.forEach((field, index) => {
if (field.contents.type === transactions_1.StacksMessageType.MessageSignature) {
const signature = field.contents;
const nextVerify = (0, transactions_1.nextVerification)(sigHash, authType, new bn_js_1.default(this._fee.fee), new bn_js_1.default(this._nonce), transactions_1.PubKeyEncoding.Compressed, // useless param as Compressed is hardcoded in stacks lib
signature);
sigHash = nextVerify.nextSigHash;
this._signatures.push({ ...signature, index, sigHash });
this._fromPubKeys.push(nextVerify.pubKey.data.toString('hex'));
}
else {
this._fromPubKeys.push(field.contents.data.toString('hex'));
}
});
}
}
/** @inheritdoc */
fromImplementation(rawTransaction) {
const tx = new transaction_1.Transaction(this._coinConfig);
this.validateRawTransaction(rawTransaction);
const stackstransaction = (0, transactions_1.deserializeTransaction)(transactions_1.BufferReader.fromBuffer(Buffer.from((0, utils_1.removeHexPrefix)(rawTransaction), 'hex')));
tx.stxTransaction = stackstransaction;
this.initBuilder(tx);
return this.transaction;
}
// region Base Builder
/** @inheritdoc */
async buildImplementation() {
const isMultiSig = this._fromPubKeys.length > 1;
this._transaction.stxTransaction.setFee(new bn_js_1.default(this._fee.fee));
this._transaction.stxTransaction.setNonce(new bn_js_1.default(this._nonce));
for (let index = 0; index < this._fromPubKeys.length; index++) {
const pubKey = this._fromPubKeys[index];
const signature = this.getSignature(pubKey, index);
if (signature) {
await this.transaction.signWithSignatures(signature, isMultiSig);
}
else {
const prvKey = this.getPrivateKey(pubKey, index);
if (prvKey) {
await this.transaction.sign(prvKey);
}
else if (isMultiSig) {
await this.transaction.appendOrigin(pubKey);
}
}
}
this._transaction.loadInputsAndOutputs();
return this._transaction;
}
/** @inheritdoc */
signImplementation(key) {
this.checkDuplicatedKeys(key);
let prv = key.key;
if (prv.startsWith('xprv')) {
const rawPrv = (0, sdk_core_1.xprvToRawPrv)(prv);
prv = new keyPair_1.KeyPair({ prv: rawPrv }).getKeys(true).prv;
}
const signer = new keyPair_1.KeyPair({ prv: prv });
// Signing the transaction is an operation that relies on all the data being set,
// so we set the source here and leave the actual signing for the build step
this._multiSignerKeyPairs.push(signer);
const publicKey = signer.getKeys(signer.getCompressed()).pub;
if (!this._fromPubKeys.includes(publicKey)) {
this._fromPubKeys.push(publicKey);
}
return this.transaction;
}
/** @inheritdoc */
get transaction() {
return this._transaction;
}
/** @inheritdoc */
set transaction(transaction) {
this._transaction = transaction;
}
/**
* Validates that the given key is not already in this._multiSignerKeyPairs
*
* @param {BaseKey} key - The key to check
*/
checkDuplicatedKeys(key) {
this._multiSignerKeyPairs.forEach((_sourceKeyPair) => {
if (_sourceKeyPair.getKeys().prv === key.key) {
throw new sdk_core_1.SigningError('Repeated sign: ' + key.key);
}
});
}
/**
* Set the transaction fees
*
* @param {BaseFee} fee The maximum gas to pay
* @returns {TransactionBuilder} This transaction builder
*/
fee(fee) {
this.validateValue(new bignumber_js_1.default(fee.fee));
this._fee = fee;
return this;
}
nonce(n) {
this._nonce = n;
return this;
}
fromPubKey(senderPubKey) {
const pubKeys = senderPubKey instanceof Array ? senderPubKey : [senderPubKey];
this._fromPubKeys = [];
pubKeys.forEach((key) => {
if ((0, utils_1.isValidPublicKey)(key)) {
this._fromPubKeys.push(key);
}
else {
throw new sdk_core_1.InvalidParameterValueError('Invalid public key');
}
});
return this;
}
/**
* Set the memo
*
* @param {string} memo
* @returns {TransactionBuilder} This transaction builder
*/
memo(memo) {
if (!(0, utils_1.isValidMemo)(memo)) {
throw new sdk_core_1.BuildTransactionError('Memo is too long');
}
this._memo = memo;
return this;
}
/**
* Set the number of signatures for multi-sig
*
* @param {number} numSigns
* @returns {TransactionBuilder} This transaction builder
*/
numberSignatures(numSigns) {
this.validateValue(new bignumber_js_1.default(numSigns));
this._numberSignatures = numSigns;
return this;
}
// region Validators
/** @inheritdoc */
validateAddress(address, addressFormat) {
if (!(0, utils_1.isValidAddress)(address.address)) {
throw new sdk_core_1.BuildTransactionError('Invalid address ' + address.address);
}
}
/** @inheritdoc */
validateKey(key) {
const keyPair = new keyPair_1.KeyPair({ prv: key.key });
if (!keyPair.getKeys().prv) {
throw new sdk_core_1.BuildTransactionError('Invalid key');
}
}
/** @inheritdoc */
validateRawTransaction(rawTransaction) {
if (!rawTransaction) {
throw new sdk_core_1.InvalidTransactionError('Raw transaction is empty');
}
try {
(0, transactions_1.deserializeTransaction)(transactions_1.BufferReader.fromBuffer(Buffer.from((0, utils_1.removeHexPrefix)(rawTransaction), 'hex')));
}
catch (e) {
throw new sdk_core_1.ParseTransactionError('There was an error parsing the raw transaction');
}
}
/** @inheritdoc */
validateTransaction(transaction) {
this.validateFee();
this.validateNonce();
}
/** @inheritdoc */
validateValue(value) {
if (value.isLessThan(0)) {
throw new sdk_core_1.BuildTransactionError('Value cannot be less than zero');
}
}
/**
* Validates that the fee field is defined
*/
validateFee() {
if (this._fee === undefined) {
throw new sdk_core_1.BuildTransactionError('Invalid transaction: missing fee');
}
try {
this.validateValue(new bignumber_js_1.default(this._fee.fee));
}
catch (e) {
throw new sdk_core_1.BuildTransactionError('Invalid fee');
}
}
/**
* Validates that nonce is defined
*/
validateNonce() {
if (this._nonce === undefined) {
throw new sdk_core_1.BuildTransactionError('Invalid transaction: missing nonce');
}
try {
this.validateValue(new bignumber_js_1.default(this._nonce));
}
catch (e) {
throw new sdk_core_1.BuildTransactionError(`Invalid nonce ${this._nonce}`);
}
}
}
exports.TransactionBuilder = TransactionBuilder;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNhY3Rpb25CdWlsZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi90cmFuc2FjdGlvbkJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsZ0VBQXFDO0FBQ3JDLGtEQUEyQjtBQUMzQiw0Q0FBcUU7QUFDckUsdURBVzhCO0FBQzlCLDZDQUE4RTtBQUM5RSw4Q0FXeUI7QUFDekIsK0NBQTRDO0FBQzVDLHVDQUFvQztBQUVwQyxtQ0FBeUY7QUFDekYsMkNBQXVFO0FBRXZFLE1BQXNCLGtCQUFtQixTQUFRLGlDQUFzQjtJQVlyRSxZQUFZLFdBQWlDO1FBQzNDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQztRQWdHYixpQkFBWSxHQUFHLENBQUMsQ0FBUyxFQUFFLEtBQWEsRUFBNkIsRUFBRSxDQUM3RSxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssS0FBSyxLQUFLLENBQUMsQ0FBQztRQUMxQyxrQkFBYSxHQUFHLENBQUMsTUFBYyxFQUFFLENBQVMsRUFBdUIsRUFBRSxDQUN6RSxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsS0FBSyxNQUFNLElBQUksRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDLEdBQUcsS0FBSyxNQUFNLENBQUMsQ0FBQztRQWxHdkcsSUFBSSxDQUFDLFdBQVcsR0FBRyx1QkFBVyxDQUFDO1FBQy9CLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxFQUFFLENBQUM7UUFDL0IsSUFBSSxDQUFDLFlBQVksR0FBRyxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLFdBQVcsR0FBRyxFQUFFLENBQUM7UUFDdEIsSUFBSSxDQUFDLGlCQUFpQixHQUFHLHVDQUEyQixDQUFDO1FB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QUFHLENBQUMsQ0FBQyxDQUFDO1FBQ25ELENBQUM7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ1gsTUFBTSxJQUFJLGdDQUFxQixDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ2pELENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxhQUFhO1FBQ25CLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUM5QixNQUFNLElBQUksZ0NBQXFCLENBQUMsb0NBQW9DLENBQUMsQ0FBQztRQUN4RSxDQUFDO1FBQ0QsSUFBSSxDQUFDO1lBQ0gsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLHNCQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDakQsQ0FBQztRQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDWCxNQUFNLElBQUksZ0NBQXFCLENBQUMsaUJBQWlCLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ2xFLENBQUM7SUFDSCxDQUFDO0NBQ0Y7QUF6UkQsZ0RBeVJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEJpZ051bWJlciBmcm9tICdiaWdudW1iZXIuanMnO1xuaW1wb3J0IEJpZ051bSBmcm9tICdibi5qcyc7XG5pbXBvcnQgeyBCYXNlQ29pbiBhcyBDb2luQ29uZmlnLCBOZXR3b3JrVHlwZSB9IGZyb20gJ0BiaXRnby9zdGF0aWNzJztcbmltcG9ydCB7XG4gIEF1dGhUeXBlLFxuICBCdWZmZXJSZWFkZXIsXG4gIGRlc2VyaWFsaXplVHJhbnNhY3Rpb24sXG4gIGVtcHR5TWVzc2FnZVNpZ25hdHVyZSxcbiAgaXNTaW5nbGVTaWcsXG4gIG1ha2VTaWdIYXNoUHJlU2lnbixcbiAgbmV4dFZlcmlmaWNhdGlvbixcbiAgcHVibGljS2V5RnJvbVNpZ25hdHVyZSxcbiAgU3RhY2tzTWVzc2FnZVR5cGUsXG4gIFB1YktleUVuY29kaW5nLFxufSBmcm9tICdAc3RhY2tzL3RyYW5zYWN0aW9ucyc7XG5pbXBvcnQgeyBTdGFja3NOZXR3b3JrLCBTdGFja3NUZXN0bmV0LCBTdGFja3NNYWlubmV0IH0gZnJvbSAnQHN0YWNrcy9uZXR3b3JrJztcbmltcG9ydCB7XG4gIEJhc2VBZGRyZXNzLFxuICBCYXNlRmVlLFxuICBCYXNlS2V5LFxuICBCYXNlVHJhbnNhY3Rpb25CdWlsZGVyLFxuICBCdWlsZFRyYW5zYWN0aW9uRXJyb3IsXG4gIEludmFsaWRQYXJhbWV0ZXJWYWx1ZUVycm9yLFxuICBJbnZhbGlkVHJhbnNhY3Rpb25FcnJvcixcbiAgUGFyc2VUcmFuc2FjdGlvbkVycm9yLFxuICBTaWduaW5nRXJyb3IsXG4gIHhwcnZUb1Jhd1Bydixcbn0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcbmltcG9ydCB7IFRyYW5zYWN0aW9uIH0gZnJvbSAnLi90cmFuc2FjdGlvbic7XG5pbXBvcnQgeyBLZXlQYWlyIH0gZnJvbSAnLi9rZXlQYWlyJztcbmltcG9ydCB7IFNpZ25hdHVyZURhdGEgfSBmcm9tICcuL2lmYWNlJztcbmltcG9ydCB7IGlzVmFsaWRBZGRyZXNzLCByZW1vdmVIZXhQcmVmaXgsIGlzVmFsaWRNZW1vLCBpc1ZhbGlkUHVibGljS2V5IH0gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQgeyBBTkNIT1JfTU9ERSwgREVGQVVMVF9NVUxUSVNJR19TSUdfTlVNQkVSIH0gZnJvbSAnLi9jb25zdGFudHMnO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgVHJhbnNhY3Rpb25CdWlsZGVyIGV4dGVuZHMgQmFzZVRyYW5zYWN0aW9uQnVpbGRlciB7XG4gIHByaXZhdGUgX3RyYW5zYWN0aW9uOiBUcmFuc2FjdGlvbjtcbiAgcHJvdGVjdGVkIF9hbmNob3JNb2RlOiBudW1iZXI7XG4gIHByb3RlY3RlZCBfZmVlOiBCYXNlRmVlO1xuICBwcm90ZWN0ZWQgX25vbmNlOiBudW1iZXI7XG4gIHByb3RlY3RlZCBfbWVtbzogc3RyaW5nO1xuICBwcm90ZWN0ZWQgX251bWJlclNpZ25hdHVyZXM6IG51bWJlcjtcbiAgcHJvdGVjdGVkIF9tdWx0aVNpZ25lcktleVBhaXJzOiBLZXlQYWlyW107XG4gIHByb3RlY3RlZCBfc2lnbmF0dXJlczogU2lnbmF0dXJlRGF0YVtdO1xuICBwcm90ZWN0ZWQgX25ldHdvcms6IFN0YWNrc05ldHdvcms7XG4gIHByb3RlY3RlZCBfZnJvbVB1YktleXM6IHN0cmluZ1tdO1xuXG4gIGNvbnN0cnVjdG9yKF9jb2luQ29uZmlnOiBSZWFkb25seTxDb2luQ29uZmlnPikge1xuICAgIHN1cGVyKF9jb2luQ29uZmlnKTtcbiAgICB0aGlzLl9hbmNob3JNb2RlID0gQU5DSE9SX01PREU7XG4gICAgdGhpcy5fbXVsdGlTaWduZXJLZXlQYWlycyA9IFtdO1xuICAgIHRoaXMuX2Zyb21QdWJLZXlzID0gW107XG4gICAgdGhpcy5fc2lnbmF0dXJlcyA9IFtdO1xuICAgIHRoaXMuX251bWJlclNpZ25hdHVyZXMgPSBERUZBVUxUX01VTFRJU0lHX1NJR19OVU1CRVI7XG4gICAgdGhpcy5fbmV0d29yayA9IF9jb2luQ29uZmlnLm5ldHdvcmsudHlwZSA9PT0gTmV0d29ya1R5cGUuTUFJTk5FVCA/IG5ldyBTdGFja3NNYWlubmV0KCkgOiBuZXcgU3RhY2tzVGVzdG5ldCgpO1xuICAgIHRoaXMuX3RyYW5zYWN0aW9uID0gbmV3IFRyYW5zYWN0aW9uKF9jb2luQ29uZmlnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIHRoZSB0cmFuc2FjdGlvbiBidWlsZGVyIGZpZWxkcyB1c2luZyB0aGUgZGVjb2RlZCB0cmFuc2FjdGlvbiBkYXRhXG4gICAqXG4gICAqIEBwYXJhbSB7VHJhbnNhY3Rpb259IHR4IHRoZSB0cmFuc2FjdGlvbiBkYXRhXG4gICAqL1xuICBpbml0QnVpbGRlcih0eDogVHJhbnNhY3Rpb24pOiB2b2lkIHtcbiAgICB0aGlzLnRyYW5zYWN0aW9uID0gdHg7XG4gICAgLy8gY2hlY2sgaWYgaXQgaXMgc2lnbmVkIG9yIHVuc2lnbmVkIHR4XG4gICAgaWYgKHR4LnN0eFRyYW5zYWN0aW9uLmF1dGguc3BlbmRpbmdDb25kaXRpb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKCdzcGVuZGluZyBjb25kaXRpb24gY2Fubm90IGJlIHVuZGVmaW5lZCcpO1xuICAgIH1cbiAgICBjb25zdCB0eERhdGEgPSB0eC50b0pzb24oKTtcbiAgICB0aGlzLmZlZSh7IGZlZTogdHhEYXRhLmZlZS50b1N0cmluZygpIH0pO1xuICAgIHRoaXMubm9uY2UodHhEYXRhLm5vbmNlKTtcbiAgICBsZXQgc2lnSGFzaCA9IHR4LnN0eFRyYW5zYWN0aW9uLnZlcmlmeUJlZ2luKCk7XG5cbiAgICBjb25zdCBhdXRoVHlwZSA9IHR4LnN0eFRyYW5zYWN0aW9uLmF1dGguYXV0aFR5cGUgPyB0eC5zdHhUcmFuc2FjdGlvbi5hdXRoLmF1dGhUeXBlIDogQXV0aFR5cGUuU3RhbmRhcmQ7XG4gICAgaWYgKGlzU2luZ2xlU2lnKHR4LnN0eFRyYW5zYWN0aW9uLmF1dGguc3BlbmRpbmdDb25kaXRpb24pKSB7XG4gICAgICB0aGlzLl9udW1iZXJTaWduYXR1cmVzID0gMTtcbiAgICAgIGlmICh0eC5zdHhUcmFuc2FjdGlvbi5hdXRoLnNwZW5kaW5nQ29uZGl0aW9uLnNpZ25hdHVyZS5kYXRhICE9PSBlbXB0eU1lc3NhZ2VTaWduYXR1cmUoKS5kYXRhKSB7XG4gICAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IHR4LnN0eFRyYW5zYWN0aW9uLmF1dGguc3BlbmRpbmdDb25kaXRpb24uc2lnbmF0dXJlO1xuICAgICAgICBzaWdIYXNoID0gbWFrZVNpZ0hhc2hQcmVTaWduKHNpZ0hhc2gsIGF1dGhUeXBlLCBuZXcgQmlnTnVtKHRoaXMuX2ZlZS5mZWUpLCBuZXcgQmlnTnVtKHRoaXMuX25vbmNlKSk7XG4gICAgICAgIHRoaXMuX3NpZ25hdHVyZXMucHVzaCh7IC4uLnNpZ25hdHVyZSwgaW5kZXg6IDAsIHNpZ0hhc2ggfSk7XG4gICAgICAgIHRoaXMuX2Zyb21QdWJLZXlzID0gW3B1YmxpY0tleUZyb21TaWduYXR1cmUoc2lnSGFzaCwgc2lnbmF0dXJlKV07XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX251bWJlclNpZ25hdHVyZXMgPSB0eC5zdHhUcmFuc2FjdGlvbi5hdXRoLnNwZW5kaW5nQ29uZGl0aW9uLnNpZ25hdHVyZXNSZXF1aXJlZDtcbiAgICAgIHR4LnN0eFRyYW5zYWN0aW9uLmF1dGguc3BlbmRpbmdDb25kaXRpb24uZmllbGRzLmZvckVhY2goKGZpZWxkLCBpbmRleCkgPT4ge1xuICAgICAgICBpZiAoZmllbGQuY29udGVudHMudHlwZSA9PT0gU3RhY2tzTWVzc2FnZVR5cGUuTWVzc2FnZVNpZ25hdHVyZSkge1xuICAgICAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IGZpZWxkLmNvbnRlbnRzO1xuICAgICAgICAgIGNvbnN0IG5leHRWZXJpZnkgPSBuZXh0VmVyaWZpY2F0aW9uKFxuICAgICAgICAgICAgc2lnSGFzaCxcbiAgICAgICAgICAgIGF1dGhUeXBlLFxuICAgICAgICAgICAgbmV3IEJpZ051bSh0aGlzLl9mZWUuZmVlKSxcbiAgICAgICAgICAgIG5ldyBCaWdOdW0odGhpcy5fbm9uY2UpLFxuICAgICAgICAgICAgUHViS2V5RW5jb2RpbmcuQ29tcHJlc3NlZCwgLy8gdXNlbGVzcyBwYXJhbSBhcyBDb21wcmVzc2VkIGlzIGhhcmRjb2RlZCBpbiBzdGFja3MgbGliXG4gICAgICAgICAgICBzaWduYXR1cmVcbiAgICAgICAgICApO1xuICAgICAgICAgIHNpZ0hhc2ggPSBuZXh0VmVyaWZ5Lm5leHRTaWdIYXNoO1xuICAgICAgICAgIHRoaXMuX3NpZ25hdHVyZXMucHVzaCh7IC4uLnNpZ25hdHVyZSwgaW5kZXgsIHNpZ0hhc2ggfSk7XG4gICAgICAgICAgdGhpcy5fZnJvbVB1YktleXMucHVzaChuZXh0VmVyaWZ5LnB1YktleS5kYXRhLnRvU3RyaW5nKCdoZXgnKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5fZnJvbVB1YktleXMucHVzaChmaWVsZC5jb250ZW50cy5kYXRhLnRvU3RyaW5nKCdoZXgnKSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICBwcm90ZWN0ZWQgZnJvbUltcGxlbWVudGF0aW9uKHJhd1RyYW5zYWN0aW9uOiBzdHJpbmcpOiBUcmFuc2FjdGlvbiB7XG4gICAgY29uc3QgdHggPSBuZXcgVHJhbnNhY3Rpb24odGhpcy5fY29pbkNvbmZpZyk7XG4gICAgdGhpcy52YWxpZGF0ZVJhd1RyYW5zYWN0aW9uKHJhd1RyYW5zYWN0aW9uKTtcbiAgICBjb25zdCBzdGFja3N0cmFuc2FjdGlvbiA9IGRlc2VyaWFsaXplVHJhbnNhY3Rpb24oXG4gICAgICBCdWZmZXJSZWFkZXIuZnJvbUJ1ZmZlcihCdWZmZXIuZnJvbShyZW1vdmVIZXhQcmVmaXgocmF3VHJhbnNhY3Rpb24pLCAnaGV4JykpXG4gICAgKTtcbiAgICB0eC5zdHhUcmFuc2FjdGlvbiA9IHN0YWNrc3RyYW5zYWN0aW9uO1xuICAgIHRoaXMuaW5pdEJ1aWxkZXIodHgpO1xuICAgIHJldHVybiB0aGlzLnRyYW5zYWN0aW9uO1xuICB9XG5cbiAgLy8gcmVnaW9uIEJhc2UgQnVpbGRlclxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIGJ1aWxkSW1wbGVtZW50YXRpb24oKTogUHJvbWlzZTxUcmFuc2FjdGlvbj4ge1xuICAgIGNvbnN0IGlzTXVsdGlTaWc6IGJvb2xlYW4gPSB0aGlzLl9mcm9tUHViS2V5cy5sZW5ndGggPiAxO1xuICAgIHRoaXMuX3RyYW5zYWN0aW9uLnN0eFRyYW5zYWN0aW9uLnNldEZlZShuZXcgQmlnTnVtKHRoaXMuX2ZlZS5mZWUpKTtcbiAgICB0aGlzLl90cmFuc2FjdGlvbi5zdHhUcmFuc2FjdGlvbi5zZXROb25jZShuZXcgQmlnTnVtKHRoaXMuX25vbmNlKSk7XG5cbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgdGhpcy5fZnJvbVB1YktleXMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICBjb25zdCBwdWJLZXkgPSB0aGlzLl9mcm9tUHViS2V5c1tpbmRleF07XG4gICAgICBjb25zdCBzaWduYXR1cmUgPSB0aGlzLmdldFNpZ25hdHVyZShwdWJLZXksIGluZGV4KTtcbiAgICAgIGlmIChzaWduYXR1cmUpIHtcbiAgICAgICAgYXdhaXQgdGhpcy50cmFuc2FjdGlvbi5zaWduV2l0aFNpZ25hdHVyZXMoc2lnbmF0dXJlLCBpc011bHRpU2lnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHBydktleSA9IHRoaXMuZ2V0UHJpdmF0ZUtleShwdWJLZXksIGluZGV4KTtcbiAgICAgICAgaWYgKHBydktleSkge1xuICAgICAgICAgIGF3YWl0IHRoaXMudHJhbnNhY3Rpb24uc2lnbihwcnZLZXkpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzTXVsdGlTaWcpIHtcbiAgICAgICAgICBhd2FpdCB0aGlzLnRyYW5zYWN0aW9uLmFwcGVuZE9yaWdpbihwdWJLZXkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5fdHJhbnNhY3Rpb24ubG9hZElucHV0c0FuZE91dHB1dHMoKTtcbiAgICByZXR1cm4gdGhpcy5fdHJhbnNhY3Rpb247XG4gIH1cblxuICBwcml2YXRlIGdldFNpZ25hdHVyZSA9IChfOiBzdHJpbmcsIGluZGV4OiBudW1iZXIpOiBTaWduYXR1cmVEYXRhIHwgdW5kZWZpbmVkID0+XG4gICAgdGhpcy5fc2lnbmF0dXJlcy5maW5kKChzKSA9PiBzLmluZGV4ID09PSBpbmRleCk7XG4gIHByaXZhdGUgZ2V0UHJpdmF0ZUtleSA9IChwdWJLZXk6IHN0cmluZywgXzogbnVtYmVyKTogS2V5UGFpciB8IHVuZGVmaW5lZCA9PlxuICAgIHRoaXMuX211bHRpU2lnbmVyS2V5UGFpcnMuZmluZCgoa3ApID0+IGtwLmdldEtleXModHJ1ZSkucHViID09PSBwdWJLZXkgfHwga3AuZ2V0S2V5cygpLnB1YiA9PT0gcHViS2V5KTtcblxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgcHJvdGVjdGVkIHNpZ25JbXBsZW1lbnRhdGlvbihrZXk6IEJhc2VLZXkpOiBUcmFuc2FjdGlvbiB7XG4gICAgdGhpcy5jaGVja0R1cGxpY2F0ZWRLZXlzKGtleSk7XG4gICAgbGV0IHBydiA9IGtleS5rZXk7XG4gICAgaWYgKHBydi5zdGFydHNXaXRoKCd4cHJ2JykpIHtcbiAgICAgIGNvbnN0IHJhd1BydiA9IHhwcnZUb1Jhd1BydihwcnYpO1xuICAgICAgcHJ2ID0gbmV3IEtleVBhaXIoeyBwcnY6IHJhd1BydiB9KS5nZXRLZXlzKHRydWUpLnBydjtcbiAgICB9XG4gICAgY29uc3Qgc2lnbmVyID0gbmV3IEtleVBhaXIoeyBwcnY6IHBydiB9KTtcblxuICAgIC8vIFNpZ25pbmcgdGhlIHRyYW5zYWN0aW9uIGlzIGFuIG9wZXJhdGlvbiB0aGF0IHJlbGllcyBvbiBhbGwgdGhlIGRhdGEgYmVpbmcgc2V0LFxuICAgIC8vIHNvIHdlIHNldCB0aGUgc291cmNlIGhlcmUgYW5kIGxlYXZlIHRoZSBhY3R1YWwgc2lnbmluZyBmb3IgdGhlIGJ1aWxkIHN0ZXBcbiAgICB0aGlzLl9tdWx0aVNpZ25lcktleVBhaXJzLnB1c2goc2lnbmVyKTtcbiAgICBjb25zdCBwdWJsaWNLZXkgPSBzaWduZXIuZ2V0S2V5cyhzaWduZXIuZ2V0Q29tcHJlc3NlZCgpKS5wdWI7XG4gICAgaWYgKCF0aGlzLl9mcm9tUHViS2V5cy5pbmNsdWRlcyhwdWJsaWNLZXkpKSB7XG4gICAgICB0aGlzLl9mcm9tUHViS2V5cy5wdXNoKHB1YmxpY0tleSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnRyYW5zYWN0aW9uO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0ZG9jICovXG4gIHByb3RlY3RlZCBnZXQgdHJhbnNhY3Rpb24oKTogVHJhbnNhY3Rpb24ge1xuICAgIHJldHVybiB0aGlzLl90cmFuc2FjdGlvbjtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICBwcm90ZWN0ZWQgc2V0IHRyYW5zYWN0aW9uKHRyYW5zYWN0aW9uOiBUcmFuc2FjdGlvbikge1xuICAgIHRoaXMuX3RyYW5zYWN0aW9uID0gdHJhbnNhY3Rpb247XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIHRoYXQgdGhlIGdpdmVuIGtleSBpcyBub3QgYWxyZWFkeSBpbiB0aGlzLl9tdWx0aVNpZ25lcktleVBhaXJzXG4gICAqXG4gICAqIEBwYXJhbSB7QmFzZUtleX0ga2V5IC0gVGhlIGtleSB0byBjaGVja1xuICAgKi9cbiAgcHJpdmF0ZSBjaGVja0R1cGxpY2F0ZWRLZXlzKGtleTogQmFzZUtleSkge1xuICAgIHRoaXMuX211bHRpU2lnbmVyS2V5UGFpcnMuZm9yRWFjaCgoX3NvdXJjZUtleVBhaXIpID0+IHtcbiAgICAgIGlmIChfc291cmNlS2V5UGFpci5nZXRLZXlzKCkucHJ2ID09PSBrZXkua2V5KSB7XG4gICAgICAgIHRocm93IG5ldyBTaWduaW5nRXJyb3IoJ1JlcGVhdGVkIHNpZ246ICcgKyBrZXkua2V5KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgdGhlIHRyYW5zYWN0aW9uIGZlZXNcbiAgICpcbiAgICogQHBhcmFtIHtCYXNlRmVlfSBmZWUgVGhlIG1heGltdW0gZ2FzIHRvIHBheVxuICAgKiBAcmV0dXJucyB7VHJhbnNhY3Rpb25CdWlsZGVyfSBUaGlzIHRyYW5zYWN0aW9uIGJ1aWxkZXJcbiAgICovXG4gIGZlZShmZWU6IEJhc2VGZWUpOiB0aGlzIHtcbiAgICB0aGlzLnZhbGlkYXRlVmFsdWUobmV3IEJpZ051bWJlcihmZWUuZmVlKSk7XG4gICAgdGhpcy5fZmVlID0gZmVlO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgbm9uY2UobjogbnVtYmVyKTogdGhpcyB7XG4gICAgdGhpcy5fbm9uY2UgPSBuO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgZnJvbVB1YktleShzZW5kZXJQdWJLZXk6IHN0cmluZyB8IHN0cmluZ1tdKTogdGhpcyB7XG4gICAgY29uc3QgcHViS2V5cyA9IHNlbmRlclB1YktleSBpbnN0YW5jZW9mIEFycmF5ID8gc2VuZGVyUHViS2V5IDogW3NlbmRlclB1YktleV07XG4gICAgdGhpcy5fZnJvbVB1YktleXMgPSBbXTtcbiAgICBwdWJLZXlzLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgaWYgKGlzVmFsaWRQdWJsaWNLZXkoa2V5KSkge1xuICAgICAgICB0aGlzLl9mcm9tUHViS2V5cy5wdXNoKGtleSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgSW52YWxpZFBhcmFtZXRlclZhbHVlRXJyb3IoJ0ludmFsaWQgcHVibGljIGtleScpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqICBTZXQgdGhlIG1lbW9cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IG1lbW9cbiAgICogQHJldHVybnMge1RyYW5zYWN0aW9uQnVpbGRlcn0gVGhpcyB0cmFuc2FjdGlvbiBidWlsZGVyXG4gICAqL1xuICBtZW1vKG1lbW86IHN0cmluZyk6IHRoaXMge1xuICAgIGlmICghaXNWYWxpZE1lbW8obWVtbykpIHtcbiAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoJ01lbW8gaXMgdG9vIGxvbmcnKTtcbiAgICB9XG4gICAgdGhpcy5fbWVtbyA9IG1lbW87XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogIFNldCB0aGUgbnVtYmVyIG9mIHNpZ25hdHVyZXMgZm9yIG11bHRpLXNpZ1xuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcn0gbnVtU2lnbnNcbiAgICogQHJldHVybnMge1RyYW5zYWN0aW9uQnVpbGRlcn0gVGhpcyB0cmFuc2FjdGlvbiBidWlsZGVyXG4gICAqL1xuICBudW1iZXJTaWduYXR1cmVzKG51bVNpZ25zOiBudW1iZXIpOiB0aGlzIHtcbiAgICB0aGlzLnZhbGlkYXRlVmFsdWUobmV3IEJpZ051bWJlcihudW1TaWducykpO1xuICAgIHRoaXMuX251bWJlclNpZ25hdHVyZXMgPSBudW1TaWducztcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIHJlZ2lvbiBWYWxpZGF0b3JzXG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICB2YWxpZGF0ZUFkZHJlc3MoYWRkcmVzczogQmFzZUFkZHJlc3MsIGFkZHJlc3NGb3JtYXQ/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAoIWlzVmFsaWRBZGRyZXNzKGFkZHJlc3MuYWRkcmVzcykpIHtcbiAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoJ0ludmFsaWQgYWRkcmVzcyAnICsgYWRkcmVzcy5hZGRyZXNzKTtcbiAgICB9XG4gIH1cblxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgdmFsaWRhdGVLZXkoa2V5OiBCYXNlS2V5KTogdm9pZCB7XG4gICAgY29uc3Qga2V5UGFpciA9IG5ldyBLZXlQYWlyKHsgcHJ2OiBrZXkua2V5IH0pO1xuICAgIGlmICgha2V5UGFpci5nZXRLZXlzKCkucHJ2KSB7XG4gICAgICB0aHJvdyBuZXcgQnVpbGRUcmFuc2FjdGlvbkVycm9yKCdJbnZhbGlkIGtleScpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICB2YWxpZGF0ZVJhd1RyYW5zYWN0aW9uKHJhd1RyYW5zYWN0aW9uOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAoIXJhd1RyYW5zYWN0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IoJ1JhdyB0cmFuc2FjdGlvbiBpcyBlbXB0eScpO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgZGVzZXJpYWxpemVUcmFuc2FjdGlvbihCdWZmZXJSZWFkZXIuZnJvbUJ1ZmZlcihCdWZmZXIuZnJvbShyZW1vdmVIZXhQcmVmaXgocmF3VHJhbnNhY3Rpb24pLCAnaGV4JykpKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2VUcmFuc2FjdGlvbkVycm9yKCdUaGVyZSB3YXMgYW4gZXJyb3IgcGFyc2luZyB0aGUgcmF3IHRyYW5zYWN0aW9uJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEBpbmhlcml0ZG9jICovXG4gIHZhbGlkYXRlVHJhbnNhY3Rpb24odHJhbnNhY3Rpb24/OiBUcmFuc2FjdGlvbik6IHZvaWQge1xuICAgIHRoaXMudmFsaWRhdGVGZWUoKTtcbiAgICB0aGlzLnZhbGlkYXRlTm9uY2UoKTtcbiAgfVxuXG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICB2YWxpZGF0ZVZhbHVlKHZhbHVlOiBCaWdOdW1iZXIpOiB2b2lkIHtcbiAgICBpZiAodmFsdWUuaXNMZXNzVGhhbigwKSkge1xuICAgICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignVmFsdWUgY2Fubm90IGJlIGxlc3MgdGhhbiB6ZXJvJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyB0aGF0IHRoZSBmZWUgZmllbGQgaXMgZGVmaW5lZFxuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZUZlZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fZmVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoJ0ludmFsaWQgdHJhbnNhY3Rpb246IG1pc3NpbmcgZmVlJyk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICB0aGlzLnZhbGlkYXRlVmFsdWUobmV3IEJpZ051bWJlcih0aGlzLl9mZWUuZmVlKSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhyb3cgbmV3IEJ1aWxkVHJhbnNhY3Rpb25FcnJvcignSW52YWxpZCBmZWUnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIHRoYXQgbm9uY2UgaXMgZGVmaW5lZFxuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZU5vbmNlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9ub25jZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgQnVpbGRUcmFuc2FjdGlvbkVycm9yKCdJbnZhbGlkIHRyYW5zYWN0aW9uOiBtaXNzaW5nIG5vbmNlJyk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICB0aGlzLnZhbGlkYXRlVmFsdWUobmV3IEJpZ051bWJlcih0aGlzLl9ub25jZSkpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRocm93IG5ldyBCdWlsZFRyYW5zYWN0aW9uRXJyb3IoYEludmFsaWQgbm9uY2UgJHt0aGlzLl9ub25jZX1gKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==Выполнить команду
Для локальной разработки. Не используйте в интернете!