public async Task <IBuildedTransaction> SendWithChange(TransactionBuilder builder, List <Coin> coins, IDestination destination, Money amount, IDestination changeDestination, bool includeFee) { if (amount.Satoshi <= 0) { throw new BusinessException("Amount can't be less or equal to zero", ErrorCode.BadInputParameter); } builder.AddCoins(coins) .Send(destination, amount) .SetChange(changeDestination); var calculatedFee = await _feeService.CalcFeeForTransaction(builder); if (calculatedFee >= amount) { throw new BusinessException( $"The sum of total applicable outputs is less than the required fee: {calculatedFee} satoshis.", ErrorCode.BalanceIsLessThanFee); } if (includeFee) { builder.SubtractFees(); amount = amount - calculatedFee; } builder.SendFees(calculatedFee); var tx = builder.BuildTransaction(false); return(BuildedTransaction.Create(tx, calculatedFee, amount)); }
public async Task <IBuildedTransaction> SendWithChange(TransactionBuilder builder, IList <Coin> coins, IDestination destination, Money balance, Money amount, IDestination changeDestination, bool includeFee) { if (amount.Satoshi <= 0) { throw new BusinessException("Amount can't be less or equal to zero", ErrorCode.BadInputParameter); } var change = balance - amount; var sentFees = Money.Zero; if (change < new TxOut(Money.Zero, changeDestination).GetDustThreshold(builder.StandardTransactionPolicy.MinRelayTxFee).Satoshi&& change > 0) { builder.SendFees(change); sentFees = change; } builder.AddCoins(coins) .Send(destination, amount) .SetChange(changeDestination); var calculatedFee = await _feeService.CalcFeeForTransaction(builder) - sentFees; var requiredBalance = amount + (includeFee ? Money.Zero : calculatedFee); if (balance < requiredBalance) { throw new BusinessException($"The sum of total applicable outputs is less than the required : {requiredBalance} satoshis.", ErrorCode.NotEnoughFundsAvailable); } if (includeFee) { if (calculatedFee > amount) { throw new BusinessException($"The sum of total applicable outputs is less than the required fee:{calculatedFee} satoshis.", ErrorCode.BalanceIsLessThanFee); } builder.SubtractFees(); amount = amount - calculatedFee; } if (calculatedFee > 0) { builder.SendFees(calculatedFee); } var tx = builder.BuildTransaction(false); var usedCoins = builder.FindSpentCoins(tx); return(BuildedTransaction.Create(tx, tx.GetFee(usedCoins), amount, usedCoins.OfType <Coin>())); }
public async Task <IBuildedTransaction> SendWithChange(TransactionBuilder builder, List <Coin> coins, IDestination destination, Money balance, Money amount, IDestination changeDestination, bool includeFee) { if (amount.Satoshi <= 0) { throw new BusinessException("Amount can't be less or equal to zero", ErrorCode.BadInputParameter); } builder.AddCoins(coins); var addressBalance = coins.Sum(o => o.Amount); var sentFees = Money.Zero; var change = addressBalance - amount; if (change < new TxOut(Money.Zero, destination).GetDustThreshold(builder.StandardTransactionPolicy.MinRelayTxFee).Satoshi) { builder.SendFees(change); sentFees = change; } builder.Send(destination, amount) .SetChange(changeDestination); var calculatedFee = await _feeService.CalcFeeForTransaction(builder) - sentFees; if (includeFee) { if (calculatedFee > amount) { throw new BusinessException($"The sum of total applicable outputs is less than the required fee:{calculatedFee} satoshis.", ErrorCode.BalanceIsLessThanFee); } builder.SubtractFees(); amount = amount - calculatedFee; } if (calculatedFee > 0) { builder.SendFees(calculatedFee); } var tx = builder.BuildTransaction(false); var usedCoins = tx.Inputs.Select(input => coins.First(o => o.Outpoint == input.PrevOut)).ToList(); return(BuildedTransaction.Create(tx, calculatedFee, amount, usedCoins)); }