private Transaction BuildHtlcTransaction(Htlc htlc)
        {
            bool incoming      = htlc.Direction == Direction.Incoming;
            var  fee           = TransactionFee.CalculateFee(FeeratePerKw, incoming ? TransactionFee.HtlcSuccessWeight : TransactionFee.HtlcTimeoutWeight);
            var  witnessScript = CreateHtlcWitnessScript(htlc);
            var  outputScript  = OutputScripts.ToLocal(CommitmentTxParams.RevocationPublicKey.ToPubKey(), CommitmentTxParams.DelayedPaymentPublicKey.ToPubKey(), ChannelParameters.ToSelfDelay);
            var  outputIndex   = _htlcOutputIndexMap[htlc];
            var  amount        = htlc.AmountMsat.MSatToSatoshi() - fee;

            if (amount < ChannelParameters.DustLimitSatoshis)
            {
                throw new InvalidOperationException("HTLC amount below dust limit");
            }

            Transaction tx   = Transaction.Create(Network);
            TxIn        txIn = new TxIn(new OutPoint(_commitmentTransaction, outputIndex));

            txIn.Sequence  = 0;
            txIn.ScriptSig = witnessScript.WitHash.ScriptPubKey;
            tx.Inputs.Add(txIn);

            TxOut txOut = new TxOut(Money.Satoshis(amount), outputScript.WitHash.ScriptPubKey);

            tx.Outputs.Add(txOut);

            tx.Version  = 2;
            tx.LockTime = incoming ? 0 : htlc.Expiry;

            return(tx);
        }
        private TxOut BuildToLocalDelayedOutput(ulong toLocal)
        {
            PubKey localRevocationPubkey     = new PubKey(CommitmentTxParams.RevocationPublicKey.PublicKeyCompressed);
            PubKey localDelayedPaymentPubkey = new PubKey(CommitmentTxParams.DelayedPaymentPublicKey.PublicKeyCompressed);
            Script script = OutputScripts.ToLocal(localRevocationPubkey, localDelayedPaymentPubkey, ChannelParameters.ToSelfDelay);

            return(new TxOut(Money.Satoshis(toLocal), script.WitHash.ScriptPubKey));
        }