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 BuildReceivedHtlcOutput(Htlc trimmedReceivedHtlc)
        {
            PubKey localHtlcPubkey       = new PubKey(CommitmentTxParams.HtlcPublicKey.PublicKeyCompressed);
            PubKey remoteHtlcPubkey      = new PubKey(RemoteHtlcPubkey.PublicKeyCompressed);
            PubKey localRevocationPubkey = new PubKey(CommitmentTxParams.RevocationPublicKey.PublicKeyCompressed);
            Script script = OutputScripts.ReceivedHtlc(localHtlcPubkey, remoteHtlcPubkey, localRevocationPubkey, trimmedReceivedHtlc.PaymentHash, trimmedReceivedHtlc.Expiry);

            return(new TxOut(Money.Satoshis(trimmedReceivedHtlc.AmountMsat.MSatToSatoshi()), script.WitHash.ScriptPubKey));
        }
        private WitScript CreateHtlcWitnessScript(Htlc htlc, byte[] localPubKeySignature, byte[] remotePubKeySignature,
                                                  Script witnessScript)
        {
            bool incoming = htlc.Direction == Direction.Incoming;

            return(new WitScript(new List <byte[]>()
            {
                new byte[] { 0 }, remotePubKeySignature, localPubKeySignature, incoming ? htlc.PaymentPreImage : new byte[] { 0 }, witnessScript.ToBytes()
            }));
        }
 private Script CreateHtlcWitnessScript(Htlc htlc)
 {
     return(htlc.Direction == Direction.Incoming ?
            OutputScripts.ReceivedHtlc(CommitmentTxParams.HtlcPublicKey.ToPubKey(),
                                       RemoteHtlcPubkey.ToPubKey(),
                                       CommitmentTxParams.RevocationPublicKey.ToPubKey(), htlc.PaymentHash, htlc.Expiry) :
            OutputScripts.OfferedHtlc(CommitmentTxParams.HtlcPublicKey.ToPubKey(),
                                      RemoteHtlcPubkey.ToPubKey(),
                                      CommitmentTxParams.RevocationPublicKey.ToPubKey(), htlc.PaymentHash));
 }
        public Transaction SignHtlcTransaction(Htlc htlc, Transaction transaction, byte[] htlcRemoteSignature, Key fundingPrivateKey)
        {
            var witnessScript = CreateHtlcWitnessScript(htlc);
            var input         = transaction.Inputs[0];
            var outputIndex   = _htlcOutputIndexMap[htlc];
            var amount        = _commitmentTransaction.Outputs[outputIndex].Value;
            var inputCoin     = new Coin(input.PrevOut, new TxOut(Money.Satoshis(amount), input.ScriptSig));
            var scriptCoin    = inputCoin.ToScriptCoin(witnessScript);

            TransactionBuilder builder2 = new TransactionBuilder();

            builder2.AddCoins(scriptCoin);
            builder2.AddKeys(fundingPrivateKey);

            var signature = transaction.SignInput(fundingPrivateKey, scriptCoin);
            var witScript = CreateHtlcWitnessScript(htlc, signature.ToBytes(), htlcRemoteSignature, witnessScript);

            transaction.Inputs[0].ScriptSig = Script.Empty;
            transaction.Inputs[0].WitScript = witScript;

            return(transaction);
        }