Implement inputs request for the client
MODIFY
HiddenWallet.ChaumianTumbler/Controllers/TumblerController.cs
HiddenWallet.ChaumianTumbler/Controllers/TumblerController.cs
@@ -31,10 +31,12 @@ namespace HiddenWallet.ChaumianTumbler.Controllers
{
try
{
+ Money denomination = Global.StateMachine.Denomination;
+ string denominationSting = denomination.ToString(fplus: false, trimExcessZero: true);
return new JsonResult(new StatusResponse
{
Phase = Global.StateMachine.Phase.ToString(),
- Denomination = Global.StateMachine.Denomination.ToString(fplus: false, trimExcessZero: true),
+ Denomination = denominationSting,
AnonymitySet = Global.StateMachine.AnonymitySet,
TimeSpentInInputRegistrationInSeconds = (int)Global.StateMachine.TimeSpentInInputRegistration.TotalSeconds,
MaximumInputsPerAlices = (int)Global.Config.MaximumInputsPerAlices,
@@ -52,7 +54,7 @@ namespace HiddenWallet.ChaumianTumbler.Controllers
private readonly AsyncLock InputRegistrationLock = new AsyncLock();
[Route("inputs")]
[HttpPost]
- public async Task<IActionResult> InputsAsync(InputsRequest request)
+ public async Task<IActionResult> InputsAsync([FromBody]InputsRequest request)
{
try
{
@@ -209,7 +211,7 @@ namespace HiddenWallet.ChaumianTumbler.Controllers
[Route("connection-confirmation")]
[HttpPost]
- public IActionResult ConnectionConfirmation(ConnectionConfirmationRequest request)
+ public IActionResult ConnectionConfirmation([FromBody]ConnectionConfirmationRequest request)
{
try
{
@@ -248,7 +250,7 @@ namespace HiddenWallet.ChaumianTumbler.Controllers
[Route("output")]
[HttpPost]
- public IActionResult Output(OutputRequest request)
+ public IActionResult Output([FromBody]OutputRequest request)
{
try
{
@@ -323,7 +325,7 @@ namespace HiddenWallet.ChaumianTumbler.Controllers
private readonly AsyncLock SignatureProvidedAsyncLock = new AsyncLock();
[Route("signature")]
[HttpPost]
- public async Task<IActionResult> SignatureAsync(SignatureRequest request)
+ public async Task<IActionResult> SignatureAsync([FromBody]SignatureRequest request)
{
try
{

MODIFY
HiddenWallet.ChaumianTumbler/TumblerStateMachine.cs
HiddenWallet.ChaumianTumbler/TumblerStateMachine.cs
@@ -207,7 +207,14 @@ namespace HiddenWallet.ChaumianTumbler
var exchangeRates = await SmartBitClient.GetExchangeRatesAsync(cancel);
decimal price = exchangeRates.Single(x => x.Code == "USD").Rate;
decimal denominationUSD = (decimal)Global.Config.DenominationUSD;
- decimal denominationBTC = Math.Round(denominationUSD / price, 2);
+
+ decimal denominationBTC = 0;
+ var i = 1;
+ while(denominationBTC == 0 && i <= 8)
+ {
+ denominationBTC = Math.Round(denominationUSD / price, i);
+ i++;
+ }
Denomination = new Money(denominationBTC, MoneyUnit.BTC);
}
catch

MODIFY
HiddenWallet.Daemon/Global.cs
HiddenWallet.Daemon/Global.cs
@@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
+using HiddenWallet.Crypto;
namespace HiddenWallet.Daemon
{
@@ -11,5 +12,6 @@ namespace HiddenWallet.Daemon
{
public static WalletWrapper WalletWrapper;
public static Config Config;
+ public static BlindingRsaPubKey RsaPubKey;
}
}

MODIFY
HiddenWallet.Daemon/Program.cs
HiddenWallet.Daemon/Program.cs
@@ -10,6 +10,9 @@ using Microsoft.DotNet.PlatformAbstractions;
using System.Runtime.InteropServices;
using NBitcoin;
using System.Threading;
+using System.Text;
+using HiddenWallet.Crypto;
+using Org.BouncyCastle.Math;
namespace HiddenWallet.Daemon
{
@@ -23,6 +26,30 @@ namespace HiddenWallet.Daemon
Global.Config = new Config();
await Global.Config.LoadOrCreateDefaultFileAsync(configFilePath, CancellationToken.None);
+ string rsaPath;
+ if (Global.Config.Network == Network.Main)
+ {
+ rsaPath = Path.Combine(FullSpvWallet.Global.DataDir, "RsaPubKeyTestNet.json");
+ }
+ else
+ {
+ rsaPath = Path.Combine(FullSpvWallet.Global.DataDir, "RsaPubKeyMain.json");
+ }
+ if (File.Exists(rsaPath))
+ {
+ string rsaPubKeyJson = await File.ReadAllTextAsync(rsaPath, Encoding.UTF8);
+ Global.RsaPubKey = BlindingRsaPubKey.CreateFromJson(rsaPubKeyJson);
+ }
+ else
+ {
+ // TODO: change these default values to the default testnet and mainnet server's keys
+ var modulus = new BigInteger("23589394558000769094389882515724018755668807942927294461300128316443908394269505275903255579660647420728395606511481595615274221757680896183302901501925850296754719819863284461202461933453035616403571429927625259423834885626633643917138260424572248721156753288868407467908326062046250434581856159002739075698923536178721479169980865352795356860391627279931218179034394535213633628061061525586225808965225547470074014895411041599390841768961511372955835648824597673786292957294962958948903155018531955318632198851755013447911244491178476628417300289292303120213670519763639881558155258131869186859524584048386096963449");
+ var exponent = new BigInteger("65537");
+ Global.RsaPubKey = new BlindingRsaPubKey(modulus, exponent);
+ await File.WriteAllTextAsync(rsaPath, Global.RsaPubKey.ToJson(), Encoding.UTF8);
+ Console.WriteLine($"Created RSA key at: {rsaPath}");
+ }
+
var endPoint = "http://localhost:37120/";
var alreadyRunning = false;
using (var client = new HttpClient())

MODIFY
HiddenWallet.Daemon/Wrappers/WalletWrapper.cs
HiddenWallet.Daemon/Wrappers/WalletWrapper.cs
@@ -103,11 +103,11 @@ namespace HiddenWallet.Daemon.Wrappers
if(Network == Network.Main)
{
- _walletJob.CoinJoinService.SetConnection(Global.Config.ChaumianTumblerMainAddress, Tor.SocksPortHandler, disposeHandler: false);
+ _walletJob.CoinJoinService.SetConnection(Global.Config.ChaumianTumblerMainAddress, Global.RsaPubKey, Tor.SocksPortHandler, disposeHandler: false);
}
else
{
- _walletJob.CoinJoinService.SetConnection(Global.Config.ChaumianTumblerTestNetAddress, Tor.SocksPortHandler, disposeHandler: false);
+ _walletJob.CoinJoinService.SetConnection(Global.Config.ChaumianTumblerTestNetAddress, Global.RsaPubKey, Tor.SocksPortHandler, disposeHandler: false);
}
await _walletJob.CoinJoinService.SubscribePhaseChangeAsync();
}
@@ -276,6 +276,9 @@ namespace HiddenWallet.Daemon.Wrappers
public async Task<BaseResponse> BuildTransactionAsync(string password, SafeAccount safeAccount, BitcoinAddress address, Money amount, FeeType feeType)
{
+ // todo: delete this code comment, it was just a test, if you see it, I forgot to delete it
+ // await _walletJob.CoinJoinService.TumbleAsync(AliceAccount, BobAccount, CancellationToken.None);
+
if (password != _password) throw new InvalidOperationException("Wrong password");
var result = await _walletJob.BuildTransactionAsync(address.ScriptPubKey, amount, feeType, safeAccount, (bool)Global.Config.CanSpendUnconfirmed);

MODIFY
HiddenWallet/ChaumianCoinJoin/ChaumianTumblerClient.cs
HiddenWallet/ChaumianCoinJoin/ChaumianTumblerClient.cs
@@ -63,6 +63,27 @@ namespace HiddenWallet.ChaumianCoinJoin
}
}
+ public async Task<InputsResponse> PostInputsAsync(InputsRequest request, CancellationToken cancel)
+ {
+ using (await _asyncLock.LockAsync())
+ {
+ string requestJsonString = JsonConvert.SerializeObject(request);
+ var content = new StringContent(
+ requestJsonString,
+ Encoding.UTF8,
+ "application/json");
+
+ HttpResponseMessage response =
+ await HttpClient.PostAsync("inputs", content, cancel);
+
+ if (!response.IsSuccessStatusCode) throw new HttpRequestException(response.StatusCode.ToString());
+ string responseString = await response.Content.ReadAsStringAsync();
+ AssertSuccess(responseString);
+
+ return JsonConvert.DeserializeObject<InputsResponse>(responseString);
+ }
+ }
+
public async Task<InputRegistrationStatusResponse> GetInputRegistrationStatusAsync(CancellationToken cancel)
{
using (await _asyncLock.LockAsync())

Implement inputs request for the client