@bitgo/utxo-ord
Version:
Utilities for building ordinals with BitGo utxo-lib
94 lines (92 loc) • 14.7 kB
JavaScript
;
/*
Functions for dealing with inscriptions.
Wrapper around @bitgo/wasm-utxo inscription functions for utxo-ord consumers.
See https://docs.ordinals.com/inscriptions.html
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.createOutputScriptForInscription = createOutputScriptForInscription;
exports.createInscriptionRevealData = createInscriptionRevealData;
exports.signRevealTransaction = signRevealTransaction;
const wasm_utxo_1 = require("@bitgo/wasm-utxo");
// default "postage" amount
// https://github.com/ordinals/ord/blob/0.24.2/src/lib.rs#L149
const DEFAULT_POSTAGE_SATS = BigInt(10000);
function isBIP32Like(key) {
return typeof key === 'object' && key !== null && 'publicKey' in key && !ArrayBuffer.isView(key);
}
/**
* Extract compressed public key from key input.
* Handles BIP32-like objects and raw pubkey bytes (32 or 33 bytes).
*/
function getCompressedPublicKey(key) {
const pubkey = isBIP32Like(key) ? key.publicKey : key;
if (pubkey.length === 33) {
return pubkey;
}
if (pubkey.length === 32) {
// x-only pubkey - prepend 0x02 parity byte to make compressed
const compressedPubkey = new Uint8Array(33);
compressedPubkey[0] = 0x02;
compressedPubkey.set(pubkey, 1);
return compressedPubkey;
}
throw new Error(`Invalid public key length: ${pubkey.length}. Expected 32 or 33 bytes.`);
}
/**
* Create the P2TR output script for an inscription.
*
* @param key - BIP32 key or public key bytes (32-byte x-only or 33-byte compressed)
* @param contentType - MIME type of the inscription (e.g., "text/plain", "image/png")
* @param inscriptionData - The inscription data bytes
* @returns The P2TR output script for the inscription commit address
*/
function createOutputScriptForInscription(key, contentType, inscriptionData) {
const compressedPubkey = getCompressedPublicKey(key);
const ecpair = wasm_utxo_1.ECPair.fromPublicKey(compressedPubkey);
const result = wasm_utxo_1.inscriptions.createInscriptionRevealData(ecpair, contentType, inscriptionData);
return result.outputScript;
}
/**
* Create inscription reveal data including the commit address and tap leaf script.
*
* @param key - BIP32 key or public key bytes (32-byte x-only or 33-byte compressed)
* @param contentType - MIME type of the inscription (e.g., "text/plain", "image/png")
* @param inscriptionData - The inscription data bytes
* @param coinName - Coin name (e.g., "btc", "tbtc")
* @returns PreparedInscriptionRevealData with address, vsize estimate, and tap leaf script
*/
function createInscriptionRevealData(key, contentType, inscriptionData, coinName) {
const compressedPubkey = getCompressedPublicKey(key);
const ecpair = wasm_utxo_1.ECPair.fromPublicKey(compressedPubkey);
const wasmResult = wasm_utxo_1.inscriptions.createInscriptionRevealData(ecpair, contentType, inscriptionData);
// Convert outputScript to address for the given network
const address = wasm_utxo_1.address.fromOutputScriptWithCoin(wasmResult.outputScript, coinName);
return {
address,
revealTransactionVSize: wasmResult.revealTransactionVSize,
tapLeafScript: wasmResult.tapLeafScript,
};
}
/**
* Sign a reveal transaction.
*
* Creates and signs the reveal transaction that spends from the commit output
* and sends the inscription to the recipient.
*
* @param privateKey - 32-byte private key
* @param tapLeafScript - The tap leaf script from createInscriptionRevealData
* @param commitAddress - The commit address
* @param recipientAddress - Where to send the inscription
* @param unsignedCommitTx - The unsigned commit transaction bytes
* @param coinName - Coin name (e.g., "btc", "tbtc")
* @returns The signed PSBT as bytes
*/
function signRevealTransaction(privateKey, tapLeafScript, commitAddress, recipientAddress, unsignedCommitTx, coinName) {
const ecpair = wasm_utxo_1.ECPair.fromPrivateKey(privateKey);
const commitTx = wasm_utxo_1.Transaction.fromBytes(unsignedCommitTx);
const commitOutputScript = wasm_utxo_1.address.toOutputScriptWithCoin(commitAddress, coinName);
const recipientOutputScript = wasm_utxo_1.address.toOutputScriptWithCoin(recipientAddress, coinName);
return wasm_utxo_1.inscriptions.signRevealTransaction(ecpair, tapLeafScript, commitTx, commitOutputScript, recipientOutputScript, DEFAULT_POSTAGE_SATS);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5zY3JpcHRpb25zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2luc2NyaXB0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7OztFQU1FOztBQXlFRiw0RUFTQztBQVdELGtFQW1CQztBQWdCRCxzREFxQkM7QUFuSkQsZ0RBTzBCO0FBSTFCLDJCQUEyQjtBQUMzQiw4REFBOEQ7QUFDOUQsTUFBTSxvQkFBb0IsR0FBRyxNQUFNLENBQUMsS0FBTSxDQUFDLENBQUM7QUEwQjVDLFNBQVMsV0FBVyxDQUFDLEdBQWE7SUFDaEMsT0FBTyxPQUFPLEdBQUcsS0FBSyxRQUFRLElBQUksR0FBRyxLQUFLLElBQUksSUFBSSxXQUFXLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNuRyxDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBUyxzQkFBc0IsQ0FBQyxHQUFhO0lBQzNDLE1BQU0sTUFBTSxHQUFHLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO0lBRXRELElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxFQUFFLEVBQUUsQ0FBQztRQUN6QixPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBQ0QsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLEVBQUUsRUFBRSxDQUFDO1FBQ3pCLDhEQUE4RDtRQUM5RCxNQUFNLGdCQUFnQixHQUFHLElBQUksVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzVDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQztRQUMzQixnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2hDLE9BQU8sZ0JBQWdCLENBQUM7SUFDMUIsQ0FBQztJQUNELE1BQU0sSUFBSSxLQUFLLENBQUMsOEJBQThCLE1BQU0sQ0FBQyxNQUFNLDRCQUE0QixDQUFDLENBQUM7QUFDM0YsQ0FBQztBQUVEOzs7Ozs7O0dBT0c7QUFDSCxTQUFnQixnQ0FBZ0MsQ0FDOUMsR0FBYSxFQUNiLFdBQW1CLEVBQ25CLGVBQTJCO0lBRTNCLE1BQU0sZ0JBQWdCLEdBQUcsc0JBQXNCLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDckQsTUFBTSxNQUFNLEdBQUcsa0JBQU0sQ0FBQyxhQUFhLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUN0RCxNQUFNLE1BQU0sR0FBRyx3QkFBZ0IsQ0FBQywyQkFBMkIsQ0FBQyxNQUFNLEVBQUUsV0FBVyxFQUFFLGVBQWUsQ0FBQyxDQUFDO0lBQ2xHLE9BQU8sTUFBTSxDQUFDLFlBQVksQ0FBQztBQUM3QixDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxTQUFnQiwyQkFBMkIsQ0FDekMsR0FBYSxFQUNiLFdBQW1CLEVBQ25CLGVBQTJCLEVBQzNCLFFBQWtCO0lBRWxCLE1BQU0sZ0JBQWdCLEdBQUcsc0JBQXNCLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDckQsTUFBTSxNQUFNLEdBQUcsa0JBQU0sQ0FBQyxhQUFhLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUV0RCxNQUFNLFVBQVUsR0FBRyx3QkFBZ0IsQ0FBQywyQkFBMkIsQ0FBQyxNQUFNLEVBQUUsV0FBVyxFQUFFLGVBQWUsQ0FBQyxDQUFDO0lBRXRHLHdEQUF3RDtJQUN4RCxNQUFNLE9BQU8sR0FBRyxtQkFBVyxDQUFDLHdCQUF3QixDQUFDLFVBQVUsQ0FBQyxZQUFZLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFFeEYsT0FBTztRQUNMLE9BQU87UUFDUCxzQkFBc0IsRUFBRSxVQUFVLENBQUMsc0JBQXNCO1FBQ3pELGFBQWEsRUFBRSxVQUFVLENBQUMsYUFBYTtLQUN4QyxDQUFDO0FBQ0osQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7O0dBYUc7QUFDSCxTQUFnQixxQkFBcUIsQ0FDbkMsVUFBc0IsRUFDdEIsYUFBNEIsRUFDNUIsYUFBcUIsRUFDckIsZ0JBQXdCLEVBQ3hCLGdCQUE0QixFQUM1QixRQUFrQjtJQUVsQixNQUFNLE1BQU0sR0FBRyxrQkFBTSxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNqRCxNQUFNLFFBQVEsR0FBRyx1QkFBVyxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQ3pELE1BQU0sa0JBQWtCLEdBQUcsbUJBQVcsQ0FBQyxzQkFBc0IsQ0FBQyxhQUFhLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDdkYsTUFBTSxxQkFBcUIsR0FBRyxtQkFBVyxDQUFDLHNCQUFzQixDQUFDLGdCQUFnQixFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBRTdGLE9BQU8sd0JBQWdCLENBQUMscUJBQXFCLENBQzNDLE1BQU0sRUFDTixhQUFhLEVBQ2IsUUFBUSxFQUNSLGtCQUFrQixFQUNsQixxQkFBcUIsRUFDckIsb0JBQW9CLENBQ3JCLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbkZ1bmN0aW9ucyBmb3IgZGVhbGluZyB3aXRoIGluc2NyaXB0aW9ucy5cblxuV3JhcHBlciBhcm91bmQgQGJpdGdvL3dhc20tdXR4byBpbnNjcmlwdGlvbiBmdW5jdGlvbnMgZm9yIHV0eG8tb3JkIGNvbnN1bWVycy5cblxuU2VlIGh0dHBzOi8vZG9jcy5vcmRpbmFscy5jb20vaW5zY3JpcHRpb25zLmh0bWxcbiovXG5cbmltcG9ydCB7XG4gIGluc2NyaXB0aW9ucyBhcyB3YXNtSW5zY3JpcHRpb25zLFxuICBhZGRyZXNzIGFzIHdhc21BZGRyZXNzLFxuICBUcmFuc2FjdGlvbixcbiAgRUNQYWlyLFxuICB0eXBlIFRhcExlYWZTY3JpcHQsXG4gIHR5cGUgQ29pbk5hbWUsXG59IGZyb20gJ0BiaXRnby93YXNtLXV0eG8nO1xuXG5leHBvcnQgdHlwZSB7IFRhcExlYWZTY3JpcHQgfTtcblxuLy8gZGVmYXVsdCBcInBvc3RhZ2VcIiBhbW91bnRcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9vcmRpbmFscy9vcmQvYmxvYi8wLjI0LjIvc3JjL2xpYi5ycyNMMTQ5XG5jb25zdCBERUZBVUxUX1BPU1RBR0VfU0FUUyA9IEJpZ0ludCgxMF8wMDApO1xuXG4vKipcbiAqIFByZXBhcmVkIGRhdGEgZm9yIGFuIGluc2NyaXB0aW9uIHJldmVhbCB0cmFuc2FjdGlvbi5cbiAqIENvbXBhdGlibGUgd2l0aCBzZGstY29yZSdzIFByZXBhcmVkSW5zY3JpcHRpb25SZXZlYWxEYXRhLlxuICovXG5leHBvcnQgdHlwZSBQcmVwYXJlZEluc2NyaXB0aW9uUmV2ZWFsRGF0YSA9IHtcbiAgLyoqIFRoZSBjb21taXQgYWRkcmVzcyAoZGVyaXZlZCBmcm9tIG91dHB1dFNjcmlwdCBmb3IgdGhlIGdpdmVuIG5ldHdvcmspICovXG4gIGFkZHJlc3M6IHN0cmluZztcbiAgLyoqIEVzdGltYXRlZCB2aXJ0dWFsIHNpemUgb2YgdGhlIHJldmVhbCB0cmFuc2FjdGlvbiAqL1xuICByZXZlYWxUcmFuc2FjdGlvblZTaXplOiBudW1iZXI7XG4gIC8qKiBUYXAgbGVhZiBzY3JpcHQgZm9yIHNwZW5kaW5nIHRoZSBjb21taXQgb3V0cHV0ICovXG4gIHRhcExlYWZTY3JpcHQ6IFRhcExlYWZTY3JpcHQ7XG59O1xuXG4vKipcbiAqIEJJUDMyLWxpa2UgaW50ZXJmYWNlIGNvbXBhdGlibGUgd2l0aCBib3RoIHV0eG8tbGliIGFuZCB3YXNtLXV0eG8gQklQMzIgdHlwZXMuXG4gKiBUaGUgcHVibGljS2V5IGNhbiBiZSBCdWZmZXIgKHV0eG8tbGliKSBvciBVaW50OEFycmF5ICh3YXNtLXV0eG8pLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEJJUDMyTGlrZSB7XG4gIHB1YmxpY0tleTogVWludDhBcnJheTtcbn1cblxuLyoqIElucHV0IHR5cGUgZm9yIGluc2NyaXB0aW9uIGZ1bmN0aW9ucyAtIGVpdGhlciBhIEJJUDMyLWxpa2Uga2V5IG9yIHJhdyBwdWJsaWMga2V5IGJ5dGVzICovXG5leHBvcnQgdHlwZSBLZXlJbnB1dCA9IEJJUDMyTGlrZSB8IFVpbnQ4QXJyYXk7XG5cbmZ1bmN0aW9uIGlzQklQMzJMaWtlKGtleTogS2V5SW5wdXQpOiBrZXkgaXMgQklQMzJMaWtlIHtcbiAgcmV0dXJuIHR5cGVvZiBrZXkgPT09ICdvYmplY3QnICYmIGtleSAhPT0gbnVsbCAmJiAncHVibGljS2V5JyBpbiBrZXkgJiYgIUFycmF5QnVmZmVyLmlzVmlldyhrZXkpO1xufVxuXG4vKipcbiAqIEV4dHJhY3QgY29tcHJlc3NlZCBwdWJsaWMga2V5IGZyb20ga2V5IGlucHV0LlxuICogSGFuZGxlcyBCSVAzMi1saWtlIG9iamVjdHMgYW5kIHJhdyBwdWJrZXkgYnl0ZXMgKDMyIG9yIDMzIGJ5dGVzKS5cbiAqL1xuZnVuY3Rpb24gZ2V0Q29tcHJlc3NlZFB1YmxpY0tleShrZXk6IEtleUlucHV0KTogVWludDhBcnJheSB7XG4gIGNvbnN0IHB1YmtleSA9IGlzQklQMzJMaWtlKGtleSkgPyBrZXkucHVibGljS2V5IDoga2V5O1xuXG4gIGlmIChwdWJrZXkubGVuZ3RoID09PSAzMykge1xuICAgIHJldHVybiBwdWJrZXk7XG4gIH1cbiAgaWYgKHB1YmtleS5sZW5ndGggPT09IDMyKSB7XG4gICAgLy8geC1vbmx5IHB1YmtleSAtIHByZXBlbmQgMHgwMiBwYXJpdHkgYnl0ZSB0byBtYWtlIGNvbXByZXNzZWRcbiAgICBjb25zdCBjb21wcmVzc2VkUHVia2V5ID0gbmV3IFVpbnQ4QXJyYXkoMzMpO1xuICAgIGNvbXByZXNzZWRQdWJrZXlbMF0gPSAweDAyO1xuICAgIGNvbXByZXNzZWRQdWJrZXkuc2V0KHB1YmtleSwgMSk7XG4gICAgcmV0dXJuIGNvbXByZXNzZWRQdWJrZXk7XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHB1YmxpYyBrZXkgbGVuZ3RoOiAke3B1YmtleS5sZW5ndGh9LiBFeHBlY3RlZCAzMiBvciAzMyBieXRlcy5gKTtcbn1cblxuLyoqXG4gKiBDcmVhdGUgdGhlIFAyVFIgb3V0cHV0IHNjcmlwdCBmb3IgYW4gaW5zY3JpcHRpb24uXG4gKlxuICogQHBhcmFtIGtleSAtIEJJUDMyIGtleSBvciBwdWJsaWMga2V5IGJ5dGVzICgzMi1ieXRlIHgtb25seSBvciAzMy1ieXRlIGNvbXByZXNzZWQpXG4gKiBAcGFyYW0gY29udGVudFR5cGUgLSBNSU1FIHR5cGUgb2YgdGhlIGluc2NyaXB0aW9uIChlLmcuLCBcInRleHQvcGxhaW5cIiwgXCJpbWFnZS9wbmdcIilcbiAqIEBwYXJhbSBpbnNjcmlwdGlvbkRhdGEgLSBUaGUgaW5zY3JpcHRpb24gZGF0YSBieXRlc1xuICogQHJldHVybnMgVGhlIFAyVFIgb3V0cHV0IHNjcmlwdCBmb3IgdGhlIGluc2NyaXB0aW9uIGNvbW1pdCBhZGRyZXNzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVPdXRwdXRTY3JpcHRGb3JJbnNjcmlwdGlvbihcbiAga2V5OiBLZXlJbnB1dCxcbiAgY29udGVudFR5cGU6IHN0cmluZyxcbiAgaW5zY3JpcHRpb25EYXRhOiBVaW50OEFycmF5XG4pOiBVaW50OEFycmF5IHtcbiAgY29uc3QgY29tcHJlc3NlZFB1YmtleSA9IGdldENvbXByZXNzZWRQdWJsaWNLZXkoa2V5KTtcbiAgY29uc3QgZWNwYWlyID0gRUNQYWlyLmZyb21QdWJsaWNLZXkoY29tcHJlc3NlZFB1YmtleSk7XG4gIGNvbnN0IHJlc3VsdCA9IHdhc21JbnNjcmlwdGlvbnMuY3JlYXRlSW5zY3JpcHRpb25SZXZlYWxEYXRhKGVjcGFpciwgY29udGVudFR5cGUsIGluc2NyaXB0aW9uRGF0YSk7XG4gIHJldHVybiByZXN1bHQub3V0cHV0U2NyaXB0O1xufVxuXG4vKipcbiAqIENyZWF0ZSBpbnNjcmlwdGlvbiByZXZlYWwgZGF0YSBpbmNsdWRpbmcgdGhlIGNvbW1pdCBhZGRyZXNzIGFuZCB0YXAgbGVhZiBzY3JpcHQuXG4gKlxuICogQHBhcmFtIGtleSAtIEJJUDMyIGtleSBvciBwdWJsaWMga2V5IGJ5dGVzICgzMi1ieXRlIHgtb25seSBvciAzMy1ieXRlIGNvbXByZXNzZWQpXG4gKiBAcGFyYW0gY29udGVudFR5cGUgLSBNSU1FIHR5cGUgb2YgdGhlIGluc2NyaXB0aW9uIChlLmcuLCBcInRleHQvcGxhaW5cIiwgXCJpbWFnZS9wbmdcIilcbiAqIEBwYXJhbSBpbnNjcmlwdGlvbkRhdGEgLSBUaGUgaW5zY3JpcHRpb24gZGF0YSBieXRlc1xuICogQHBhcmFtIGNvaW5OYW1lIC0gQ29pbiBuYW1lIChlLmcuLCBcImJ0Y1wiLCBcInRidGNcIilcbiAqIEByZXR1cm5zIFByZXBhcmVkSW5zY3JpcHRpb25SZXZlYWxEYXRhIHdpdGggYWRkcmVzcywgdnNpemUgZXN0aW1hdGUsIGFuZCB0YXAgbGVhZiBzY3JpcHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUluc2NyaXB0aW9uUmV2ZWFsRGF0YShcbiAga2V5OiBLZXlJbnB1dCxcbiAgY29udGVudFR5cGU6IHN0cmluZyxcbiAgaW5zY3JpcHRpb25EYXRhOiBVaW50OEFycmF5LFxuICBjb2luTmFtZTogQ29pbk5hbWVcbik6IFByZXBhcmVkSW5zY3JpcHRpb25SZXZlYWxEYXRhIHtcbiAgY29uc3QgY29tcHJlc3NlZFB1YmtleSA9IGdldENvbXByZXNzZWRQdWJsaWNLZXkoa2V5KTtcbiAgY29uc3QgZWNwYWlyID0gRUNQYWlyLmZyb21QdWJsaWNLZXkoY29tcHJlc3NlZFB1YmtleSk7XG5cbiAgY29uc3Qgd2FzbVJlc3VsdCA9IHdhc21JbnNjcmlwdGlvbnMuY3JlYXRlSW5zY3JpcHRpb25SZXZlYWxEYXRhKGVjcGFpciwgY29udGVudFR5cGUsIGluc2NyaXB0aW9uRGF0YSk7XG5cbiAgLy8gQ29udmVydCBvdXRwdXRTY3JpcHQgdG8gYWRkcmVzcyBmb3IgdGhlIGdpdmVuIG5ldHdvcmtcbiAgY29uc3QgYWRkcmVzcyA9IHdhc21BZGRyZXNzLmZyb21PdXRwdXRTY3JpcHRXaXRoQ29pbih3YXNtUmVzdWx0Lm91dHB1dFNjcmlwdCwgY29pbk5hbWUpO1xuXG4gIHJldHVybiB7XG4gICAgYWRkcmVzcyxcbiAgICByZXZlYWxUcmFuc2FjdGlvblZTaXplOiB3YXNtUmVzdWx0LnJldmVhbFRyYW5zYWN0aW9uVlNpemUsXG4gICAgdGFwTGVhZlNjcmlwdDogd2FzbVJlc3VsdC50YXBMZWFmU2NyaXB0LFxuICB9O1xufVxuXG4vKipcbiAqIFNpZ24gYSByZXZlYWwgdHJhbnNhY3Rpb24uXG4gKlxuICogQ3JlYXRlcyBhbmQgc2lnbnMgdGhlIHJldmVhbCB0cmFuc2FjdGlvbiB0aGF0IHNwZW5kcyBmcm9tIHRoZSBjb21taXQgb3V0cHV0XG4gKiBhbmQgc2VuZHMgdGhlIGluc2NyaXB0aW9uIHRvIHRoZSByZWNpcGllbnQuXG4gKlxuICogQHBhcmFtIHByaXZhdGVLZXkgLSAzMi1ieXRlIHByaXZhdGUga2V5XG4gKiBAcGFyYW0gdGFwTGVhZlNjcmlwdCAtIFRoZSB0YXAgbGVhZiBzY3JpcHQgZnJvbSBjcmVhdGVJbnNjcmlwdGlvblJldmVhbERhdGFcbiAqIEBwYXJhbSBjb21taXRBZGRyZXNzIC0gVGhlIGNvbW1pdCBhZGRyZXNzXG4gKiBAcGFyYW0gcmVjaXBpZW50QWRkcmVzcyAtIFdoZXJlIHRvIHNlbmQgdGhlIGluc2NyaXB0aW9uXG4gKiBAcGFyYW0gdW5zaWduZWRDb21taXRUeCAtIFRoZSB1bnNpZ25lZCBjb21taXQgdHJhbnNhY3Rpb24gYnl0ZXNcbiAqIEBwYXJhbSBjb2luTmFtZSAtIENvaW4gbmFtZSAoZS5nLiwgXCJidGNcIiwgXCJ0YnRjXCIpXG4gKiBAcmV0dXJucyBUaGUgc2lnbmVkIFBTQlQgYXMgYnl0ZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNpZ25SZXZlYWxUcmFuc2FjdGlvbihcbiAgcHJpdmF0ZUtleTogVWludDhBcnJheSxcbiAgdGFwTGVhZlNjcmlwdDogVGFwTGVhZlNjcmlwdCxcbiAgY29tbWl0QWRkcmVzczogc3RyaW5nLFxuICByZWNpcGllbnRBZGRyZXNzOiBzdHJpbmcsXG4gIHVuc2lnbmVkQ29tbWl0VHg6IFVpbnQ4QXJyYXksXG4gIGNvaW5OYW1lOiBDb2luTmFtZVxuKTogVWludDhBcnJheSB7XG4gIGNvbnN0IGVjcGFpciA9IEVDUGFpci5mcm9tUHJpdmF0ZUtleShwcml2YXRlS2V5KTtcbiAgY29uc3QgY29tbWl0VHggPSBUcmFuc2FjdGlvbi5mcm9tQnl0ZXModW5zaWduZWRDb21taXRUeCk7XG4gIGNvbnN0IGNvbW1pdE91dHB1dFNjcmlwdCA9IHdhc21BZGRyZXNzLnRvT3V0cHV0U2NyaXB0V2l0aENvaW4oY29tbWl0QWRkcmVzcywgY29pbk5hbWUpO1xuICBjb25zdCByZWNpcGllbnRPdXRwdXRTY3JpcHQgPSB3YXNtQWRkcmVzcy50b091dHB1dFNjcmlwdFdpdGhDb2luKHJlY2lwaWVudEFkZHJlc3MsIGNvaW5OYW1lKTtcblxuICByZXR1cm4gd2FzbUluc2NyaXB0aW9ucy5zaWduUmV2ZWFsVHJhbnNhY3Rpb24oXG4gICAgZWNwYWlyLFxuICAgIHRhcExlYWZTY3JpcHQsXG4gICAgY29tbWl0VHgsXG4gICAgY29tbWl0T3V0cHV0U2NyaXB0LFxuICAgIHJlY2lwaWVudE91dHB1dFNjcmlwdCxcbiAgICBERUZBVUxUX1BPU1RBR0VfU0FUU1xuICApO1xufVxuIl19