PHP WebShell

Текущая директория: /opt/BitGoJS/modules/babylonlabs-io-btc-staking-ts/build/src/staking

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

"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getUnbondingTxStakerSignature = exports.BabylonBtcStakingManager = exports.SigningStep = void 0;
const bitcoinjs_lib_1 = require("bitcoinjs-lib");
const _1 = require(".");
const babylon_proto_ts_1 = require("@babylonlabs-io/babylon-proto-ts");
const pop_1 = require("@babylonlabs-io/babylon-proto-ts/dist/generated/babylon/btcstaking/v1/pop");
const registry_1 = require("../constants/registry");
const transactions_1 = require("./transactions");
const param_1 = require("../utils/staking/param");
const utils_1 = require("../utils");
const staking_1 = require("../utils/staking");
const staking_2 = require("../utils/staking");
const babylon_1 = require("../utils/babylon");
const error_1 = require("../error");
const error_2 = require("../error");
const btc_1 = require("../utils/btc");
// Event types for the Signing event
var SigningStep;
(function (SigningStep) {
    SigningStep["STAKING_SLASHING"] = "staking-slashing";
    SigningStep["UNBONDING_SLASHING"] = "unbonding-slashing";
    SigningStep["PROOF_OF_POSSESSION"] = "proof-of-possession";
    SigningStep["CREATE_BTC_DELEGATION_MSG"] = "create-btc-delegation-msg";
    SigningStep["STAKING"] = "staking";
    SigningStep["UNBONDING"] = "unbonding";
    SigningStep["WITHDRAW_STAKING_EXPIRED"] = "withdraw-staking-expired";
    SigningStep["WITHDRAW_EARLY_UNBONDED"] = "withdraw-early-unbonded";
    SigningStep["WITHDRAW_SLASHING"] = "withdraw-slashing";
})(SigningStep || (exports.SigningStep = SigningStep = {}));
class BabylonBtcStakingManager {
    constructor(network, stakingParams, btcProvider, babylonProvider) {
        this.network = network;
        this.btcProvider = btcProvider;
        this.babylonProvider = babylonProvider;
        if (stakingParams.length === 0) {
            throw new Error("No staking parameters provided");
        }
        this.stakingParams = stakingParams;
    }
    /**
     * Creates a signed Pre-Staking Registration transaction that is ready to be
     * sent to the Babylon chain.
     * @param stakerBtcInfo - The staker BTC info which includes the BTC address
     * and the no-coord public key in hex format.
     * @param stakingInput - The staking inputs.
     * @param babylonBtcTipHeight - The Babylon BTC tip height.
     * @param inputUTXOs - The UTXOs that will be used to pay for the staking
     * transaction.
     * @param feeRate - The fee rate in satoshis per byte. Typical value for the
     * fee rate is above 1. If the fee rate is too low, the transaction will not
     * be included in a block.
     * @param babylonAddress - The Babylon bech32 encoded address of the staker.
     * @returns The signed babylon pre-staking registration transaction in base64
     * format.
     */
    preStakeRegistrationBabylonTransaction(stakerBtcInfo, stakingInput, babylonBtcTipHeight, inputUTXOs, feeRate, babylonAddress) {
        return __awaiter(this, void 0, void 0, function* () {
            if (babylonBtcTipHeight === 0) {
                throw new Error("Babylon BTC tip height cannot be 0");
            }
            if (inputUTXOs.length === 0) {
                throw new Error("No input UTXOs provided");
            }
            if (!(0, babylon_1.isValidBabylonAddress)(babylonAddress)) {
                throw new Error("Invalid Babylon address");
            }
            // Get the Babylon params based on the BTC tip height from Babylon chain
            const params = (0, param_1.getBabylonParamByBtcHeight)(babylonBtcTipHeight, this.stakingParams);
            const staking = new _1.Staking(this.network, stakerBtcInfo, params, stakingInput.finalityProviderPkNoCoordHex, stakingInput.stakingTimelock);
            // Create unsigned staking transaction
            const { transaction } = staking.createStakingTransaction(stakingInput.stakingAmountSat, inputUTXOs, feeRate);
            // Create delegation message without including inclusion proof
            const msg = yield this.createBtcDelegationMsg(staking, stakingInput, transaction, babylonAddress, stakerBtcInfo, params);
            return {
                signedBabylonTx: yield this.babylonProvider.signTransaction(SigningStep.CREATE_BTC_DELEGATION_MSG, msg),
                stakingTx: transaction,
            };
        });
    }
    /**
     * Creates a signed post-staking registration transaction that is ready to be
     * sent to the Babylon chain. This is used when a staking transaction is
     * already created and included in a BTC block and we want to register it on
     * the Babylon chain.
     * @param stakerBtcInfo - The staker BTC info which includes the BTC address
     * and the no-coord public key in hex format.
     * @param stakingTx - The staking transaction.
     * @param stakingTxHeight - The BTC height in which the staking transaction
     * is included.
     * @param stakingInput - The staking inputs.
     * @param inclusionProof - Merkle Proof of Inclusion: Verifies transaction
     * inclusion in a Bitcoin block that is k-deep.
     * @param babylonAddress - The Babylon bech32 encoded address of the staker.
     * @returns The signed babylon transaction in base64 format.
     */
    postStakeRegistrationBabylonTransaction(stakerBtcInfo, stakingTx, stakingTxHeight, stakingInput, inclusionProof, babylonAddress) {
        return __awaiter(this, void 0, void 0, function* () {
            // Get the Babylon params at the time of the staking transaction
            const params = (0, param_1.getBabylonParamByBtcHeight)(stakingTxHeight, this.stakingParams);
            if (!(0, babylon_1.isValidBabylonAddress)(babylonAddress)) {
                throw new Error("Invalid Babylon address");
            }
            const stakingInstance = new _1.Staking(this.network, stakerBtcInfo, params, stakingInput.finalityProviderPkNoCoordHex, stakingInput.stakingTimelock);
            // Validate if the stakingTx is valid based on the retrieved Babylon param
            const scripts = stakingInstance.buildScripts();
            const stakingOutputInfo = (0, staking_1.deriveStakingOutputInfo)(scripts, this.network);
            // Error will be thrown if the expected staking output address is not found
            // in the stakingTx
            (0, staking_2.findMatchingTxOutputIndex)(stakingTx, stakingOutputInfo.outputAddress, this.network);
            // Create delegation message
            const delegationMsg = yield this.createBtcDelegationMsg(stakingInstance, stakingInput, stakingTx, babylonAddress, stakerBtcInfo, params, this.getInclusionProof(inclusionProof));
            return {
                signedBabylonTx: yield this.babylonProvider.signTransaction(SigningStep.CREATE_BTC_DELEGATION_MSG, delegationMsg),
            };
        });
    }
    /**
     * Estimates the BTC fee required for staking.
     * @param stakerBtcInfo - The staker BTC info which includes the BTC address
     * and the no-coord public key in hex format.
     * @param babylonBtcTipHeight - The BTC tip height recorded on the Babylon
     * chain.
     * @param stakingInput - The staking inputs.
     * @param inputUTXOs - The UTXOs that will be used to pay for the staking
     * transaction.
     * @param feeRate - The fee rate in satoshis per byte. Typical value for the
     * fee rate is above 1. If the fee rate is too low, the transaction will not
     * be included in a block.
     * @returns The estimated BTC fee in satoshis.
     */
    estimateBtcStakingFee(stakerBtcInfo, babylonBtcTipHeight, stakingInput, inputUTXOs, feeRate) {
        if (babylonBtcTipHeight === 0) {
            throw new Error("Babylon BTC tip height cannot be 0");
        }
        // Get the param based on the tip height
        const params = (0, param_1.getBabylonParamByBtcHeight)(babylonBtcTipHeight, this.stakingParams);
        const staking = new _1.Staking(this.network, stakerBtcInfo, params, stakingInput.finalityProviderPkNoCoordHex, stakingInput.stakingTimelock);
        const { fee: stakingFee } = staking.createStakingTransaction(stakingInput.stakingAmountSat, inputUTXOs, feeRate);
        return stakingFee;
    }
    /**
     * Creates a signed staking transaction that is ready to be sent to the BTC
     * network.
     * @param stakerBtcInfo - The staker BTC info which includes the BTC address
     * and the no-coord public key in hex format.
     * @param stakingInput - The staking inputs.
     * @param unsignedStakingTx - The unsigned staking transaction.
     * @param inputUTXOs - The UTXOs that will be used to pay for the staking
     * transaction.
     * @param stakingParamsVersion - The params version that was used to create the
     * delegation in Babylon chain
     * @returns The signed staking transaction.
     */
    createSignedBtcStakingTransaction(stakerBtcInfo, stakingInput, unsignedStakingTx, inputUTXOs, stakingParamsVersion) {
        return __awaiter(this, void 0, void 0, function* () {
            const params = (0, param_1.getBabylonParamByVersion)(stakingParamsVersion, this.stakingParams);
            if (inputUTXOs.length === 0) {
                throw new Error("No input UTXOs provided");
            }
            const staking = new _1.Staking(this.network, stakerBtcInfo, params, stakingInput.finalityProviderPkNoCoordHex, stakingInput.stakingTimelock);
            const stakingPsbt = staking.toStakingPsbt(unsignedStakingTx, inputUTXOs);
            const signedStakingPsbtHex = yield this.btcProvider.signPsbt(SigningStep.STAKING, stakingPsbt.toHex());
            return bitcoinjs_lib_1.Psbt.fromHex(signedStakingPsbtHex).extractTransaction();
        });
    }
    /**
     * Creates a partial signed unbonding transaction that is only signed by the
     * staker. In order to complete the unbonding transaction, the covenant
     * unbonding signatures need to be added to the transaction before sending it
     * to the BTC network.
     * NOTE: This method should only be used for Babylon phase-1 unbonding.
     * @param stakerBtcInfo - The staker BTC info which includes the BTC address
     * and the no-coord public key in hex format.
     * @param stakingInput - The staking inputs.
     * @param stakingParamsVersion - The params version that was used to create the
     * delegation in Babylon chain
     * @param stakingTx - The staking transaction.
     * @returns The partial signed unbonding transaction and its fee.
     */
    createPartialSignedBtcUnbondingTransaction(stakerBtcInfo, stakingInput, stakingParamsVersion, stakingTx) {
        return __awaiter(this, void 0, void 0, function* () {
            // Get the staking params at the time of the staking transaction
            const params = (0, param_1.getBabylonParamByVersion)(stakingParamsVersion, this.stakingParams);
            const staking = new _1.Staking(this.network, stakerBtcInfo, params, stakingInput.finalityProviderPkNoCoordHex, stakingInput.stakingTimelock);
            const { transaction: unbondingTx, fee, } = staking.createUnbondingTransaction(stakingTx);
            const psbt = staking.toUnbondingPsbt(unbondingTx, stakingTx);
            const signedUnbondingPsbtHex = yield this.btcProvider.signPsbt(SigningStep.UNBONDING, psbt.toHex());
            const signedUnbondingTx = bitcoinjs_lib_1.Psbt.fromHex(signedUnbondingPsbtHex).extractTransaction();
            return {
                transaction: signedUnbondingTx,
                fee,
            };
        });
    }
    /**
     * Creates a signed unbonding transaction that is ready to be sent to the BTC
     * network.
     * @param stakerBtcInfo - The staker BTC info which includes the BTC address
     * and the no-coord public key in hex format.
     * @param stakingInput - The staking inputs.
     * @param stakingParamsVersion - The params version that was used to create the
     * delegation in Babylon chain
     * @param stakingTx - The staking transaction.
     * @param unsignedUnbondingTx - The unsigned unbonding transaction.
     * @param covenantUnbondingSignatures - The covenant unbonding signatures.
     * It can be retrieved from the Babylon chain or API.
     * @returns The signed unbonding transaction and its fee.
     */
    createSignedBtcUnbondingTransaction(stakerBtcInfo, stakingInput, stakingParamsVersion, stakingTx, unsignedUnbondingTx, covenantUnbondingSignatures) {
        return __awaiter(this, void 0, void 0, function* () {
            // Get the staking params at the time of the staking transaction
            const params = (0, param_1.getBabylonParamByVersion)(stakingParamsVersion, this.stakingParams);
            const { transaction: signedUnbondingTx, fee, } = yield this.createPartialSignedBtcUnbondingTransaction(stakerBtcInfo, stakingInput, stakingParamsVersion, stakingTx);
            // Check the computed txid of the signed unbonding transaction is the same as
            // the txid of the unsigned unbonding transaction
            if (signedUnbondingTx.getId() !== unsignedUnbondingTx.getId()) {
                throw new Error("Unbonding transaction hash does not match the computed hash");
            }
            // Add covenant unbonding signatures
            // Convert the params of covenants to buffer
            const covenantBuffers = params.covenantNoCoordPks.map((covenant) => Buffer.from(covenant, "hex"));
            const witness = (0, transactions_1.createCovenantWitness)(
            // Since unbonding transactions always have a single input and output,
            // we expect exactly one signature in TaprootScriptSpendSig when the
            // signing is successful
            signedUnbondingTx.ins[0].witness, covenantBuffers, covenantUnbondingSignatures, params.covenantQuorum);
            // Overwrite the witness to include the covenant unbonding signatures
            signedUnbondingTx.ins[0].witness = witness;
            return {
                transaction: signedUnbondingTx,
                fee,
            };
        });
    }
    /**
     * Creates a signed withdrawal transaction on the unbodning output expiry path
     * that is ready to be sent to the BTC network.
     * @param stakingInput - The staking inputs.
     * @param stakingParamsVersion - The params version that was used to create the
     * delegation in Babylon chain
     * @param earlyUnbondingTx - The early unbonding transaction.
     * @param feeRate - The fee rate in satoshis per byte. Typical value for the
     * fee rate is above 1. If the fee rate is too low, the transaction will not
     * be included in a block.
     * @returns The signed withdrawal transaction and its fee.
     */
    createSignedBtcWithdrawEarlyUnbondedTransaction(stakerBtcInfo, stakingInput, stakingParamsVersion, earlyUnbondingTx, feeRate) {
        return __awaiter(this, void 0, void 0, function* () {
            const params = (0, param_1.getBabylonParamByVersion)(stakingParamsVersion, this.stakingParams);
            const staking = new _1.Staking(this.network, stakerBtcInfo, params, stakingInput.finalityProviderPkNoCoordHex, stakingInput.stakingTimelock);
            const { psbt: unbondingPsbt, fee } = staking.createWithdrawEarlyUnbondedTransaction(earlyUnbondingTx, feeRate);
            const signedWithdrawalPsbtHex = yield this.btcProvider.signPsbt(SigningStep.WITHDRAW_EARLY_UNBONDED, unbondingPsbt.toHex());
            return {
                transaction: bitcoinjs_lib_1.Psbt.fromHex(signedWithdrawalPsbtHex).extractTransaction(),
                fee,
            };
        });
    }
    /**
     * Creates a signed withdrawal transaction on the staking output expiry path
     * that is ready to be sent to the BTC network.
     * @param stakerBtcInfo - The staker BTC info which includes the BTC address
     * and the no-coord public key in hex format.
     * @param stakingInput - The staking inputs.
     * @param stakingParamsVersion - The params version that was used to create the
     * delegation in Babylon chain
     * @param stakingTx - The staking transaction.
     * @param feeRate - The fee rate in satoshis per byte. Typical value for the
     * fee rate is above 1. If the fee rate is too low, the transaction will not
     * be included in a block.
     * @returns The signed withdrawal transaction and its fee.
     */
    createSignedBtcWithdrawStakingExpiredTransaction(stakerBtcInfo, stakingInput, stakingParamsVersion, stakingTx, feeRate) {
        return __awaiter(this, void 0, void 0, function* () {
            const params = (0, param_1.getBabylonParamByVersion)(stakingParamsVersion, this.stakingParams);
            const staking = new _1.Staking(this.network, stakerBtcInfo, params, stakingInput.finalityProviderPkNoCoordHex, stakingInput.stakingTimelock);
            const { psbt, fee } = staking.createWithdrawStakingExpiredPsbt(stakingTx, feeRate);
            const signedWithdrawalPsbtHex = yield this.btcProvider.signPsbt(SigningStep.WITHDRAW_STAKING_EXPIRED, psbt.toHex());
            return {
                transaction: bitcoinjs_lib_1.Psbt.fromHex(signedWithdrawalPsbtHex).extractTransaction(),
                fee,
            };
        });
    }
    /**
     * Creates a signed withdrawal transaction for the expired slashing output that
     * is ready to be sent to the BTC network.
     * @param stakerBtcInfo - The staker BTC info which includes the BTC address
     * and the no-coord public key in hex format.
     * @param stakingInput - The staking inputs.
     * @param stakingParamsVersion - The params version that was used to create the
     * delegation in Babylon chain
     * @param slashingTx - The slashing transaction.
     * @param feeRate - The fee rate in satoshis per byte. Typical value for the
     * fee rate is above 1. If the fee rate is too low, the transaction will not
     * be included in a block.
     * @returns The signed withdrawal transaction and its fee.
     */
    createSignedBtcWithdrawSlashingTransaction(stakerBtcInfo, stakingInput, stakingParamsVersion, slashingTx, feeRate) {
        return __awaiter(this, void 0, void 0, function* () {
            const params = (0, param_1.getBabylonParamByVersion)(stakingParamsVersion, this.stakingParams);
            const staking = new _1.Staking(this.network, stakerBtcInfo, params, stakingInput.finalityProviderPkNoCoordHex, stakingInput.stakingTimelock);
            const { psbt, fee } = staking.createWithdrawSlashingPsbt(slashingTx, feeRate);
            const signedSlashingPsbtHex = yield this.btcProvider.signPsbt(SigningStep.WITHDRAW_SLASHING, psbt.toHex());
            return {
                transaction: bitcoinjs_lib_1.Psbt.fromHex(signedSlashingPsbtHex).extractTransaction(),
                fee,
            };
        });
    }
    /**
     * Creates a proof of possession for the staker based on ECDSA signature.
     * @param bech32Address - The staker's bech32 address on the babylon chain
     * @param stakerBtcAddress - The staker's BTC address.
     * @returns The proof of possession.
     */
    createProofOfPossession(bech32Address, stakerBtcAddress) {
        return __awaiter(this, void 0, void 0, function* () {
            let sigType = pop_1.BTCSigType.ECDSA;
            // For Taproot or Native SegWit addresses, use the BIP322 signature scheme
            // in the proof of possession as it uses the same signature type as the regular
            // input UTXO spend. For legacy addresses, use the ECDSA signature scheme.
            if ((0, btc_1.isTaproot)(stakerBtcAddress, this.network)
                || (0, btc_1.isNativeSegwit)(stakerBtcAddress, this.network)) {
                sigType = pop_1.BTCSigType.BIP322;
            }
            const signedBabylonAddress = yield this.btcProvider.signMessage(SigningStep.PROOF_OF_POSSESSION, bech32Address, sigType === pop_1.BTCSigType.BIP322 ? "bip322-simple" : "ecdsa");
            let btcSig;
            if (sigType === pop_1.BTCSigType.BIP322) {
                const bip322Sig = pop_1.BIP322Sig.fromPartial({
                    address: stakerBtcAddress,
                    sig: Buffer.from(signedBabylonAddress, "base64"),
                });
                // Encode the BIP322 protobuf message to a Uint8Array
                btcSig = pop_1.BIP322Sig.encode(bip322Sig).finish();
            }
            else {
                // Encode the ECDSA signature to a Uint8Array
                btcSig = Buffer.from(signedBabylonAddress, "base64");
            }
            return {
                btcSigType: sigType,
                btcSig
            };
        });
    }
    /**
     * Creates the unbonding, slashing, and unbonding slashing transactions and
     * PSBTs.
     * @param stakingInstance - The staking instance.
     * @param stakingTx - The staking transaction.
     * @returns The unbonding, slashing, and unbonding slashing transactions and
     * PSBTs.
     */
    createDelegationTransactionsAndPsbts(stakingInstance, stakingTx) {
        return __awaiter(this, void 0, void 0, function* () {
            const { transaction: unbondingTx } = stakingInstance.createUnbondingTransaction(stakingTx);
            // Create slashing transactions and extract signatures
            const { psbt: slashingPsbt } = stakingInstance.createStakingOutputSlashingPsbt(stakingTx);
            const { psbt: unbondingSlashingPsbt } = stakingInstance.createUnbondingOutputSlashingPsbt(unbondingTx);
            return {
                unbondingTx,
                slashingPsbt,
                unbondingSlashingPsbt,
            };
        });
    }
    /**
     * Creates a protobuf message for the BTC delegation.
     * @param stakingInstance - The staking instance.
     * @param stakingInput - The staking inputs.
     * @param stakingTx - The staking transaction.
     * @param bech32Address - The staker's babylon chain bech32 address
     * @param stakerBtcInfo - The staker's BTC information such as address and
     * public key
     * @param params - The staking parameters.
     * @param inclusionProof - The inclusion proof of the staking transaction.
     * @returns The protobuf message.
     */
    createBtcDelegationMsg(stakingInstance, stakingInput, stakingTx, bech32Address, stakerBtcInfo, params, inclusionProof) {
        return __awaiter(this, void 0, void 0, function* () {
            const { unbondingTx, slashingPsbt, unbondingSlashingPsbt } = yield this.createDelegationTransactionsAndPsbts(stakingInstance, stakingTx);
            // Sign the slashing PSBT
            const signedSlashingPsbtHex = yield this.btcProvider.signPsbt(SigningStep.STAKING_SLASHING, slashingPsbt.toHex());
            const signedSlashingTx = bitcoinjs_lib_1.Psbt.fromHex(signedSlashingPsbtHex).extractTransaction();
            const slashingSig = extractFirstSchnorrSignatureFromTransaction(signedSlashingTx);
            if (!slashingSig) {
                throw new Error("No signature found in the staking output slashing PSBT");
            }
            // Sign the unbonding slashing PSBT
            const signedUnbondingSlashingPsbtHex = yield this.btcProvider.signPsbt(SigningStep.UNBONDING_SLASHING, unbondingSlashingPsbt.toHex());
            const signedUnbondingSlashingTx = bitcoinjs_lib_1.Psbt.fromHex(signedUnbondingSlashingPsbtHex).extractTransaction();
            const unbondingSignatures = extractFirstSchnorrSignatureFromTransaction(signedUnbondingSlashingTx);
            if (!unbondingSignatures) {
                throw new Error("No signature found in the unbonding output slashing PSBT");
            }
            // Create proof of possession
            const proofOfPossession = yield this.createProofOfPossession(bech32Address, stakerBtcInfo.address);
            // Prepare the final protobuf message
            const msg = babylon_proto_ts_1.btcstakingtx.MsgCreateBTCDelegation.fromPartial({
                stakerAddr: bech32Address,
                pop: proofOfPossession,
                btcPk: Uint8Array.from(Buffer.from(stakerBtcInfo.publicKeyNoCoordHex, "hex")),
                fpBtcPkList: [
                    Uint8Array.from(Buffer.from(stakingInput.finalityProviderPkNoCoordHex, "hex")),
                ],
                stakingTime: stakingInput.stakingTimelock,
                stakingValue: stakingInput.stakingAmountSat,
                stakingTx: Uint8Array.from(stakingTx.toBuffer()),
                slashingTx: Uint8Array.from(Buffer.from(clearTxSignatures(signedSlashingTx).toHex(), "hex")),
                delegatorSlashingSig: Uint8Array.from(slashingSig),
                unbondingTime: params.unbondingTime,
                unbondingTx: Uint8Array.from(unbondingTx.toBuffer()),
                unbondingValue: stakingInput.stakingAmountSat - params.unbondingFeeSat,
                unbondingSlashingTx: Uint8Array.from(Buffer.from(clearTxSignatures(signedUnbondingSlashingTx).toHex(), "hex")),
                delegatorUnbondingSlashingSig: Uint8Array.from(unbondingSignatures),
                stakingTxInclusionProof: inclusionProof,
            });
            return {
                typeUrl: registry_1.BABYLON_REGISTRY_TYPE_URLS.MsgCreateBTCDelegation,
                value: msg,
            };
        });
    }
    ;
    /**
     * Gets the inclusion proof for the staking transaction.
     * See the type `InclusionProof` for more information
     * @param inclusionProof - The inclusion proof.
     * @returns The inclusion proof.
     */
    getInclusionProof(inclusionProof) {
        const { pos, merkle, blockHashHex } = inclusionProof;
        const proofHex = deriveMerkleProof(merkle);
        const hash = (0, utils_1.reverseBuffer)(Uint8Array.from(Buffer.from(blockHashHex, "hex")));
        const inclusionProofKey = babylon_proto_ts_1.btccheckpoint.TransactionKey.fromPartial({
            index: pos,
            hash,
        });
        return babylon_proto_ts_1.btcstaking.InclusionProof.fromPartial({
            key: inclusionProofKey,
            proof: Uint8Array.from(Buffer.from(proofHex, "hex")),
        });
    }
    ;
}
exports.BabylonBtcStakingManager = BabylonBtcStakingManager;
/**
 * Extracts the first valid Schnorr signature from a signed transaction.
 *
 * Since we only handle transactions with a single input and request a signature
 * for one public key, there can be at most one signature from the Bitcoin node.
 * A valid Schnorr signature is exactly 64 bytes in length.
 *
 * @param singedTransaction - The signed Bitcoin transaction to extract the signature from
 * @returns The first valid 64-byte Schnorr signature found in the transaction witness data,
 *          or undefined if no valid signature exists
 */
const extractFirstSchnorrSignatureFromTransaction = (singedTransaction) => {
    // Loop through each input to extract the witness signature
    for (const input of singedTransaction.ins) {
        if (input.witness && input.witness.length > 0) {
            const schnorrSignature = input.witness[0];
            // Check that it's a 64-byte Schnorr signature
            if (schnorrSignature.length === 64) {
                return schnorrSignature; // Return the first valid signature found
            }
        }
    }
    return undefined;
};
/**
 * Strips all signatures from a transaction by clearing both the script and
 * witness data. This is due to the fact that we only need the raw unsigned
 * transaction structure. The signatures are sent in a separate protobuf field
 * when creating the delegation message in the Babylon.
 * @param tx - The transaction to strip signatures from
 * @returns A copy of the transaction with all signatures removed
 */
const clearTxSignatures = (tx) => {
    tx.ins.forEach((input) => {
        input.script = Buffer.alloc(0);
        input.witness = [];
    });
    return tx;
};
/**
 * Derives the merkle proof from the list of hex strings. Note the
 * sibling hashes are reversed from hex before concatenation.
 * @param merkle - The merkle proof hex strings.
 * @returns The merkle proof in hex string format.
 */
const deriveMerkleProof = (merkle) => {
    const proofHex = merkle.reduce((acc, m) => {
        return acc + Buffer.from(m, "hex").reverse().toString("hex");
    }, "");
    return proofHex;
};
/**
 * Get the staker signature from the unbonding transaction
 * This is used mostly for unbonding transactions from phase-1(Observable)
 * @param unbondingTx - The unbonding transaction
 * @returns The staker signature
 */
const getUnbondingTxStakerSignature = (unbondingTx) => {
    try {
        // There is only one input and one output in the unbonding transaction
        return unbondingTx.ins[0].witness[0].toString("hex");
    }
    catch (error) {
        throw error_1.StakingError.fromUnknown(error, error_2.StakingErrorCode.INVALID_INPUT, "Failed to get staker signature");
    }
};
exports.getUnbondingTxStakerSignature = getUnbondingTxStakerSignature;

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


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