public IBitcoinBasedTransaction CreateHtlcP2PkhSwapPaymentTx(BitcoinBasedCurrency currency) { var initTx = BitcoinBasedCommon.CreateFakeTx(currency, Common.Alice.PubKey, 1_0000_0000, 1_0000_0000); const int amount = 1_0000_0000; const int fee = 1_0000; //const int change = 9999_0000; var tx = currency.CreateHtlcP2PkhSwapPaymentTx( unspentOutputs: initTx.Outputs, aliceRefundAddress: Common.Alice.PubKey.GetAddress(currency), bobAddress: Common.Bob.PubKey.GetAddress(currency), lockTime: DateTimeOffset.UtcNow.AddHours(1), secretHash: Common.SecretHash, secretSize: Common.Secret.Length, amount: amount, fee: fee); Assert.NotNull(tx); Assert.True(tx.Check()); Assert.Equal(initTx.TotalOut - fee, tx.TotalOut); Assert.Equal(fee, tx.GetFee(initTx.Outputs)); return(tx); }
public async Task <IBitcoinBasedTransaction> CreateSwapPaymentTxAsync( BitcoinBasedCurrency currency, ClientSwap swap, IEnumerable <string> fromWallets, string refundAddress, string toAddress, DateTimeOffset lockTime, byte[] secretHash, int secretSize, ITxOutputSource outputsSource) { var availableOutputs = (await outputsSource .GetAvailableOutputsAsync(currency, fromWallets) .ConfigureAwait(false)) .ToList(); var fee = 0L; var orderAmount = (long)(AmountHelper.QtyToAmount(swap.Side, swap.Qty, swap.Price) * currency.DigitsMultiplier); var requiredAmount = orderAmount + fee; long usedAmount; IList <ITxOutput> usedOutputs; IBitcoinBasedTransaction tx; do { usedOutputs = availableOutputs .SelectOutputsForAmount(requiredAmount) .ToList(); usedAmount = usedOutputs.Sum(o => o.Value); if (usedAmount < requiredAmount) { throw new Exception($"Insufficient funds. Available {usedAmount}, required {requiredAmount}"); } var estimatedSigSize = EstimateSigSize(usedOutputs); tx = currency.CreateHtlcP2PkhSwapPaymentTx( unspentOutputs: usedOutputs, aliceRefundAddress: refundAddress, bobAddress: toAddress, lockTime: lockTime, secretHash: secretHash, secretSize: secretSize, amount: orderAmount, fee: fee); var txSize = tx.VirtualSize(); fee = (long)(currency.FeeRate * (txSize + estimatedSigSize)); requiredAmount = orderAmount + fee; } while (usedAmount < requiredAmount); tx = currency.CreateHtlcP2PkhSwapPaymentTx( unspentOutputs: usedOutputs, aliceRefundAddress: refundAddress, bobAddress: toAddress, lockTime: lockTime, secretHash: secretHash, secretSize: secretSize, amount: orderAmount, fee: fee); return(tx); }