private async Task <BtcTxnSignature> getBtcTxnSignaturesAsync( ECurrency currency, string address, string amount, string fee, string target, string reserve, string reservedFundsRedeemScript, string privateKey ) { GluwaClient client = new GluwaClient(mEnv); Result <BalanceResponse, ErrorResponse> getUnspentOutput = await client.GetBalanceAsync(currency, address, true); List <UnspentOutput> unspentOutputs = getUnspentOutput.Data.UnspentOutputs.OrderByDescending(u => u.Amount).ToList(); Money amountValue = Money.Parse(amount); Money feeValue = Money.Parse(fee); Money reserveAmount = amountValue + feeValue; Money totalRequiredAmountMoney = reserveAmount + feeValue; BigInteger totalRequiredAmount = new BigInteger(totalRequiredAmountMoney.Satoshi); BitcoinAddress sourceAddress = BitcoinAddress.Create(address, mEnv.Network); BitcoinAddress targetAddress = BitcoinAddress.Create(target, mEnv.Network); BitcoinAddress reserveAddress = BitcoinAddress.Create(reserve, mEnv.Network); BitcoinSecret secret = new BitcoinSecret(privateKey, mEnv.Network); List <UnspentOutput> usingUnspentOutputs = new List <UnspentOutput>(); BigInteger unspentOutputTotalAmount = BigInteger.Zero; for (int i = 0; i < unspentOutputs.Count; i++) { if (unspentOutputTotalAmount < totalRequiredAmount && i >= MAX_UNSPENTOUTPUTS_COUNT) { throw new InvalidOperationException($"Could not find up to {MAX_UNSPENTOUTPUTS_COUNT} BTC unspent outputs that can cover the amount and fee."); } if (unspentOutputTotalAmount >= totalRequiredAmount) { break; } usingUnspentOutputs.Add(unspentOutputs[i]); Money sumAmount = Money.Parse(unspentOutputs[i].Amount); unspentOutputTotalAmount += new BigInteger(sumAmount.Satoshi); } List <Coin> coins = new List <Coin>(); for (int i = 0; i < usingUnspentOutputs.Count; i++) { coins.Add(new Coin( fromTxHash: new uint256(usingUnspentOutputs[i].TxHash), fromOutputIndex: (uint)usingUnspentOutputs[i].Index, amount: usingUnspentOutputs[i].Amount, scriptPubKey: Script.FromHex(sourceAddress.ScriptPubKey.ToHex()) )); } TransactionBuilder builder = mEnv.Network.CreateTransactionBuilder(); NBitcoin.Transaction reserveTxSignature = builder .AddKeys(secret) .AddCoins(coins) .Send(reserveAddress, reserveAmount) .SetChange(sourceAddress) .SendFees(fee) .BuildTransaction(true); IEnumerable <Coin> reserveTxCoins = reserveTxSignature.Outputs.AsCoins(); Coin reserveTxCoin = reserveTxCoins.First( c => c.TxOut.ScriptPubKey.GetDestinationAddress(mEnv.Network) == reserveAddress); Script reservedFundsRedeemScriptValue = new Script(reservedFundsRedeemScript); ScriptCoin reservedCoin = new ScriptCoin(reserveTxCoin, reservedFundsRedeemScriptValue); builder = mEnv.Network.CreateTransactionBuilder(); PSBT executePsbt = builder .AddKeys(secret) .AddCoins(reservedCoin) .Send(targetAddress, amount) .SendFees(feeValue) .SetChange(reserveAddress) .BuildPSBT(true); builder = mEnv.Network.CreateTransactionBuilder(); PSBT reclaimPsbt = builder .AddKeys(secret) .AddCoins(reservedCoin) .Send(sourceAddress, amount) .SendFees(feeValue) .SetChange(reserveAddress) .BuildPSBT(true); BtcTxnSignature bTCTxnSignature = new BtcTxnSignature() { ReserveTxnSignature = reserveTxSignature.ToHex(), ExecuteTxnSignature = executePsbt.ToHex(), ReclaimTxnSignature = reclaimPsbt.ToHex() }; return(bTCTxnSignature); }