diff --git a/Plugins/BTCPayServer.Plugins.AOPP/AOPPController.cs b/Plugins/BTCPayServer.Plugins.AOPP/AOPPController.cs deleted file mode 100644 index 0e034a9..0000000 --- a/Plugins/BTCPayServer.Plugins.AOPP/AOPPController.cs +++ /dev/null @@ -1,222 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Net.Http; -using System.Text; -using System.Threading.Tasks; -using System.Web; -using BTCPayServer.Abstractions.Constants; -using BTCPayServer.Abstractions.Contracts; -using BTCPayServer.Client; -using BTCPayServer.Client.Models; -using BTCPayServer.Common; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using NBitcoin; -using NBitcoin.Crypto; -using NBitcoin.Protocol; -using NBXplorer; -using Newtonsoft.Json; - -namespace BTCPayServer.Plugins.AOPP -{ - [Authorize(AuthenticationSchemes = AuthenticationSchemes.Cookie)] - [Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)] - [Route("plugins/{storeId}/AOPP")] - public class AOPPController : Controller - { - private readonly BTCPayServerClient _btcPayServerClient; - private readonly AOPPService _AOPPService; - - public AOPPController(BTCPayServerClient btcPayServerClient, AOPPService AOPPService) - { - _btcPayServerClient = btcPayServerClient; - _AOPPService = AOPPService; - } - - [HttpGet("")] - public async Task UpdateAOPPSettings(string storeId) - { - var store = await _btcPayServerClient.GetStore(storeId); - - UpdateAOPPSettingsViewModel vm = new UpdateAOPPSettingsViewModel(); - vm.StoreName = store.Name; - AOPPSettings AOPP = null; - try - { - AOPP = await _AOPPService.GetAOPPForStore(storeId); - } - catch (Exception) - { - // ignored - } - - SetExistingValues(AOPP, vm); - return View(vm); - } - - private void SetExistingValues(AOPPSettings existing, UpdateAOPPSettingsViewModel vm) - { - if (existing == null) - return; - vm.Enabled = existing.Enabled; - } - - [HttpPost("")] - public async Task UpdateAOPPSettings(string storeId, UpdateAOPPSettingsViewModel vm, - string command) - { - if (vm.Enabled) - { - if (!ModelState.IsValid) - { - return View(vm); - } - } - - var AOPPSettings = new AOPPSettings() - { - Enabled = vm.Enabled, - }; - - switch (command) - { - case "save": - await _AOPPService.SetAOPPForStore(storeId, AOPPSettings); - TempData["SuccessMessage"] = "AOPP settings modified"; - return RedirectToAction(nameof(UpdateAOPPSettings), new {storeId}); - - default: - return View(vm); - } - } - - - - internal static String BITCOIN_SIGNED_MESSAGE_HEADER = "Bitcoin Signed Message:\n"; - internal static byte[] BITCOIN_SIGNED_MESSAGE_HEADER_BYTES = Encoding.UTF8.GetBytes(BITCOIN_SIGNED_MESSAGE_HEADER); - - //http://bitcoinj.googlecode.com/git-history/keychain/core/src/main/java/com/google/bitcoin/core/Utils.java - private static byte[] FormatMessageForSigning(byte[] messageBytes) - { - MemoryStream ms = new MemoryStream(); - - ms.WriteByte((byte)BITCOIN_SIGNED_MESSAGE_HEADER_BYTES.Length); - ms.Write(BITCOIN_SIGNED_MESSAGE_HEADER_BYTES, 0, BITCOIN_SIGNED_MESSAGE_HEADER_BYTES.Length); - - VarInt size = new VarInt((ulong)messageBytes.Length); - ms.Write(size.ToBytes(), 0, size.ToBytes().Length); - ms.Write(messageBytes, 0, messageBytes.Length); - return ms.ToArray(); - } - - public class AoppRequest - { - public Uri aopp { get; set; } - } - - [HttpPost] - [Route("{invoiceId}")] - [AllowAnonymous] - public async Task AOPPExecute(string storeId, string invoiceId, - [FromBody] AoppRequest request , - [FromServices] IHttpClientFactory httpClientFactory, - [FromServices] BTCPayNetworkProvider btcPayNetworkProvider, - [FromServices] IExplorerClientProvider explorerClientProvider, - [FromServices] BTCPayServerClient btcPayServerClient, - [FromServices] IBTCPayServerClientFactory btcPayServerClientFactory) - { - try - { - var client = await btcPayServerClientFactory.Create(null, new[] {storeId}); - - var invoice = await client.GetInvoice(storeId, invoiceId); - if (invoice.Status is not InvoiceStatus.New) - { - return NotFound(); - } - - var qs = HttpUtility.ParseQueryString(request.aopp.Query); - var asset = qs.Get("asset"); - var network = btcPayNetworkProvider.GetNetwork(asset); - - - - var invoicePaymentMethods = await client.GetInvoicePaymentMethods(storeId, invoiceId); - - var pm = invoicePaymentMethods.FirstOrDefault(model => - model.PaymentMethod.Equals(asset, StringComparison.InvariantCultureIgnoreCase)); - if (pm is null) - { - return NotFound(); - } - var supported = (await client.GetStoreOnChainPaymentMethods(storeId)) - .FirstOrDefault(settings => settings.CryptoCode.Equals(asset, StringComparison.InvariantCultureIgnoreCase)); -; - var msg = qs.Get("msg"); - var format = qs.Get("format"); - var callback = new Uri(qs.Get("callback")!, UriKind.Absolute); - ScriptType? expectedType = null; - switch (format) - { - case "p2pkh": - expectedType = ScriptType.P2PKH; - break; - case "p2wpkh": - expectedType = ScriptType.P2WPKH; - break; - case "p2sh": - expectedType = ScriptType.P2SH; - break; - case "p2tr": - expectedType = ScriptType.Taproot; - break; - case "any": - break; - } - - var address = BitcoinAddress.Create(pm.Destination, network.NBitcoinNetwork); - if (expectedType is not null && !address.ScriptPubKey - .IsScriptType(expectedType.Value)) - { - return BadRequest(); - } - var derivatonScheme = - network.NBXplorerNetwork.DerivationStrategyFactory.Parse(supported.DerivationScheme); - var explorerClient = explorerClientProvider.GetExplorerClient(network); - var extKeyStr = await explorerClient.GetMetadataAsync( - derivatonScheme, - WellknownMetadataKeys.AccountHDKey); - if (extKeyStr == null) - { - return BadRequest(); - } - - var accountKey = ExtKey.Parse(extKeyStr, network.NBitcoinNetwork); - - var keyInfo = await explorerClient.GetKeyInformationAsync(derivatonScheme, address.ScriptPubKey); - var privateKey = accountKey.Derive(keyInfo.KeyPath).PrivateKey; - - var messageBytes = Encoding.UTF8.GetBytes(msg); - byte[] data = FormatMessageForSigning(messageBytes); - var hash = Hashes.DoubleSHA256(data); - var sig = Convert.ToBase64String(privateKey.SignCompact(hash, true).Signature); - - var response = new - { - version = 0, - address = pm.Destination, - signature = sig - }; - using var httpClient = httpClientFactory.CreateClient(); - await httpClient.PostAsync(callback, - new StringContent(JsonConvert.SerializeObject(response), Encoding.UTF8, "application/json")); - return Ok(); - } - catch (Exception e) - { - return BadRequest(new {ErrorMessage = e.Message}); - } - } - } -} diff --git a/Plugins/BTCPayServer.Plugins.AOPP/AOPPPlugin.cs b/Plugins/BTCPayServer.Plugins.AOPP/AOPPPlugin.cs deleted file mode 100644 index e31beae..0000000 --- a/Plugins/BTCPayServer.Plugins.AOPP/AOPPPlugin.cs +++ /dev/null @@ -1,34 +0,0 @@ -using BTCPayServer.Abstractions.Contracts; -using BTCPayServer.Abstractions.Models; -using BTCPayServer.Abstractions.Services; -using Microsoft.Extensions.DependencyInjection; - -namespace BTCPayServer.Plugins.AOPP -{ - public class AOPPPlugin : BaseBTCPayServerPlugin - { - public override IBTCPayServerPlugin.PluginDependency[] Dependencies { get; } = - { - new() { Identifier = nameof(BTCPayServer), Condition = ">=1.7.4" } - }; - public override void Execute(IServiceCollection applicationBuilder) - { - applicationBuilder.AddSingleton(); - applicationBuilder.AddSingleton(new UIExtension("AOPP/StoreIntegrationAOPPOption", - "store-integrations-list")); - applicationBuilder.AddSingleton(new UIExtension("AOPP/CheckoutContentExtension", - "checkout-bitcoin-post-content")); - applicationBuilder.AddSingleton(new UIExtension("AOPP/CheckoutContentExtension", - "checkout-lightning-post-content")); - applicationBuilder.AddSingleton(new UIExtension("AOPP/CheckoutTabExtension", - "checkout-bitcoin-post-tabs")); - applicationBuilder.AddSingleton(new UIExtension("AOPP/CheckoutTabExtension", - "checkout-lightning-post-tabs")); - applicationBuilder.AddSingleton(new UIExtension("AOPP/CheckoutEnd", - "checkout-end")); - applicationBuilder.AddSingleton(new UIExtension("AOPP/AOPPNav", - "store-integrations-nav")); - base.Execute(applicationBuilder); - } - } -} diff --git a/Plugins/BTCPayServer.Plugins.AOPP/AOPPService.cs b/Plugins/BTCPayServer.Plugins.AOPP/AOPPService.cs deleted file mode 100644 index 87ba10b..0000000 --- a/Plugins/BTCPayServer.Plugins.AOPP/AOPPService.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System.Threading.Tasks; -using BTCPayServer.Abstractions.Contracts; -using Microsoft.Extensions.Caching.Memory; - -namespace BTCPayServer.Plugins.AOPP -{ - public class AOPPService - { - private readonly ISettingsRepository _settingsRepository; - private readonly IMemoryCache _memoryCache; - private readonly IStoreRepository _storeRepository; - - public AOPPService(ISettingsRepository settingsRepository, IMemoryCache memoryCache, - IStoreRepository storeRepository) - { - _settingsRepository = settingsRepository; - _memoryCache = memoryCache; - _storeRepository = storeRepository; - } - - - public async Task GetAOPPForStore(string storeId) - { - var k = $"{nameof(AOPPSettings)}_{storeId}"; - return await _memoryCache.GetOrCreateAsync(k, async _ => - { - var res = await _storeRepository.GetSettingAsync(storeId, - nameof(AOPPSettings)); - if (res is not null) return res; - res = await _settingsRepository.GetSettingAsync(k); - - if (res is not null) - { - await SetAOPPForStore(storeId, res); - } - - await _settingsRepository.UpdateSetting(null, k); - return res; - }); - } - - public async Task SetAOPPForStore(string storeId, AOPPSettings AOPPSettings) - { - var k = $"{nameof(AOPPSettings)}_{storeId}"; - await _storeRepository.UpdateSetting(storeId, nameof(AOPPSettings), AOPPSettings); - _memoryCache.Set(k, AOPPSettings); - } - - - } -} diff --git a/Plugins/BTCPayServer.Plugins.AOPP/AOPPSettings.cs b/Plugins/BTCPayServer.Plugins.AOPP/AOPPSettings.cs deleted file mode 100644 index 02677f0..0000000 --- a/Plugins/BTCPayServer.Plugins.AOPP/AOPPSettings.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace BTCPayServer.Plugins.AOPP -{ - public class AOPPSettings - { - public bool Enabled { get; set; } - } -} diff --git a/Plugins/BTCPayServer.Plugins.Prism/BTCPayServer.Plugins.Prism.csproj b/Plugins/BTCPayServer.Plugins.Prism/BTCPayServer.Plugins.Prism.csproj index b210668..95fe5a8 100644 --- a/Plugins/BTCPayServer.Plugins.Prism/BTCPayServer.Plugins.Prism.csproj +++ b/Plugins/BTCPayServer.Plugins.Prism/BTCPayServer.Plugins.Prism.csproj @@ -9,8 +9,8 @@ - LN Prism - Automated value splits for lightning. + Prism + Automated value splits for Bitcoin. 1.2.0 diff --git a/Plugins/BTCPayServer.Plugins.Wabisabi/BTCPayServer.Plugins.Wabisabi.csproj b/Plugins/BTCPayServer.Plugins.Wabisabi/BTCPayServer.Plugins.Wabisabi.csproj index 28a12a1..ccbbf02 100644 --- a/Plugins/BTCPayServer.Plugins.Wabisabi/BTCPayServer.Plugins.Wabisabi.csproj +++ b/Plugins/BTCPayServer.Plugins.Wabisabi/BTCPayServer.Plugins.Wabisabi.csproj @@ -13,7 +13,7 @@ Wabisabi Coinjoin Allows you to integrate your btcpayserver store with coinjoins. - 1.0.60 + 1.0.61 diff --git a/Plugins/BTCPayServer.Plugins.Wabisabi/Coordinator/Filters/ExceptionTranslateAttribute.cs b/Plugins/BTCPayServer.Plugins.Wabisabi/Coordinator/Filters/ExceptionTranslateAttribute.cs index cbf8f3f..f50bda8 100644 --- a/Plugins/BTCPayServer.Plugins.Wabisabi/Coordinator/Filters/ExceptionTranslateAttribute.cs +++ b/Plugins/BTCPayServer.Plugins.Wabisabi/Coordinator/Filters/ExceptionTranslateAttribute.cs @@ -1,6 +1,9 @@ using System.Net; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using NLog; using WabiSabi.Crypto; using WalletWasabi.Affiliation; using WalletWasabi.WabiSabi; @@ -13,8 +16,9 @@ public class ExceptionTranslateAttribute : ExceptionFilterAttribute { public override void OnException(ExceptionContext context) { + var logger = context.HttpContext.RequestServices.GetRequiredService>(); var exception = context.Exception.InnerException ?? context.Exception; - + logger.LogError(exception, "Exception occured in WabiSabiCoordinator API, "); context.Result = exception switch { WabiSabiProtocolException e => new JsonResult(new Error( diff --git a/Plugins/BTCPayServer.Plugins.Wabisabi/Coordinator/Filters/LateResponseLoggerFilter.cs b/Plugins/BTCPayServer.Plugins.Wabisabi/Coordinator/Filters/LateResponseLoggerFilter.cs index 17cbe54..32bcee9 100644 --- a/Plugins/BTCPayServer.Plugins.Wabisabi/Coordinator/Filters/LateResponseLoggerFilter.cs +++ b/Plugins/BTCPayServer.Plugins.Wabisabi/Coordinator/Filters/LateResponseLoggerFilter.cs @@ -1,5 +1,8 @@ using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; using WalletWasabi.Logging; +using WalletWasabi.WabiSabi; using WalletWasabi.WabiSabi.Backend.Models; namespace WalletWasabi.Backend.Filters; @@ -8,6 +11,7 @@ public class LateResponseLoggerFilter : ExceptionFilterAttribute { public override void OnException(ExceptionContext context) { + var logger = context.HttpContext.RequestServices.GetRequiredService>(); if (context.Exception is not WrongPhaseException ex) { return; @@ -15,6 +19,6 @@ public class LateResponseLoggerFilter : ExceptionFilterAttribute var actionName = ((Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor)context.ActionDescriptor).ActionName; - Logger.LogInfo($"Request '{actionName}' missing the phase '{string.Join(",", ex.ExpectedPhases)}' ('{ex.PhaseTimeout}' timeout) by '{ex.Late}'. Round id '{ex.RoundId}'."); + logger.LogInformation($"Request '{actionName}' missing the phase '{string.Join(",", ex.ExpectedPhases)}' ('{ex.PhaseTimeout}' timeout) by '{ex.Late}'. Round id '{ex.RoundId}'."); } } diff --git a/Plugins/BTCPayServer.Plugins.Wabisabi/SettingsCoinPrison.cs b/Plugins/BTCPayServer.Plugins.Wabisabi/SettingsCoinPrison.cs index faaf70a..278ed50 100644 --- a/Plugins/BTCPayServer.Plugins.Wabisabi/SettingsCoinPrison.cs +++ b/Plugins/BTCPayServer.Plugins.Wabisabi/SettingsCoinPrison.cs @@ -3,9 +3,12 @@ using System.Collections.Generic; using System.IO; using System.Threading.Tasks; using BTCPayServer.Services; +using Microsoft.Extensions.Logging; using Newtonsoft.Json; -using WalletWasabi.Logging; +using NLog; using WalletWasabi.WabiSabi.Client.Banning; +using ILogger = Microsoft.Extensions.Logging.ILogger; +using Logger = WalletWasabi.Logging.Logger; namespace BTCPayServer.Plugins.Wabisabi; @@ -27,7 +30,7 @@ public class SettingsCoinPrison : CoinPrison } public static async Task CreateFromCoordinatorName(SettingsRepository settingsRepository, - string coordinatorName) + string coordinatorName, ILogger logger) { HashSet prisonedCoinRecords = new(); try @@ -35,7 +38,7 @@ public class SettingsCoinPrison : CoinPrison var data = await settingsRepository.GetSettingAsync("wabisabi_" + coordinatorName + "_bannedcoins"); if (string.IsNullOrWhiteSpace(data)) { - Logger.LogDebug("Prisoned coins file is empty."); + logger.LogDebug("Prisoned coins file is empty."); return new(settingsRepository, coordinatorName); } prisonedCoinRecords = JsonConvert.DeserializeObject>(data) @@ -43,7 +46,7 @@ public class SettingsCoinPrison : CoinPrison } catch (Exception exc) { - Logger.LogError($"There was an error during loading {nameof(SettingsCoinPrison)}. Ignoring corrupt data.", exc); + logger.LogError($"There was an error during loading {nameof(SettingsCoinPrison)}. Ignoring corrupt data.", exc); } return new(settingsRepository, coordinatorName){ BannedCoins = prisonedCoinRecords }; } diff --git a/Plugins/BTCPayServer.Plugins.Wabisabi/Smartifier.cs b/Plugins/BTCPayServer.Plugins.Wabisabi/Smartifier.cs index 50fd168..ed154de 100644 --- a/Plugins/BTCPayServer.Plugins.Wabisabi/Smartifier.cs +++ b/Plugins/BTCPayServer.Plugins.Wabisabi/Smartifier.cs @@ -50,13 +50,14 @@ public class Smartifier public static async Task GetOrCreate(ConcurrentDictionary>> collection, Y key, Func> create, ILogger logger = null) { - var lazyTask = new Lazy>(() => FetchFromServer(create, logger, key)); - - // Even if multiple threads provide their own new Lazy instances, only one will be stored. - var task = collection.GetOrAdd(key, lazyTask).Value; - + try { + var lazyTask = new Lazy>(() => FetchFromServer(create, logger, key)); + + // Even if multiple threads provide their own new Lazy instances, only one will be stored. + var task = collection.GetOrAdd(key, lazyTask).Value; + return await task; } catch (Exception) diff --git a/Plugins/BTCPayServer.Plugins.Wabisabi/Views/Shared/Wabisabi/WabisabiDashboard.cshtml b/Plugins/BTCPayServer.Plugins.Wabisabi/Views/Shared/Wabisabi/WabisabiDashboard.cshtml index e3212a7..8460831 100644 --- a/Plugins/BTCPayServer.Plugins.Wabisabi/Views/Shared/Wabisabi/WabisabiDashboard.cshtml +++ b/Plugins/BTCPayServer.Plugins.Wabisabi/Views/Shared/Wabisabi/WabisabiDashboard.cshtml @@ -203,6 +203,10 @@ @coin.AnonymitySet.ToString("0.##") + @if (!coin.IsSufficientlyDistancedFromExternalKeys) + { + (too close to entry) + } @coin.Amount.ToDecimal(MoneyUnit.BTC) BTC diff --git a/Plugins/BTCPayServer.Plugins.Wabisabi/WabisabiCoordinatorClientInstance.cs b/Plugins/BTCPayServer.Plugins.Wabisabi/WabisabiCoordinatorClientInstance.cs index 18e954c..96b7d7e 100644 --- a/Plugins/BTCPayServer.Plugins.Wabisabi/WabisabiCoordinatorClientInstance.cs +++ b/Plugins/BTCPayServer.Plugins.Wabisabi/WabisabiCoordinatorClientInstance.cs @@ -298,7 +298,7 @@ public class WabisabiCoordinatorClientInstance:IHostedService CoinPrison = SettingsCoinPrison.CreateFromCoordinatorName( serviceProvider.GetRequiredService(), - CoordinatorName).GetAwaiter().GetResult(); + CoordinatorName, _logger).GetAwaiter().GetResult(); CoinJoinManager = new CoinJoinManager(coordinatorName, WalletProvider, RoundStateUpdater, WasabiHttpClientFactory,