Refactor WasabiClient
MODIFY
WalletWasabi.Backend/Controllers/BlockchainController.cs
WalletWasabi.Backend/Controllers/BlockchainController.cs
@@ -65,6 +65,10 @@ namespace WalletWasabi.Backend.Controllers
continue;
confirmationTargetsInts.Add(target);
}
+ else
+ {
+ return BadRequest($"Invalid {nameof(confirmationTargets)} are specified.");
+ }
}
var feeEstimations = new SortedDictionary<int, FeeEstimationPair>();

MODIFY
WalletWasabi.Tests/P2pTests.cs
WalletWasabi.Tests/P2pTests.cs
@@ -90,7 +90,6 @@ namespace WalletWasabi.Tests
});
KeyManager keyManager = KeyManager.CreateNew(out _, "password");
- WasabiClient wasabiClient = new WasabiClient(new Uri("http://localhost:1337"));
WalletService walletService = new WalletService(
keyManager,
new IndexDownloader(network, Path.Combine(SharedFixture.DataDir, nameof(TestServicesAsync), "IndexDownloader.txt"), new Uri("http://localhost:12345")),

MODIFY
WalletWasabi.Tests/RegTests.cs
WalletWasabi.Tests/RegTests.cs
@@ -720,7 +720,7 @@ namespace WalletWasabi.Tests
}
var scp = new Key().ScriptPubKey;
- var res2 = await wallet.BuildTransactionAsync(password, new[] { new WalletService.Operation(scp, Money.Coins(0.05m), "foo") }, 5, new Uri(RegTestFixture.BackendEndPoint), false);
+ var res2 = await wallet.BuildTransactionAsync(password, new[] { new WalletService.Operation(scp, Money.Coins(0.05m), "foo") }, 5, false);
Assert.NotNull(res2.Transaction);
Assert.Single(res2.OuterWalletOutputs);
@@ -733,7 +733,7 @@ namespace WalletWasabi.Tests
Assert.Equal(Money.Coins(1m), res2.SpentCoins.Single().Amount);
Assert.False(res2.SpendsUnconfirmed);
- await wallet.SendTransactionAsync(res2.Transaction, new Uri(RegTestFixture.BackendEndPoint));
+ await wallet.SendTransactionAsync(res2.Transaction);
Assert.Contains(res2.InnerWalletOutputs.Single(), wallet.Coins);
@@ -741,7 +741,7 @@ namespace WalletWasabi.Tests
Script receive = wallet.GetReceiveKey("Basic").GetP2wpkhScript();
Money amountToSend = wallet.Coins.Where(x => !x.SpentOrLocked).Sum(x => x.Amount) / 2;
- var res = await wallet.BuildTransactionAsync(password, new[] { new WalletService.Operation(receive, amountToSend, "foo") }, 1008, new Uri(RegTestFixture.BackendEndPoint), allowUnconfirmed: true);
+ var res = await wallet.BuildTransactionAsync(password, new[] { new WalletService.Operation(receive, amountToSend, "foo") }, 1008, allowUnconfirmed: true);
Assert.Equal(2, res.InnerWalletOutputs.Count());
Assert.Empty(res.OuterWalletOutputs);
@@ -773,7 +773,7 @@ namespace WalletWasabi.Tests
}
Assert.True(foundReceive);
- await wallet.SendTransactionAsync(res.Transaction, new Uri(RegTestFixture.BackendEndPoint));
+ await wallet.SendTransactionAsync(res.Transaction);
#endregion Basic
@@ -781,7 +781,7 @@ namespace WalletWasabi.Tests
receive = wallet.GetReceiveKey("SubtractFeeFromAmount").GetP2wpkhScript();
amountToSend = wallet.Coins.Where(x => !x.SpentOrLocked).Sum(x => x.Amount) / 2;
- res = await wallet.BuildTransactionAsync(password, new[] { new WalletService.Operation(receive, amountToSend, "foo") }, 1008, new Uri(RegTestFixture.BackendEndPoint), allowUnconfirmed: true, subtractFeeFromAmountIndex: 0);
+ res = await wallet.BuildTransactionAsync(password, new[] { new WalletService.Operation(receive, amountToSend, "foo") }, 1008, allowUnconfirmed: true, subtractFeeFromAmountIndex: 0);
Assert.Equal(2, res.InnerWalletOutputs.Count());
Assert.Empty(res.OuterWalletOutputs);
@@ -814,7 +814,7 @@ namespace WalletWasabi.Tests
#region LowFee
- res = await wallet.BuildTransactionAsync(password, new[] { new WalletService.Operation(receive, amountToSend, "foo") }, 1008, new Uri(RegTestFixture.BackendEndPoint), allowUnconfirmed: true);
+ res = await wallet.BuildTransactionAsync(password, new[] { new WalletService.Operation(receive, amountToSend, "foo") }, 1008, allowUnconfirmed: true);
Assert.Equal(2, res.InnerWalletOutputs.Count());
Assert.Empty(res.OuterWalletOutputs);
@@ -847,7 +847,7 @@ namespace WalletWasabi.Tests
#region MediumFee
- res = await wallet.BuildTransactionAsync(password, new[] { new WalletService.Operation(receive, amountToSend, "foo") }, 144, new Uri(RegTestFixture.BackendEndPoint), allowUnconfirmed: true);
+ res = await wallet.BuildTransactionAsync(password, new[] { new WalletService.Operation(receive, amountToSend, "foo") }, 144, allowUnconfirmed: true);
Assert.Equal(2, res.InnerWalletOutputs.Count());
Assert.Empty(res.OuterWalletOutputs);
@@ -880,7 +880,7 @@ namespace WalletWasabi.Tests
#region HighFee
- res = await wallet.BuildTransactionAsync(password, new[] { new WalletService.Operation(receive, amountToSend, "foo") }, 2, new Uri(RegTestFixture.BackendEndPoint), allowUnconfirmed: true);
+ res = await wallet.BuildTransactionAsync(password, new[] { new WalletService.Operation(receive, amountToSend, "foo") }, 2, allowUnconfirmed: true);
Assert.Equal(2, res.InnerWalletOutputs.Count());
Assert.Empty(res.OuterWalletOutputs);
@@ -912,14 +912,14 @@ namespace WalletWasabi.Tests
Assert.InRange(res.Fee, Money.Zero, res.Fee);
Assert.InRange(res.Fee, res.Fee, res.Fee);
- await wallet.SendTransactionAsync(res.Transaction, new Uri(RegTestFixture.BackendEndPoint));
+ await wallet.SendTransactionAsync(res.Transaction);
#endregion HighFee
#region MaxAmount
receive = wallet.GetReceiveKey("MaxAmount").GetP2wpkhScript();
- res = await wallet.BuildTransactionAsync(password, new[] { new WalletService.Operation(receive, Money.Zero, "foo") }, 1008, new Uri(RegTestFixture.BackendEndPoint), allowUnconfirmed: true);
+ res = await wallet.BuildTransactionAsync(password, new[] { new WalletService.Operation(receive, Money.Zero, "foo") }, 1008, allowUnconfirmed: true);
Assert.Single(res.InnerWalletOutputs);
Assert.Empty(res.OuterWalletOutputs);
@@ -938,7 +938,7 @@ namespace WalletWasabi.Tests
Assert.Equal(receive, maxBuiltTxOutput.ScriptPubKey);
Assert.Equal(wallet.Coins.Where(x => !x.SpentOrLocked).Sum(x => x.Amount) - res.Fee, maxBuiltTxOutput.Value);
- await wallet.SendTransactionAsync(res.Transaction, new Uri(RegTestFixture.BackendEndPoint));
+ await wallet.SendTransactionAsync(res.Transaction);
#endregion MaxAmount
@@ -948,7 +948,6 @@ namespace WalletWasabi.Tests
var inputCountBefore = res.SpentCoins.Count();
res = await wallet.BuildTransactionAsync(password, new[] { new WalletService.Operation(receive, Money.Zero, "foo") }, 1008,
- new Uri(RegTestFixture.BackendEndPoint),
allowUnconfirmed: true,
allowedInputs: wallet.Coins.Where(x => !x.SpentOrLocked).Select(x => new TxoRef(x.TransactionId, x.Index)).Take(1));
@@ -969,7 +968,6 @@ namespace WalletWasabi.Tests
Assert.Single(res.Transaction.Transaction.Outputs);
res = await wallet.BuildTransactionAsync(password, new[] { new WalletService.Operation(receive, Money.Zero, "foo") }, 1008,
- new Uri(RegTestFixture.BackendEndPoint),
allowUnconfirmed: true,
allowedInputs: new[] { res.SpentCoins.Select(x => new TxoRef(x.TransactionId, x.Index)).First() });
@@ -986,7 +984,6 @@ namespace WalletWasabi.Tests
#region Labeling
res = await wallet.BuildTransactionAsync(password, new[] { new WalletService.Operation(receive, Money.Zero, "my label") }, 1008,
- new Uri(RegTestFixture.BackendEndPoint),
allowUnconfirmed: true);
Assert.Single(res.InnerWalletOutputs);
@@ -997,14 +994,13 @@ namespace WalletWasabi.Tests
new WalletService.Operation(new Key().ScriptPubKey, amountToSend, "outgoing"),
new WalletService.Operation(new Key().ScriptPubKey, amountToSend, "outgoing2")
}, 1008,
- new Uri(RegTestFixture.BackendEndPoint),
allowUnconfirmed: true);
Assert.Single(res.InnerWalletOutputs);
Assert.Equal(2, res.OuterWalletOutputs.Count());
Assert.Equal("change of (outgoing, outgoing2)", res.InnerWalletOutputs.Single().Label);
- await wallet.SendTransactionAsync(res.Transaction, new Uri(RegTestFixture.BackendEndPoint));
+ await wallet.SendTransactionAsync(res.Transaction);
Assert.Contains("change of (outgoing, outgoing2)", wallet.Coins.Where(x => x.Height == Height.MemPool).Select(x => x.Label));
Assert.Contains("change of (outgoing, outgoing2)", keyManager.GetKeys().Select(x => x.Label));
@@ -1031,7 +1027,7 @@ namespace WalletWasabi.Tests
// covers:
// disallow unconfirmed with allowed inputs
// feeTarget < 2 // NOTE: need to correct alowing 0 and 1
- res = await wallet.BuildTransactionAsync(password, toSend, 0, new Uri(RegTestFixture.BackendEndPoint), false, allowedInputs: allowedInputs);
+ res = await wallet.BuildTransactionAsync(password, toSend, 0, false, allowedInputs: allowedInputs);
activeOutput = res.InnerWalletOutputs.Single(x => x.ScriptPubKey == receive);
Assert.Single(res.InnerWalletOutputs);
@@ -1061,7 +1057,7 @@ namespace WalletWasabi.Tests
// covers:
// customchange
// feePc > 1
- res = await wallet.BuildTransactionAsync(password, new[] { new WalletService.Operation(new Key().ScriptPubKey, new Money(100, MoneyUnit.MilliBTC), "outgoing") }, 1008, new Uri(RegTestFixture.BackendEndPoint), customChange: new Key().ScriptPubKey);
+ res = await wallet.BuildTransactionAsync(password, new[] { new WalletService.Operation(new Key().ScriptPubKey, new Money(100, MoneyUnit.MilliBTC), "outgoing") }, 1008, customChange: new Key().ScriptPubKey);
Assert.True(res.FeePercentOfSent > 1);
@@ -1138,52 +1134,52 @@ namespace WalletWasabi.Tests
Logger.TurnOff();
// toSend cannot be null
- await Assert.ThrowsAsync<ArgumentNullException>(async () => await wallet.BuildTransactionAsync(null, null, 0, new Uri(RegTestFixture.BackendEndPoint)));
+ await Assert.ThrowsAsync<ArgumentNullException>(async () => await wallet.BuildTransactionAsync(null, null, 0));
// toSend cannot have a null element
- await Assert.ThrowsAsync<ArgumentNullException>(async () => await wallet.BuildTransactionAsync(null, new[] { (WalletService.Operation)null }, 0, new Uri(RegTestFixture.BackendEndPoint)));
+ await Assert.ThrowsAsync<ArgumentNullException>(async () => await wallet.BuildTransactionAsync(null, new[] { (WalletService.Operation)null }, 0));
// toSend cannot have a zero elements
- await Assert.ThrowsAsync<ArgumentException>(async () => await wallet.BuildTransactionAsync(null, new WalletService.Operation[0], 0, new Uri(RegTestFixture.BackendEndPoint)));
+ await Assert.ThrowsAsync<ArgumentException>(async () => await wallet.BuildTransactionAsync(null, new WalletService.Operation[0], 0));
// feeTarget has to be in the range 0 to 1008
- await Assert.ThrowsAsync<ArgumentOutOfRangeException>(async () => await wallet.BuildTransactionAsync(null, validOperationList, -10, new Uri(RegTestFixture.BackendEndPoint)));
- await Assert.ThrowsAsync<ArgumentOutOfRangeException>(async () => await wallet.BuildTransactionAsync(null, validOperationList, 2000, new Uri(RegTestFixture.BackendEndPoint)));
+ await Assert.ThrowsAsync<ArgumentOutOfRangeException>(async () => await wallet.BuildTransactionAsync(null, validOperationList, -10));
+ await Assert.ThrowsAsync<ArgumentOutOfRangeException>(async () => await wallet.BuildTransactionAsync(null, validOperationList, 2000));
// subtractFeeFromAmountIndex has to be valid
- await Assert.ThrowsAsync<ArgumentOutOfRangeException>(async () => await wallet.BuildTransactionAsync(null, validOperationList, 2, new Uri(RegTestFixture.BackendEndPoint), false, -10));
- await Assert.ThrowsAsync<ArgumentOutOfRangeException>(async () => await wallet.BuildTransactionAsync(null, validOperationList, 2, new Uri(RegTestFixture.BackendEndPoint), false, 1));
+ await Assert.ThrowsAsync<ArgumentOutOfRangeException>(async () => await wallet.BuildTransactionAsync(null, validOperationList, 2, false, -10));
+ await Assert.ThrowsAsync<ArgumentOutOfRangeException>(async () => await wallet.BuildTransactionAsync(null, validOperationList, 2, false, 1));
// toSend amount sum has to be in range 0 to 2099999997690000
- await Assert.ThrowsAsync<ArgumentOutOfRangeException>(async () => await wallet.BuildTransactionAsync(null, invalidOperationList, 2, new Uri(RegTestFixture.BackendEndPoint)));
+ await Assert.ThrowsAsync<ArgumentOutOfRangeException>(async () => await wallet.BuildTransactionAsync(null, invalidOperationList, 2));
// toSend negative sum amount
var operations = new[]{
new WalletService.Operation(scp, -10000, "") };
- await Assert.ThrowsAsync<ArgumentException>(async () => await wallet.BuildTransactionAsync(null, operations, 2, new Uri(RegTestFixture.BackendEndPoint)));
+ await Assert.ThrowsAsync<ArgumentException>(async () => await wallet.BuildTransactionAsync(null, operations, 2));
// toSend negative operation amount
operations = new[]{
new WalletService.Operation(scp, 20000, ""),
new WalletService.Operation(scp, -10000, "") };
- await Assert.ThrowsAsync<ArgumentException>(async () => await wallet.BuildTransactionAsync(null, operations, 2, new Uri(RegTestFixture.BackendEndPoint)));
+ await Assert.ThrowsAsync<ArgumentException>(async () => await wallet.BuildTransactionAsync(null, operations, 2));
// toSend ammount sum has to be less than ulong.MaxValue
- await Assert.ThrowsAsync<OverflowException>(async () => await wallet.BuildTransactionAsync(null, overflowOperationList, 2, new Uri(RegTestFixture.BackendEndPoint)));
+ await Assert.ThrowsAsync<OverflowException>(async () => await wallet.BuildTransactionAsync(null, overflowOperationList, 2));
// allowedInputs cannot be empty
- await Assert.ThrowsAsync<ArgumentException>(async () => await wallet.BuildTransactionAsync(null, validOperationList, 2, new Uri(RegTestFixture.BackendEndPoint), false, null, null, new TxoRef[0]));
+ await Assert.ThrowsAsync<ArgumentException>(async () => await wallet.BuildTransactionAsync(null, validOperationList, 2, false, null, null, new TxoRef[0]));
// "Only one element can contain Money.Zero
var toSendWithTwoZeros = new[]{
new WalletService.Operation(scp, Money.Zero, "zero"),
new WalletService.Operation(scp, Money.Zero, "zero") };
- await Assert.ThrowsAsync<ArgumentException>(async () => await wallet.BuildTransactionAsync(password, toSendWithTwoZeros, 1008, new Uri(RegTestFixture.BackendEndPoint), false));
+ await Assert.ThrowsAsync<ArgumentException>(async () => await wallet.BuildTransactionAsync(password, toSendWithTwoZeros, 1008, false));
// cannot specify spend all and custom change
var spendAll = new[]{
new WalletService.Operation(scp, Money.Zero, "spendAll") };
- await Assert.ThrowsAsync<ArgumentException>(async () => await wallet.BuildTransactionAsync(password, spendAll, 1008, new Uri(RegTestFixture.BackendEndPoint), false, customChange: new Key().ScriptPubKey));
+ await Assert.ThrowsAsync<ArgumentException>(async () => await wallet.BuildTransactionAsync(password, spendAll, 1008, false, customChange: new Key().ScriptPubKey));
// Get some money, make it confirm.
var key = wallet.GetReceiveKey("foo label");
@@ -1212,24 +1208,24 @@ namespace WalletWasabi.Tests
operations = new[]{
new WalletService.Operation(scp, Money.Satoshis(1m), ""),
new WalletService.Operation(scp, Money.Coins(0.5m), "") };
- await Assert.ThrowsAsync<InsufficientBalanceException>(async () => await wallet.BuildTransactionAsync(password, operations, 2, new Uri(RegTestFixture.BackendEndPoint), false, 0));
+ await Assert.ThrowsAsync<InsufficientBalanceException>(async () => await wallet.BuildTransactionAsync(password, operations, 2, false, 0));
// No enough money (only one confirmed coin, no unconfirmed allowed)
operations = new[] { new WalletService.Operation(scp, Money.Coins(1.5m), "") };
- await Assert.ThrowsAsync<InsufficientBalanceException>(async () => await wallet.BuildTransactionAsync(null, operations, 2, new Uri(RegTestFixture.BackendEndPoint)));
+ await Assert.ThrowsAsync<InsufficientBalanceException>(async () => await wallet.BuildTransactionAsync(null, operations, 2));
// No enough money (only one confirmed coin, unconfirmed allowed)
- await Assert.ThrowsAsync<InsufficientBalanceException>(async () => await wallet.BuildTransactionAsync(null, operations, 2, new Uri(RegTestFixture.BackendEndPoint), true));
+ await Assert.ThrowsAsync<InsufficientBalanceException>(async () => await wallet.BuildTransactionAsync(null, operations, 2, true));
// Add new money with no confirmation
var txid2 = await rpc.SendToAddressAsync(key.GetP2wpkhAddress(network), Money.Coins(1m));
await Task.Delay(1000); // Wait tx to arrive and get processed.
// Enough money (one confirmed coin and one unconfirmed coin, unconfirmed are NOT allowed)
- await Assert.ThrowsAsync<InsufficientBalanceException>(async () => await wallet.BuildTransactionAsync(null, operations, 2, new Uri(RegTestFixture.BackendEndPoint), false));
+ await Assert.ThrowsAsync<InsufficientBalanceException>(async () => await wallet.BuildTransactionAsync(null, operations, 2, false));
// Enough money (one confirmed coin and one unconfirmed coin, unconfirmed are allowed)
- var btx = await wallet.BuildTransactionAsync(password, operations, 2, new Uri(RegTestFixture.BackendEndPoint), true);
+ var btx = await wallet.BuildTransactionAsync(password, operations, 2, true);
Assert.Equal(2, btx.SpentCoins.Count());
Assert.Equal(1, btx.SpentCoins.Count(c => c.Confirmed));
Assert.Equal(1, btx.SpentCoins.Count(c => !c.Confirmed));
@@ -1238,17 +1234,17 @@ namespace WalletWasabi.Tests
operations = new[]{
new WalletService.Operation(scp, Money.Zero, ""),
new WalletService.Operation(scp, Money.Zero, "") };
- await Assert.ThrowsAsync<ArgumentException>(async () => await wallet.BuildTransactionAsync(null, operations, 2, new Uri(RegTestFixture.BackendEndPoint)));
+ await Assert.ThrowsAsync<ArgumentException>(async () => await wallet.BuildTransactionAsync(null, operations, 2));
// `Custom change` and `spend all` cannot be specified at the same time
- await Assert.ThrowsAsync<ArgumentException>(async () => await wallet.BuildTransactionAsync(null, operations, 2, new Uri(RegTestFixture.BackendEndPoint), false, null, Script.Empty));
+ await Assert.ThrowsAsync<ArgumentException>(async () => await wallet.BuildTransactionAsync(null, operations, 2, false, null, Script.Empty));
Logger.TurnOn();
operations = new[] { new WalletService.Operation(scp, Money.Coins(0.5m), "") };
- btx = await wallet.BuildTransactionAsync(password, operations, 2, new Uri(RegTestFixture.BackendEndPoint));
+ btx = await wallet.BuildTransactionAsync(password, operations, 2);
operations = new[] { new WalletService.Operation(scp, Money.Coins(0.00005m), "") };
- btx = await wallet.BuildTransactionAsync(password, operations, 2, new Uri(RegTestFixture.BackendEndPoint), false, 0);
+ btx = await wallet.BuildTransactionAsync(password, operations, 2, false, 0);
Assert.True(btx.FeePercentOfSent > 20);
Assert.Single(btx.SpentCoins);
Assert.Equal(txid, btx.SpentCoins.First().TransactionId);
@@ -1340,13 +1336,13 @@ namespace WalletWasabi.Tests
// Send money before reorg.
var operations = new[]{
new WalletService.Operation(scp, Money.Coins(0.011m), "") };
- var btx1 = await wallet.BuildTransactionAsync(password, operations, 2, new Uri(RegTestFixture.BackendEndPoint));
- await wallet.SendTransactionAsync(btx1.Transaction, new Uri(RegTestFixture.BackendEndPoint));
+ var btx1 = await wallet.BuildTransactionAsync(password, operations, 2);
+ await wallet.SendTransactionAsync(btx1.Transaction);
operations = new[]{
new WalletService.Operation(scp, Money.Coins(0.012m), "") };
- var btx2 = await wallet.BuildTransactionAsync(password, operations, 2, new Uri(RegTestFixture.BackendEndPoint), allowUnconfirmed: true);
- await wallet.SendTransactionAsync(btx2.Transaction, new Uri(RegTestFixture.BackendEndPoint));
+ var btx2 = await wallet.BuildTransactionAsync(password, operations, 2, allowUnconfirmed: true);
+ await wallet.SendTransactionAsync(btx2.Transaction);
// Test synchronization after fork.
// Invalidate the blocks containing the funding transaction
@@ -1365,13 +1361,13 @@ namespace WalletWasabi.Tests
// are reintroduced when we generate a new block though the rpc call
operations = new[]{
new WalletService.Operation(scp, Money.Coins(0.013m), "") };
- var btx3 = await wallet.BuildTransactionAsync(password, operations, 2, new Uri(RegTestFixture.BackendEndPoint));
- await wallet.SendTransactionAsync(btx3.Transaction, new Uri(RegTestFixture.BackendEndPoint));
+ var btx3 = await wallet.BuildTransactionAsync(password, operations, 2);
+ await wallet.SendTransactionAsync(btx3.Transaction);
operations = new[]{
new WalletService.Operation(scp, Money.Coins(0.014m), "") };
- var btx4 = await wallet.BuildTransactionAsync(password, operations, 2, new Uri(RegTestFixture.BackendEndPoint), allowUnconfirmed: true);
- await wallet.SendTransactionAsync(btx4.Transaction, new Uri(RegTestFixture.BackendEndPoint));
+ var btx4 = await wallet.BuildTransactionAsync(password, operations, 2, allowUnconfirmed: true);
+ await wallet.SendTransactionAsync(btx4.Transaction);
// Test synchronization after fork with different transactions.
// Create a fork that invalidates the blocks containing the funding transaction
@@ -1517,13 +1513,13 @@ namespace WalletWasabi.Tests
new WalletService.Operation(new Key().ScriptPubKey, Money.Coins(0.01m), ""),
new WalletService.Operation(new Key().ScriptPubKey, Money.Coins(0.01m), "")
};
- var tx1Res = await wallet.BuildTransactionAsync(password, operations, 2, new Uri(RegTestFixture.BackendEndPoint), allowUnconfirmed: true);
+ var tx1Res = await wallet.BuildTransactionAsync(password, operations, 2, allowUnconfirmed: true);
Assert.Equal(2, tx1Res.OuterWalletOutputs.Single(x => x.ScriptPubKey == key.GetP2wpkhScript()).Mixin);
// Spend the unconfirmed coin (send it to ourself)
operations = new[] { new WalletService.Operation(key.PubKey.WitHash.ScriptPubKey, Money.Coins(0.5m), "") };
- tx1Res = await wallet.BuildTransactionAsync(password, operations, 2, new Uri(RegTestFixture.BackendEndPoint), allowUnconfirmed: true);
- await wallet.SendTransactionAsync(tx1Res.Transaction, new Uri(RegTestFixture.BackendEndPoint));
+ tx1Res = await wallet.BuildTransactionAsync(password, operations, 2, allowUnconfirmed: true);
+ await wallet.SendTransactionAsync(tx1Res.Transaction);
while (wallet.Coins.Count != 3)
await Task.Delay(500); // Waits for the funding transaction get to the mempool.
@@ -1542,8 +1538,8 @@ namespace WalletWasabi.Tests
// Spend the unconfirmed and unspent coin (send it to ourself)
operations = new[] { new WalletService.Operation(key.PubKey.WitHash.ScriptPubKey, Money.Coins(0.5m), "") };
- var tx2Res = await wallet.BuildTransactionAsync(password, operations, 2, new Uri(RegTestFixture.BackendEndPoint), allowUnconfirmed: true, subtractFeeFromAmountIndex: 0);
- await wallet.SendTransactionAsync(tx2Res.Transaction, new Uri(RegTestFixture.BackendEndPoint));
+ var tx2Res = await wallet.BuildTransactionAsync(password, operations, 2, allowUnconfirmed: true, subtractFeeFromAmountIndex: 0);
+ await wallet.SendTransactionAsync(tx2Res.Transaction);
while (wallet.Coins.Count != 4)
await Task.Delay(500); // Waits for the transaction get to the mempool.

MODIFY
WalletWasabi/Services/WalletService.cs
WalletWasabi/Services/WalletService.cs
@@ -534,9 +534,9 @@ namespace WalletWasabi.Services
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentOutOfRangeException"></exception>
- public async Task<BuildTransactionResult> BuildTransactionAsync(string password, Operation[] toSend, int feeTarget, Uri baseUri, bool allowUnconfirmed = false,
+ public async Task<BuildTransactionResult> BuildTransactionAsync(string password, Operation[] toSend, int feeTarget, bool allowUnconfirmed = false,
int? subtractFeeFromAmountIndex = null, Script customChange = null,
- IEnumerable<TxoRef> allowedInputs = null, IPEndPoint torSocks5EndPoint = null)
+ IEnumerable<TxoRef> allowedInputs = null)
{
password = password ?? ""; // Correction.
toSend = Guard.NotNullOrEmpty(nameof(toSend), toSend);
@@ -613,10 +613,13 @@ namespace WalletWasabi.Services
// 4. Get and calculate fee
Logger.LogInfo<WalletService>("Calculating dynamic transaction fee...");
- WasabiClient wasabiClient = new WasabiClient(baseUri, torSocks5EndPoint);
- var fees = await wasabiClient.GetFeesAsync(feeTarget, baseUri, torSocks5EndPoint);
- Money feePerBytes = new Money(fees.Single().Value.Conservative);
+ Money feePerBytes = null;
+ using (var client = new WasabiClient(IndexDownloader.Client.DestinationUri, IndexDownloader.Client.TorSocks5EndPoint))
+ {
+ var fees = await client.GetFeesAsync(feeTarget);
+ feePerBytes = new Money(fees.Single().Value.Conservative);
+ }
bool spendAll = spendAllCount == 1;
int inNum;
@@ -824,10 +827,12 @@ namespace WalletWasabi.Services
}
}
- public async Task SendTransactionAsync(SmartTransaction transaction, Uri baseUri, IPEndPoint torSocks5EndPoint = null)
+ public async Task SendTransactionAsync(SmartTransaction transaction)
{
- WasabiClient wasabiClient = new WasabiClient(baseUri, torSocks5EndPoint);
- await wasabiClient.BroadcastTransactionAsync(transaction, baseUri, torSocks5EndPoint);
+ using (var client = new WasabiClient(IndexDownloader.Client.DestinationUri, IndexDownloader.Client.TorSocks5EndPoint))
+ {
+ await client.BroadcastAsync(transaction);
+ }
ProcessTransaction(new SmartTransaction(transaction.Transaction, Height.MemPool));

MODIFY
WalletWasabi/WebClients/ChaumianCoinJoin/AliceClient.cs
WalletWasabi/WebClients/ChaumianCoinJoin/AliceClient.cs
@@ -22,6 +22,7 @@ namespace WalletWasabi.WebClients.ChaumianCoinJoin
public long RoundId { get; private set; }
public Guid UniqueId { get; private set; }
public byte[] BlindedOutputSignature { get; private set; }
+
/// <inheritdoc/>
private AliceClient(Uri baseUri, IPEndPoint torSocks5EndPoint = null) : base(baseUri, torSocks5EndPoint)
{

MODIFY
WalletWasabi/WebClients/ChaumianCoinJoin/WasabiClient.cs
WalletWasabi/WebClients/ChaumianCoinJoin/WasabiClient.cs
@@ -21,39 +21,49 @@ namespace WalletWasabi.WebClients.ChaumianCoinJoin
{
}
- public async Task<IDictionary<int, FeeEstimationPair>> GetFeesAsync(int feeTarget, Uri baseUri, IPEndPoint torSocks5EndPoint = null)
+ public async Task<IDictionary<int, FeeEstimationPair>> GetFeesAsync(params int[] confirmationTargets)
{
- WasabiClient client = new WasabiClient(baseUri, torSocks5EndPoint);
+ var confirmationTargetsString = string.Join(",", confirmationTargets);
- using (var response = await client.TorClient.SendAndRetryAsync(HttpMethod.Get, HttpStatusCode.OK, $"/api/v1/btc/blockchain/fees/{feeTarget}"))
+ using (var response = await TorClient.SendAndRetryAsync(HttpMethod.Get, HttpStatusCode.OK, $"/api/v1/btc/blockchain/fees/{confirmationTargetsString}"))
{
if (response.StatusCode != HttpStatusCode.OK)
- throw new HttpRequestException($"Couldn't query network fees. Reason: {response.StatusCode.ToReasonString()}");
+ {
+ string error = await response.Content.ReadAsJsonAsync<string>();
+ var errorMessage = error == null ? string.Empty : $"\n{error}";
+ throw new HttpRequestException($"{response.StatusCode.ToReasonString()}{errorMessage}");
+ }
- using (var content = response.Content)
+ using (HttpContent content = response.Content)
{
- var json = await content.ReadAsJsonAsync<SortedDictionary<int, FeeEstimationPair>>();
- return json;
+ var ret = await content.ReadAsJsonAsync<IDictionary<int, FeeEstimationPair>>();
+ return ret;
}
}
}
- public async Task BroadcastTransactionAsync(SmartTransaction transaction, Uri baseUri, IPEndPoint torSocks5EndPoint = null)
+ public async Task BroadcastAsync(string hex)
{
- WasabiClient client = new WasabiClient(baseUri, torSocks5EndPoint);
-
- using (var content = new StringContent($"'{transaction.Transaction.ToHex()}'", Encoding.UTF8, "application/json"))
- using (var response = await client.TorClient.SendAsync(HttpMethod.Post, "/api/v1/btc/blockchain/broadcast", content))
+ using (var content = new StringContent($"'{hex}'", Encoding.UTF8, "application/json"))
+ using (var response = await TorClient.SendAsync(HttpMethod.Post, "/api/v1/btc/blockchain/broadcast", content))
{
- if (response.StatusCode == HttpStatusCode.BadRequest)
+ if (response.StatusCode != HttpStatusCode.OK)
{
- throw new HttpRequestException($"Couldn't broadcast transaction. Reason: {await response.Content.ReadAsStringAsync()}");
+ string error = await response.Content.ReadAsJsonAsync<string>();
+ var errorMessage = error == null ? string.Empty : $"\n{error}";
+ throw new HttpRequestException($"{response.StatusCode.ToReasonString()}{errorMessage}");
}
- if (response.StatusCode != HttpStatusCode.OK) // Try again.
- {
- throw new HttpRequestException($"Couldn't broadcast transaction. Reason: {response.StatusCode.ToReasonString()}");
}
}
+
+ public async Task BroadcastAsync(Transaction transaction)
+ {
+ await BroadcastAsync(transaction.ToHex());
+ }
+
+ public async Task BroadcastAsync(SmartTransaction transaction)
+ {
+ await BroadcastAsync(transaction.Transaction);
}
}
}

Refactor WasabiClient