PHP WebShell
Текущая директория: /usr/lib/node_modules/bitgo/node_modules/@bitgo/abstract-lightning/dist/src/lightning
Просмотр файла: lightningUtils.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;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.lightningNetworkName = exports.signerMacaroonPermissions = void 0;
exports.isLightningCoinName = isLightningCoinName;
exports.getLightningNetwork = getLightningNetwork;
exports.getLightningCoinName = getLightningCoinName;
exports.isValidLightningNetworkName = isValidLightningNetworkName;
exports.isValidLightningNetwork = isValidLightningNetwork;
exports.getStaticsLightningNetwork = getStaticsLightningNetwork;
exports.getUtxolibNetwork = getUtxolibNetwork;
exports.unwrapLightningCoinSpecific = unwrapLightningCoinSpecific;
exports.addIPCaveatToMacaroon = addIPCaveatToMacaroon;
exports.createWatchOnly = createWatchOnly;
exports.deriveLightningServiceSharedSecret = deriveLightningServiceSharedSecret;
exports.deriveMiddlewareSharedSecret = deriveMiddlewareSharedSecret;
exports.deriveTatSharedSecret = deriveTatSharedSecret;
exports.computeBip32DerivationIndexFromSeed = computeBip32DerivationIndexFromSeed;
const statics = __importStar(require("@bitgo/statics"));
const utxolib = __importStar(require("@bitgo/utxo-lib"));
const crypto_1 = require("crypto");
const macaroon_1 = require("macaroon");
const bs58check = __importStar(require("bs58check"));
const sdkcore = __importStar(require("@bitgo/sdk-core"));
// https://github.com/lightningnetwork/lnd/blob/master/docs/remote-signing.md#the-signer-node
exports.signerMacaroonPermissions = [
{
entity: 'message',
action: 'write',
},
{
entity: 'signer',
action: 'generate',
},
{
entity: 'address',
action: 'read',
},
{
entity: 'onchain',
action: 'write',
},
];
exports.lightningNetworkName = ['bitcoin', 'testnet'];
/**
* Checks if the coin name is a lightning coin name.
*/
function isLightningCoinName(coinName) {
return coinName === 'lnbtc' || coinName === 'tlnbtc';
}
/**
* Get the utxolib network for a lightning network.
*/
function getLightningNetwork(networkName) {
return utxolib.networks[networkName];
}
/**
* Get the lightning coin name for a utxolib network.
*/
function getLightningCoinName(network) {
return network === utxolib.networks.bitcoin ? 'lnbtc' : 'tlnbtc';
}
/**
* Checks if the network name is a valid lightning network name.
*/
function isValidLightningNetworkName(networkName) {
return exports.lightningNetworkName.includes(networkName);
}
/**
* Checks if the network is a valid lightning network.
*/
function isValidLightningNetwork(network) {
return utxolib.isValidNetwork(network) && isValidLightningNetworkName(utxolib.getNetworkName(network));
}
/**
* Returns the statics network data for a lightning coin.
*/
function getStaticsLightningNetwork(coinName) {
if (!isLightningCoinName(coinName)) {
throw new Error(`${coinName} is not a lightning coin`);
}
const coin = statics.coins.get(coinName);
if (!(coin instanceof statics.LightningCoin)) {
throw new Error('coin is not a lightning coin');
}
return coin.network;
}
/**
* Returns the utxolib network for a lightning coin.
*/
function getUtxolibNetwork(coinName) {
const networkName = getStaticsLightningNetwork(coinName).utxolibName;
if (!isValidLightningNetworkName(networkName)) {
throw new Error('invalid lightning network');
}
return getLightningNetwork(networkName);
}
/**
* Returns coin specific data for a lightning coin.
*/
function unwrapLightningCoinSpecific(obj, coinSpecificPath) {
if (coinSpecificPath !== 'lnbtc' && coinSpecificPath !== 'tlnbtc') {
throw new Error(`invalid coinSpecificPath ${coinSpecificPath} for lightning coin`);
}
if (coinSpecificPath === 'lnbtc' && 'lnbtc' in obj) {
return obj.lnbtc;
}
if (coinSpecificPath === 'tlnbtc' && 'tlnbtc' in obj) {
return obj.tlnbtc;
}
throw new Error('invalid lightning coin specific');
}
/**
* Adds an IP caveat to a macaroon and returns the modified macaroon as a Base64 string.
*/
function addIPCaveatToMacaroon(macaroonBase64, ip) {
const macaroon = (0, macaroon_1.importMacaroon)(macaroonBase64);
macaroon.addFirstPartyCaveat(`ipaddr ${ip}`);
return (0, macaroon_1.bytesToBase64)(macaroon.exportBinary());
}
const PURPOSE_WRAPPED_P2WKH = 49;
const PURPOSE_P2WKH = 84;
const PURPOSE_P2TR = 86;
const PURPOSE_ALL_OTHERS = 1017;
/**
* Converts an extended public key (xpub) to the appropriate prefix (ypub, vpub, etc.) based on its purpose and network.
*/
function convertXpubPrefix(xpub, purpose, isMainnet) {
if (purpose === PURPOSE_P2TR || purpose === PURPOSE_ALL_OTHERS) {
return xpub;
}
const data = bs58check.decode(xpub);
let versionBytes;
switch (purpose) {
case PURPOSE_WRAPPED_P2WKH:
versionBytes = isMainnet ? Buffer.from([0x04, 0x9d, 0x7c, 0xb2]) : Buffer.from([0x04, 0x4a, 0x52, 0x62]); // ypub/upub for p2sh-p2wpkh
break;
case PURPOSE_P2WKH:
versionBytes = isMainnet ? Buffer.from([0x04, 0xb2, 0x47, 0x46]) : Buffer.from([0x04, 0x5f, 0x1c, 0xf6]); // zpub/vpub for p2wpkh
break;
default:
throw new Error('Unsupported purpose');
}
versionBytes.copy(data, 0, 0, 4);
return bs58check.encode(data);
}
/**
* Derives watch-only accounts from the master HD node for the given purposes and network.
*/
function deriveWatchOnlyAccounts(masterHDNode, isMainnet) {
// https://github.com/lightningnetwork/lnd/blob/master/docs/remote-signing.md#required-accounts
if (masterHDNode.isNeutered()) {
throw new Error('masterHDNode must not be neutered');
}
const purposes = [PURPOSE_WRAPPED_P2WKH, PURPOSE_P2WKH, PURPOSE_P2TR, PURPOSE_ALL_OTHERS];
return purposes.flatMap((purpose) => {
const maxAccount = purpose === PURPOSE_ALL_OTHERS ? 255 : 0;
const coinType = purpose !== PURPOSE_ALL_OTHERS || isMainnet ? 0 : 1;
return Array.from({ length: maxAccount + 1 }, (_, account) => {
const path = `m/${purpose}'/${coinType}'/${account}'`;
const derivedNode = masterHDNode.derivePath(path);
// Ensure the node is neutered (i.e., converted to public key only)
const neuteredNode = derivedNode.neutered();
const xpub = convertXpubPrefix(neuteredNode.toBase58(), purpose, isMainnet);
return {
purpose,
coin_type: coinType,
account,
xpub,
};
});
});
}
/**
* Creates a watch-only wallet init data from the provided signer root key and network.
*/
function createWatchOnly(signerRootKey, network) {
const masterHDNode = utxolib.bip32.fromBase58(signerRootKey, network);
const getCurrentUnixTimestamp = () => {
return Math.floor(Date.now() / 1000);
};
const master_key_birthday_timestamp = getCurrentUnixTimestamp().toString();
const master_key_fingerprint = masterHDNode.fingerprint.toString('hex');
const accounts = deriveWatchOnlyAccounts(masterHDNode, utxolib.isMainnet(network));
return { master_key_birthday_timestamp, master_key_fingerprint, accounts };
}
/**
* Derives the shared Elliptic Curve Diffie-Hellman (ECDH) secret between the user's auth extended private key
* and the Lightning service's public key for secure communication.
*/
function deriveLightningServiceSharedSecret(coinName, userAuthXprv) {
const publicKey = Buffer.from(getStaticsLightningNetwork(coinName).lightningServicePubKey, 'hex');
const userAuthHdNode = utxolib.bip32.fromBase58(userAuthXprv);
return sdkcore.getSharedSecret(userAuthHdNode, publicKey);
}
/**
* Derives the shared secret for the middleware using a private key and the middleware's public key.
*/
function deriveMiddlewareSharedSecret(coinName, xprv) {
const publicKey = Buffer.from(getStaticsLightningNetwork(coinName).middlewarePubKey, 'hex');
const userAuthHdNode = utxolib.bip32.fromBase58(xprv);
return sdkcore.getSharedSecret(userAuthHdNode, publicKey);
}
/**
* Derives the shared secret for TAT service using ta private key and the TAT public key.
*/
function deriveTatSharedSecret(coinName, xprv) {
const publicKey = Buffer.from(getStaticsLightningNetwork(coinName).tatPubKey, 'hex');
const userAuthHdNode = utxolib.bip32.fromBase58(xprv);
return sdkcore.getSharedSecret(userAuthHdNode, publicKey);
}
/**
* Given a seed, compute a BIP32 derivation index.
* 0 <= index < 2147483648 (largest 31 bit number). This needs to be 2^31 - 1 so that the bip32 library
* can derive the hardened key.
* @param seed (optional) If nothing provided, we will generate one randomly
*/
function computeBip32DerivationIndexFromSeed(seed) {
return ((Buffer.from(utxolib.crypto.sha256(Buffer.from(seed ?? (0, crypto_1.randomBytes)(32).toString('hex'), 'utf8'))).readUint32BE(0) %
Math.pow(2, 31)) -
1);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlnaHRuaW5nVXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGlnaHRuaW5nL2xpZ2h0bmluZ1V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWtDQSxrREFFQztBQUtELGtEQUVDO0FBS0Qsb0RBRUM7QUFLRCxrRUFFQztBQUtELDBEQUVDO0FBS0QsZ0VBU0M7QUFLRCw4Q0FNQztBQUtELGtFQVdDO0FBS0Qsc0RBSUM7QUEyRUQsMENBU0M7QUFNRCxnRkFJQztBQUtELG9FQUlDO0FBS0Qsc0RBSUM7QUFRRCxrRkFNQztBQWhQRCx3REFBMEM7QUFDMUMseURBQTJDO0FBQzNDLG1DQUFxQztBQUNyQyx1Q0FBeUQ7QUFDekQscURBQXVDO0FBQ3ZDLHlEQUEyQztBQUczQyw2RkFBNkY7QUFDaEYsUUFBQSx5QkFBeUIsR0FBRztJQUN2QztRQUNFLE1BQU0sRUFBRSxTQUFTO1FBQ2pCLE1BQU0sRUFBRSxPQUFPO0tBQ2hCO0lBQ0Q7UUFDRSxNQUFNLEVBQUUsUUFBUTtRQUNoQixNQUFNLEVBQUUsVUFBVTtLQUNuQjtJQUNEO1FBQ0UsTUFBTSxFQUFFLFNBQVM7UUFDakIsTUFBTSxFQUFFLE1BQU07S0FDZjtJQUNEO1FBQ0UsTUFBTSxFQUFFLFNBQVM7UUFDakIsTUFBTSxFQUFFLE9BQU87S0FDaEI7Q0FDRixDQUFDO0FBRVcsUUFBQSxvQkFBb0IsR0FBRyxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQVUsQ0FBQztBQUdwRTs7R0FFRztBQUNILFNBQWdCLG1CQUFtQixDQUFDLFFBQWlCO0lBQ25ELE9BQU8sUUFBUSxLQUFLLE9BQU8sSUFBSSxRQUFRLEtBQUssUUFBUSxDQUFDO0FBQ3ZELENBQUM7QUFFRDs7R0FFRztBQUNILFNBQWdCLG1CQUFtQixDQUFDLFdBQWlDO0lBQ25FLE9BQU8sT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQztB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b3J0ICogYXMgdXR4b2xpYiBmcm9tICdAYml0Z28vdXR4by1saWInO1xuaW1wb3J0IHsgcmFuZG9tQnl0ZXMgfSBmcm9tICdjcnlwdG8nO1xuaW1wb3J0IHsgaW1wb3J0TWFjYXJvb24sIGJ5dGVzVG9CYXNlNjQgfSBmcm9tICdtYWNhcm9vbic7XG5pbXBvcnQgKiBhcyBiczU4Y2hlY2sgZnJvbSAnYnM1OGNoZWNrJztcbmltcG9ydCAqIGFzIHNka2NvcmUgZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcbmltcG9ydCB7IFdhdGNoT25seSwgV2F0Y2hPbmx5QWNjb3VudCB9IGZyb20gJy4uL2NvZGVjcyc7XG5cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9saWdodG5pbmduZXR3b3JrL2xuZC9ibG9iL21hc3Rlci9kb2NzL3JlbW90ZS1zaWduaW5nLm1kI3RoZS1zaWduZXItbm9kZVxuZXhwb3J0IGNvbnN0IHNpZ25lck1hY2Fyb29uUGVybWlzc2lvbnMgPSBbXG4gIHtcbiAgICBlbnRpdHk6ICdtZXNzYWdlJyxcbiAgICBhY3Rpb246ICd3cml0ZScsXG4gIH0sXG4gIHtcbiAgICBlbnRpdHk6ICdzaWduZXInLFxuICAgIGFjdGlvbjogJ2dlbmVyYXRlJyxcbiAgfSxcbiAge1xuICAgIGVudGl0eTogJ2FkZHJlc3MnLFxuICAgIGFjdGlvbjogJ3JlYWQnLFxuICB9LFxuICB7XG4gICAgZW50aXR5OiAnb25jaGFpbicsXG4gICAgYWN0aW9uOiAnd3JpdGUnLFxuICB9LFxuXTtcblxuZXhwb3J0IGNvbnN0IGxpZ2h0bmluZ05ldHdvcmtOYW1lID0gWydiaXRjb2luJywgJ3Rlc3RuZXQnXSBhcyBjb25zdDtcbmV4cG9ydCB0eXBlIExpZ2h0bmluZ05ldHdvcmtOYW1lID0gKHR5cGVvZiBsaWdodG5pbmdOZXR3b3JrTmFtZSlbbnVtYmVyXTtcblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGNvaW4gbmFtZSBpcyBhIGxpZ2h0bmluZyBjb2luIG5hbWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0xpZ2h0bmluZ0NvaW5OYW1lKGNvaW5OYW1lOiB1bmtub3duKTogY29pbk5hbWUgaXMgJ2xuYnRjJyB8ICd0bG5idGMnIHtcbiAgcmV0dXJuIGNvaW5OYW1lID09PSAnbG5idGMnIHx8IGNvaW5OYW1lID09PSAndGxuYnRjJztcbn1cblxuLyoqXG4gKiBHZXQgdGhlIHV0eG9saWIgbmV0d29yayBmb3IgYSBsaWdodG5pbmcgbmV0d29yay5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldExpZ2h0bmluZ05ldHdvcmsobmV0d29ya05hbWU6IExpZ2h0bmluZ05ldHdvcmtOYW1lKTogdXR4b2xpYi5OZXR3b3JrIHtcbiAgcmV0dXJuIHV0eG9saWIubmV0d29ya3NbbmV0d29ya05hbWVdO1xufVxuXG4vKipcbiAqIEdldCB0aGUgbGlnaHRuaW5nIGNvaW4gbmFtZSBmb3IgYSB1dHhvbGliIG5ldHdvcmsuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRMaWdodG5pbmdDb2luTmFtZShuZXR3b3JrOiB1dHhvbGliLk5ldHdvcmspOiBzdHJpbmcge1xuICByZXR1cm4gbmV0d29yayA9PT0gdXR4b2xpYi5uZXR3b3Jrcy5iaXRjb2luID8gJ2xuYnRjJyA6ICd0bG5idGMnO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgbmV0d29yayBuYW1lIGlzIGEgdmFsaWQgbGlnaHRuaW5nIG5ldHdvcmsgbmFtZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVmFsaWRMaWdodG5pbmdOZXR3b3JrTmFtZShuZXR3b3JrTmFtZTogdW5rbm93bik6IG5ldHdvcmtOYW1lIGlzIExpZ2h0bmluZ05ldHdvcmtOYW1lIHtcbiAgcmV0dXJuIGxpZ2h0bmluZ05ldHdvcmtOYW1lLmluY2x1ZGVzKG5ldHdvcmtOYW1lIGFzIExpZ2h0bmluZ05ldHdvcmtOYW1lKTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIG5ldHdvcmsgaXMgYSB2YWxpZCBsaWdodG5pbmcgbmV0d29yay5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVmFsaWRMaWdodG5pbmdOZXR3b3JrKG5ldHdvcms6IHVua25vd24pOiBuZXR3b3JrIGlzIHV0eG9saWIuTmV0d29yayB7XG4gIHJldHVybiB1dHhvbGliLmlzVmFsaWROZXR3b3JrKG5ldHdvcmspICYmIGlzVmFsaWRMaWdodG5pbmdOZXR3b3JrTmFtZSh1dHhvbGliLmdldE5ldHdvcmtOYW1lKG5ldHdvcmspKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBzdGF0aWNzIG5ldHdvcmsgZGF0YSBmb3IgYSBsaWdodG5pbmcgY29pbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFN0YXRpY3NMaWdodG5pbmdOZXR3b3JrKGNvaW5OYW1lOiBzdHJpbmcpOiBzdGF0aWNzLkxpZ2h0bmluZ05ldHdvcmsge1xuICBpZiAoIWlzTGlnaHRuaW5nQ29pbk5hbWUoY29pbk5hbWUpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGAke2NvaW5OYW1lfSBpcyBub3QgYSBsaWdodG5pbmcgY29pbmApO1xuICB9XG4gIGNvbnN0IGNvaW4gPSBzdGF0aWNzLmNvaW5zLmdldChjb2luTmFtZSk7XG4gIGlmICghKGNvaW4gaW5zdGFuY2VvZiBzdGF0aWNzLkxpZ2h0bmluZ0NvaW4pKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjb2luIGlzIG5vdCBhIGxpZ2h0bmluZyBjb2luJyk7XG4gIH1cbiAgcmV0dXJuIGNvaW4ubmV0d29yaztcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSB1dHhvbGliIG5ldHdvcmsgZm9yIGEgbGlnaHRuaW5nIGNvaW4uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRVdHhvbGliTmV0d29yayhjb2luTmFtZTogc3RyaW5nKTogdXR4b2xpYi5OZXR3b3JrIHtcbiAgY29uc3QgbmV0d29ya05hbWUgPSBnZXRTdGF0aWNzTGlnaHRuaW5nTmV0d29yayhjb2luTmFtZSkudXR4b2xpYk5hbWU7XG4gIGlmICghaXNWYWxpZExpZ2h0bmluZ05ldHdvcmtOYW1lKG5ldHdvcmtOYW1lKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBsaWdodG5pbmcgbmV0d29yaycpO1xuICB9XG4gIHJldHVybiBnZXRMaWdodG5pbmdOZXR3b3JrKG5ldHdvcmtOYW1lKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGNvaW4gc3BlY2lmaWMgZGF0YSBmb3IgYSBsaWdodG5pbmcgY29pbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVud3JhcExpZ2h0bmluZ0NvaW5TcGVjaWZpYzxWPihvYmo6IHsgbG5idGM6IFYgfSB8IHsgdGxuYnRjOiBWIH0sIGNvaW5TcGVjaWZpY1BhdGg6IHN0cmluZyk6IFYge1xuICBpZiAoY29pblNwZWNpZmljUGF0aCAhPT0gJ2xuYnRjJyAmJiBjb2luU3BlY2lmaWNQYXRoICE9PSAndGxuYnRjJykge1xuICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBjb2luU3BlY2lmaWNQYXRoICR7Y29pblNwZWNpZmljUGF0aH0gZm9yIGxpZ2h0bmluZyBjb2luYCk7XG4gIH1cbiAgaWYgKGNvaW5TcGVjaWZpY1BhdGggPT09ICdsbmJ0YycgJiYgJ2xuYnRjJyBpbiBvYmopIHtcbiAgICByZXR1cm4gb2JqLmxuYnRjO1xuICB9XG4gIGlmIChjb2luU3BlY2lmaWNQYXRoID09PSAndGxuYnRjJyAmJiAndGxuYnRjJyBpbiBvYmopIHtcbiAgICByZXR1cm4gb2JqLnRsbmJ0YztcbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgbGlnaHRuaW5nIGNvaW4gc3BlY2lmaWMnKTtcbn1cblxuLyoqXG4gKiBBZGRzIGFuIElQIGNhdmVhdCB0byBhIG1hY2Fyb29uIGFuZCByZXR1cm5zIHRoZSBtb2RpZmllZCBtYWNhcm9vbiBhcyBhIEJhc2U2NCBzdHJpbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGRJUENhdmVhdFRvTWFjYXJvb24obWFjYXJvb25CYXNlNjQ6IHN0cmluZywgaXA6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IG1hY2Fyb29uID0gaW1wb3J0TWFjYXJvb24obWFjYXJvb25CYXNlNjQpO1xuICBtYWNhcm9vbi5hZGRGaXJzdFBhcnR5Q2F2ZWF0KGBpcGFkZHIgJHtpcH1gKTtcbiAgcmV0dXJuIGJ5dGVzVG9CYXNlNjQobWFjYXJvb24uZXhwb3J0QmluYXJ5KCkpO1xufVxuXG5jb25zdCBQVVJQT1NFX1dSQVBQRURfUDJXS0ggPSA0OTtcbmNvbnN0IFBVUlBPU0VfUDJXS0ggPSA4NDtcbmNvbnN0IFBVUlBPU0VfUDJUUiA9IDg2O1xuY29uc3QgUFVSUE9TRV9BTExfT1RIRVJTID0gMTAxNztcblxudHlwZSBFeHRlbmRlZEtleVB1cnBvc2UgPVxuICB8IHR5cGVvZiBQVVJQT1NFX1dSQVBQRURfUDJXS0hcbiAgfCB0eXBlb2YgUFVSUE9TRV9QMldLSFxuICB8IHR5cGVvZiBQVVJQT1NFX1AyVFJcbiAgfCB0eXBlb2YgUFVSUE9TRV9BTExfT1RIRVJTO1xuXG4vKipcbiAqIENvbnZlcnRzIGFuIGV4dGVuZGVkIHB1YmxpYyBrZXkgKHhwdWIpIHRvIHRoZSBhcHByb3ByaWF0ZSBwcmVmaXggKHlwdWIsIHZwdWIsIGV0Yy4pIGJhc2VkIG9uIGl0cyBwdXJwb3NlIGFuZCBuZXR3b3JrLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0WHB1YlByZWZpeCh4cHViOiBzdHJpbmcsIHB1cnBvc2U6IEV4dGVuZGVkS2V5UHVycG9zZSwgaXNNYWlubmV0OiBib29sZWFuKTogc3RyaW5nIHtcbiAgaWYgKHB1cnBvc2UgPT09IFBVUlBPU0VfUDJUUiB8fCBwdXJwb3NlID09PSBQVVJQT1NFX0FMTF9PVEhFUlMpIHtcbiAgICByZXR1cm4geHB1YjtcbiAgfVxuICBjb25zdCBkYXRhID0gYnM1OGNoZWNrLmRlY29kZSh4cHViKTtcblxuICBsZXQgdmVyc2lvbkJ5dGVzOiBCdWZmZXI7XG5cbiAgc3dpdGNoIChwdXJwb3NlKSB7XG4gICAgY2FzZSBQVVJQT1NFX1dSQVBQRURfUDJXS0g6XG4gICAgICB2ZXJzaW9uQnl0ZXMgPSBpc01haW5uZXQgPyBCdWZmZXIuZnJvbShbMHgwNCwgMHg5ZCwgMHg3YywgMHhiMl0pIDogQnVmZmVyLmZyb20oWzB4MDQsIDB4NGEsIDB4NTIsIDB4NjJdKTsgLy8geXB1Yi91cHViIGZvciBwMnNoLXAyd3BraFxuICAgICAgYnJlYWs7XG4gICAgY2FzZSBQVVJQT1NFX1AyV0tIOlxuICAgICAgdmVyc2lvbkJ5dGVzID0gaXNNYWlubmV0ID8gQnVmZmVyLmZyb20oWzB4MDQsIDB4YjIsIDB4NDcsIDB4NDZdKSA6IEJ1ZmZlci5mcm9tKFsweDA0LCAweDVmLCAweDFjLCAweGY2XSk7IC8vIHpwdWIvdnB1YiBmb3IgcDJ3cGtoXG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBwdXJwb3NlJyk7XG4gIH1cblxuICB2ZXJzaW9uQnl0ZXMuY29weShkYXRhLCAwLCAwLCA0KTtcbiAgcmV0dXJuIGJzNThjaGVjay5lbmNvZGUoZGF0YSk7XG59XG5cbi8qKlxuICogRGVyaXZlcyB3YXRjaC1vbmx5IGFjY291bnRzIGZyb20gdGhlIG1hc3RlciBIRCBub2RlIGZvciB0aGUgZ2l2ZW4gcHVycG9zZXMgYW5kIG5ldHdvcmsuXG4gKi9cbmZ1bmN0aW9uIGRlcml2ZVdhdGNoT25seUFjY291bnRzKG1hc3RlckhETm9kZTogdXR4b2xpYi5CSVAzMkludGVyZmFjZSwgaXNNYWlubmV0OiBib29sZWFuKTogV2F0Y2hPbmx5QWNjb3VudFtdIHtcbiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2xpZ2h0bmluZ25ldHdvcmsvbG5kL2Jsb2IvbWFzdGVyL2RvY3MvcmVtb3RlLXNpZ25pbmcubWQjcmVxdWlyZWQtYWNjb3VudHNcbiAgaWYgKG1hc3RlckhETm9kZS5pc05ldXRlcmVkKCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ21hc3RlckhETm9kZSBtdXN0IG5vdCBiZSBuZXV0ZXJlZCcpO1xuICB9XG5cbiAgY29uc3QgcHVycG9zZXMgPSBbUFVSUE9TRV9XUkFQUEVEX1AyV0tILCBQVVJQT1NFX1AyV0tILCBQVVJQT1NFX1AyVFIsIFBVUlBPU0VfQUxMX09USEVSU10gYXMgY29uc3Q7XG5cbiAgcmV0dXJuIHB1cnBvc2VzLmZsYXRNYXAoKHB1cnBvc2UpID0+IHtcbiAgICBjb25zdCBtYXhBY2NvdW50ID0gcHVycG9zZSA9PT0gUFVSUE9TRV9BTExfT1RIRVJTID8gMjU1IDogMDtcbiAgICBjb25zdCBjb2luVHlwZSA9IHB1cnBvc2UgIT09IFBVUlBPU0VfQUxMX09USEVSUyB8fCBpc01haW5uZXQgPyAwIDogMTtcblxuICAgIHJldHVybiBBcnJheS5mcm9tKHsgbGVuZ3RoOiBtYXhBY2NvdW50ICsgMSB9LCAoXywgYWNjb3VudCkgPT4ge1xuICAgICAgY29uc3QgcGF0aCA9IGBtLyR7cHVycG9zZX0nLyR7Y29pblR5cGV9Jy8ke2FjY291bnR9J2A7XG4gICAgICBjb25zdCBkZXJpdmVkTm9kZSA9IG1hc3RlckhETm9kZS5kZXJpdmVQYXRoKHBhdGgpO1xuXG4gICAgICAvLyBFbnN1cmUgdGhlIG5vZGUgaXMgbmV1dGVyZWQgKGkuZS4sIGNvbnZlcnRlZCB0byBwdWJsaWMga2V5IG9ubHkpXG4gICAgICBjb25zdCBuZXV0ZXJlZE5vZGUgPSBkZXJpdmVkTm9kZS5uZXV0ZXJlZCgpO1xuICAgICAgY29uc3QgeHB1YiA9IGNvbnZlcnRYcHViUHJlZml4KG5ldXRlcmVkTm9kZS50b0Jhc2U1OCgpLCBwdXJwb3NlLCBpc01haW5uZXQpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBwdXJwb3NlLFxuICAgICAgICBjb2luX3R5cGU6IGNvaW5UeXBlLFxuICAgICAgICBhY2NvdW50LFxuICAgICAgICB4cHViLFxuICAgICAgfTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIHdhdGNoLW9ubHkgd2FsbGV0IGluaXQgZGF0YSBmcm9tIHRoZSBwcm92aWRlZCBzaWduZXIgcm9vdCBrZXkgYW5kIG5ldHdvcmsuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVXYXRjaE9ubHkoc2lnbmVyUm9vdEtleTogc3RyaW5nLCBuZXR3b3JrOiB1dHhvbGliLk5ldHdvcmspOiBXYXRjaE9ubHkge1xuICBjb25zdCBtYXN0ZXJIRE5vZGUgPSB1dHhvbGliLmJpcDMyLmZyb21CYXNlNTgoc2lnbmVyUm9vdEtleSwgbmV0d29yayk7XG4gIGNvbnN0IGdldEN1cnJlbnRVbml4VGltZXN0YW1wID0gKCkgPT4ge1xuICAgIHJldHVybiBNYXRoLmZsb29yKERhdGUubm93KCkgLyAxMDAwKTtcbiAgfTtcbiAgY29uc3QgbWFzdGVyX2tleV9iaXJ0aGRheV90aW1lc3RhbXAgPSBnZXRDdXJyZW50VW5peFRpbWVzdGFtcCgpLnRvU3RyaW5nKCk7XG4gIGNvbnN0IG1hc3Rlcl9rZXlfZmluZ2VycHJpbnQgPSBtYXN0ZXJIRE5vZGUuZmluZ2VycHJpbnQudG9TdHJpbmcoJ2hleCcpO1xuICBjb25zdCBhY2NvdW50cyA9IGRlcml2ZVdhdGNoT25seUFjY291bnRzKG1hc3RlckhETm9kZSwgdXR4b2xpYi5pc01haW5uZXQobmV0d29yaykpO1xuICByZXR1cm4geyBtYXN0ZXJfa2V5X2JpcnRoZGF5X3RpbWVzdGFtcCwgbWFzdGVyX2tleV9maW5nZXJwcmludCwgYWNjb3VudHMgfTtcbn1cblxuLyoqXG4gKiBEZXJpdmVzIHRoZSBzaGFyZWQgRWxsaXB0aWMgQ3VydmUgRGlmZmllLUhlbGxtYW4gKEVDREgpIHNlY3JldCBiZXR3ZWVuIHRoZSB1c2VyJ3MgYXV0aCBleHRlbmRlZCBwcml2YXRlIGtleVxuICogYW5kIHRoZSBMaWdodG5pbmcgc2VydmljZSdzIHB1YmxpYyBrZXkgZm9yIHNlY3VyZSBjb21tdW5pY2F0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVyaXZlTGlnaHRuaW5nU2VydmljZVNoYXJlZFNlY3JldChjb2luTmFtZTogJ2xuYnRjJyB8ICd0bG5idGMnLCB1c2VyQXV0aFhwcnY6IHN0cmluZyk6IEJ1ZmZlciB7XG4gIGNvbnN0IHB1YmxpY0tleSA9IEJ1ZmZlci5mcm9tKGdldFN0YXRpY3NMaWdodG5pbmdOZXR3b3JrKGNvaW5OYW1lKS5saWdodG5pbmdTZXJ2aWNlUHViS2V5LCAnaGV4Jyk7XG4gIGNvbnN0IHVzZXJBdXRoSGROb2RlID0gdXR4b2xpYi5iaXAzMi5mcm9tQmFzZTU4KHVzZXJBdXRoWHBydik7XG4gIHJldHVybiBzZGtjb3JlLmdldFNoYXJlZFNlY3JldCh1c2VyQXV0aEhkTm9kZSwgcHVibGljS2V5KTtcbn1cblxuLyoqXG4gKiBEZXJpdmVzIHRoZSBzaGFyZWQgc2VjcmV0IGZvciB0aGUgbWlkZGxld2FyZSB1c2luZyBhIHByaXZhdGUga2V5IGFuZCB0aGUgbWlkZGxld2FyZSdzIHB1YmxpYyBrZXkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZXJpdmVNaWRkbGV3YXJlU2hhcmVkU2VjcmV0KGNvaW5OYW1lOiAnbG5idGMnIHwgJ3RsbmJ0YycsIHhwcnY6IHN0cmluZyk6IEJ1ZmZlciB7XG4gIGNvbnN0IHB1YmxpY0tleSA9IEJ1ZmZlci5mcm9tKGdldFN0YXRpY3NMaWdodG5pbmdOZXR3b3JrKGNvaW5OYW1lKS5taWRkbGV3YXJlUHViS2V5LCAnaGV4Jyk7XG4gIGNvbnN0IHVzZXJBdXRoSGROb2RlID0gdXR4b2xpYi5iaXAzMi5mcm9tQmFzZTU4KHhwcnYpO1xuICByZXR1cm4gc2RrY29yZS5nZXRTaGFyZWRTZWNyZXQodXNlckF1dGhIZE5vZGUsIHB1YmxpY0tleSk7XG59XG5cbi8qKlxuICogRGVyaXZlcyB0aGUgc2hhcmVkIHNlY3JldCBmb3IgVEFUIHNlcnZpY2UgdXNpbmcgdGEgcHJpdmF0ZSBrZXkgYW5kIHRoZSBUQVQgcHVibGljIGtleS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlcml2ZVRhdFNoYXJlZFNlY3JldChjb2luTmFtZTogJ2xuYnRjJyB8ICd0bG5idGMnLCB4cHJ2OiBzdHJpbmcpOiBCdWZmZXIge1xuICBjb25zdCBwdWJsaWNLZXkgPSBCdWZmZXIuZnJvbShnZXRTdGF0aWNzTGlnaHRuaW5nTmV0d29yayhjb2luTmFtZSkudGF0UHViS2V5LCAnaGV4Jyk7XG4gIGNvbnN0IHVzZXJBdXRoSGROb2RlID0gdXR4b2xpYi5iaXAzMi5mcm9tQmFzZTU4KHhwcnYpO1xuICByZXR1cm4gc2RrY29yZS5nZXRTaGFyZWRTZWNyZXQodXNlckF1dGhIZE5vZGUsIHB1YmxpY0tleSk7XG59XG5cbi8qKlxuICogR2l2ZW4gYSBzZWVkLCBjb21wdXRlIGEgQklQMzIgZGVyaXZhdGlvbiBpbmRleC5cbiAqIDAgPD0gaW5kZXggPCAyMTQ3NDgzNjQ4IChsYXJnZXN0IDMxIGJpdCBudW1iZXIpLiBUaGlzIG5lZWRzIHRvIGJlIDJeMzEgLSAxIHNvIHRoYXQgdGhlIGJpcDMyIGxpYnJhcnlcbiAqIGNhbiBkZXJpdmUgdGhlIGhhcmRlbmVkIGtleS5cbiAqIEBwYXJhbSBzZWVkIChvcHRpb25hbCkgSWYgbm90aGluZyBwcm92aWRlZCwgd2Ugd2lsbCBnZW5lcmF0ZSBvbmUgcmFuZG9tbHlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbXB1dGVCaXAzMkRlcml2YXRpb25JbmRleEZyb21TZWVkKHNlZWQ/OiBzdHJpbmcpOiBudW1iZXIge1xuICByZXR1cm4gKFxuICAgIChCdWZmZXIuZnJvbSh1dHhvbGliLmNyeXB0by5zaGEyNTYoQnVmZmVyLmZyb20oc2VlZCA/PyByYW5kb21CeXRlcygzMikudG9TdHJpbmcoJ2hleCcpLCAndXRmOCcpKSkucmVhZFVpbnQzMkJFKDApICVcbiAgICAgIE1hdGgucG93KDIsIDMxKSkgLVxuICAgIDFcbiAgKTtcbn1cbiJdfQ==Выполнить команду
Для локальной разработки. Не используйте в интернете!