public async Task <IBitcoinBasedTransaction> CreateSwapRefundTxAsync(
            IBitcoinBasedTransaction paymentTx,
            long amount,
            string refundAddress,
            byte[] redeemScript,
            DateTimeOffset lockTime,
            BitcoinBasedConfig currencyConfig)
        {
            var swapOutput = paymentTx.Outputs
                             .Cast <BitcoinBasedTxOutput>()
                             .FirstOrDefault(o => o.IsPayToScriptHash(redeemScript));

            if (swapOutput == null)
            {
                throw new Exception("Can't find pay to script hash output");
            }

            var feeRate = await currencyConfig
                          .GetFeeRateAsync()
                          .ConfigureAwait(false);

            var inputSize = new BitcoinInputToSign
            {
                Output = swapOutput,
                Signer = new BitcoinRefundSigner()
            }.SizeWithSignature();

            var outputSize = new BitcoinDestination
            {
                AmountInSatoshi = amount,
                Script          = BitcoinAddress.Create(refundAddress, currencyConfig.Network).ScriptPubKey
            }.Size();

            var(txSize, _) = BitcoinTransactionParams.CalculateTxSize(
                inputsCount: 1,
                inputsSize: inputSize,
                outputsCount: 1,
                outputsSize: outputSize,
                witnessCount: swapOutput.IsSegWit ? 1 : 0,
                changeOutputSize: 0);

            var feeInSatoshi = (long)(txSize * feeRate);

            if (amount - feeInSatoshi < 0)
            {
                throw new Exception($"Insufficient funds for fee. Available {amount}, required {feeInSatoshi}");
            }

            return(currencyConfig.CreateP2PkhTx(
                       unspentOutputs: new ITxOutput[] { swapOutput },
                       destinationAddress: refundAddress,
                       changeAddress: refundAddress,
                       amount: amount - feeInSatoshi,
                       fee: feeInSatoshi,
                       lockTime: lockTime,
                       knownRedeems: new Script(redeemScript)));
        }
 public static IBitcoinBasedTransaction CreatePaymentTx(
     BitcoinBasedConfig currency,
     IEnumerable <ITxOutput> outputs,
     PubKey from,
     PubKey to,
     int amount,
     int fee,
     DateTimeOffset lockTime,
     params Script[] knownRedeems)
 {
     return(currency.CreateP2PkhTx(
                unspentOutputs: outputs,
                destinationAddress: to.GetAddress(ScriptPubKeyType.Legacy, currency.Network).ToString(),
                changeAddress: from.GetAddress(ScriptPubKeyType.Legacy, currency.Network).ToString(),
                amount: amount,
                fee: fee,
                lockTime: lockTime,
                knownRedeems: knownRedeems));
 }