diff --git a/BTCPayServer.Tests/docker-compose.altcoins.yml b/BTCPayServer.Tests/docker-compose.altcoins.yml index 3f3e09f31..41a6a4849 100644 --- a/BTCPayServer.Tests/docker-compose.altcoins.yml +++ b/BTCPayServer.Tests/docker-compose.altcoins.yml @@ -58,7 +58,6 @@ services: - merchant_lnd - sshd - tor - - monero_wallet sshd: build: @@ -317,28 +316,6 @@ services: - "torrcdir:/usr/local/etc/tor" - "tor_servicesdir:/var/lib/tor/hidden_services" - monerod: - image: btcpayserver/monero:0.18.3.3 - restart: unless-stopped - container_name: xmr_monerod - entrypoint: monerod --fixed-difficulty 200 --rpc-bind-ip=0.0.0.0 --confirm-external-bind --rpc-bind-port=18081 --block-notify="/bin/sh ./scripts/notifier.sh -k -X GET https://host.docker.internal:14142/monerolikedaemoncallback/block?cryptoCode=xmr&hash=%s" --testnet --no-igd --hide-my-port --offline --non-interactive - volumes: - - "monero_data:/home/monero/.bitmonero" - ports: - - "18081:18081" - - monero_wallet: - image: btcpayserver/monero:0.18.3.3 - restart: unless-stopped - container_name: xmr_wallet_rpc - entrypoint: monero-wallet-rpc --testnet --rpc-bind-ip=0.0.0.0 --disable-rpc-login --confirm-external-bind --rpc-bind-port=18082 --non-interactive --trusted-daemon --daemon-address=monerod:18081 --wallet-dir=/wallet --tx-notify="/bin/sh ./scripts/notifier.sh -k -X GET https://host.docker.internal:14142/monerolikedaemoncallback/tx?cryptoCode=xmr&hash=%s" - ports: - - "18082:18082" - volumes: - - "./monero_wallet:/wallet" - depends_on: - - monerod - litecoind: restart: unless-stopped image: btcpayserver/litecoin:0.18.1 @@ -400,7 +377,6 @@ volumes: tor_datadir: torrcdir: tor_servicesdir: - monero_data: networks: default: diff --git a/BTCPayServer/Filters/OnlyIfSupportAttribute.cs b/BTCPayServer/Filters/OnlyIfSupportAttribute.cs deleted file mode 100644 index 7ca67f4f9..000000000 --- a/BTCPayServer/Filters/OnlyIfSupportAttribute.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Threading.Tasks; -using BTCPayServer.Payments; -using BTCPayServer.Services.Invoices; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Filters; -using Microsoft.Extensions.DependencyInjection; - -namespace BTCPayServer.Filters -{ - public class OnlyIfSupportAttribute : Attribute, IAsyncActionFilter - { - private readonly string _paymentMethodId; - - public OnlyIfSupportAttribute(string paymentMethodId) - { - _paymentMethodId = paymentMethodId; - } - - public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) - { - var handlers = context.HttpContext.RequestServices.GetService(); - if (!handlers.Support(PaymentMethodId.Parse(_paymentMethodId))) - { - context.Result = new NotFoundResult(); - return; - } - await next(); - } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/AltcoinsPlugin.cs b/BTCPayServer/Plugins/Altcoins/AltcoinsPlugin.cs index 7bd9ff9f5..a356cc0bb 100644 --- a/BTCPayServer/Plugins/Altcoins/AltcoinsPlugin.cs +++ b/BTCPayServer/Plugins/Altcoins/AltcoinsPlugin.cs @@ -52,10 +52,6 @@ namespace BTCPayServer.Plugins.Altcoins InitDash(services); if (selectedChains.Contains("GRS")) InitGroestlcoin(services); - if (selectedChains.Contains("XMR")) - InitMonero(services); - if (selectedChains.Contains("ZEC")) - InitZcash(services); } } } diff --git a/BTCPayServer/Plugins/Altcoins/Monero/AltcoinsPlugin.Monero.cs b/BTCPayServer/Plugins/Altcoins/Monero/AltcoinsPlugin.Monero.cs deleted file mode 100644 index 3736e21e8..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/AltcoinsPlugin.Monero.cs +++ /dev/null @@ -1,122 +0,0 @@ -using BTCPayServer.Abstractions.Contracts; -using BTCPayServer.Abstractions.Services; -using System.Net.Http; -using System.Net; -using BTCPayServer.Hosting; -using BTCPayServer.Payments; -using BTCPayServer.Payments.Bitcoin; -using BTCPayServer.Services.Altcoins.Monero.Configuration; -using BTCPayServer.Services.Altcoins.Monero.Payments; -using BTCPayServer.Services.Altcoins.Monero.Services; -using Microsoft.AspNetCore.HttpOverrides; -using Microsoft.Extensions.DependencyInjection; -using NBitcoin; -using BTCPayServer.Configuration; -using System.Linq; -using System; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection.Extensions; - -namespace BTCPayServer.Plugins.Altcoins; - -public partial class AltcoinsPlugin -{ - public void InitMonero(IServiceCollection services) - { - var network = new MoneroLikeSpecificBtcPayNetwork() - { - CryptoCode = "XMR", - DisplayName = "Monero", - Divisibility = 12, - DefaultRateRules = new[] - { - "XMR_X = XMR_BTC * BTC_X", - "XMR_BTC = kraken(XMR_BTC)" - }, - CryptoImagePath = "/imlegacy/monero.svg", - UriScheme = "monero" - }; - var blockExplorerLink = ChainName == ChainName.Mainnet - ? "https://www.exploremonero.com/transaction/{0}" - : "https://testnet.xmrchain.net/tx/{0}"; - var pmi = PaymentTypes.CHAIN.GetPaymentMethodId("XMR"); - services.AddDefaultPrettyName(pmi, network.DisplayName); - services.AddBTCPayNetwork(network) - .AddTransactionLinkProvider(pmi, new SimpleTransactionLinkProvider(blockExplorerLink)); - - - services.AddSingleton(provider => - ConfigureMoneroLikeConfiguration(provider)); - services.AddHttpClient("XMRclient") - .ConfigurePrimaryHttpMessageHandler(provider => - { - var configuration = provider.GetRequiredService(); - if (!configuration.MoneroLikeConfigurationItems.TryGetValue("XMR", out var xmrConfig) || xmrConfig.Username is null || xmrConfig.Password is null) - { - return new HttpClientHandler(); - } - return new HttpClientHandler - { - Credentials = new NetworkCredential(xmrConfig.Username, xmrConfig.Password), - PreAuthenticate = true - }; - }); - services.AddSingleton(); - services.AddHostedService(); - services.AddHostedService(); - services.AddSingleton(provider => - (IPaymentMethodHandler)ActivatorUtilities.CreateInstance(provider, typeof(MoneroLikePaymentMethodHandler), new object[] { network })); - services.AddSingleton(provider => -(IPaymentLinkExtension)ActivatorUtilities.CreateInstance(provider, typeof(MoneroPaymentLinkExtension), new object[] { network, pmi })); - services.AddSingleton(provider => -(ICheckoutModelExtension)ActivatorUtilities.CreateInstance(provider, typeof(MoneroCheckoutModelExtension), new object[] { network, pmi })); - - services.AddUIExtension("store-nav", "Monero/StoreNavMoneroExtension"); - services.AddUIExtension("store-wallets-nav", "Monero/StoreWalletsNavMoneroExtension"); - services.AddUIExtension("store-invoices-payments", "Monero/ViewMoneroLikePaymentData"); - services.AddSingleton(); - } - private static MoneroLikeConfiguration ConfigureMoneroLikeConfiguration(IServiceProvider serviceProvider) - { - var configuration = serviceProvider.GetService(); - var btcPayNetworkProvider = serviceProvider.GetService(); - var result = new MoneroLikeConfiguration(); - - var supportedNetworks = btcPayNetworkProvider.GetAll() - .OfType(); - - foreach (var moneroLikeSpecificBtcPayNetwork in supportedNetworks) - { - var daemonUri = - configuration.GetOrDefault($"{moneroLikeSpecificBtcPayNetwork.CryptoCode}_daemon_uri", - null); - var walletDaemonUri = - configuration.GetOrDefault( - $"{moneroLikeSpecificBtcPayNetwork.CryptoCode}_wallet_daemon_uri", null); - var walletDaemonWalletDirectory = - configuration.GetOrDefault( - $"{moneroLikeSpecificBtcPayNetwork.CryptoCode}_wallet_daemon_walletdir", null); - var daemonUsername = - configuration.GetOrDefault( - $"{moneroLikeSpecificBtcPayNetwork.CryptoCode}_daemon_username", null); - var daemonPassword = - configuration.GetOrDefault( - $"{moneroLikeSpecificBtcPayNetwork.CryptoCode}_daemon_password", null); - if (daemonUri == null || walletDaemonUri == null || walletDaemonWalletDirectory == null) - { - throw new ConfigException($"{moneroLikeSpecificBtcPayNetwork.CryptoCode} is misconfigured"); - } - - result.MoneroLikeConfigurationItems.Add(moneroLikeSpecificBtcPayNetwork.CryptoCode, new MoneroLikeConfigurationItem() - { - DaemonRpcUri = daemonUri, - Username = daemonUsername, - Password = daemonPassword, - InternalWalletRpcUri = walletDaemonUri, - WalletDirectory = walletDaemonWalletDirectory - }); - } - return result; - } -} - diff --git a/BTCPayServer/Plugins/Altcoins/Monero/MoneroLikeSpecificBtcPayNetwork.cs b/BTCPayServer/Plugins/Altcoins/Monero/MoneroLikeSpecificBtcPayNetwork.cs deleted file mode 100644 index 9f4fd4530..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/MoneroLikeSpecificBtcPayNetwork.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace BTCPayServer.Plugins.Altcoins; - -public class MoneroLikeSpecificBtcPayNetwork : BTCPayNetworkBase -{ - public int MaxTrackedConfirmation = 10; - public string UriScheme { get; set; } -} - diff --git a/BTCPayServer/Plugins/Altcoins/Monero/RPC/JsonRpcClient.cs b/BTCPayServer/Plugins/Altcoins/Monero/RPC/JsonRpcClient.cs deleted file mode 100644 index d8051c99c..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/RPC/JsonRpcClient.cs +++ /dev/null @@ -1,121 +0,0 @@ -using System; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; - -namespace BTCPayServer.Services.Altcoins.Monero.RPC -{ - public class JsonRpcClient - { - private readonly Uri _address; - private readonly string _username; - private readonly string _password; - private readonly HttpClient _httpClient; - - public JsonRpcClient(Uri address, string username, string password, HttpClient client = null) - { - _address = address; - _username = username; - _password = password; - _httpClient = client ?? new HttpClient(); - } - - - public async Task SendCommandAsync(string method, TRequest data, - CancellationToken cts = default(CancellationToken)) - { - var jsonSerializer = new JsonSerializerSettings - { - ContractResolver = new CamelCasePropertyNamesContractResolver() - }; - var httpRequest = new HttpRequestMessage() - { - Method = HttpMethod.Post, - RequestUri = new Uri(_address, "json_rpc"), - Content = new StringContent( - JsonConvert.SerializeObject(new JsonRpcCommand(method, data), jsonSerializer), - Encoding.UTF8, "application/json") - }; - httpRequest.Headers.Accept.Clear(); - httpRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - httpRequest.Headers.Authorization = new AuthenticationHeaderValue("Basic", - Convert.ToBase64String(Encoding.Default.GetBytes($"{_username}:{_password}"))); - - HttpResponseMessage rawResult = await _httpClient.SendAsync(httpRequest, cts); - rawResult.EnsureSuccessStatusCode(); - var rawJson = await rawResult.Content.ReadAsStringAsync(); - - JsonRpcResult response; - try - { - response = JsonConvert.DeserializeObject>(rawJson, jsonSerializer); - } - catch (Exception e) - { - Console.WriteLine(e.Message); - Console.WriteLine(rawJson); - throw; - } - - if (response.Error != null) - { - throw new JsonRpcApiException() - { - Error = response.Error - }; - } - - return response.Result; - } - - public class NoRequestModel - { - public static NoRequestModel Instance = new NoRequestModel(); - } - - internal class JsonRpcApiException : Exception - { - public JsonRpcResultError Error { get; set; } - - public override string Message => Error?.Message; - } - - public class JsonRpcResultError - { - [JsonProperty("code")] public int Code { get; set; } - [JsonProperty("message")] public string Message { get; set; } - [JsonProperty("data")] dynamic Data { get; set; } - } - internal class JsonRpcResult - { - - - [JsonProperty("result")] public T Result { get; set; } - [JsonProperty("error")] public JsonRpcResultError Error { get; set; } - [JsonProperty("id")] public string Id { get; set; } - } - - internal class JsonRpcCommand - { - [JsonProperty("jsonRpc")] public string JsonRpc { get; set; } = "2.0"; - [JsonProperty("id")] public string Id { get; set; } = Guid.NewGuid().ToString(); - [JsonProperty("method")] public string Method { get; set; } - - [JsonProperty("params")] public T Parameters { get; set; } - - public JsonRpcCommand() - { - } - - public JsonRpcCommand(string method, T parameters) - { - Method = method; - Parameters = parameters; - } - } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/CreateAccountRequest.cs b/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/CreateAccountRequest.cs deleted file mode 100644 index 10ab914b8..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/CreateAccountRequest.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Monero.RPC.Models -{ - public partial class CreateAccountRequest - { - [JsonProperty("label")] public string Label { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/CreateAccountResponse.cs b/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/CreateAccountResponse.cs deleted file mode 100644 index ed60cb677..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/CreateAccountResponse.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Monero.RPC.Models -{ - public partial class CreateAccountResponse - { - [JsonProperty("account_index")] public long AccountIndex { get; set; } - [JsonProperty("address")] public string Address { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/CreateAddressRequest.cs b/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/CreateAddressRequest.cs deleted file mode 100644 index 057f4f101..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/CreateAddressRequest.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Monero.RPC.Models -{ - public partial class CreateAddressRequest - { - [JsonProperty("account_index")] public long AccountIndex { get; set; } - [JsonProperty("label")] public string Label { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/CreateAddressResponse.cs b/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/CreateAddressResponse.cs deleted file mode 100644 index 657b3d0c9..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/CreateAddressResponse.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Monero.RPC.Models -{ - public partial class CreateAddressResponse - { - [JsonProperty("address")] public string Address { get; set; } - [JsonProperty("address_index")] public long AddressIndex { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetAccountsRequest.cs b/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetAccountsRequest.cs deleted file mode 100644 index 86dd55ee7..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetAccountsRequest.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Monero.RPC.Models -{ - public partial class GetAccountsRequest - { - [JsonProperty("tag")] public string Tag { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetAccountsResponse.cs b/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetAccountsResponse.cs deleted file mode 100644 index 6d6da2987..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetAccountsResponse.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Monero.RPC.Models -{ - public partial class GetAccountsResponse - { - [JsonProperty("subaddress_accounts")] public List SubaddressAccounts { get; set; } - [JsonProperty("total_balance")] public decimal TotalBalance { get; set; } - - [JsonProperty("total_unlocked_balance")] - public decimal TotalUnlockedBalance { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetFeeEstimateRequest.cs b/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetFeeEstimateRequest.cs deleted file mode 100644 index 936af70c9..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetFeeEstimateRequest.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Monero.RPC.Models -{ - public class GetFeeEstimateRequest - { - [JsonProperty("grace_blocks")] public int? GraceBlocks { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetFeeEstimateResponse.cs b/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetFeeEstimateResponse.cs deleted file mode 100644 index 6e383bc34..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetFeeEstimateResponse.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Monero.RPC.Models -{ - public class GetFeeEstimateResponse - { - [JsonProperty("fee")] public long Fee { get; set; } - [JsonProperty("status")] public string Status { get; set; } - [JsonProperty("untrusted")] public bool Untrusted { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetHeightResponse.cs b/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetHeightResponse.cs deleted file mode 100644 index 1040b51a1..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetHeightResponse.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Monero.RPC.Models -{ - public partial class GetHeightResponse - { - [JsonProperty("height")] public long Height { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetInfoResponse.cs b/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetInfoResponse.cs deleted file mode 100644 index 864c42953..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetInfoResponse.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Monero.RPC.Models -{ - public partial class GetInfoResponse - { - [JsonProperty("height")] public long Height { get; set; } - [JsonProperty("busy_syncing")] public bool BusySyncing { get; set; } - [JsonProperty("status")] public string Status { get; set; } - [JsonProperty("target_height")] public long? TargetHeight { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetTransferByTransactionIdRequest.cs b/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetTransferByTransactionIdRequest.cs deleted file mode 100644 index d11f9ac58..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetTransferByTransactionIdRequest.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Monero.RPC.Models -{ - public class GetTransferByTransactionIdRequest - { - [JsonProperty("txid")] public string TransactionId { get; set; } - - [JsonProperty("account_index", DefaultValueHandling = DefaultValueHandling.Ignore)] public long? AccountIndex { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetTransferByTransactionIdResponse.cs b/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetTransferByTransactionIdResponse.cs deleted file mode 100644 index 025c22151..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetTransferByTransactionIdResponse.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Monero.RPC.Models -{ - public partial class GetTransferByTransactionIdResponse - { - [JsonProperty("transfer")] public TransferItem Transfer { get; set; } - [JsonProperty("transfers")] public IEnumerable Transfers { get; set; } - - public partial class TransferItem - { - [JsonProperty("address")] public string Address { get; set; } - [JsonProperty("amount")] public long Amount { get; set; } - [JsonProperty("confirmations")] public long Confirmations { get; set; } - [JsonProperty("double_spend_seen")] public bool DoubleSpendSeen { get; set; } - [JsonProperty("height")] public long Height { get; set; } - [JsonProperty("note")] public string Note { get; set; } - [JsonProperty("payment_id")] public string PaymentId { get; set; } - [JsonProperty("subaddr_index")] public SubaddrIndex SubaddrIndex { get; set; } - - [JsonProperty("suggested_confirmations_threshold")] - public long SuggestedConfirmationsThreshold { get; set; } - - [JsonProperty("timestamp")] public long Timestamp { get; set; } - [JsonProperty("txid")] public string Txid { get; set; } - [JsonProperty("type")] public string Type { get; set; } - [JsonProperty("unlock_time")] public long UnlockTime { get; set; } - } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetTransfersRequest.cs b/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetTransfersRequest.cs deleted file mode 100644 index 506a96483..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetTransfersRequest.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Monero.RPC.Models -{ - public partial class GetTransfersRequest - { - [JsonProperty("in")] public bool In { get; set; } - [JsonProperty("out")] public bool Out { get; set; } - [JsonProperty("pending")] public bool Pending { get; set; } - [JsonProperty("failed")] public bool Failed { get; set; } - [JsonProperty("pool")] public bool Pool { get; set; } - [JsonProperty("filter_by_height ")] public bool FilterByHeight { get; set; } - [JsonProperty("min_height")] public long MinHeight { get; set; } - [JsonProperty("max_height")] public long MaxHeight { get; set; } - [JsonProperty("account_index")] public long AccountIndex { get; set; } - [JsonProperty("subaddr_indices")] public List SubaddrIndices { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetTransfersResponse.cs b/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetTransfersResponse.cs deleted file mode 100644 index f0d3b4076..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/GetTransfersResponse.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Monero.RPC.Models -{ - public partial class GetTransfersResponse - { - [JsonProperty("in")] public List In { get; set; } - [JsonProperty("out")] public List Out { get; set; } - [JsonProperty("pending")] public List Pending { get; set; } - [JsonProperty("failed")] public List Failed { get; set; } - [JsonProperty("pool")] public List Pool { get; set; } - - public partial class GetTransfersResponseItem - - { - [JsonProperty("address")] public string Address { get; set; } - [JsonProperty("amount")] public long Amount { get; set; } - [JsonProperty("confirmations")] public long Confirmations { get; set; } - [JsonProperty("double_spend_seen")] public bool DoubleSpendSeen { get; set; } - [JsonProperty("height")] public long Height { get; set; } - [JsonProperty("note")] public string Note { get; set; } - [JsonProperty("payment_id")] public string PaymentId { get; set; } - [JsonProperty("subaddr_index")] public SubaddrIndex SubaddrIndex { get; set; } - - [JsonProperty("suggested_confirmations_threshold")] - public long SuggestedConfirmationsThreshold { get; set; } - - [JsonProperty("timestamp")] public long Timestamp { get; set; } - [JsonProperty("txid")] public string Txid { get; set; } - [JsonProperty("type")] public string Type { get; set; } - [JsonProperty("unlock_time")] public long UnlockTime { get; set; } - } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/Info.cs b/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/Info.cs deleted file mode 100644 index ca9f55741..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/Info.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Monero.RPC.Models -{ - public partial class Info - { - [JsonProperty("address")] public string Address { get; set; } - [JsonProperty("avg_download")] public long AvgDownload { get; set; } - [JsonProperty("avg_upload")] public long AvgUpload { get; set; } - [JsonProperty("connection_id")] public string ConnectionId { get; set; } - [JsonProperty("current_download")] public long CurrentDownload { get; set; } - [JsonProperty("current_upload")] public long CurrentUpload { get; set; } - [JsonProperty("height")] public long Height { get; set; } - [JsonProperty("host")] public string Host { get; set; } - [JsonProperty("incoming")] public bool Incoming { get; set; } - [JsonProperty("ip")] public string Ip { get; set; } - [JsonProperty("live_time")] public long LiveTime { get; set; } - [JsonProperty("local_ip")] public bool LocalIp { get; set; } - [JsonProperty("localhost")] public bool Localhost { get; set; } - [JsonProperty("peer_id")] public string PeerId { get; set; } - - [JsonProperty("port")] - [JsonConverter(typeof(ParseStringConverter))] - public long Port { get; set; } - - [JsonProperty("recv_count")] public long RecvCount { get; set; } - [JsonProperty("recv_idle_time")] public long RecvIdleTime { get; set; } - [JsonProperty("send_count")] public long SendCount { get; set; } - [JsonProperty("send_idle_time")] public long SendIdleTime { get; set; } - [JsonProperty("state")] public string State { get; set; } - [JsonProperty("support_flags")] public long SupportFlags { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/MakeUriRequest.cs b/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/MakeUriRequest.cs deleted file mode 100644 index ba1a503b3..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/MakeUriRequest.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Monero.RPC.Models -{ - public partial class MakeUriRequest - { - [JsonProperty("address")] public string Address { get; set; } - [JsonProperty("amount")] public long Amount { get; set; } - [JsonProperty("payment_id")] public string PaymentId { get; set; } - [JsonProperty("tx_description")] public string TxDescription { get; set; } - [JsonProperty("recipient_name")] public string RecipientName { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/MakeUriResponse.cs b/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/MakeUriResponse.cs deleted file mode 100644 index 160297139..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/MakeUriResponse.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Monero.RPC.Models -{ - public partial class MakeUriResponse - { - [JsonProperty("uri")] public string Uri { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/OpenWallerErrorResponse.cs b/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/OpenWallerErrorResponse.cs deleted file mode 100644 index 90c4e6e22..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/OpenWallerErrorResponse.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Monero.RPC.Models -{ - public partial class OpenWalletErrorResponse - { - [JsonProperty("code")] public int Code { get; set; } - [JsonProperty("message")] public string Message { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/OpenWalletRequest.cs b/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/OpenWalletRequest.cs deleted file mode 100644 index 3da005827..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/OpenWalletRequest.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Monero.RPC.Models -{ - public partial class OpenWalletRequest - { - [JsonProperty("filename")] public string Filename { get; set; } - [JsonProperty("password")] public string Password { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/OpenWalletResponse.cs b/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/OpenWalletResponse.cs deleted file mode 100644 index 75c2a3a86..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/OpenWalletResponse.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Monero.RPC.Models -{ - public partial class OpenWalletResponse - { - [JsonProperty("id")] public string Id { get; set; } - [JsonProperty("jsonrpc")] public string Jsonrpc { get; set; } - [JsonProperty("result")] public object Result { get; set; } - [JsonProperty("error")] public OpenWalletErrorResponse Error { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/ParseStringConverter.cs b/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/ParseStringConverter.cs deleted file mode 100644 index 3e929f3da..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/ParseStringConverter.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using System.Globalization; -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Monero.RPC.Models -{ - internal class ParseStringConverter : JsonConverter - { - public override bool CanConvert(Type t) => t == typeof(long) || t == typeof(long?); - - public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) - { - if (reader.TokenType == JsonToken.Null) - return null; - var value = serializer.Deserialize(reader); - long l; - if (Int64.TryParse(value, out l)) - { - return l; - } - - throw new Exception("Cannot unmarshal type long"); - } - - public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) - { - if (untypedValue == null) - { - serializer.Serialize(writer, null); - return; - } - - var value = (long)untypedValue; - serializer.Serialize(writer, value.ToString(CultureInfo.InvariantCulture)); - return; - } - - public static readonly ParseStringConverter Singleton = new ParseStringConverter(); - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/Peer.cs b/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/Peer.cs deleted file mode 100644 index 48f5a2d82..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/Peer.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Monero.RPC.Models -{ - public partial class Peer - { - [JsonProperty("info")] public Info Info { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/SubaddrIndex.cs b/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/SubaddrIndex.cs deleted file mode 100644 index dab5c3c56..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/SubaddrIndex.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Monero.RPC.Models -{ - public partial class SubaddrIndex - { - [JsonProperty("major")] public long Major { get; set; } - [JsonProperty("minor")] public long Minor { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/SubaddressAccount.cs b/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/SubaddressAccount.cs deleted file mode 100644 index 2f6a7913b..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/RPC/Models/SubaddressAccount.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Monero.RPC.Models -{ - public partial class SubaddressAccount - { - [JsonProperty("account_index")] public long AccountIndex { get; set; } - [JsonProperty("balance")] public decimal Balance { get; set; } - [JsonProperty("base_address")] public string BaseAddress { get; set; } - [JsonProperty("label")] public string Label { get; set; } - [JsonProperty("tag")] public string Tag { get; set; } - [JsonProperty("unlocked_balance")] public decimal UnlockedBalance { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Monero/Utils/MoneroMoney.cs b/BTCPayServer/Plugins/Altcoins/Monero/Utils/MoneroMoney.cs deleted file mode 100644 index fc4a73005..000000000 --- a/BTCPayServer/Plugins/Altcoins/Monero/Utils/MoneroMoney.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Globalization; - -namespace BTCPayServer.Services.Altcoins.Monero.Utils -{ - public class MoneroMoney - { - public static decimal Convert(long piconero) - { - var amt = piconero.ToString(CultureInfo.InvariantCulture).PadLeft(12, '0'); - amt = amt.Length == 12 ? $"0.{amt}" : amt.Insert(amt.Length - 12, "."); - - return decimal.Parse(amt, CultureInfo.InvariantCulture); - } - - public static long Convert(decimal monero) - { - return System.Convert.ToInt64(monero * 1000000000000); - } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Zcash/AltcoinsPlugin.Zcash.cs b/BTCPayServer/Plugins/Altcoins/Zcash/AltcoinsPlugin.Zcash.cs deleted file mode 100644 index 5ac5dc5f1..000000000 --- a/BTCPayServer/Plugins/Altcoins/Zcash/AltcoinsPlugin.Zcash.cs +++ /dev/null @@ -1,118 +0,0 @@ -#nullable enable -using BTCPayServer.Services; -using System.Globalization; -using System.Linq; -using NBitcoin; -using Microsoft.AspNetCore.HttpOverrides; -using Microsoft.Extensions.DependencyInjection; -using BTCPayServer.Hosting; -using BTCPayServer.Payments; -using BTCPayServer.Payments.Bitcoin; -using BTCPayServer.Abstractions.Contracts; -using BTCPayServer.Abstractions.Services; -using BTCPayServer.Services.Altcoins.Zcash.Payments; -using BTCPayServer.Services.Altcoins.Zcash.Services; -using BTCPayServer.Configuration; -using BTCPayServer.Services.Altcoins.Zcash.Configuration; -using System; -using Microsoft.Extensions.Configuration; - -namespace BTCPayServer.Plugins.Altcoins; - -public partial class AltcoinsPlugin -{ - // Change this if you want another zcash coin - public void InitZcash(IServiceCollection services) - { - var network = new ZcashLikeSpecificBtcPayNetwork() - { - CryptoCode = "ZEC", - DisplayName = "Zcash", - Divisibility = 8, - DefaultRateRules = new[] - { - "ZEC_X = ZEC_BTC * BTC_X", - "ZEC_BTC = kraken(ZEC_BTC)" - }, - CryptoImagePath = "/imlegacy/zcash.png", - UriScheme = "zcash" - }; - var blockExplorerLink = ChainName == ChainName.Mainnet - ? "https://www.exploreZcash.com/transaction/{0}" - : "https://testnet.xmrchain.net/tx/{0}"; - var pmi = PaymentTypes.CHAIN.GetPaymentMethodId("ZEC"); - services.AddDefaultPrettyName(pmi, network.DisplayName); - services.AddBTCPayNetwork(network) - .AddTransactionLinkProvider(pmi, new SimpleTransactionLinkProvider(blockExplorerLink)); - - - services.AddSingleton(provider => - ConfigureZcashLikeConfiguration(provider)); - services.AddSingleton(); - services.AddHostedService(); - services.AddHostedService(); - - - services.AddSingleton(provider => - (IPaymentMethodHandler)ActivatorUtilities.CreateInstance(provider, typeof(ZcashLikePaymentMethodHandler), new object[] { network })); - services.AddSingleton(provider => -(IPaymentLinkExtension)ActivatorUtilities.CreateInstance(provider, typeof(ZcashPaymentLinkExtension), new object[] { network, pmi })); - services.AddSingleton(provider => -(ICheckoutModelExtension)ActivatorUtilities.CreateInstance(provider, typeof(ZcashCheckoutModelExtension), new object[] { network, pmi })); - - services.AddSingleton(); - services.AddSingleton(provider => provider.GetRequiredService()); - services.AddUIExtension("store-nav", "Zcash/StoreNavZcashExtension"); - services.AddUIExtension("store-invoices-payments", "Zcash/ViewZcashLikePaymentData"); - services.AddSingleton(); - - } - static ZcashLikeConfiguration ConfigureZcashLikeConfiguration(IServiceProvider serviceProvider) - { - var configuration = serviceProvider.GetService(); - var btcPayNetworkProvider = serviceProvider.GetRequiredService(); - var result = new ZcashLikeConfiguration(); - - var supportedNetworks = btcPayNetworkProvider.GetAll() - .OfType(); - - foreach (var ZcashLikeSpecificBtcPayNetwork in supportedNetworks) - { - var daemonUri = - configuration.GetOrDefault($"{ZcashLikeSpecificBtcPayNetwork.CryptoCode}_daemon_uri", - null); - var walletDaemonUri = - configuration.GetOrDefault( - $"{ZcashLikeSpecificBtcPayNetwork.CryptoCode}_wallet_daemon_uri", null); - var walletDaemonWalletDirectory = - configuration.GetOrDefault( - $"{ZcashLikeSpecificBtcPayNetwork.CryptoCode}_wallet_daemon_walletdir", null); - if (daemonUri == null || walletDaemonUri == null || walletDaemonWalletDirectory == null) - { - throw new ConfigException($"{ZcashLikeSpecificBtcPayNetwork.CryptoCode} is misconfigured"); - } - - result.ZcashLikeConfigurationItems.Add(ZcashLikeSpecificBtcPayNetwork.CryptoCode, new ZcashLikeConfigurationItem() - { - DaemonRpcUri = daemonUri, - InternalWalletRpcUri = walletDaemonUri, - WalletDirectory = walletDaemonWalletDirectory - }); - } - return result; - } - class SimpleTransactionLinkProvider : DefaultTransactionLinkProvider - { - public SimpleTransactionLinkProvider(string blockExplorerLink) : base(blockExplorerLink) - { - } - - public override string? GetTransactionLink(string paymentId) - { - if (string.IsNullOrEmpty(BlockExplorerLink)) - return null; - return string.Format(CultureInfo.InvariantCulture, BlockExplorerLink, paymentId); - } - } -} - diff --git a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/JsonRpcClient.cs b/BTCPayServer/Plugins/Altcoins/Zcash/RPC/JsonRpcClient.cs deleted file mode 100644 index fd6cb1bd1..000000000 --- a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/JsonRpcClient.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; - -namespace BTCPayServer.Services.Altcoins.Zcash.RPC -{ - public class JsonRpcClient - { - private readonly Uri _address; - private readonly string _username; - private readonly string _password; - private readonly HttpClient _httpClient; - - public JsonRpcClient(Uri address, string username, string password, HttpClient client = null) - { - _address = address; - _username = username; - _password = password; - _httpClient = client ?? new HttpClient(); - } - - - public async Task SendCommandAsync(string method, TRequest data, - CancellationToken cts = default(CancellationToken)) - { - var jsonSerializer = new JsonSerializerSettings - { - ContractResolver = new CamelCasePropertyNamesContractResolver() - }; - var httpRequest = new HttpRequestMessage() - { - Method = HttpMethod.Post, - RequestUri = new Uri(_address, method), - Content = new StringContent( - JsonConvert.SerializeObject(data, jsonSerializer), - Encoding.UTF8, "application/json") - }; - // httpRequest.Headers.Accept.Clear(); - // httpRequest.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - // httpRequest.Headers.Authorization = new AuthenticationHeaderValue("Basic", - // Convert.ToBase64String(Encoding.Default.GetBytes($"{_username}:{_password}"))); - - var rawResult = await _httpClient.SendAsync(httpRequest, cts); - - var rawJson = await rawResult.Content.ReadAsStringAsync(); - rawResult.EnsureSuccessStatusCode(); - var response = JsonConvert.DeserializeObject(rawJson, jsonSerializer); - return response; - } - - public class NoRequestModel - { - public static NoRequestModel Instance = new NoRequestModel(); - } - - internal class JsonRpcApiException : Exception - { - public JsonRpcResultError Error { get; set; } - - public override string Message => Error?.Message; - } - - public class JsonRpcResultError - { - [JsonProperty("code")] public int Code { get; set; } - [JsonProperty("message")] public string Message { get; set; } - [JsonProperty("data")] dynamic Data { get; set; } - } - internal class JsonRpcResult - { - - - [JsonProperty("result")] public T Result { get; set; } - [JsonProperty("error")] public JsonRpcResultError Error { get; set; } - [JsonProperty("id")] public string Id { get; set; } - } - - internal class JsonRpcCommand - { - [JsonProperty("jsonRpc")] public string JsonRpc { get; set; } = "2.0"; - [JsonProperty("id")] public string Id { get; set; } = Guid.NewGuid().ToString(); - [JsonProperty("method")] public string Method { get; set; } - - [JsonProperty("params")] public T Parameters { get; set; } - - public JsonRpcCommand() - { - } - - public JsonRpcCommand(string method, T parameters) - { - Method = method; - Parameters = parameters; - } - } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/CreateAccountRequest.cs b/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/CreateAccountRequest.cs deleted file mode 100644 index 6ce4a3f80..000000000 --- a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/CreateAccountRequest.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Zcash.RPC.Models -{ - public partial class CreateAccountRequest - { - [JsonProperty("label")] public string Label { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/CreateAccountResponse.cs b/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/CreateAccountResponse.cs deleted file mode 100644 index 16f8c6587..000000000 --- a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/CreateAccountResponse.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Zcash.RPC.Models -{ - public partial class CreateAccountResponse - { - [JsonProperty("account_index")] public long AccountIndex { get; set; } - [JsonProperty("address")] public string Address { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/CreateAddressRequest.cs b/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/CreateAddressRequest.cs deleted file mode 100644 index 752579007..000000000 --- a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/CreateAddressRequest.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Zcash.RPC.Models -{ - public partial class CreateAddressRequest - { - [JsonProperty("account_index")] public long AccountIndex { get; set; } - [JsonProperty("label")] public string Label { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/CreateAddressResponse.cs b/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/CreateAddressResponse.cs deleted file mode 100644 index 9603363b8..000000000 --- a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/CreateAddressResponse.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Zcash.RPC.Models -{ - public partial class CreateAddressResponse - { - [JsonProperty("address")] public string Address { get; set; } - [JsonProperty("address_index")] public long AddressIndex { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/GetAccountsRequest.cs b/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/GetAccountsRequest.cs deleted file mode 100644 index fa70211b9..000000000 --- a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/GetAccountsRequest.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Zcash.RPC.Models -{ - public partial class GetAccountsRequest - { - [JsonProperty("tag")] public string Tag { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/GetAccountsResponse.cs b/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/GetAccountsResponse.cs deleted file mode 100644 index 77cbe5703..000000000 --- a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/GetAccountsResponse.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Zcash.RPC.Models -{ - public partial class GetAccountsResponse - { - [JsonProperty("subaddress_accounts")] public List SubaddressAccounts { get; set; } - [JsonProperty("total_balance")] public decimal TotalBalance { get; set; } - - [JsonProperty("total_unlocked_balance")] - public decimal TotalUnlockedBalance { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/GetFeeEstimateRequest.cs b/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/GetFeeEstimateRequest.cs deleted file mode 100644 index 8f3979bd8..000000000 --- a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/GetFeeEstimateRequest.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Zcash.RPC.Models -{ - public class GetFeeEstimateRequest - { - [JsonProperty("grace_blocks")] public int? GraceBlocks { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/GetFeeEstimateResponse.cs b/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/GetFeeEstimateResponse.cs deleted file mode 100644 index f778f1d4b..000000000 --- a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/GetFeeEstimateResponse.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Zcash.RPC.Models -{ - public class GetFeeEstimateResponse - { - [JsonProperty("fee")] public long Fee { get; set; } - [JsonProperty("status")] public string Status { get; set; } - [JsonProperty("untrusted")] public bool Untrusted { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/GetHeightResponse.cs b/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/GetHeightResponse.cs deleted file mode 100644 index 22a867721..000000000 --- a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/GetHeightResponse.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Zcash.RPC.Models -{ - public partial class GetHeightResponse - { - [JsonProperty("height")] public long Height { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/GetTransferByTransactionIdRequest.cs b/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/GetTransferByTransactionIdRequest.cs deleted file mode 100644 index 5e1da36a9..000000000 --- a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/GetTransferByTransactionIdRequest.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Zcash.RPC.Models -{ - public class GetTransferByTransactionIdRequest - { - [JsonProperty("txid")] public string TransactionId { get; set; } - - [JsonProperty("account_index")] public long AccountIndex { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/GetTransferByTransactionIdResponse.cs b/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/GetTransferByTransactionIdResponse.cs deleted file mode 100644 index c985c4425..000000000 --- a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/GetTransferByTransactionIdResponse.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Zcash.RPC.Models -{ - public partial class GetTransferByTransactionIdResponse - { - [JsonProperty("transfer")] public TransferItem Transfer { get; set; } - [JsonProperty("transfers")] public IEnumerable Transfers { get; set; } - - public partial class TransferItem - { - [JsonProperty("address")] public string Address { get; set; } - [JsonProperty("amount")] public long Amount { get; set; } - [JsonProperty("confirmations")] public long Confirmations { get; set; } - [JsonProperty("double_spend_seen")] public bool DoubleSpendSeen { get; set; } - [JsonProperty("height")] public long Height { get; set; } - [JsonProperty("note")] public string Note { get; set; } - [JsonProperty("payment_id")] public string PaymentId { get; set; } - [JsonProperty("subaddr_index")] public SubaddrIndex SubaddrIndex { get; set; } - - [JsonProperty("suggested_confirmations_threshold")] - public long SuggestedConfirmationsThreshold { get; set; } - - [JsonProperty("timestamp")] public long Timestamp { get; set; } - [JsonProperty("txid")] public string Txid { get; set; } - [JsonProperty("type")] public string Type { get; set; } - [JsonProperty("unlock_time")] public long UnlockTime { get; set; } - } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/GetTransfersRequest.cs b/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/GetTransfersRequest.cs deleted file mode 100644 index 8776b958e..000000000 --- a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/GetTransfersRequest.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Zcash.RPC.Models -{ - public partial class GetTransfersRequest - { - [JsonProperty("in")] public bool In { get; set; } - [JsonProperty("out")] public bool Out { get; set; } - [JsonProperty("pending")] public bool Pending { get; set; } - [JsonProperty("failed")] public bool Failed { get; set; } - [JsonProperty("pool")] public bool Pool { get; set; } - [JsonProperty("filter_by_height ")] public bool FilterByHeight { get; set; } - [JsonProperty("min_height")] public long MinHeight { get; set; } - [JsonProperty("max_height")] public long MaxHeight { get; set; } - [JsonProperty("account_index")] public long AccountIndex { get; set; } - [JsonProperty("subaddr_indices")] public List SubaddrIndices { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/GetTransfersResponse.cs b/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/GetTransfersResponse.cs deleted file mode 100644 index faba474ab..000000000 --- a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/GetTransfersResponse.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Zcash.RPC.Models -{ - public partial class GetTransfersResponse - { - [JsonProperty("in")] public List In { get; set; } - [JsonProperty("out")] public List Out { get; set; } - [JsonProperty("pending")] public List Pending { get; set; } - [JsonProperty("failed")] public List Failed { get; set; } - [JsonProperty("pool")] public List Pool { get; set; } - - public partial class GetTransfersResponseItem - - { - [JsonProperty("address")] public string Address { get; set; } - [JsonProperty("amount")] public long Amount { get; set; } - [JsonProperty("confirmations")] public long Confirmations { get; set; } - [JsonProperty("double_spend_seen")] public bool DoubleSpendSeen { get; set; } - [JsonProperty("height")] public long Height { get; set; } - [JsonProperty("note")] public string Note { get; set; } - [JsonProperty("payment_id")] public string PaymentId { get; set; } - [JsonProperty("subaddr_index")] public SubaddrIndex SubaddrIndex { get; set; } - - [JsonProperty("suggested_confirmations_threshold")] - public long SuggestedConfirmationsThreshold { get; set; } - - [JsonProperty("timestamp")] public long Timestamp { get; set; } - [JsonProperty("txid")] public string Txid { get; set; } - [JsonProperty("type")] public string Type { get; set; } - [JsonProperty("unlock_time")] public long UnlockTime { get; set; } - } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/Info.cs b/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/Info.cs deleted file mode 100644 index 6f2ce5e61..000000000 --- a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/Info.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Zcash.RPC.Models -{ - public partial class Info - { - [JsonProperty("address")] public string Address { get; set; } - [JsonProperty("avg_download")] public long AvgDownload { get; set; } - [JsonProperty("avg_upload")] public long AvgUpload { get; set; } - [JsonProperty("connection_id")] public string ConnectionId { get; set; } - [JsonProperty("current_download")] public long CurrentDownload { get; set; } - [JsonProperty("current_upload")] public long CurrentUpload { get; set; } - [JsonProperty("height")] public long Height { get; set; } - [JsonProperty("host")] public string Host { get; set; } - [JsonProperty("incoming")] public bool Incoming { get; set; } - [JsonProperty("ip")] public string Ip { get; set; } - [JsonProperty("live_time")] public long LiveTime { get; set; } - [JsonProperty("local_ip")] public bool LocalIp { get; set; } - [JsonProperty("localhost")] public bool Localhost { get; set; } - [JsonProperty("peer_id")] public string PeerId { get; set; } - - [JsonProperty("port")] - [JsonConverter(typeof(ParseStringConverter))] - public long Port { get; set; } - - [JsonProperty("recv_count")] public long RecvCount { get; set; } - [JsonProperty("recv_idle_time")] public long RecvIdleTime { get; set; } - [JsonProperty("send_count")] public long SendCount { get; set; } - [JsonProperty("send_idle_time")] public long SendIdleTime { get; set; } - [JsonProperty("state")] public string State { get; set; } - [JsonProperty("support_flags")] public long SupportFlags { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/MakeUriRequest.cs b/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/MakeUriRequest.cs deleted file mode 100644 index 0ea22f945..000000000 --- a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/MakeUriRequest.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Zcash.RPC.Models -{ - public partial class MakeUriRequest - { - [JsonProperty("address")] public string Address { get; set; } - [JsonProperty("amount")] public long Amount { get; set; } - [JsonProperty("payment_id")] public string PaymentId { get; set; } - [JsonProperty("tx_description")] public string TxDescription { get; set; } - [JsonProperty("recipient_name")] public string RecipientName { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/MakeUriResponse.cs b/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/MakeUriResponse.cs deleted file mode 100644 index 6a4235dd1..000000000 --- a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/MakeUriResponse.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Zcash.RPC.Models -{ - public partial class MakeUriResponse - { - [JsonProperty("uri")] public string Uri { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/ParseStringConverter.cs b/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/ParseStringConverter.cs deleted file mode 100644 index 3b419d519..000000000 --- a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/ParseStringConverter.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using System.Globalization; -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Zcash.RPC.Models -{ - internal class ParseStringConverter : JsonConverter - { - public override bool CanConvert(Type t) => t == typeof(long) || t == typeof(long?); - - public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) - { - if (reader.TokenType == JsonToken.Null) - return null; - var value = serializer.Deserialize(reader); - long l; - if (Int64.TryParse(value, out l)) - { - return l; - } - - throw new Exception("Cannot unmarshal type long"); - } - - public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) - { - if (untypedValue == null) - { - serializer.Serialize(writer, null); - return; - } - - var value = (long)untypedValue; - serializer.Serialize(writer, value.ToString(CultureInfo.InvariantCulture)); - return; - } - - public static readonly ParseStringConverter Singleton = new ParseStringConverter(); - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/Peer.cs b/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/Peer.cs deleted file mode 100644 index 3425049a0..000000000 --- a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/Peer.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Zcash.RPC.Models -{ - public partial class Peer - { - [JsonProperty("info")] public Info Info { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/SubaddrIndex.cs b/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/SubaddrIndex.cs deleted file mode 100644 index 516ee81cc..000000000 --- a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/SubaddrIndex.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Zcash.RPC.Models -{ - public partial class SubaddrIndex - { - [JsonProperty("major")] public long Major { get; set; } - [JsonProperty("minor")] public long Minor { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/SubaddressAccount.cs b/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/SubaddressAccount.cs deleted file mode 100644 index 6523f0ba0..000000000 --- a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/SubaddressAccount.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Zcash.RPC.Models -{ - public partial class SubaddressAccount - { - [JsonProperty("account_index")] public long AccountIndex { get; set; } - [JsonProperty("balance")] public decimal Balance { get; set; } - [JsonProperty("base_address")] public string BaseAddress { get; set; } - [JsonProperty("label")] public string Label { get; set; } - [JsonProperty("tag")] public string Tag { get; set; } - [JsonProperty("unlocked_balance")] public decimal UnlockedBalance { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/SyncInfoResponse.cs b/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/SyncInfoResponse.cs deleted file mode 100644 index 989ad3d74..000000000 --- a/BTCPayServer/Plugins/Altcoins/Zcash/RPC/Models/SyncInfoResponse.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Zcash.RPC.Models -{ - public partial class SyncInfoResponse - { - [JsonProperty("height")] public long Height { get; set; } - [JsonProperty("peers")] public List Peers { get; set; } - [JsonProperty("status")] public string Status { get; set; } - [JsonProperty("target_height")] public long? TargetHeight { get; set; } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Zcash/Utils/ZcashMoney.cs b/BTCPayServer/Plugins/Altcoins/Zcash/Utils/ZcashMoney.cs deleted file mode 100644 index fe109e0c7..000000000 --- a/BTCPayServer/Plugins/Altcoins/Zcash/Utils/ZcashMoney.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Globalization; - -namespace BTCPayServer.Services.Altcoins.Zcash.Utils -{ - public class ZcashMoney - { - public static decimal Convert(long zat) - { - var amt = zat.ToString(CultureInfo.InvariantCulture).PadLeft(8, '0'); - amt = amt.Length == 8 ? $"0.{amt}" : amt.Insert(amt.Length - 8, "."); - - return decimal.Parse(amt, CultureInfo.InvariantCulture); - } - - public static long Convert(decimal Zcash) - { - return System.Convert.ToInt64(Zcash * 100000000); - } - } -} diff --git a/BTCPayServer/Plugins/Altcoins/Zcash/ZcashLikeSpecificBtcPayNetwork.cs b/BTCPayServer/Plugins/Altcoins/Zcash/ZcashLikeSpecificBtcPayNetwork.cs deleted file mode 100644 index 98fc75e31..000000000 --- a/BTCPayServer/Plugins/Altcoins/Zcash/ZcashLikeSpecificBtcPayNetwork.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace BTCPayServer.Plugins.Altcoins; - -public class ZcashLikeSpecificBtcPayNetwork : BTCPayNetworkBase -{ - public int MaxTrackedConfirmation = 10; - public string UriScheme { get; set; } -} diff --git a/BTCPayServer/Properties/launchSettings.json b/BTCPayServer/Properties/launchSettings.json index f471ce64a..9d26da915 100644 --- a/BTCPayServer/Properties/launchSettings.json +++ b/BTCPayServer/Properties/launchSettings.json @@ -181,8 +181,7 @@ "BTCPAY_CHEATMODE": "true", "BTCPAY_EXPLORERPOSTGRES": "User ID=postgres;Include Error Detail=true;Host=127.0.0.1;Port=39372;Database=nbxplorer", "BTCPAY_XMR_DAEMON_URI": "http://127.0.0.1:18081", - "BTCPAY_XMR_WALLET_DAEMON_URI": "http://127.0.0.1:18082", - "BTCPAY_XMR_WALLET_DAEMON_WALLETDIR": "/path/to/monero_wallet" + "BTCPAY_XMR_WALLET_DAEMON_URI": "http://127.0.0.1:18082" }, "applicationUrl": "https://localhost:14142/" }, @@ -221,10 +220,7 @@ "BTCPAY_DOCKERDEPLOYMENT": "true", "BTCPAY_RECOMMENDED-PLUGINS": "", "BTCPAY_CHEATMODE": "true", - "BTCPAY_EXPLORERPOSTGRES": "User ID=postgres;Include Error Detail=true;Host=127.0.0.1;Port=39372;Database=nbxplorer", - "BTCPAY_XMR_DAEMON_URI": "http://127.0.0.1:18081", - "BTCPAY_XMR_WALLET_DAEMON_URI": "http://127.0.0.1:18082", - "BTCPAY_XMR_WALLET_DAEMON_WALLETDIR": "/path/to/monero_wallet" + "BTCPAY_EXPLORERPOSTGRES": "User ID=postgres;Include Error Detail=true;Host=127.0.0.1;Port=39372;Database=nbxplorer" }, "applicationUrl": "https://localhost:14142/" } diff --git a/BTCPayServer/Services/Altcoins/Monero/Configuration/MoneroLikeConfiguration.cs b/BTCPayServer/Services/Altcoins/Monero/Configuration/MoneroLikeConfiguration.cs deleted file mode 100644 index c99002abe..000000000 --- a/BTCPayServer/Services/Altcoins/Monero/Configuration/MoneroLikeConfiguration.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace BTCPayServer.Services.Altcoins.Monero.Configuration -{ - public class MoneroLikeConfiguration - { - public Dictionary MoneroLikeConfigurationItems { get; set; } = - new Dictionary(); - } - - public class MoneroLikeConfigurationItem - { - public Uri DaemonRpcUri { get; set; } - public Uri InternalWalletRpcUri { get; set; } - public string WalletDirectory { get; set; } - public string Username { get; set; } - public string Password { get; set; } - } -} diff --git a/BTCPayServer/Services/Altcoins/Monero/Payments/MoneroCheckoutModelExtension.cs b/BTCPayServer/Services/Altcoins/Monero/Payments/MoneroCheckoutModelExtension.cs deleted file mode 100644 index 7d00784b0..000000000 --- a/BTCPayServer/Services/Altcoins/Monero/Payments/MoneroCheckoutModelExtension.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using BTCPayServer.Payments; -using BTCPayServer.Payments.Bitcoin; -using BTCPayServer.Payments.Lightning; -using BTCPayServer.Services.Altcoins.Monero.Services; -using BTCPayServer.Services.Invoices; - -namespace BTCPayServer.Services.Altcoins.Monero.Payments -{ - public class MoneroCheckoutModelExtension : ICheckoutModelExtension - { - private readonly BTCPayNetworkBase _network; - private readonly PaymentMethodHandlerDictionary _handlers; - private readonly IPaymentLinkExtension paymentLinkExtension; - - public MoneroCheckoutModelExtension( - PaymentMethodId paymentMethodId, - IEnumerable paymentLinkExtensions, - BTCPayNetworkBase network, - PaymentMethodHandlerDictionary handlers) - { - PaymentMethodId = paymentMethodId; - _network = network; - _handlers = handlers; - paymentLinkExtension = paymentLinkExtensions.Single(p => p.PaymentMethodId == PaymentMethodId); - } - public PaymentMethodId PaymentMethodId { get; } - - public string Image => _network.CryptoImagePath; - public string Badge => ""; - - public void ModifyCheckoutModel(CheckoutModelContext context) - { - if (context is not { Handler: MoneroLikePaymentMethodHandler handler }) - return; - context.Model.CheckoutBodyComponentName = BitcoinCheckoutModelExtension.CheckoutBodyComponentName; - var details = context.InvoiceEntity.GetPayments(true) - .Select(p => p.GetDetails(handler)) - .Where(p => p is not null) - .FirstOrDefault(); - if (details is not null) - { - context.Model.ReceivedConfirmations = details.ConfirmationCount; - context.Model.RequiredConfirmations = (int)MoneroListener.ConfirmationsRequired(details, context.InvoiceEntity.SpeedPolicy); - } - - context.Model.InvoiceBitcoinUrl = paymentLinkExtension.GetPaymentLink(context.Prompt, context.UrlHelper); - context.Model.InvoiceBitcoinUrlQR = context.Model.InvoiceBitcoinUrl; - } - } -} diff --git a/BTCPayServer/Services/Altcoins/Monero/Payments/MoneroLikeOnChainPaymentMethodDetails.cs b/BTCPayServer/Services/Altcoins/Monero/Payments/MoneroLikeOnChainPaymentMethodDetails.cs deleted file mode 100644 index a0d29ec23..000000000 --- a/BTCPayServer/Services/Altcoins/Monero/Payments/MoneroLikeOnChainPaymentMethodDetails.cs +++ /dev/null @@ -1,11 +0,0 @@ -using BTCPayServer.Payments; - -namespace BTCPayServer.Services.Altcoins.Monero.Payments -{ - public class MoneroLikeOnChainPaymentMethodDetails - { - public long AccountIndex { get; set; } - public long AddressIndex { get; set; } - public long? InvoiceSettledConfirmationThreshold { get; set; } - } -} diff --git a/BTCPayServer/Services/Altcoins/Monero/Payments/MoneroLikePaymentData.cs b/BTCPayServer/Services/Altcoins/Monero/Payments/MoneroLikePaymentData.cs deleted file mode 100644 index 6a3d79b3d..000000000 --- a/BTCPayServer/Services/Altcoins/Monero/Payments/MoneroLikePaymentData.cs +++ /dev/null @@ -1,20 +0,0 @@ -using BTCPayServer.Client.Models; -using BTCPayServer.Payments; -using BTCPayServer.Plugins.Altcoins; -using BTCPayServer.Services.Altcoins.Monero.Utils; -using BTCPayServer.Services.Invoices; - -namespace BTCPayServer.Services.Altcoins.Monero.Payments -{ - public class MoneroLikePaymentData - { - public long SubaddressIndex { get; set; } - public long SubaccountIndex { get; set; } - public long BlockHeight { get; set; } - public long ConfirmationCount { get; set; } - public string TransactionId { get; set; } - public long? InvoiceSettledConfirmationThreshold { get; set; } - - public long LockTime { get; set; } = 0; - } -} diff --git a/BTCPayServer/Services/Altcoins/Monero/Payments/MoneroLikePaymentMethodHandler.cs b/BTCPayServer/Services/Altcoins/Monero/Payments/MoneroLikePaymentMethodHandler.cs deleted file mode 100644 index 5101b73f2..000000000 --- a/BTCPayServer/Services/Altcoins/Monero/Payments/MoneroLikePaymentMethodHandler.cs +++ /dev/null @@ -1,120 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Threading.Tasks; -using AngleSharp.Dom; -using BTCPayServer.Abstractions.Extensions; -using BTCPayServer.BIP78.Sender; -using BTCPayServer.Data; -using BTCPayServer.Logging; -using BTCPayServer.Models; -using BTCPayServer.Models.InvoicingModels; -using BTCPayServer.Payments; -using BTCPayServer.Plugins.Altcoins; -using BTCPayServer.Rating; -using BTCPayServer.Services.Altcoins.Monero.RPC.Models; -using BTCPayServer.Services.Altcoins.Monero.Services; -using BTCPayServer.Services.Altcoins.Monero.Utils; -using BTCPayServer.Services.Altcoins.Zcash.Payments; -using BTCPayServer.Services.Invoices; -using BTCPayServer.Services.Rates; -using NBitcoin; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - -namespace BTCPayServer.Services.Altcoins.Monero.Payments -{ - public class MoneroLikePaymentMethodHandler : IPaymentMethodHandler - { - private readonly MoneroLikeSpecificBtcPayNetwork _network; - public MoneroLikeSpecificBtcPayNetwork Network => _network; - public JsonSerializer Serializer { get; } - private readonly MoneroRPCProvider _moneroRpcProvider; - - public PaymentMethodId PaymentMethodId { get; } - - public MoneroLikePaymentMethodHandler(MoneroLikeSpecificBtcPayNetwork network, MoneroRPCProvider moneroRpcProvider) - { - PaymentMethodId = PaymentTypes.CHAIN.GetPaymentMethodId(network.CryptoCode); - _network = network; - Serializer = BlobSerializer.CreateSerializer().Serializer; - _moneroRpcProvider = moneroRpcProvider; - } - - public Task BeforeFetchingRates(PaymentMethodContext context) - { - context.Prompt.Currency = _network.CryptoCode; - context.Prompt.Divisibility = _network.Divisibility; - if (context.Prompt.Activated) - { - var supportedPaymentMethod = ParsePaymentMethodConfig(context.PaymentMethodConfig); - var walletClient = _moneroRpcProvider.WalletRpcClients[_network.CryptoCode]; - var daemonClient = _moneroRpcProvider.DaemonRpcClients[_network.CryptoCode]; - context.State = new Prepare() - { - GetFeeRate = daemonClient.SendCommandAsync("get_fee_estimate", new GetFeeEstimateRequest()), - ReserveAddress = s => walletClient.SendCommandAsync("create_address", new CreateAddressRequest() { Label = $"btcpay invoice #{s}", AccountIndex = supportedPaymentMethod.AccountIndex }), - AccountIndex = supportedPaymentMethod.AccountIndex - }; - } - return Task.CompletedTask; - } - - public async Task ConfigurePrompt(PaymentMethodContext context) - { - if (!_moneroRpcProvider.IsAvailable(_network.CryptoCode)) - throw new PaymentMethodUnavailableException($"Node or wallet not available"); - var invoice = context.InvoiceEntity; - Prepare moneroPrepare = (Prepare)context.State; - var feeRatePerKb = await moneroPrepare.GetFeeRate; - var address = await moneroPrepare.ReserveAddress(invoice.Id); - - var feeRatePerByte = feeRatePerKb.Fee / 1024; - var details = new MoneroLikeOnChainPaymentMethodDetails() - { - AccountIndex = moneroPrepare.AccountIndex, - AddressIndex = address.AddressIndex, - InvoiceSettledConfirmationThreshold = ParsePaymentMethodConfig(context.PaymentMethodConfig).InvoiceSettledConfirmationThreshold - }; - context.Prompt.Destination = address.Address; - context.Prompt.PaymentMethodFee = MoneroMoney.Convert(feeRatePerByte * 100); - context.Prompt.Details = JObject.FromObject(details, Serializer); - context.TrackedDestinations.Add(address.Address); - } - private MoneroPaymentPromptDetails ParsePaymentMethodConfig(JToken config) - { - return config.ToObject(Serializer) ?? throw new FormatException($"Invalid {nameof(MoneroLikePaymentMethodHandler)}"); - } - object IPaymentMethodHandler.ParsePaymentMethodConfig(JToken config) - { - return ParsePaymentMethodConfig(config); - } - - class Prepare - { - public Task GetFeeRate; - public Func> ReserveAddress; - - public long AccountIndex { get; internal set; } - } - - public MoneroLikeOnChainPaymentMethodDetails ParsePaymentPromptDetails(Newtonsoft.Json.Linq.JToken details) - { - return details.ToObject(Serializer); - } - object IPaymentMethodHandler.ParsePaymentPromptDetails(Newtonsoft.Json.Linq.JToken details) - { - return ParsePaymentPromptDetails(details); - } - - public MoneroLikePaymentData ParsePaymentDetails(JToken details) - { - return details.ToObject(Serializer) ?? throw new FormatException($"Invalid {nameof(MoneroLikePaymentMethodHandler)}"); - } - object IPaymentMethodHandler.ParsePaymentDetails(JToken details) - { - return ParsePaymentDetails(details); - } - } -} diff --git a/BTCPayServer/Services/Altcoins/Monero/Payments/MoneroPaymentLinkExtension.cs b/BTCPayServer/Services/Altcoins/Monero/Payments/MoneroPaymentLinkExtension.cs deleted file mode 100644 index 88a3718df..000000000 --- a/BTCPayServer/Services/Altcoins/Monero/Payments/MoneroPaymentLinkExtension.cs +++ /dev/null @@ -1,27 +0,0 @@ -#nullable enable -using System.Globalization; -using BTCPayServer.Payments; -using BTCPayServer.Plugins.Altcoins; -using BTCPayServer.Services.Invoices; -using Microsoft.AspNetCore.Mvc; - -namespace BTCPayServer.Services.Altcoins.Monero.Payments -{ - public class MoneroPaymentLinkExtension : IPaymentLinkExtension - { - private readonly MoneroLikeSpecificBtcPayNetwork _network; - - public MoneroPaymentLinkExtension(PaymentMethodId paymentMethodId, MoneroLikeSpecificBtcPayNetwork network) - { - PaymentMethodId = paymentMethodId; - _network = network; - } - public PaymentMethodId PaymentMethodId { get; } - - public string? GetPaymentLink(PaymentPrompt prompt, IUrlHelper? urlHelper) - { - var due = prompt.Calculate().Due; - return $"{_network.UriScheme}:{prompt.Destination}?tx_amount={due.ToString(CultureInfo.InvariantCulture)}"; - } - } -} diff --git a/BTCPayServer/Services/Altcoins/Monero/Payments/MoneroPaymentPromptDetails.cs b/BTCPayServer/Services/Altcoins/Monero/Payments/MoneroPaymentPromptDetails.cs deleted file mode 100644 index 7e7212b91..000000000 --- a/BTCPayServer/Services/Altcoins/Monero/Payments/MoneroPaymentPromptDetails.cs +++ /dev/null @@ -1,11 +0,0 @@ -using BTCPayServer.Payments; -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Monero.Payments -{ - public class MoneroPaymentPromptDetails - { - public long AccountIndex { get; set; } - public long? InvoiceSettledConfirmationThreshold { get; set; } - } -} diff --git a/BTCPayServer/Services/Altcoins/Monero/RPC/MoneroDaemonCallbackController.cs b/BTCPayServer/Services/Altcoins/Monero/RPC/MoneroDaemonCallbackController.cs deleted file mode 100644 index 3b2634d94..000000000 --- a/BTCPayServer/Services/Altcoins/Monero/RPC/MoneroDaemonCallbackController.cs +++ /dev/null @@ -1,38 +0,0 @@ -using BTCPayServer.Filters; -using Microsoft.AspNetCore.Mvc; - -namespace BTCPayServer.Services.Altcoins.Monero.RPC -{ - [Route("[controller]")] - [OnlyIfSupportAttribute("XMR-CHAIN")] - public class MoneroLikeDaemonCallbackController : Controller - { - private readonly EventAggregator _eventAggregator; - - public MoneroLikeDaemonCallbackController(EventAggregator eventAggregator) - { - _eventAggregator = eventAggregator; - } - [HttpGet("block")] - public IActionResult OnBlockNotify(string hash, string cryptoCode) - { - _eventAggregator.Publish(new MoneroEvent() - { - BlockHash = hash, - CryptoCode = cryptoCode.ToUpperInvariant() - }); - return Ok(); - } - [HttpGet("tx")] - public IActionResult OnTransactionNotify(string hash, string cryptoCode) - { - _eventAggregator.Publish(new MoneroEvent() - { - TransactionHash = hash, - CryptoCode = cryptoCode.ToUpperInvariant() - }); - return Ok(); - } - - } -} diff --git a/BTCPayServer/Services/Altcoins/Monero/RPC/MoneroEvent.cs b/BTCPayServer/Services/Altcoins/Monero/RPC/MoneroEvent.cs deleted file mode 100644 index 4821730ec..000000000 --- a/BTCPayServer/Services/Altcoins/Monero/RPC/MoneroEvent.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace BTCPayServer.Services.Altcoins.Monero.RPC -{ - public class MoneroEvent - { - public string BlockHash { get; set; } - public string TransactionHash { get; set; } - public string CryptoCode { get; set; } - - public override string ToString() - { - return - $"{CryptoCode}: {(string.IsNullOrEmpty(TransactionHash) ? string.Empty : "Tx Update")}{(string.IsNullOrEmpty(BlockHash) ? string.Empty : "New Block")} ({TransactionHash ?? string.Empty}{BlockHash ?? string.Empty})"; - } - } -} diff --git a/BTCPayServer/Services/Altcoins/Monero/Services/MoneroLikeSummaryUpdaterHostedService.cs b/BTCPayServer/Services/Altcoins/Monero/Services/MoneroLikeSummaryUpdaterHostedService.cs deleted file mode 100644 index 0aeff2c58..000000000 --- a/BTCPayServer/Services/Altcoins/Monero/Services/MoneroLikeSummaryUpdaterHostedService.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Threading; -using System.Threading.Tasks; -using BTCPayServer.Logging; -using BTCPayServer.Services.Altcoins.Monero.Configuration; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; - -namespace BTCPayServer.Services.Altcoins.Monero.Services -{ - public class MoneroLikeSummaryUpdaterHostedService : IHostedService - { - private readonly MoneroRPCProvider _MoneroRpcProvider; - private readonly MoneroLikeConfiguration _moneroLikeConfiguration; - - public Logs Logs { get; } - - private CancellationTokenSource _Cts; - public MoneroLikeSummaryUpdaterHostedService(MoneroRPCProvider moneroRpcProvider, MoneroLikeConfiguration moneroLikeConfiguration, Logs logs) - { - _MoneroRpcProvider = moneroRpcProvider; - _moneroLikeConfiguration = moneroLikeConfiguration; - Logs = logs; - } - public Task StartAsync(CancellationToken cancellationToken) - { - _Cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); - foreach (var moneroLikeConfigurationItem in _moneroLikeConfiguration.MoneroLikeConfigurationItems) - { - _ = StartLoop(_Cts.Token, moneroLikeConfigurationItem.Key); - } - return Task.CompletedTask; - } - - private async Task StartLoop(CancellationToken cancellation, string cryptoCode) - { - Logs.PayServer.LogInformation($"Starting listening Monero-like daemons ({cryptoCode})"); - try - { - while (!cancellation.IsCancellationRequested) - { - try - { - await _MoneroRpcProvider.UpdateSummary(cryptoCode); - if (_MoneroRpcProvider.IsAvailable(cryptoCode)) - { - await Task.Delay(TimeSpan.FromMinutes(1), cancellation); - } - else - { - await Task.Delay(TimeSpan.FromSeconds(10), cancellation); - } - } - catch (Exception ex) when (!cancellation.IsCancellationRequested) - { - Logs.PayServer.LogError(ex, $"Unhandled exception in Summary updater ({cryptoCode})"); - await Task.Delay(TimeSpan.FromSeconds(10), cancellation); - } - } - } - catch when (cancellation.IsCancellationRequested) { } - } - - public Task StopAsync(CancellationToken cancellationToken) - { - _Cts?.Cancel(); - return Task.CompletedTask; - } - } -} diff --git a/BTCPayServer/Services/Altcoins/Monero/Services/MoneroListener.cs b/BTCPayServer/Services/Altcoins/Monero/Services/MoneroListener.cs deleted file mode 100644 index dd2cdac37..000000000 --- a/BTCPayServer/Services/Altcoins/Monero/Services/MoneroListener.cs +++ /dev/null @@ -1,401 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Channels; -using System.Threading.Tasks; -using BTCPayServer.Client.Models; -using BTCPayServer.Data; -using BTCPayServer.Events; -using BTCPayServer.HostedServices; -using BTCPayServer.Payments; -using BTCPayServer.Plugins.Altcoins; -using BTCPayServer.Services.Altcoins.Monero.Configuration; -using BTCPayServer.Services.Altcoins.Monero.Payments; -using BTCPayServer.Services.Altcoins.Monero.RPC; -using BTCPayServer.Services.Altcoins.Monero.RPC.Models; -using BTCPayServer.Services.Altcoins.Monero.Utils; -using BTCPayServer.Services.Altcoins.Zcash.Utils; -using BTCPayServer.Services.Invoices; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -using NBitcoin; -using NBXplorer; -using Newtonsoft.Json.Linq; - -namespace BTCPayServer.Services.Altcoins.Monero.Services -{ - public class MoneroListener : EventHostedServiceBase - { - private readonly InvoiceRepository _invoiceRepository; - private readonly EventAggregator _eventAggregator; - private readonly MoneroRPCProvider _moneroRpcProvider; - private readonly MoneroLikeConfiguration _MoneroLikeConfiguration; - private readonly BTCPayNetworkProvider _networkProvider; - private readonly ILogger _logger; - private readonly PaymentMethodHandlerDictionary _handlers; - private readonly InvoiceActivator _invoiceActivator; - private readonly PaymentService _paymentService; - - public MoneroListener(InvoiceRepository invoiceRepository, - EventAggregator eventAggregator, - MoneroRPCProvider moneroRpcProvider, - MoneroLikeConfiguration moneroLikeConfiguration, - BTCPayNetworkProvider networkProvider, - ILogger logger, - PaymentMethodHandlerDictionary handlers, - InvoiceActivator invoiceActivator, - PaymentService paymentService) : base(eventAggregator, logger) - { - _invoiceRepository = invoiceRepository; - _eventAggregator = eventAggregator; - _moneroRpcProvider = moneroRpcProvider; - _MoneroLikeConfiguration = moneroLikeConfiguration; - _networkProvider = networkProvider; - _logger = logger; - _handlers = handlers; - _invoiceActivator = invoiceActivator; - _paymentService = paymentService; - } - - protected override void SubscribeToEvents() - { - base.SubscribeToEvents(); - Subscribe(); - Subscribe(); - } - - protected override async Task ProcessEvent(object evt, CancellationToken cancellationToken) - { - if (evt is MoneroRPCProvider.MoneroDaemonStateChange stateChange) - { - if (_moneroRpcProvider.IsAvailable(stateChange.CryptoCode)) - { - _logger.LogInformation($"{stateChange.CryptoCode} just became available"); - _ = UpdateAnyPendingMoneroLikePayment(stateChange.CryptoCode); - } - else - { - _logger.LogInformation($"{stateChange.CryptoCode} just became unavailable"); - } - } - else if (evt is MoneroEvent moneroEvent) - { - if (!_moneroRpcProvider.IsAvailable(moneroEvent.CryptoCode)) - return; - - if (!string.IsNullOrEmpty(moneroEvent.BlockHash)) - { - await OnNewBlock(moneroEvent.CryptoCode); - } - if (!string.IsNullOrEmpty(moneroEvent.TransactionHash)) - { - await OnTransactionUpdated(moneroEvent.CryptoCode, moneroEvent.TransactionHash); - } - } - } - - private async Task ReceivedPayment(InvoiceEntity invoice, PaymentEntity payment) - { - _logger.LogInformation( - $"Invoice {invoice.Id} received payment {payment.Value} {payment.Currency} {payment.Id}"); - - var prompt = invoice.GetPaymentPrompt(payment.PaymentMethodId); - - if (prompt != null && - prompt.Activated && - prompt.Destination == payment.Destination && - prompt.Calculate().Due > 0.0m) - { - await _invoiceActivator.ActivateInvoicePaymentMethod(invoice.Id, payment.PaymentMethodId, true); - invoice = await _invoiceRepository.GetInvoice(invoice.Id); - } - - _eventAggregator.Publish( - new InvoiceEvent(invoice, InvoiceEvent.ReceivedPayment) { Payment = payment }); - } - - private async Task UpdatePaymentStates(string cryptoCode, InvoiceEntity[] invoices) - { - if (!invoices.Any()) - { - return; - } - - var moneroWalletRpcClient = _moneroRpcProvider.WalletRpcClients[cryptoCode]; - var network = _networkProvider.GetNetwork(cryptoCode); - var paymentId = PaymentTypes.CHAIN.GetPaymentMethodId(network.CryptoCode); - var handler = (MoneroLikePaymentMethodHandler)_handlers[paymentId]; - - //get all the required data in one list (invoice, its existing payments and the current payment method details) - var expandedInvoices = invoices.Select(entity => (Invoice: entity, - ExistingPayments: GetAllMoneroLikePayments(entity, cryptoCode), - Prompt: entity.GetPaymentPrompt(paymentId), - PaymentMethodDetails: handler.ParsePaymentPromptDetails(entity.GetPaymentPrompt(paymentId).Details))) - .Select(tuple => ( - tuple.Invoice, - tuple.PaymentMethodDetails, - tuple.Prompt, - ExistingPayments: tuple.ExistingPayments.Select(entity => - (Payment: entity, PaymentData: handler.ParsePaymentDetails(entity.Details), - tuple.Invoice)) - )); - - var existingPaymentData = expandedInvoices.SelectMany(tuple => tuple.ExistingPayments); - - var accountToAddressQuery = new Dictionary>(); - //create list of subaddresses to account to query the monero wallet - foreach (var expandedInvoice in expandedInvoices) - { - var addressIndexList = - accountToAddressQuery.GetValueOrDefault(expandedInvoice.PaymentMethodDetails.AccountIndex, - new List()); - - addressIndexList.AddRange( - expandedInvoice.ExistingPayments.Select(tuple => tuple.PaymentData.SubaddressIndex)); - addressIndexList.Add(expandedInvoice.PaymentMethodDetails.AddressIndex); - accountToAddressQuery.AddOrReplace(expandedInvoice.PaymentMethodDetails.AccountIndex, addressIndexList); - } - - var tasks = accountToAddressQuery.ToDictionary(datas => datas.Key, - datas => moneroWalletRpcClient.SendCommandAsync( - "get_transfers", - new GetTransfersRequest() - { - AccountIndex = datas.Key, - In = true, - SubaddrIndices = datas.Value.Distinct().ToList() - })); - - await Task.WhenAll(tasks.Values); - - - var transferProcessingTasks = new List(); - - var updatedPaymentEntities = new List<(PaymentEntity Payment, InvoiceEntity invoice)>(); - foreach (var keyValuePair in tasks) - { - var transfers = keyValuePair.Value.Result.In; - if (transfers == null) - { - continue; - } - - transferProcessingTasks.AddRange(transfers.Select(transfer => - { - InvoiceEntity invoice = null; - var existingMatch = existingPaymentData.SingleOrDefault(tuple => - tuple.Payment.Destination == transfer.Address && - tuple.PaymentData.TransactionId == transfer.Txid); - - if (existingMatch.Invoice != null) - { - invoice = existingMatch.Invoice; - } - else - { - var newMatch = expandedInvoices.SingleOrDefault(tuple => - tuple.Prompt.Destination == transfer.Address); - - if (newMatch.Invoice == null) - { - return Task.CompletedTask; - } - - invoice = newMatch.Invoice; - } - - - return HandlePaymentData(cryptoCode, transfer.Address, transfer.Amount, transfer.SubaddrIndex.Major, - transfer.SubaddrIndex.Minor, transfer.Txid, transfer.Confirmations, transfer.Height, transfer.UnlockTime,invoice, - updatedPaymentEntities); - })); - } - - transferProcessingTasks.Add( - _paymentService.UpdatePayments(updatedPaymentEntities.Select(tuple => tuple.Item1).ToList())); - await Task.WhenAll(transferProcessingTasks); - foreach (var valueTuples in updatedPaymentEntities.GroupBy(entity => entity.Item2)) - { - if (valueTuples.Any()) - { - _eventAggregator.Publish(new Events.InvoiceNeedUpdateEvent(valueTuples.Key.Id)); - } - } - } - - private async Task OnNewBlock(string cryptoCode) - { - await UpdateAnyPendingMoneroLikePayment(cryptoCode); - _eventAggregator.Publish(new NewBlockEvent() { PaymentMethodId = PaymentTypes.CHAIN.GetPaymentMethodId(cryptoCode) }); - } - - private async Task OnTransactionUpdated(string cryptoCode, string transactionHash) - { - var paymentMethodId = PaymentTypes.CHAIN.GetPaymentMethodId(cryptoCode); - var transfer = await GetTransferByTxId(cryptoCode, transactionHash, this.CancellationToken); - - var paymentsToUpdate = new List<(PaymentEntity Payment, InvoiceEntity invoice)>(); - - //group all destinations of the tx together and loop through the sets - foreach (var destination in transfer.Transfers.GroupBy(destination => destination.Address)) - { - //find the invoice corresponding to this address, else skip - var invoice = await _invoiceRepository.GetInvoiceFromAddress(paymentMethodId, destination.Key); - if (invoice == null) - continue; - - var index = destination.First().SubaddrIndex; - - await HandlePaymentData(cryptoCode, - destination.Key, - destination.Sum(destination1 => destination1.Amount), - index.Major, - index.Minor, - transfer.Transfer.Txid, - transfer.Transfer.Confirmations, - transfer.Transfer.Height - , transfer.Transfer.UnlockTime,invoice, paymentsToUpdate); - } - - if (paymentsToUpdate.Any()) - { - await _paymentService.UpdatePayments(paymentsToUpdate.Select(tuple => tuple.Payment).ToList()); - foreach (var valueTuples in paymentsToUpdate.GroupBy(entity => entity.invoice)) - { - if (valueTuples.Any()) - { - _eventAggregator.Publish(new Events.InvoiceNeedUpdateEvent(valueTuples.Key.Id)); - } - } - } - } - - private async Task GetTransferByTxId(string cryptoCode, - string transactionHash, CancellationToken cancellationToken) - { - var accounts = await _moneroRpcProvider.WalletRpcClients[cryptoCode].SendCommandAsync("get_accounts", new GetAccountsRequest(), cancellationToken); - var accountIndexes = accounts - .SubaddressAccounts - .Select(a => new long?(a.AccountIndex)) - .ToList(); - if (accountIndexes.Count is 0) - accountIndexes.Add(null); - var req = accountIndexes - .Select(i => GetTransferByTxId(cryptoCode, transactionHash, i)) - .ToArray(); - foreach (var task in req) - { - var result = await task; - if (result != null) - return result; - } - - return null; - } - - private async Task GetTransferByTxId(string cryptoCode, string transactionHash, long? accountIndex) - { - try - { - var result = await _moneroRpcProvider.WalletRpcClients[cryptoCode] - .SendCommandAsync( - "get_transfer_by_txid", - new GetTransferByTransactionIdRequest() - { - TransactionId = transactionHash, - AccountIndex = accountIndex - }); - return result; - } - catch (JsonRpcClient.JsonRpcApiException) - { - return null; - } - } - - private async Task HandlePaymentData(string cryptoCode, string address, long totalAmount, long subaccountIndex, - long subaddressIndex, - string txId, long confirmations, long blockHeight, long locktime, InvoiceEntity invoice, - List<(PaymentEntity Payment, InvoiceEntity invoice)> paymentsToUpdate) - { - var network = _networkProvider.GetNetwork(cryptoCode); - var pmi = PaymentTypes.CHAIN.GetPaymentMethodId(network.CryptoCode); - var handler = (MoneroLikePaymentMethodHandler)_handlers[pmi]; - var promptDetails = handler.ParsePaymentPromptDetails(invoice.GetPaymentPrompt(pmi).Details); - var details = new MoneroLikePaymentData() - { - SubaccountIndex = subaccountIndex, - SubaddressIndex = subaddressIndex, - TransactionId = txId, - ConfirmationCount = confirmations, - BlockHeight = blockHeight, - LockTime = locktime, - InvoiceSettledConfirmationThreshold = promptDetails.InvoiceSettledConfirmationThreshold - }; - var status = GetStatus(details, invoice.SpeedPolicy) ? PaymentStatus.Settled : PaymentStatus.Processing; - var paymentData = new Data.PaymentData() - { - Status = status, - Amount = MoneroMoney.Convert(totalAmount), - Created = DateTimeOffset.UtcNow, - Id = $"{txId}#{subaccountIndex}#{subaddressIndex}", - Currency = network.CryptoCode, - InvoiceDataId = invoice.Id, - }.Set(invoice, handler, details); - - - //check if this tx exists as a payment to this invoice already - var alreadyExistingPaymentThatMatches = GetAllMoneroLikePayments(invoice, cryptoCode) - .SingleOrDefault(c => c.Id == paymentData.Id && c.PaymentMethodId == pmi); - - //if it doesnt, add it and assign a new monerolike address to the system if a balance is still due - if (alreadyExistingPaymentThatMatches == null) - { - var payment = await _paymentService.AddPayment(paymentData, [txId]); - if (payment != null) - await ReceivedPayment(invoice, payment); - } - else - { - //else update it with the new data - alreadyExistingPaymentThatMatches.Status = status; - alreadyExistingPaymentThatMatches.Details = JToken.FromObject(details, handler.Serializer); - paymentsToUpdate.Add((alreadyExistingPaymentThatMatches, invoice)); - } - } - - private bool GetStatus(MoneroLikePaymentData details, SpeedPolicy speedPolicy) - => ConfirmationsRequired(details, speedPolicy) <= details.ConfirmationCount; - - public static long ConfirmationsRequired(MoneroLikePaymentData details, SpeedPolicy speedPolicy) - => (details, speedPolicy) switch - { - (_, _) when details.ConfirmationCount < details.LockTime => details.LockTime - details.ConfirmationCount, - ({ InvoiceSettledConfirmationThreshold: long v }, _) => v, - (_, SpeedPolicy.HighSpeed) => 0, - (_, SpeedPolicy.MediumSpeed) => 1, - (_, SpeedPolicy.LowMediumSpeed) => 2, - (_, SpeedPolicy.LowSpeed) => 6, - _ => 6, - }; - - - private async Task UpdateAnyPendingMoneroLikePayment(string cryptoCode) - { - var paymentMethodId = PaymentTypes.CHAIN.GetPaymentMethodId(cryptoCode); - var invoices = await _invoiceRepository.GetMonitoredInvoices(paymentMethodId); - if (!invoices.Any()) - return; - invoices = invoices.Where(entity => entity.GetPaymentPrompt(paymentMethodId)?.Activated is true).ToArray(); - await UpdatePaymentStates(cryptoCode, invoices); - } - - private IEnumerable GetAllMoneroLikePayments(InvoiceEntity invoice, string cryptoCode) - { - return invoice.GetPayments(false) - .Where(p => p.PaymentMethodId == PaymentTypes.CHAIN.GetPaymentMethodId(cryptoCode)); - } - } -} diff --git a/BTCPayServer/Services/Altcoins/Monero/Services/MoneroRPCProvider.cs b/BTCPayServer/Services/Altcoins/Monero/Services/MoneroRPCProvider.cs deleted file mode 100644 index 72a81bf9f..000000000 --- a/BTCPayServer/Services/Altcoins/Monero/Services/MoneroRPCProvider.cs +++ /dev/null @@ -1,118 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Immutable; -using System.Net.Http; -using System.Threading.Tasks; -using BTCPayServer.Services.Altcoins.Monero.Configuration; -using BTCPayServer.Services.Altcoins.Monero.RPC; -using BTCPayServer.Services.Altcoins.Monero.RPC.Models; -using NBitcoin; - -namespace BTCPayServer.Services.Altcoins.Monero.Services -{ - public class MoneroRPCProvider - { - private readonly MoneroLikeConfiguration _moneroLikeConfiguration; - private readonly EventAggregator _eventAggregator; - public ImmutableDictionary DaemonRpcClients; - public ImmutableDictionary WalletRpcClients; - - private readonly ConcurrentDictionary _summaries = - new ConcurrentDictionary(); - - public ConcurrentDictionary Summaries => _summaries; - - public MoneroRPCProvider(MoneroLikeConfiguration moneroLikeConfiguration, EventAggregator eventAggregator, IHttpClientFactory httpClientFactory) - { - _moneroLikeConfiguration = moneroLikeConfiguration; - _eventAggregator = eventAggregator; - DaemonRpcClients = - _moneroLikeConfiguration.MoneroLikeConfigurationItems.ToImmutableDictionary(pair => pair.Key, - pair => new JsonRpcClient(pair.Value.DaemonRpcUri, pair.Value.Username, pair.Value.Password, httpClientFactory.CreateClient($"{pair.Key}client"))); - WalletRpcClients = - _moneroLikeConfiguration.MoneroLikeConfigurationItems.ToImmutableDictionary(pair => pair.Key, - pair => new JsonRpcClient(pair.Value.InternalWalletRpcUri, "", "", httpClientFactory.CreateClient($"{pair.Key}client"))); - } - - public bool IsAvailable(string cryptoCode) - { - cryptoCode = cryptoCode.ToUpperInvariant(); - return _summaries.ContainsKey(cryptoCode) && IsAvailable(_summaries[cryptoCode]); - } - - private bool IsAvailable(MoneroLikeSummary summary) - { - return summary.Synced && - summary.WalletAvailable; - } - - public async Task UpdateSummary(string cryptoCode) - { - if (!DaemonRpcClients.TryGetValue(cryptoCode.ToUpperInvariant(), out var daemonRpcClient) || - !WalletRpcClients.TryGetValue(cryptoCode.ToUpperInvariant(), out var walletRpcClient)) - { - return null; - } - - var summary = new MoneroLikeSummary(); - try - { - var daemonResult = - await daemonRpcClient.SendCommandAsync("get_info", - JsonRpcClient.NoRequestModel.Instance); - summary.TargetHeight = daemonResult.TargetHeight.GetValueOrDefault(0); - summary.CurrentHeight = daemonResult.Height; - summary.TargetHeight = summary.TargetHeight == 0 ? summary.CurrentHeight : summary.TargetHeight; - summary.Synced = !daemonResult.BusySyncing; - summary.UpdatedAt = DateTime.UtcNow; - summary.DaemonAvailable = true; - } - catch - { - summary.DaemonAvailable = false; - } - - try - { - var walletResult = - await walletRpcClient.SendCommandAsync( - "get_height", JsonRpcClient.NoRequestModel.Instance); - - summary.WalletHeight = walletResult.Height; - summary.WalletAvailable = true; - } - catch - { - summary.WalletAvailable = false; - } - - var changed = !_summaries.ContainsKey(cryptoCode) || IsAvailable(cryptoCode) != IsAvailable(summary); - - _summaries.AddOrReplace(cryptoCode, summary); - if (changed) - { - _eventAggregator.Publish(new MoneroDaemonStateChange() { Summary = summary, CryptoCode = cryptoCode }); - } - - return summary; - } - - - public class MoneroDaemonStateChange - { - public string CryptoCode { get; set; } - public MoneroLikeSummary Summary { get; set; } - } - - public class MoneroLikeSummary - { - public bool Synced { get; set; } - public long CurrentHeight { get; set; } - public long WalletHeight { get; set; } - public long TargetHeight { get; set; } - public DateTime UpdatedAt { get; set; } - public bool DaemonAvailable { get; set; } - public bool WalletAvailable { get; set; } - } - } -} diff --git a/BTCPayServer/Services/Altcoins/Monero/Services/MoneroSyncSummaryProvider.cs b/BTCPayServer/Services/Altcoins/Monero/Services/MoneroSyncSummaryProvider.cs deleted file mode 100644 index 0376fa006..000000000 --- a/BTCPayServer/Services/Altcoins/Monero/Services/MoneroSyncSummaryProvider.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using BTCPayServer.Abstractions.Contracts; -using BTCPayServer.Client.Models; -using BTCPayServer.Payments; - -namespace BTCPayServer.Services.Altcoins.Monero.Services -{ - public class MoneroSyncSummaryProvider : ISyncSummaryProvider - { - private readonly MoneroRPCProvider _moneroRpcProvider; - - public MoneroSyncSummaryProvider(MoneroRPCProvider moneroRpcProvider) - { - _moneroRpcProvider = moneroRpcProvider; - } - - public bool AllAvailable() - { - return _moneroRpcProvider.Summaries.All(pair => pair.Value.WalletAvailable); - } - - public string Partial { get; } = "Monero/MoneroSyncSummary"; - public IEnumerable GetStatuses() - { - return _moneroRpcProvider.Summaries.Select(pair => new MoneroSyncStatus() - { - Summary = pair.Value, PaymentMethodId = PaymentMethodId.Parse(pair.Key).ToString() - }); - } - } - - public class MoneroSyncStatus: SyncStatus, ISyncStatus - { - public override bool Available - { - get - { - return Summary?.WalletAvailable ?? false; - } - } - - public MoneroRPCProvider.MoneroLikeSummary Summary { get; set; } - } -} diff --git a/BTCPayServer/Services/Altcoins/Monero/UI/MoneroLikeStoreController.cs b/BTCPayServer/Services/Altcoins/Monero/UI/MoneroLikeStoreController.cs deleted file mode 100644 index 8b84620da..000000000 --- a/BTCPayServer/Services/Altcoins/Monero/UI/MoneroLikeStoreController.cs +++ /dev/null @@ -1,393 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Diagnostics; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using BTCPayServer.Abstractions.Constants; -using BTCPayServer.Abstractions.Extensions; -using BTCPayServer.Abstractions.Models; -using BTCPayServer.Client; -using BTCPayServer.Data; -using BTCPayServer.Filters; -using BTCPayServer.Payments; -using BTCPayServer.Services.Altcoins.Monero.Configuration; -using BTCPayServer.Services.Altcoins.Monero.Payments; -using BTCPayServer.Services.Altcoins.Monero.RPC.Models; -using BTCPayServer.Services.Altcoins.Monero.Services; -using BTCPayServer.Services.Invoices; -using BTCPayServer.Services.Stores; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Rendering; -using Microsoft.Extensions.Localization; - -namespace BTCPayServer.Services.Altcoins.Monero.UI -{ - [Route("stores/{storeId}/monerolike")] - [OnlyIfSupportAttribute("XMR-CHAIN")] - [Authorize(AuthenticationSchemes = AuthenticationSchemes.Cookie)] - [Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)] - [Authorize(Policy = Policies.CanModifyServerSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)] - public class UIMoneroLikeStoreController : Controller - { - private readonly MoneroLikeConfiguration _MoneroLikeConfiguration; - private readonly StoreRepository _StoreRepository; - private readonly MoneroRPCProvider _MoneroRpcProvider; - private readonly PaymentMethodHandlerDictionary _handlers; - private IStringLocalizer StringLocalizer { get; } - - public UIMoneroLikeStoreController(MoneroLikeConfiguration moneroLikeConfiguration, - StoreRepository storeRepository, MoneroRPCProvider moneroRpcProvider, - PaymentMethodHandlerDictionary handlers, - IStringLocalizer stringLocalizer) - { - _MoneroLikeConfiguration = moneroLikeConfiguration; - _StoreRepository = storeRepository; - _MoneroRpcProvider = moneroRpcProvider; - _handlers = handlers; - StringLocalizer = stringLocalizer; - } - - public StoreData StoreData => HttpContext.GetStoreData(); - - [HttpGet()] - public async Task GetStoreMoneroLikePaymentMethods() - { - return View(await GetVM(StoreData)); - } -[NonAction] - public async Task GetVM(StoreData storeData) - { - var excludeFilters = storeData.GetStoreBlob().GetExcludedPaymentMethods(); - - var accountsList = _MoneroLikeConfiguration.MoneroLikeConfigurationItems.ToDictionary(pair => pair.Key, - pair => GetAccounts(pair.Key)); - - await Task.WhenAll(accountsList.Values); - return new MoneroLikePaymentMethodListViewModel() - { - Items = _MoneroLikeConfiguration.MoneroLikeConfigurationItems.Select(pair => - GetMoneroLikePaymentMethodViewModel(storeData, pair.Key, excludeFilters, - accountsList[pair.Key].Result)) - }; - } - - private Task GetAccounts(string cryptoCode) - { - try - { - if (_MoneroRpcProvider.Summaries.TryGetValue(cryptoCode, out var summary) && summary.WalletAvailable) - { - - return _MoneroRpcProvider.WalletRpcClients[cryptoCode].SendCommandAsync("get_accounts", new GetAccountsRequest()); - } - } - catch { } - return Task.FromResult(null); - } - - private MoneroLikePaymentMethodViewModel GetMoneroLikePaymentMethodViewModel( - StoreData storeData, string cryptoCode, - IPaymentFilter excludeFilters, GetAccountsResponse accountsResponse) - { - var monero = storeData.GetPaymentMethodConfigs(_handlers) - .Where(s => s.Value is MoneroPaymentPromptDetails) - .Select(s => (PaymentMethodId: s.Key, Details: (MoneroPaymentPromptDetails)s.Value)); - var pmi = PaymentTypes.CHAIN.GetPaymentMethodId(cryptoCode); - var settings = monero.Where(method => method.PaymentMethodId == pmi).Select(m => m.Details).SingleOrDefault(); - _MoneroRpcProvider.Summaries.TryGetValue(cryptoCode, out var summary); - _MoneroLikeConfiguration.MoneroLikeConfigurationItems.TryGetValue(cryptoCode, - out var configurationItem); - var fileAddress = Path.Combine(configurationItem.WalletDirectory, "wallet"); - var accounts = accountsResponse?.SubaddressAccounts?.Select(account => - new SelectListItem( - $"{account.AccountIndex} - {(string.IsNullOrEmpty(account.Label) ? "No label" : account.Label)}", - account.AccountIndex.ToString(CultureInfo.InvariantCulture))); - - var settlementThresholdChoice = MoneroLikeSettlementThresholdChoice.StoreSpeedPolicy; - if (settings != null && settings.InvoiceSettledConfirmationThreshold is { } confirmations) - { - settlementThresholdChoice = confirmations switch - { - 0 => MoneroLikeSettlementThresholdChoice.ZeroConfirmation, - 1 => MoneroLikeSettlementThresholdChoice.AtLeastOne, - 10 => MoneroLikeSettlementThresholdChoice.AtLeastTen, - _ => MoneroLikeSettlementThresholdChoice.Custom - }; - } - - return new MoneroLikePaymentMethodViewModel() - { - WalletFileFound = System.IO.File.Exists(fileAddress), - Enabled = - settings != null && - !excludeFilters.Match(PaymentTypes.CHAIN.GetPaymentMethodId(cryptoCode)), - Summary = summary, - CryptoCode = cryptoCode, - AccountIndex = settings?.AccountIndex ?? accountsResponse?.SubaddressAccounts?.FirstOrDefault()?.AccountIndex ?? 0, - Accounts = accounts == null ? null : new SelectList(accounts, nameof(SelectListItem.Value), - nameof(SelectListItem.Text)), - SettlementConfirmationThresholdChoice = settlementThresholdChoice, - CustomSettlementConfirmationThreshold = - settings != null && - settlementThresholdChoice is MoneroLikeSettlementThresholdChoice.Custom - ? settings.InvoiceSettledConfirmationThreshold - : null - }; - } - - [HttpGet("{cryptoCode}")] - public async Task GetStoreMoneroLikePaymentMethod(string cryptoCode) - { - cryptoCode = cryptoCode.ToUpperInvariant(); - if (!_MoneroLikeConfiguration.MoneroLikeConfigurationItems.ContainsKey(cryptoCode)) - { - return NotFound(); - } - - var vm = GetMoneroLikePaymentMethodViewModel(StoreData, cryptoCode, - StoreData.GetStoreBlob().GetExcludedPaymentMethods(), await GetAccounts(cryptoCode)); - return View(nameof(GetStoreMoneroLikePaymentMethod), vm); - } - - [HttpPost("{cryptoCode}")] - [DisableRequestSizeLimit] - public async Task GetStoreMoneroLikePaymentMethod(MoneroLikePaymentMethodViewModel viewModel, string command, string cryptoCode) - { - cryptoCode = cryptoCode.ToUpperInvariant(); - if (!_MoneroLikeConfiguration.MoneroLikeConfigurationItems.TryGetValue(cryptoCode, - out var configurationItem)) - { - return NotFound(); - } - - if (command == "add-account") - { - try - { - var newAccount = await _MoneroRpcProvider.WalletRpcClients[cryptoCode].SendCommandAsync("create_account", new CreateAccountRequest() - { - Label = viewModel.NewAccountLabel - }); - viewModel.AccountIndex = newAccount.AccountIndex; - } - catch (Exception) - { - ModelState.AddModelError(nameof(viewModel.AccountIndex), StringLocalizer["Could not create a new account."]); - } - - } - else if (command == "upload-wallet") - { - var valid = true; - if (viewModel.WalletFile == null) - { - ModelState.AddModelError(nameof(viewModel.WalletFile), StringLocalizer["Please select the view-only wallet file"]); - valid = false; - } - if (viewModel.WalletKeysFile == null) - { - ModelState.AddModelError(nameof(viewModel.WalletKeysFile), StringLocalizer["Please select the view-only wallet keys file"]); - valid = false; - } - - if (valid) - { - if (_MoneroRpcProvider.Summaries.TryGetValue(cryptoCode, out var summary)) - { - if (summary.WalletAvailable) - { - TempData.SetStatusMessageModel(new StatusMessageModel - { - Severity = StatusMessageModel.StatusSeverity.Error, - Message = StringLocalizer["There is already an active wallet configured for {0}. Replacing it would break any existing invoices!", cryptoCode].Value - }); - return RedirectToAction(nameof(GetStoreMoneroLikePaymentMethod), - new { cryptoCode }); - } - } - - var fileAddress = Path.Combine(configurationItem.WalletDirectory, "wallet"); - using (var fileStream = new FileStream(fileAddress, FileMode.Create)) - { - await viewModel.WalletFile.CopyToAsync(fileStream); - try - { - Exec($"chmod 666 {fileAddress}"); - } - catch - { - } - } - - fileAddress = Path.Combine(configurationItem.WalletDirectory, "wallet.keys"); - using (var fileStream = new FileStream(fileAddress, FileMode.Create)) - { - await viewModel.WalletKeysFile.CopyToAsync(fileStream); - try - { - Exec($"chmod 666 {fileAddress}"); - } - catch - { - } - - } - - fileAddress = Path.Combine(configurationItem.WalletDirectory, "password"); - using (var fileStream = new StreamWriter(fileAddress, false)) - { - await fileStream.WriteAsync(viewModel.WalletPassword); - try - { - Exec($"chmod 666 {fileAddress}"); - } - catch - { - } - } - - try - { - var response = await _MoneroRpcProvider.WalletRpcClients[cryptoCode].SendCommandAsync("open_wallet", new OpenWalletRequest - { - Filename = "wallet", - Password = viewModel.WalletPassword - }); - if (response?.Error != null) - { - throw new Exception(response.Error.Message); - } - } - catch (Exception ex) - { - ModelState.AddModelError(nameof(viewModel.AccountIndex), StringLocalizer["Could not open the wallet: {0}", ex.Message]); - return View(viewModel); - } - - TempData.SetStatusMessageModel(new StatusMessageModel - { - Severity = StatusMessageModel.StatusSeverity.Info, - Message = StringLocalizer["View-only wallet files uploaded. The wallet will soon become available."].Value - }); - return RedirectToAction(nameof(GetStoreMoneroLikePaymentMethod), new { cryptoCode }); - } - } - - if (!ModelState.IsValid) - { - - var vm = GetMoneroLikePaymentMethodViewModel(StoreData, cryptoCode, - StoreData.GetStoreBlob().GetExcludedPaymentMethods(), await GetAccounts(cryptoCode)); - - vm.Enabled = viewModel.Enabled; - vm.NewAccountLabel = viewModel.NewAccountLabel; - vm.AccountIndex = viewModel.AccountIndex; - vm.SettlementConfirmationThresholdChoice = viewModel.SettlementConfirmationThresholdChoice; - vm.CustomSettlementConfirmationThreshold = viewModel.CustomSettlementConfirmationThreshold; - return View(vm); - } - - var storeData = StoreData; - var blob = storeData.GetStoreBlob(); - storeData.SetPaymentMethodConfig(_handlers[PaymentTypes.CHAIN.GetPaymentMethodId(cryptoCode)], new MoneroPaymentPromptDetails() - { - AccountIndex = viewModel.AccountIndex, - InvoiceSettledConfirmationThreshold = viewModel.SettlementConfirmationThresholdChoice switch - { - MoneroLikeSettlementThresholdChoice.ZeroConfirmation => 0, - MoneroLikeSettlementThresholdChoice.AtLeastOne => 1, - MoneroLikeSettlementThresholdChoice.AtLeastTen => 10, - MoneroLikeSettlementThresholdChoice.Custom when viewModel.CustomSettlementConfirmationThreshold is { } custom => custom, - _ => null - } - }); - - blob.SetExcluded(PaymentTypes.CHAIN.GetPaymentMethodId(viewModel.CryptoCode), !viewModel.Enabled); - storeData.SetStoreBlob(blob); - await _StoreRepository.UpdateStore(storeData); - return RedirectToAction("GetStoreMoneroLikePaymentMethods", - new { StatusMessage = $"{cryptoCode} settings updated successfully", storeId = StoreData.Id }); - } - - private void Exec(string cmd) - { - - var escapedArgs = cmd.Replace("\"", "\\\"", StringComparison.InvariantCulture); - - var process = new Process - { - StartInfo = new ProcessStartInfo - { - RedirectStandardOutput = true, - UseShellExecute = false, - CreateNoWindow = true, - WindowStyle = ProcessWindowStyle.Hidden, - FileName = "/bin/sh", - Arguments = $"-c \"{escapedArgs}\"" - } - }; - -#pragma warning disable CA1416 // Validate platform compatibility - process.Start(); -#pragma warning restore CA1416 // Validate platform compatibility - process.WaitForExit(); - } - - public class MoneroLikePaymentMethodListViewModel - { - public IEnumerable Items { get; set; } - } - - public class MoneroLikePaymentMethodViewModel : IValidatableObject - { - public MoneroRPCProvider.MoneroLikeSummary Summary { get; set; } - public string CryptoCode { get; set; } - public string NewAccountLabel { get; set; } - public long AccountIndex { get; set; } - public bool Enabled { get; set; } - - public IEnumerable Accounts { get; set; } - public bool WalletFileFound { get; set; } - [Display(Name = "View-Only Wallet File")] - public IFormFile WalletFile { get; set; } - [Display(Name = "Wallet Keys File")] - public IFormFile WalletKeysFile { get; set; } - [Display(Name = "Wallet Password")] - public string WalletPassword { get; set; } - [Display(Name = "Consider the invoice settled when the payment transaction …")] - public MoneroLikeSettlementThresholdChoice SettlementConfirmationThresholdChoice { get; set; } - [Display(Name = "Required Confirmations"), Range(0, 100)] - public long? CustomSettlementConfirmationThreshold { get; set; } - - public IEnumerable Validate(ValidationContext validationContext) - { - if (SettlementConfirmationThresholdChoice is MoneroLikeSettlementThresholdChoice.Custom - && CustomSettlementConfirmationThreshold is null) - { - yield return new ValidationResult( - "You must specify the number of required confirmations when using a custom threshold.", - new[] { nameof(CustomSettlementConfirmationThreshold) }); - } - } - } - - public enum MoneroLikeSettlementThresholdChoice - { - [Display(Name = "Store Speed Policy", Description = "Use the store's speed policy")] - StoreSpeedPolicy, - [Display(Name = "Zero Confirmation", Description = "Is unconfirmed")] - ZeroConfirmation, - [Display(Name = "At Least One", Description = "Has at least 1 confirmation")] - AtLeastOne, - [Display(Name = "At Least Ten", Description = "Has at least 10 confirmations")] - AtLeastTen, - [Display(Name = "Custom", Description = "Custom")] - Custom - } - } -} diff --git a/BTCPayServer/Services/Altcoins/Monero/UI/MoneroPaymentViewModel.cs b/BTCPayServer/Services/Altcoins/Monero/UI/MoneroPaymentViewModel.cs deleted file mode 100644 index 68d172ffb..000000000 --- a/BTCPayServer/Services/Altcoins/Monero/UI/MoneroPaymentViewModel.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using BTCPayServer.Payments; - -namespace BTCPayServer.Services.Altcoins.Monero.UI -{ - public class MoneroPaymentViewModel - { - public PaymentMethodId PaymentMethodId { get; set; } - public string Confirmations { get; set; } - public string DepositAddress { get; set; } - public string Amount { get; set; } - public string TransactionId { get; set; } - public DateTimeOffset ReceivedTime { get; set; } - public string TransactionLink { get; set; } - public string Currency { get; set; } - } -} diff --git a/BTCPayServer/Services/Altcoins/Zcash/Configuration/ZcashLikeConfiguration.cs b/BTCPayServer/Services/Altcoins/Zcash/Configuration/ZcashLikeConfiguration.cs deleted file mode 100644 index 3d223c02b..000000000 --- a/BTCPayServer/Services/Altcoins/Zcash/Configuration/ZcashLikeConfiguration.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace BTCPayServer.Services.Altcoins.Zcash.Configuration -{ - public class ZcashLikeConfiguration - { - public Dictionary ZcashLikeConfigurationItems { get; set; } = - new Dictionary(); - } - - public class ZcashLikeConfigurationItem - { - public Uri DaemonRpcUri { get; set; } - public Uri InternalWalletRpcUri { get; set; } - public string WalletDirectory { get; set; } - } -} diff --git a/BTCPayServer/Services/Altcoins/Zcash/Payments/ZcashCheckoutModelExtension.cs b/BTCPayServer/Services/Altcoins/Zcash/Payments/ZcashCheckoutModelExtension.cs deleted file mode 100644 index 3d17be1c8..000000000 --- a/BTCPayServer/Services/Altcoins/Zcash/Payments/ZcashCheckoutModelExtension.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using BTCPayServer.Payments; -using BTCPayServer.Payments.Bitcoin; -using BTCPayServer.Services.Altcoins.Monero.Payments; -using BTCPayServer.Services.Altcoins.Zcash.Services; -using BTCPayServer.Services.Invoices; - -namespace BTCPayServer.Services.Altcoins.Zcash.Payments -{ - public class ZcashCheckoutModelExtension : ICheckoutModelExtension - { - private readonly BTCPayNetworkBase _network; - private readonly PaymentMethodHandlerDictionary _handlers; - private readonly IPaymentLinkExtension paymentLinkExtension; - - public ZcashCheckoutModelExtension( - PaymentMethodId paymentMethodId, - IEnumerable paymentLinkExtensions, - BTCPayNetworkBase network, - PaymentMethodHandlerDictionary handlers) - { - PaymentMethodId = paymentMethodId; - _network = network; - _handlers = handlers; - paymentLinkExtension = paymentLinkExtensions.Single(p => p.PaymentMethodId == PaymentMethodId); - } - public PaymentMethodId PaymentMethodId { get; } - - public string Image => _network.CryptoImagePath; - public string Badge => ""; - - public void ModifyCheckoutModel(CheckoutModelContext context) - { - if (context is not { Handler: ZcashLikePaymentMethodHandler handler }) - return; - context.Model.CheckoutBodyComponentName = BitcoinCheckoutModelExtension.CheckoutBodyComponentName; - var details = context.InvoiceEntity.GetPayments(true) - .Select(p => p.GetDetails(handler)) - .Where(p => p is not null) - .FirstOrDefault(); - if (details is not null) - { - context.Model.ReceivedConfirmations = details.ConfirmationCount; - context.Model.RequiredConfirmations = (int)ZcashListener.ConfirmationsRequired(context.InvoiceEntity.SpeedPolicy); - } - context.Model.InvoiceBitcoinUrl = paymentLinkExtension.GetPaymentLink(context.Prompt, context.UrlHelper); - context.Model.InvoiceBitcoinUrlQR = context.Model.InvoiceBitcoinUrl; - } - } -} diff --git a/BTCPayServer/Services/Altcoins/Zcash/Payments/ZcashLikePaymentData.cs b/BTCPayServer/Services/Altcoins/Zcash/Payments/ZcashLikePaymentData.cs deleted file mode 100644 index a30922987..000000000 --- a/BTCPayServer/Services/Altcoins/Zcash/Payments/ZcashLikePaymentData.cs +++ /dev/null @@ -1,17 +0,0 @@ -using BTCPayServer.Client.Models; -using BTCPayServer.Payments; -using BTCPayServer.Plugins.Altcoins; -using BTCPayServer.Services.Altcoins.Zcash.Utils; -using BTCPayServer.Services.Invoices; - -namespace BTCPayServer.Services.Altcoins.Zcash.Payments -{ - public class ZcashLikePaymentData - { - public long SubaddressIndex { get; set; } - public long SubaccountIndex { get; set; } - public long BlockHeight { get; set; } - public long ConfirmationCount { get; set; } - public string TransactionId { get; set; } - } -} diff --git a/BTCPayServer/Services/Altcoins/Zcash/Payments/ZcashLikePaymentMethodHandler.cs b/BTCPayServer/Services/Altcoins/Zcash/Payments/ZcashLikePaymentMethodHandler.cs deleted file mode 100644 index a9cc55f47..000000000 --- a/BTCPayServer/Services/Altcoins/Zcash/Payments/ZcashLikePaymentMethodHandler.cs +++ /dev/null @@ -1,114 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Threading.Tasks; -using AngleSharp.Dom; -using BTCPayServer.Common; -using BTCPayServer.Data; -using BTCPayServer.Logging; -using BTCPayServer.Models; -using BTCPayServer.Models.InvoicingModels; -using BTCPayServer.Payments; -using BTCPayServer.Plugins.Altcoins; -using BTCPayServer.Rating; -using BTCPayServer.Services.Altcoins.Zcash.RPC.Models; -using BTCPayServer.Services.Altcoins.Zcash.Services; -using BTCPayServer.Services.Altcoins.Zcash.Utils; -using BTCPayServer.Services.Invoices; -using BTCPayServer.Services.Rates; -using NBitcoin; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - -namespace BTCPayServer.Services.Altcoins.Zcash.Payments -{ - public class ZcashLikePaymentMethodHandler : IPaymentMethodHandler - { - private readonly ZcashLikeSpecificBtcPayNetwork _network; - public ZcashLikeSpecificBtcPayNetwork Network => _network; - public JsonSerializer Serializer { get; } - private readonly ZcashRPCProvider _ZcashRpcProvider; - public PaymentMethodId PaymentMethodId { get; } - public ZcashLikePaymentMethodHandler(BTCPayNetworkBase network, ZcashRPCProvider ZcashRpcProvider) - { - _network = (ZcashLikeSpecificBtcPayNetwork)network; - PaymentMethodId = PaymentTypes.CHAIN.GetPaymentMethodId(_network.CryptoCode); - Serializer = BlobSerializer.CreateSerializer().Serializer; - _ZcashRpcProvider = ZcashRpcProvider; - } - public Task BeforeFetchingRates(PaymentMethodContext context) - { - context.Prompt.Currency = _network.CryptoCode; - context.Prompt.Divisibility = _network.Divisibility; - if (context.Prompt.Activated) - { - var walletClient = _ZcashRpcProvider.WalletRpcClients[_network.CryptoCode]; - var daemonClient = _ZcashRpcProvider.DaemonRpcClients[_network.CryptoCode]; - var config = ParsePaymentMethodConfig(context.PaymentMethodConfig); - context.State = new Prepare() - { - GetFeeRate = daemonClient.SendCommandAsync("get_fee_estimate", new GetFeeEstimateRequest()), - ReserveAddress = s => walletClient.SendCommandAsync("create_address", new CreateAddressRequest() { Label = $"btcpay invoice #{s}", AccountIndex = config.AccountIndex }), - AccountIndex = config.AccountIndex - }; - } - return Task.CompletedTask; - } - public async Task ConfigurePrompt(PaymentMethodContext context) - { - if (!_ZcashRpcProvider.IsAvailable(_network.CryptoCode)) - throw new PaymentMethodUnavailableException($"Node or wallet not available"); - var invoice = context.InvoiceEntity; - var ZcashPrepare = (Prepare)context.State; - var feeRatePerKb = await ZcashPrepare.GetFeeRate; - var address = await ZcashPrepare.ReserveAddress(invoice.Id); - - var feeRatePerByte = feeRatePerKb.Fee / 1024; - - context.Prompt.PaymentMethodFee = ZcashMoney.Convert(feeRatePerByte * 100); - context.Prompt.Details = JObject.FromObject(new ZcashPaymentPromptDetails() - { - AccountIndex = ZcashPrepare.AccountIndex, - AddressIndex = address.AddressIndex, - DepositAddress = address.Address - }, Serializer); - context.TrackedDestinations.Add(address.Address); - } - - public ZcashPaymentPromptDetails ParsePaymentPromptDetails(Newtonsoft.Json.Linq.JToken details) - { - return details.ToObject(Serializer); - } - object IPaymentMethodHandler.ParsePaymentPromptDetails(Newtonsoft.Json.Linq.JToken details) - { - return ParsePaymentPromptDetails(details); - } - object IPaymentMethodHandler.ParsePaymentMethodConfig(JToken config) - { - return ParsePaymentMethodConfig(config); - } - public ZcashPaymentMethodConfig ParsePaymentMethodConfig(JToken config) - { - return config.ToObject(Serializer) ?? throw new FormatException($"Invalid {nameof(ZcashPaymentMethodConfig)}"); - } - - - - class Prepare - { - public Task GetFeeRate; - public Func> ReserveAddress; - public long AccountIndex { get; internal set; } - } - - public ZcashLikePaymentData ParsePaymentDetails(JToken details) - { - return details.ToObject(Serializer) ?? throw new FormatException($"Invalid {nameof(ZcashLikePaymentData)}"); - } - object IPaymentMethodHandler.ParsePaymentDetails(JToken details) - { - return ParsePaymentDetails(details); - } - } -} diff --git a/BTCPayServer/Services/Altcoins/Zcash/Payments/ZcashPaymentLinkExtension.cs b/BTCPayServer/Services/Altcoins/Zcash/Payments/ZcashPaymentLinkExtension.cs deleted file mode 100644 index 27b9f3d5e..000000000 --- a/BTCPayServer/Services/Altcoins/Zcash/Payments/ZcashPaymentLinkExtension.cs +++ /dev/null @@ -1,27 +0,0 @@ -#nullable enable -using System.Globalization; -using BTCPayServer.Payments; -using BTCPayServer.Plugins.Altcoins; -using BTCPayServer.Services.Invoices; -using Microsoft.AspNetCore.Mvc; - -namespace BTCPayServer.Services.Altcoins.Zcash.Payments -{ - public class ZcashPaymentLinkExtension : IPaymentLinkExtension - { - private readonly ZcashLikeSpecificBtcPayNetwork _network; - - public ZcashPaymentLinkExtension(PaymentMethodId paymentMethodId, ZcashLikeSpecificBtcPayNetwork network) - { - PaymentMethodId = paymentMethodId; - _network = network; - } - public PaymentMethodId PaymentMethodId { get; } - - public string? GetPaymentLink(PaymentPrompt prompt, IUrlHelper? urlHelper) - { - var due = prompt.Calculate().Due; - return $"{_network.UriScheme}:{prompt.Destination}?amount={due.ToString(CultureInfo.InvariantCulture)}"; - } - } -} diff --git a/BTCPayServer/Services/Altcoins/Zcash/Payments/ZcashPaymentMethodConfig.cs b/BTCPayServer/Services/Altcoins/Zcash/Payments/ZcashPaymentMethodConfig.cs deleted file mode 100644 index 9b83b15c4..000000000 --- a/BTCPayServer/Services/Altcoins/Zcash/Payments/ZcashPaymentMethodConfig.cs +++ /dev/null @@ -1,10 +0,0 @@ -using BTCPayServer.Payments; -using Newtonsoft.Json; - -namespace BTCPayServer.Services.Altcoins.Zcash.Payments -{ - public class ZcashPaymentMethodConfig - { - public long AccountIndex { get; set; } - } -} diff --git a/BTCPayServer/Services/Altcoins/Zcash/Payments/ZcashPaymentPromptDetails.cs b/BTCPayServer/Services/Altcoins/Zcash/Payments/ZcashPaymentPromptDetails.cs deleted file mode 100644 index c4bfa73b9..000000000 --- a/BTCPayServer/Services/Altcoins/Zcash/Payments/ZcashPaymentPromptDetails.cs +++ /dev/null @@ -1,11 +0,0 @@ -using BTCPayServer.Payments; - -namespace BTCPayServer.Services.Altcoins.Zcash.Payments -{ - public class ZcashPaymentPromptDetails - { - public long AccountIndex { get; set; } - public long AddressIndex { get; set; } - public string DepositAddress { get; set; } - } -} diff --git a/BTCPayServer/Services/Altcoins/Zcash/RPC/ZcashDaemonCallbackController.cs b/BTCPayServer/Services/Altcoins/Zcash/RPC/ZcashDaemonCallbackController.cs deleted file mode 100644 index 327952c54..000000000 --- a/BTCPayServer/Services/Altcoins/Zcash/RPC/ZcashDaemonCallbackController.cs +++ /dev/null @@ -1,38 +0,0 @@ -using BTCPayServer.Filters; -using Microsoft.AspNetCore.Mvc; - -namespace BTCPayServer.Services.Altcoins.Zcash.RPC -{ - [Route("[controller]")] - [OnlyIfSupportAttribute("ZEC-CHAIN")] - public class ZcashLikeDaemonCallbackController : Controller - { - private readonly EventAggregator _eventAggregator; - - public ZcashLikeDaemonCallbackController(EventAggregator eventAggregator) - { - _eventAggregator = eventAggregator; - } - [HttpGet("block")] - public IActionResult OnBlockNotify(string hash, string cryptoCode) - { - _eventAggregator.Publish(new ZcashEvent() - { - BlockHash = hash, - CryptoCode = cryptoCode.ToUpperInvariant() - }); - return Ok(); - } - [HttpGet("tx")] - public IActionResult OnTransactionNotify(string hash, string cryptoCode) - { - _eventAggregator.Publish(new ZcashEvent() - { - TransactionHash = hash, - CryptoCode = cryptoCode.ToUpperInvariant() - }); - return Ok(); - } - - } -} diff --git a/BTCPayServer/Services/Altcoins/Zcash/RPC/ZcashEvent.cs b/BTCPayServer/Services/Altcoins/Zcash/RPC/ZcashEvent.cs deleted file mode 100644 index 486e9d542..000000000 --- a/BTCPayServer/Services/Altcoins/Zcash/RPC/ZcashEvent.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace BTCPayServer.Services.Altcoins.Zcash.RPC -{ - public class ZcashEvent - { - public string BlockHash { get; set; } - public string TransactionHash { get; set; } - public string CryptoCode { get; set; } - - public override string ToString() - { - return - $"{CryptoCode}: {(string.IsNullOrEmpty(TransactionHash) ? string.Empty : "Tx Update")}{(string.IsNullOrEmpty(BlockHash) ? string.Empty : "New Block")} ({TransactionHash ?? string.Empty}{BlockHash ?? string.Empty})"; - } - } -} diff --git a/BTCPayServer/Services/Altcoins/Zcash/Services/ZcashLikeSummaryUpdaterHostedService.cs b/BTCPayServer/Services/Altcoins/Zcash/Services/ZcashLikeSummaryUpdaterHostedService.cs deleted file mode 100644 index 274dff203..000000000 --- a/BTCPayServer/Services/Altcoins/Zcash/Services/ZcashLikeSummaryUpdaterHostedService.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; -using System.Threading; -using System.Threading.Tasks; -using BTCPayServer.Logging; -using BTCPayServer.Services.Altcoins.Zcash.Configuration; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; - -namespace BTCPayServer.Services.Altcoins.Zcash.Services -{ - public class ZcashLikeSummaryUpdaterHostedService : IHostedService - { - private readonly ZcashRPCProvider _ZcashRpcProvider; - private readonly ZcashLikeConfiguration _ZcashLikeConfiguration; - private CancellationTokenSource _Cts; - - public Logs Logs { get; } - - public ZcashLikeSummaryUpdaterHostedService(ZcashRPCProvider ZcashRpcProvider, ZcashLikeConfiguration ZcashLikeConfiguration, Logs logs) - { - _ZcashRpcProvider = ZcashRpcProvider; - _ZcashLikeConfiguration = ZcashLikeConfiguration; - Logs = logs; - } - - public Task StartAsync(CancellationToken cancellationToken) - { - _Cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); - foreach (var ZcashLikeConfigurationItem in _ZcashLikeConfiguration.ZcashLikeConfigurationItems) - { - _ = StartLoop(_Cts.Token, ZcashLikeConfigurationItem.Key); - } - return Task.CompletedTask; - } - - private async Task StartLoop(CancellationToken cancellation, string cryptoCode) - { - Logs.PayServer.LogInformation($"Starting listening Zcash-like daemons ({cryptoCode})"); - try - { - while (!cancellation.IsCancellationRequested) - { - try - { - await _ZcashRpcProvider.UpdateSummary(cryptoCode); - if (_ZcashRpcProvider.IsAvailable(cryptoCode)) - { - await Task.Delay(TimeSpan.FromMinutes(1), cancellation); - } - else - { - await Task.Delay(TimeSpan.FromSeconds(10), cancellation); - } - } - catch (Exception ex) when (!cancellation.IsCancellationRequested) - { - Logs.PayServer.LogError(ex, $"Unhandled exception in Summary updater ({cryptoCode})"); - await Task.Delay(TimeSpan.FromSeconds(10), cancellation); - } - } - } - catch when (cancellation.IsCancellationRequested) { } - } - - public Task StopAsync(CancellationToken cancellationToken) - { - _Cts?.Cancel(); - return Task.CompletedTask; - } - } -} diff --git a/BTCPayServer/Services/Altcoins/Zcash/Services/ZcashListener.cs b/BTCPayServer/Services/Altcoins/Zcash/Services/ZcashListener.cs deleted file mode 100644 index c903fc625..000000000 --- a/BTCPayServer/Services/Altcoins/Zcash/Services/ZcashListener.cs +++ /dev/null @@ -1,356 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Channels; -using System.Threading.Tasks; -using BTCPayServer.Client.Models; -using BTCPayServer.Data; -using BTCPayServer.Events; -using BTCPayServer.HostedServices; -using BTCPayServer.Payments; -using BTCPayServer.Plugins.Altcoins; -using BTCPayServer.Services.Altcoins.Zcash.Configuration; -using BTCPayServer.Services.Altcoins.Zcash.Payments; -using BTCPayServer.Services.Altcoins.Zcash.RPC; -using BTCPayServer.Services.Altcoins.Zcash.RPC.Models; -using BTCPayServer.Services.Altcoins.Zcash.Utils; -using BTCPayServer.Services.Invoices; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -using NBitcoin; -using NBitpayClient; -using NBXplorer; -using Newtonsoft.Json.Linq; -using static BTCPayServer.Client.Models.InvoicePaymentMethodDataModel; - -namespace BTCPayServer.Services.Altcoins.Zcash.Services -{ - public class ZcashListener : EventHostedServiceBase - { - private readonly InvoiceRepository _invoiceRepository; - private readonly EventAggregator _eventAggregator; - private readonly ZcashRPCProvider _ZcashRpcProvider; - private readonly ZcashLikeConfiguration _ZcashLikeConfiguration; - private readonly BTCPayNetworkProvider _networkProvider; - private readonly ILogger _logger; - private readonly PaymentService _paymentService; - private readonly InvoiceActivator _invoiceActivator; - private readonly PaymentMethodHandlerDictionary _handlers; - - public ZcashListener(InvoiceRepository invoiceRepository, - EventAggregator eventAggregator, - ZcashRPCProvider ZcashRpcProvider, - ZcashLikeConfiguration ZcashLikeConfiguration, - BTCPayNetworkProvider networkProvider, - ILogger logger, - PaymentService paymentService, - InvoiceActivator invoiceActivator, - PaymentMethodHandlerDictionary handlers) : base(eventAggregator, logger) - { - _invoiceRepository = invoiceRepository; - _eventAggregator = eventAggregator; - _ZcashRpcProvider = ZcashRpcProvider; - _ZcashLikeConfiguration = ZcashLikeConfiguration; - _networkProvider = networkProvider; - _logger = logger; - _paymentService = paymentService; - _invoiceActivator = invoiceActivator; - _handlers = handlers; - } - - protected override void SubscribeToEvents() - { - base.SubscribeToEvents(); - Subscribe(); - Subscribe(); - } - - protected override async Task ProcessEvent(object evt, CancellationToken cancellationToken) - { - if (evt is ZcashRPCProvider.ZcashDaemonStateChange stateChanged) - { - if (_ZcashRpcProvider.IsAvailable(stateChanged.CryptoCode)) - { - _logger.LogInformation($"{stateChanged.CryptoCode} just became available"); - _ = UpdateAnyPendingZcashLikePayment(stateChanged.CryptoCode); - } - else - { - _logger.LogInformation($"{stateChanged.CryptoCode} just became unavailable"); - } - } - else if (evt is ZcashEvent zcashEvent) - { - if (!_ZcashRpcProvider.IsAvailable(zcashEvent.CryptoCode)) - return; - - if (!string.IsNullOrEmpty(zcashEvent.BlockHash)) - { - await OnNewBlock(zcashEvent.CryptoCode); - } - if (!string.IsNullOrEmpty(zcashEvent.TransactionHash)) - { - await OnTransactionUpdated(zcashEvent.CryptoCode, zcashEvent.TransactionHash); - } - } - } - - private async Task ReceivedPayment(InvoiceEntity invoice, PaymentEntity payment) - { - _logger.LogInformation( - $"Invoice {invoice.Id} received payment {payment.Value} {payment.Currency} {payment.Id}"); - - - var prompt = invoice.GetPaymentPrompt(payment.PaymentMethodId); - - if (prompt != null && - prompt.Activated && - prompt.Destination == payment.Destination && - prompt.Calculate().Due > 0.0m) - { - await _invoiceActivator.ActivateInvoicePaymentMethod(invoice.Id, payment.PaymentMethodId, true); - invoice = await _invoiceRepository.GetInvoice(invoice.Id); - } - - _eventAggregator.Publish( - new InvoiceEvent(invoice, InvoiceEvent.ReceivedPayment) { Payment = payment }); - } - - private async Task UpdatePaymentStates(string cryptoCode, InvoiceEntity[] invoices) - { - if (!invoices.Any()) - { - return; - } - - var ZcashWalletRpcClient = _ZcashRpcProvider.WalletRpcClients[cryptoCode]; - var network = _networkProvider.GetNetwork(cryptoCode); - - var paymentId = PaymentTypes.CHAIN.GetPaymentMethodId(network.CryptoCode); - var handler = (ZcashLikePaymentMethodHandler)_handlers[paymentId]; - - //get all the required data in one list (invoice, its existing payments and the current payment method details) - var expandedInvoices = invoices.Select(entity => (Invoice: entity, - ExistingPayments: GetAllZcashLikePayments(entity, cryptoCode), - Prompt: entity.GetPaymentPrompt(paymentId), - PaymentMethodDetails: handler.ParsePaymentPromptDetails(entity.GetPaymentPrompt(paymentId).Details))) - .Select(tuple => ( - tuple.Invoice, - tuple.PaymentMethodDetails, - tuple.Prompt, - ExistingPayments: tuple.ExistingPayments.Select(entity => - (Payment: entity, PaymentData: handler.ParsePaymentDetails(entity.Details), - tuple.Invoice)) - )); - - var existingPaymentData = expandedInvoices.SelectMany(tuple => tuple.ExistingPayments); - - var accountToAddressQuery = new Dictionary>(); - //create list of subaddresses to account to query the Zcash wallet - foreach (var expandedInvoice in expandedInvoices) - { - var addressIndexList = - accountToAddressQuery.GetValueOrDefault(expandedInvoice.PaymentMethodDetails.AccountIndex, - new List()); - - addressIndexList.AddRange( - expandedInvoice.ExistingPayments.Select(tuple => tuple.PaymentData.SubaddressIndex)); - addressIndexList.Add(expandedInvoice.PaymentMethodDetails.AddressIndex); - accountToAddressQuery.AddOrReplace(expandedInvoice.PaymentMethodDetails.AccountIndex, addressIndexList); - } - - var tasks = accountToAddressQuery.ToDictionary(datas => datas.Key, - datas => ZcashWalletRpcClient.SendCommandAsync( - "get_transfers", - new GetTransfersRequest() - { - AccountIndex = datas.Key, - In = true, - SubaddrIndices = datas.Value.Distinct().ToList() - })); - - await Task.WhenAll(tasks.Values); - - - var transferProcessingTasks = new List(); - - var updatedPaymentEntities = new List<(PaymentEntity Payment, InvoiceEntity invoice)>(); - foreach (var keyValuePair in tasks) - { - var transfers = keyValuePair.Value.Result.In; - if (transfers == null) - { - continue; - } - - transferProcessingTasks.AddRange(transfers.Select(transfer => - { - InvoiceEntity invoice = null; - var existingMatch = existingPaymentData.SingleOrDefault(tuple => - tuple.Payment.Destination == transfer.Address && - tuple.PaymentData.TransactionId == transfer.Txid); - - if (existingMatch.Invoice != null) - { - invoice = existingMatch.Invoice; - } - else - { - var newMatch = expandedInvoices.SingleOrDefault(tuple => - tuple.Prompt.Destination == transfer.Address); - - if (newMatch.Invoice == null) - { - return Task.CompletedTask; - } - - invoice = newMatch.Invoice; - } - - - return HandlePaymentData(cryptoCode, transfer.Address, transfer.Amount, transfer.SubaddrIndex.Major, - transfer.SubaddrIndex.Minor, transfer.Txid, transfer.Confirmations, transfer.Height, invoice, - updatedPaymentEntities); - })); - } - - transferProcessingTasks.Add( - _paymentService.UpdatePayments(updatedPaymentEntities.Select(tuple => tuple.Item1).ToList())); - await Task.WhenAll(transferProcessingTasks); - foreach (var valueTuples in updatedPaymentEntities.GroupBy(entity => entity.Item2)) - { - if (valueTuples.Any()) - { - _eventAggregator.Publish(new Events.InvoiceNeedUpdateEvent(valueTuples.Key.Id)); - } - } - } - - private async Task OnNewBlock(string cryptoCode) - { - await UpdateAnyPendingZcashLikePayment(cryptoCode); - _eventAggregator.Publish(new NewBlockEvent() { PaymentMethodId = PaymentTypes.CHAIN.GetPaymentMethodId(cryptoCode) }); - } - - private async Task OnTransactionUpdated(string cryptoCode, string transactionHash) - { - var paymentMethodId = PaymentTypes.CHAIN.GetPaymentMethodId(cryptoCode); - var transfer = await _ZcashRpcProvider.WalletRpcClients[cryptoCode] - .SendCommandAsync( - "get_transfer_by_txid", - new GetTransferByTransactionIdRequest() { TransactionId = transactionHash }); - - var paymentsToUpdate = new List<(PaymentEntity Payment, InvoiceEntity invoice)>(); - - //group all destinations of the tx together and loop through the sets - foreach (var destination in transfer.Transfers.GroupBy(destination => destination.Address)) - { - //find the invoice corresponding to this address, else skip - var invoice = await _invoiceRepository.GetInvoiceFromAddress(paymentMethodId, destination.Key); - if (invoice == null) - continue; - - var index = destination.First().SubaddrIndex; - - await HandlePaymentData(cryptoCode, - destination.Key, - destination.Sum(destination1 => destination1.Amount), - index.Major, - index.Minor, - transfer.Transfer.Txid, - transfer.Transfer.Confirmations, - transfer.Transfer.Height - , invoice, paymentsToUpdate); - } - - if (paymentsToUpdate.Any()) - { - await _paymentService.UpdatePayments(paymentsToUpdate.Select(tuple => tuple.Payment).ToList()); - foreach (var valueTuples in paymentsToUpdate.GroupBy(entity => entity.invoice)) - { - if (valueTuples.Any()) - { - _eventAggregator.Publish(new Events.InvoiceNeedUpdateEvent(valueTuples.Key.Id)); - } - } - } - } - - private async Task HandlePaymentData(string cryptoCode, string address, long totalAmount, long subaccountIndex, - long subaddressIndex, - string txId, long confirmations, long blockHeight, InvoiceEntity invoice, - List<(PaymentEntity Payment, InvoiceEntity invoice)> paymentsToUpdate) - { - var network = _networkProvider.GetNetwork(cryptoCode); - var pmi = PaymentTypes.CHAIN.GetPaymentMethodId(network.CryptoCode); - var handler = (ZcashLikePaymentMethodHandler)_handlers[pmi]; - - var details = new ZcashLikePaymentData() - { - SubaccountIndex = subaccountIndex, - SubaddressIndex = subaddressIndex, - TransactionId = txId, - ConfirmationCount = confirmations, - BlockHeight = blockHeight - }; - var status = GetStatus(details, invoice.SpeedPolicy) ? PaymentStatus.Settled : PaymentStatus.Processing; - var paymentData = new Data.PaymentData() - { - Status = status, - Amount = ZcashMoney.Convert(totalAmount), - Created = DateTimeOffset.UtcNow, - Id = $"{txId}#{subaccountIndex}#{subaddressIndex}", - Currency = network.CryptoCode - }.Set(invoice, handler, details); - - - var alreadyExistingPaymentThatMatches = GetAllZcashLikePayments(invoice, cryptoCode) - .SingleOrDefault(c => c.Id == paymentData.Id && c.PaymentMethodId == pmi); - - //if it doesnt, add it and assign a new Zcashlike address to the system if a balance is still due - if (alreadyExistingPaymentThatMatches == null) - { - var payment = await _paymentService.AddPayment(paymentData, [txId]); - if (payment != null) - await ReceivedPayment(invoice, payment); - } - else - { - //else update it with the new data - alreadyExistingPaymentThatMatches.Status = status; - alreadyExistingPaymentThatMatches.Details = JToken.FromObject(details, handler.Serializer); - paymentsToUpdate.Add((alreadyExistingPaymentThatMatches, invoice)); - } - } - - private bool GetStatus(ZcashLikePaymentData details, SpeedPolicy speedPolicy) - => details.ConfirmationCount >= ConfirmationsRequired(speedPolicy); - public static int ConfirmationsRequired(SpeedPolicy speedPolicy) - => speedPolicy switch - { - SpeedPolicy.HighSpeed => 0, - SpeedPolicy.MediumSpeed => 1, - SpeedPolicy.LowMediumSpeed => 2, - SpeedPolicy.LowSpeed => 6, - _ => 6, - }; - - private async Task UpdateAnyPendingZcashLikePayment(string cryptoCode) - { - var paymentMethodId = PaymentTypes.CHAIN.GetPaymentMethodId(cryptoCode); - var invoices = await _invoiceRepository.GetMonitoredInvoices(paymentMethodId); - if (!invoices.Any()) - return; - invoices = invoices.Where(entity => entity.GetPaymentPrompt(paymentMethodId).Activated).ToArray(); - await UpdatePaymentStates(cryptoCode, invoices); - } - - private IEnumerable GetAllZcashLikePayments(InvoiceEntity invoice, string cryptoCode) - { - return invoice.GetPayments(false) - .Where(p => p.PaymentMethodId == PaymentTypes.CHAIN.GetPaymentMethodId(cryptoCode)); - } - } -} diff --git a/BTCPayServer/Services/Altcoins/Zcash/Services/ZcashRPCProvider.cs b/BTCPayServer/Services/Altcoins/Zcash/Services/ZcashRPCProvider.cs deleted file mode 100644 index 82e2cb6e5..000000000 --- a/BTCPayServer/Services/Altcoins/Zcash/Services/ZcashRPCProvider.cs +++ /dev/null @@ -1,123 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Immutable; -using System.Globalization; -using System.Net.Http; -using System.Threading.Tasks; -using BTCPayServer.Services.Altcoins.Zcash.Configuration; -using BTCPayServer.Services.Altcoins.Zcash.RPC; -using BTCPayServer.Services.Altcoins.Zcash.RPC.Models; -using NBitcoin; - -namespace BTCPayServer.Services.Altcoins.Zcash.Services -{ - public class ZcashRPCProvider - { - private readonly ZcashLikeConfiguration _ZcashLikeConfiguration; - private readonly EventAggregator _eventAggregator; - public ImmutableDictionary DaemonRpcClients; - public ImmutableDictionary WalletRpcClients; - - private readonly ConcurrentDictionary _summaries = - new ConcurrentDictionary(); - - public ConcurrentDictionary Summaries => _summaries; - - public ZcashRPCProvider(ZcashLikeConfiguration ZcashLikeConfiguration, EventAggregator eventAggregator, IHttpClientFactory httpClientFactory) - { - _ZcashLikeConfiguration = ZcashLikeConfiguration; - _eventAggregator = eventAggregator; - DaemonRpcClients = - _ZcashLikeConfiguration.ZcashLikeConfigurationItems.ToImmutableDictionary(pair => pair.Key, - pair => new JsonRpcClient(pair.Value.DaemonRpcUri, "", "", httpClientFactory.CreateClient())); - WalletRpcClients = - _ZcashLikeConfiguration.ZcashLikeConfigurationItems.ToImmutableDictionary(pair => pair.Key, - pair => new JsonRpcClient(pair.Value.InternalWalletRpcUri, "", "", httpClientFactory.CreateClient())); - } - - public bool IsAvailable(string cryptoCode) - { - cryptoCode = cryptoCode.ToUpperInvariant(); - return _summaries.ContainsKey(cryptoCode) && IsAvailable(_summaries[cryptoCode]); - } - - private bool IsAvailable(ZcashLikeSummary summary) - { - return summary.Synced && - summary.WalletAvailable; - } - - public async Task UpdateSummary(string cryptoCode) - { - if (!DaemonRpcClients.TryGetValue(cryptoCode.ToUpperInvariant(), out var daemonRpcClient) || - !WalletRpcClients.TryGetValue(cryptoCode.ToUpperInvariant(), out var walletRpcClient)) - { - return null; - } - - var summary = new ZcashLikeSummary(); - try - { - var daemonResult = - await daemonRpcClient.SendCommandAsync("sync_info", - JsonRpcClient.NoRequestModel.Instance); - - summary.TargetHeight = daemonResult.TargetHeight.GetValueOrDefault(0); - summary.CurrentHeight = daemonResult.Height; - summary.TargetHeight = summary.TargetHeight == 0 ? summary.CurrentHeight : summary.TargetHeight; - summary.Synced = daemonResult.Height >= summary.TargetHeight && summary.CurrentHeight > 0; - summary.UpdatedAt = DateTime.Now; - summary.DaemonAvailable = true; - } - catch (Exception e) - { - Console.WriteLine(e.Message); - summary.DaemonAvailable = false; - } - - try - { - var walletResult = - await walletRpcClient.SendCommandAsync( - "get_height", JsonRpcClient.NoRequestModel.Instance); - - summary.WalletHeight = walletResult.Height; - summary.WalletAvailable = true; - } - catch - { - summary.WalletAvailable = false; - } - - var changed = !_summaries.ContainsKey(cryptoCode) || IsAvailable(cryptoCode) != IsAvailable(summary); - - _summaries.AddOrReplace(cryptoCode, summary); - if (changed) - { - _eventAggregator.Publish(new ZcashDaemonStateChange() { Summary = summary, CryptoCode = cryptoCode }); - } - - return summary; - } - - - public class ZcashDaemonStateChange - { - public string CryptoCode { get; set; } - public ZcashLikeSummary Summary { get; set; } - } - - public class ZcashLikeSummary - { - public bool Synced { get; set; } - public long CurrentHeight { get; set; } - public long WalletHeight { get; set; } - public long TargetHeight { get; set; } - public DateTime UpdatedAt { get; set; } - public bool DaemonAvailable { get; set; } - public bool WalletAvailable { get; set; } - - public override String ToString() { return String.Format(CultureInfo.InvariantCulture, "{0} {1} {2} {3} {4} {5}", Synced, CurrentHeight, TargetHeight, WalletHeight, DaemonAvailable, WalletAvailable); } - } - } -} diff --git a/BTCPayServer/Services/Altcoins/Zcash/Services/ZcashSyncSummaryProvider.cs b/BTCPayServer/Services/Altcoins/Zcash/Services/ZcashSyncSummaryProvider.cs deleted file mode 100644 index 35f1b11ee..000000000 --- a/BTCPayServer/Services/Altcoins/Zcash/Services/ZcashSyncSummaryProvider.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using BTCPayServer.Abstractions.Contracts; -using BTCPayServer.Client.Models; -using BTCPayServer.Payments; - -namespace BTCPayServer.Services.Altcoins.Zcash.Services -{ - public class ZcashSyncSummaryProvider : ISyncSummaryProvider - { - private readonly ZcashRPCProvider _ZcashRpcProvider; - - public ZcashSyncSummaryProvider(ZcashRPCProvider ZcashRpcProvider) - { - _ZcashRpcProvider = ZcashRpcProvider; - } - - public bool AllAvailable() - { - return _ZcashRpcProvider.Summaries.All(pair => pair.Value.WalletAvailable); - } - - public string Partial { get; } = "Zcash/ZcashSyncSummary"; - public IEnumerable GetStatuses() - { - return _ZcashRpcProvider.Summaries.Select(pair => new ZcashSyncStatus() - { - Summary = pair.Value, PaymentMethodId = PaymentMethodId.Parse(pair.Key).ToString() - }); - } - } - - public class ZcashSyncStatus: SyncStatus, ISyncStatus - { - public override bool Available - { - get - { - return Summary?.WalletAvailable ?? false; - } - } - - public ZcashRPCProvider.ZcashLikeSummary Summary { get; set; } - } -} diff --git a/BTCPayServer/Services/Altcoins/Zcash/UI/ZcashLikeStoreController.cs b/BTCPayServer/Services/Altcoins/Zcash/UI/ZcashLikeStoreController.cs deleted file mode 100644 index c7db2ddb1..000000000 --- a/BTCPayServer/Services/Altcoins/Zcash/UI/ZcashLikeStoreController.cs +++ /dev/null @@ -1,311 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Diagnostics; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using BTCPayServer.Abstractions.Constants; -using BTCPayServer.Abstractions.Extensions; -using BTCPayServer.Abstractions.Models; -using BTCPayServer.Client; -using BTCPayServer.Data; -using BTCPayServer.Filters; -using BTCPayServer.Payments; -using BTCPayServer.Payments.Bitcoin; -using BTCPayServer.Services.Altcoins.Zcash.Configuration; -using BTCPayServer.Services.Altcoins.Zcash.Payments; -using BTCPayServer.Services.Altcoins.Zcash.RPC.Models; -using BTCPayServer.Services.Altcoins.Zcash.Services; -using BTCPayServer.Services.Invoices; -using BTCPayServer.Services.Stores; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Rendering; -using Microsoft.Extensions.Localization; - -namespace BTCPayServer.Services.Altcoins.Zcash.UI -{ - [Route("stores/{storeId}/Zcashlike")] - [OnlyIfSupportAttribute("ZEC-CHAIN")] - [Authorize(AuthenticationSchemes = AuthenticationSchemes.Cookie)] - [Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)] - [Authorize(Policy = Policies.CanModifyServerSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)] - public class UIZcashLikeStoreController : Controller - { - private readonly ZcashLikeConfiguration _ZcashLikeConfiguration; - private readonly StoreRepository _StoreRepository; - private readonly ZcashRPCProvider _ZcashRpcProvider; - private readonly PaymentMethodHandlerDictionary _handlers; - private IStringLocalizer StringLocalizer { get; } - - public UIZcashLikeStoreController(ZcashLikeConfiguration ZcashLikeConfiguration, - StoreRepository storeRepository, ZcashRPCProvider ZcashRpcProvider, - PaymentMethodHandlerDictionary handlers, - IStringLocalizer stringLocalizer) - { - _ZcashLikeConfiguration = ZcashLikeConfiguration; - _StoreRepository = storeRepository; - _ZcashRpcProvider = ZcashRpcProvider; - _handlers = handlers; - StringLocalizer = stringLocalizer; - } - - public StoreData StoreData => HttpContext.GetStoreData(); - - [HttpGet()] - public async Task GetStoreZcashLikePaymentMethods() - { - var Zcash = StoreData.GetPaymentMethodConfigs(_handlers); - - var excludeFilters = StoreData.GetStoreBlob().GetExcludedPaymentMethods(); - - var accountsList = _ZcashLikeConfiguration.ZcashLikeConfigurationItems.ToDictionary(pair => pair.Key, - pair => GetAccounts(pair.Key)); - - await Task.WhenAll(accountsList.Values); - return View(new ZcashLikePaymentMethodListViewModel() - { - Items = _ZcashLikeConfiguration.ZcashLikeConfigurationItems.Select(pair => - GetZcashLikePaymentMethodViewModel(StoreData, pair.Key, excludeFilters, - accountsList[pair.Key].Result)) - }); - } - - private Task GetAccounts(string cryptoCode) - { - try - { - if (_ZcashRpcProvider.Summaries.TryGetValue(cryptoCode, out var summary) && summary.WalletAvailable) - { - - return _ZcashRpcProvider.WalletRpcClients[cryptoCode].SendCommandAsync("get_accounts", new GetAccountsRequest()); - } - } - catch { } - return Task.FromResult(null); - } - - private ZcashLikePaymentMethodViewModel GetZcashLikePaymentMethodViewModel( - StoreData store, string cryptoCode, - IPaymentFilter excludeFilters, GetAccountsResponse accountsResponse) - { - var Zcash = store.GetPaymentMethodConfigs(_handlers); - var settings = Zcash.SingleOrDefault(method => ((IHasNetwork)_handlers[method.Key]).Network.CryptoCode == cryptoCode).Value; - _ZcashRpcProvider.Summaries.TryGetValue(cryptoCode, out var summary); - _ZcashLikeConfiguration.ZcashLikeConfigurationItems.TryGetValue(cryptoCode, - out var configurationItem); - var fileAddress = Path.Combine(configurationItem.WalletDirectory, "wallet"); - var accounts = accountsResponse?.SubaddressAccounts?.Select(account => - new SelectListItem( - $"{account.AccountIndex} - {(string.IsNullOrEmpty(account.Label) ? "No label" : account.Label)}", - account.AccountIndex.ToString(CultureInfo.InvariantCulture))); - return new ZcashLikePaymentMethodViewModel() - { - WalletFileFound = System.IO.File.Exists(fileAddress), - Enabled = - settings != null && - !excludeFilters.Match(PaymentTypes.CHAIN.GetPaymentMethodId(cryptoCode)), - Summary = summary, - CryptoCode = cryptoCode, - AccountIndex = settings?.AccountIndex ?? accountsResponse?.SubaddressAccounts?.FirstOrDefault()?.AccountIndex ?? 0, - Accounts = accounts == null ? null : new SelectList(accounts, nameof(SelectListItem.Value), - nameof(SelectListItem.Text)) - }; - } - - [HttpGet("{cryptoCode}")] - public async Task GetStoreZcashLikePaymentMethod(string cryptoCode) - { - cryptoCode = cryptoCode.ToUpperInvariant(); - if (!_ZcashLikeConfiguration.ZcashLikeConfigurationItems.ContainsKey(cryptoCode)) - { - return NotFound(); - } - - var vm = GetZcashLikePaymentMethodViewModel(StoreData, cryptoCode, - StoreData.GetStoreBlob().GetExcludedPaymentMethods(), await GetAccounts(cryptoCode)); - return View(nameof(GetStoreZcashLikePaymentMethod), vm); - } - - [DisableRequestSizeLimit] - [HttpPost("{cryptoCode}")] - public async Task GetStoreZcashLikePaymentMethod(ZcashLikePaymentMethodViewModel viewModel, string command, string cryptoCode) - { - cryptoCode = cryptoCode.ToUpperInvariant(); - if (!_ZcashLikeConfiguration.ZcashLikeConfigurationItems.TryGetValue(cryptoCode, - out var configurationItem)) - { - return NotFound(); - } - - if (command == "add-account") - { - try - { - var newAccount = await _ZcashRpcProvider.WalletRpcClients[cryptoCode].SendCommandAsync("create_account", new CreateAccountRequest() - { - Label = viewModel.NewAccountLabel - }); - viewModel.AccountIndex = newAccount.AccountIndex; - } - catch (Exception) - { - ModelState.AddModelError(nameof(viewModel.AccountIndex), StringLocalizer["Could not create new account."]); - } - - } - else if (command == "upload-wallet") - { - var valid = true; - if (viewModel.WalletFile == null) - { - ModelState.AddModelError(nameof(viewModel.WalletFile), StringLocalizer["Please select the wallet file"]); - valid = false; - } - if (viewModel.WalletKeysFile == null) - { - ModelState.AddModelError(nameof(viewModel.WalletKeysFile), StringLocalizer["Please select the wallet.keys file"]); - valid = false; - } - - if (valid) - { - if (_ZcashRpcProvider.Summaries.TryGetValue(cryptoCode, out var summary)) - { - if (summary.WalletAvailable) - { - TempData.SetStatusMessageModel(new StatusMessageModel - { - Severity = StatusMessageModel.StatusSeverity.Error, - Message = StringLocalizer["There is already an active wallet configured for {0}. Replacing it would break any existing invoices!", cryptoCode].Value - }); - return RedirectToAction(nameof(GetStoreZcashLikePaymentMethod), - new { cryptoCode }); - } - } - - var fileAddress = Path.Combine(configurationItem.WalletDirectory, "wallet"); - using (var fileStream = new FileStream(fileAddress, FileMode.Create)) - { - await viewModel.WalletFile.CopyToAsync(fileStream); - try - { - Exec($"chmod 666 {fileAddress}"); - } - catch - { - } - } - - fileAddress = Path.Combine(configurationItem.WalletDirectory, "wallet.keys"); - using (var fileStream = new FileStream(fileAddress, FileMode.Create)) - { - await viewModel.WalletKeysFile.CopyToAsync(fileStream); - try - { - Exec($"chmod 666 {fileAddress}"); - } - catch - { - } - - } - - fileAddress = Path.Combine(configurationItem.WalletDirectory, "password"); - using (var fileStream = new StreamWriter(fileAddress, false)) - { - await fileStream.WriteAsync(viewModel.WalletPassword); - try - { - Exec($"chmod 666 {fileAddress}"); - } - catch - { - } - } - - return RedirectToAction(nameof(GetStoreZcashLikePaymentMethod), new - { - cryptoCode, - StatusMessage = "Wallet files uploaded. If it was valid, the wallet will become available soon" - - }); - } - } - - if (!ModelState.IsValid) - { - - var vm = GetZcashLikePaymentMethodViewModel(StoreData, cryptoCode, - StoreData.GetStoreBlob().GetExcludedPaymentMethods(), await GetAccounts(cryptoCode)); - - vm.Enabled = viewModel.Enabled; - vm.NewAccountLabel = viewModel.NewAccountLabel; - vm.AccountIndex = viewModel.AccountIndex; - return View(vm); - } - - var storeData = StoreData; - var blob = storeData.GetStoreBlob(); - var pmi = PaymentTypes.CHAIN.GetPaymentMethodId(cryptoCode); - storeData.SetPaymentMethodConfig(_handlers[pmi], new ZcashPaymentMethodConfig() - { - AccountIndex = viewModel.AccountIndex - }); - - blob.SetExcluded(PaymentTypes.CHAIN.GetPaymentMethodId(viewModel.CryptoCode), !viewModel.Enabled); - storeData.SetStoreBlob(blob); - await _StoreRepository.UpdateStore(storeData); - return RedirectToAction("GetStoreZcashLikePaymentMethods", - new { StatusMessage = $"{cryptoCode} settings updated successfully", storeId = StoreData.Id }); - } - - private void Exec(string cmd) - { - - var escapedArgs = cmd.Replace("\"", "\\\"", StringComparison.InvariantCulture); - - var process = new Process - { - StartInfo = new ProcessStartInfo - { - RedirectStandardOutput = true, - UseShellExecute = false, - CreateNoWindow = true, - WindowStyle = ProcessWindowStyle.Hidden, - FileName = "/bin/sh", - Arguments = $"-c \"{escapedArgs}\"" - } - }; - -#pragma warning disable CA1416 // Validate platform compatibility - process.Start(); -#pragma warning restore CA1416 // Validate platform compatibility - process.WaitForExit(); - } - - public class ZcashLikePaymentMethodListViewModel - { - public IEnumerable Items { get; set; } - } - - public class ZcashLikePaymentMethodViewModel - { - public ZcashRPCProvider.ZcashLikeSummary Summary { get; set; } - public string CryptoCode { get; set; } - public string NewAccountLabel { get; set; } - public long AccountIndex { get; set; } - public bool Enabled { get; set; } - - public IEnumerable Accounts { get; set; } - public bool WalletFileFound { get; set; } - [Display(Name = "View-Only Wallet File")] - public IFormFile WalletFile { get; set; } - public IFormFile WalletKeysFile { get; set; } - public string WalletPassword { get; set; } - } - } -} diff --git a/BTCPayServer/Services/Altcoins/Zcash/UI/ZcashPaymentViewModel.cs b/BTCPayServer/Services/Altcoins/Zcash/UI/ZcashPaymentViewModel.cs deleted file mode 100644 index 2972c5993..000000000 --- a/BTCPayServer/Services/Altcoins/Zcash/UI/ZcashPaymentViewModel.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using BTCPayServer.Payments; - -namespace BTCPayServer.Services.Altcoins.Zcash.UI -{ - public class ZcashPaymentViewModel - { - public PaymentMethodId PaymentMethodId { get; set; } - public string Confirmations { get; set; } - public string DepositAddress { get; set; } - public string Amount { get; set; } - public string TransactionId { get; set; } - public DateTimeOffset ReceivedTime { get; set; } - public string TransactionLink { get; set; } - public string Currency { get; set; } - } -} diff --git a/BTCPayServer/Views/Shared/Monero/MoneroSyncSummary.cshtml b/BTCPayServer/Views/Shared/Monero/MoneroSyncSummary.cshtml deleted file mode 100644 index 231882e6f..000000000 --- a/BTCPayServer/Views/Shared/Monero/MoneroSyncSummary.cshtml +++ /dev/null @@ -1,26 +0,0 @@ -@using BTCPayServer.Services.Altcoins.Monero.Services -@inject MoneroRPCProvider MoneroRpcProvider -@inject SignInManager SignInManager; - -@if (SignInManager.IsSignedIn(User) && User.IsInRole(Roles.ServerAdmin) && MoneroRpcProvider.Summaries.Any()) -{ - @foreach (var summary in MoneroRpcProvider.Summaries) - { - @if (summary.Value != null) - { - var status = summary.Value.DaemonAvailable - ? summary.Value.Synced ? "enabled" : "pending" - : "disabled"; -
- - @summary.Key -
-
    -
  • Node available: @summary.Value.DaemonAvailable
  • -
  • Wallet available: @summary.Value.WalletAvailable
  • -
  • Last updated: @summary.Value.UpdatedAt
  • -
  • Synced: @summary.Value.Synced (@summary.Value.CurrentHeight / @summary.Value.TargetHeight)
  • -
- } - } -} diff --git a/BTCPayServer/Views/Shared/Monero/StoreNavMoneroExtension.cshtml b/BTCPayServer/Views/Shared/Monero/StoreNavMoneroExtension.cshtml deleted file mode 100644 index fc5ca8bdb..000000000 --- a/BTCPayServer/Views/Shared/Monero/StoreNavMoneroExtension.cshtml +++ /dev/null @@ -1,16 +0,0 @@ -@using BTCPayServer.Services.Altcoins.Monero.Configuration -@using BTCPayServer.Services.Altcoins.Monero.UI -@using Microsoft.AspNetCore.Mvc.TagHelpers -@using BTCPayServer.Abstractions.Contracts -@inject SignInManager SignInManager; -@inject MoneroLikeConfiguration MoneroLikeConfiguration; -@inject IScopeProvider ScopeProvider -@{ - var storeId = ScopeProvider.GetCurrentStoreId(); - var isActive = !string.IsNullOrEmpty(storeId) && ViewContext.RouteData.Values.TryGetValue("Controller", out var controller) && controller is not null && - nameof(UIMoneroLikeStoreController).StartsWith(controller.ToString() ?? string.Empty, StringComparison.InvariantCultureIgnoreCase); -} -@if (SignInManager.IsSignedIn(User) && User.IsInRole(Roles.ServerAdmin) && MoneroLikeConfiguration.MoneroLikeConfigurationItems.Any()) -{ - Monero -} diff --git a/BTCPayServer/Views/Shared/Monero/StoreWalletsNavMoneroExtension.cshtml b/BTCPayServer/Views/Shared/Monero/StoreWalletsNavMoneroExtension.cshtml deleted file mode 100644 index 2c5bcaa2e..000000000 --- a/BTCPayServer/Views/Shared/Monero/StoreWalletsNavMoneroExtension.cshtml +++ /dev/null @@ -1,34 +0,0 @@ -@using BTCPayServer.Services.Altcoins.Monero.Configuration -@using BTCPayServer.Services.Altcoins.Monero.UI -@using BTCPayServer.Abstractions.Contracts -@inject SignInManager SignInManager; -@inject MoneroLikeConfiguration MoneroLikeConfiguration; -@inject IScopeProvider ScopeProvider -@inject UIMoneroLikeStoreController UIMoneroLikeStore; -@{ - var storeId = ScopeProvider.GetCurrentStoreId(); - -} -@if (SignInManager.IsSignedIn(User) && User.IsInRole(Roles.ServerAdmin) && MoneroLikeConfiguration.MoneroLikeConfigurationItems.Any()) -{ - var store = Context.GetStoreData(); - var result = await UIMoneroLikeStore.GetVM(store); - - foreach (var item in result.Items) - { - - var isActive = !string.IsNullOrEmpty(storeId) && ViewContext.RouteData.Values.TryGetValue("Controller", out var controller) && controller is not null && - nameof(UIMoneroLikeStoreController).StartsWith(controller.ToString() ?? string.Empty, StringComparison.InvariantCultureIgnoreCase) && - ViewContext.RouteData.Values.TryGetValue("cryptoCode", out var cryptoCode) && cryptoCode is not null && cryptoCode.ToString() == item.CryptoCode; - - } -} diff --git a/BTCPayServer/Views/Shared/Monero/ViewMoneroLikePaymentData.cshtml b/BTCPayServer/Views/Shared/Monero/ViewMoneroLikePaymentData.cshtml deleted file mode 100644 index 5219b0a09..000000000 --- a/BTCPayServer/Views/Shared/Monero/ViewMoneroLikePaymentData.cshtml +++ /dev/null @@ -1,68 +0,0 @@ -@using System.Globalization -@using BTCPayServer.Plugins.Altcoins; -@using BTCPayServer.Services -@using BTCPayServer.Services.Altcoins.Monero.Payments -@using BTCPayServer.Services.Altcoins.Monero.Services -@using BTCPayServer.Services.Altcoins.Monero.UI -@using BTCPayServer.Services.Invoices -@inject DisplayFormatter DisplayFormatter -@model InvoiceDetailsModel -@inject TransactionLinkProviders TransactionLinkProviders -@inject PaymentMethodHandlerDictionary handlers - -@{ - var payments = Model.Payments.Select(payment => - { - if (!handlers.TryGetValue(payment.PaymentMethodId, out var h) || h is not MoneroLikePaymentMethodHandler handler) - return null; - var m = new MoneroPaymentViewModel(); - var onChainPaymentData = handler.ParsePaymentDetails(payment.Details); - m.PaymentMethodId = handler.PaymentMethodId; - m.DepositAddress = payment.Destination; - m.Amount = payment.Value.ToString(CultureInfo.InvariantCulture); - - var confReq = MoneroListener.ConfirmationsRequired(onChainPaymentData, payment.InvoiceEntity.SpeedPolicy); - var confCount = onChainPaymentData.ConfirmationCount; - confCount = Math.Min(confReq, confCount); - m.Confirmations = $"{confCount} / {confReq}"; - - m.TransactionId = onChainPaymentData.TransactionId; - m.ReceivedTime = payment.ReceivedTime; - if (onChainPaymentData.TransactionId != null) - m.TransactionLink = TransactionLinkProviders.GetTransactionLink(m.PaymentMethodId, onChainPaymentData.TransactionId); - m.Currency = payment.Currency; - return m; - }).Where(c => c != null).ToList(); -} - -@if (payments.Any()) -{ -
-
Monero Payments
- - - - - - - - - - - - @foreach (var payment in payments) - { - - - - - - - - } - -
Payment MethodDestinationPayment ProofConfirmationsPaid
@payment.PaymentMethodId@payment.Confirmations - @DisplayFormatter.Currency(payment.Amount, payment.Currency) -
-
-} diff --git a/BTCPayServer/Views/Shared/Zcash/StoreNavZcashExtension.cshtml b/BTCPayServer/Views/Shared/Zcash/StoreNavZcashExtension.cshtml deleted file mode 100644 index 9761c1b73..000000000 --- a/BTCPayServer/Views/Shared/Zcash/StoreNavZcashExtension.cshtml +++ /dev/null @@ -1,16 +0,0 @@ -@using BTCPayServer.Services.Altcoins.Zcash.Configuration -@using BTCPayServer.Services.Altcoins.Zcash.UI -@using Microsoft.AspNetCore.Mvc.TagHelpers -@using BTCPayServer.Abstractions.Contracts -@inject SignInManager SignInManager; -@inject ZcashLikeConfiguration ZcashLikeConfiguration; -@inject IScopeProvider ScopeProvider -@{ - var storeId = ScopeProvider.GetCurrentStoreId(); - var isActive = !string.IsNullOrEmpty(storeId) && ViewContext.RouteData.Values.TryGetValue("Controller", out var controller) && controller is not null && - nameof(UIZcashLikeStoreController).StartsWith(controller.ToString() ?? string.Empty, StringComparison.InvariantCultureIgnoreCase); -} -@if (SignInManager.IsSignedIn(User) && User.IsInRole(Roles.ServerAdmin) && ZcashLikeConfiguration.ZcashLikeConfigurationItems.Any()) -{ - Zcash -} diff --git a/BTCPayServer/Views/Shared/Zcash/ViewZcashLikePaymentData.cshtml b/BTCPayServer/Views/Shared/Zcash/ViewZcashLikePaymentData.cshtml deleted file mode 100644 index 41d291edf..000000000 --- a/BTCPayServer/Views/Shared/Zcash/ViewZcashLikePaymentData.cshtml +++ /dev/null @@ -1,69 +0,0 @@ -@using System.Globalization -@using BTCPayServer.Plugins.Altcoins; -@using BTCPayServer.Components.TruncateCenter -@using BTCPayServer.Services -@using BTCPayServer.Services.Altcoins.Zcash.Payments -@using BTCPayServer.Services.Altcoins.Zcash.Services -@using BTCPayServer.Services.Altcoins.Zcash.UI -@using BTCPayServer.Services.Invoices -@inject DisplayFormatter DisplayFormatter -@model InvoiceDetailsModel -@inject TransactionLinkProviders TransactionLinkProviders -@inject PaymentMethodHandlerDictionary handlers - -@{ - var payments = Model.Payments.Select(payment => - { - if (!handlers.TryGetValue(payment.PaymentMethodId, out var h) || h is not ZcashLikePaymentMethodHandler handler) - return null; - var m = new ZcashPaymentViewModel(); - var onChainPaymentData = handler.ParsePaymentDetails(payment.Details); - m.PaymentMethodId = handler.PaymentMethodId; - m.DepositAddress = payment.Destination; - m.Amount = payment.Value.ToString(CultureInfo.InvariantCulture); - - var confReq = ZcashListener.ConfirmationsRequired(payment.InvoiceEntity.SpeedPolicy); - var confCount = onChainPaymentData.ConfirmationCount; - confCount = Math.Min(confReq, confCount); - m.Confirmations = $"{confCount} / {confReq}"; - - m.TransactionId = onChainPaymentData.TransactionId; - m.ReceivedTime = payment.ReceivedTime; - if (onChainPaymentData.TransactionId != null) - m.TransactionLink = TransactionLinkProviders.GetTransactionLink(m.PaymentMethodId, onChainPaymentData.TransactionId); - m.Currency = payment.Currency; - return m; - }).Where(c => c != null).ToList(); -} - -@if (payments.Any()) -{ -
-
Zcash Payments
- - - - - - - - - - - - @foreach (var payment in payments) - { - - - - - - - - } - -
Payment MethodDestinationPayment ProofConfirmationsPaid
@payment.PaymentMethodId@payment.Confirmations - @DisplayFormatter.Currency(payment.Amount, payment.Currency) -
-
-} diff --git a/BTCPayServer/Views/Shared/Zcash/ZcashSyncSummary.cshtml b/BTCPayServer/Views/Shared/Zcash/ZcashSyncSummary.cshtml deleted file mode 100644 index 1274aa17e..000000000 --- a/BTCPayServer/Views/Shared/Zcash/ZcashSyncSummary.cshtml +++ /dev/null @@ -1,26 +0,0 @@ -@using BTCPayServer.Services.Altcoins.Zcash.Services -@inject ZcashRPCProvider ZcashRpcProvider -@inject SignInManager SignInManager; - -@if (SignInManager.IsSignedIn(User) && User.IsInRole(Roles.ServerAdmin) && ZcashRpcProvider.Summaries.Any()) -{ - @foreach (var summary in ZcashRpcProvider.Summaries) - { - @if (summary.Value != null) - { - var status = summary.Value.DaemonAvailable - ? summary.Value.Synced ? "enabled" : "pending" - : "disabled"; -
- - @summary.Key -
-
    -
  • Node available: @summary.Value.DaemonAvailable
  • -
  • Wallet available: @summary.Value.WalletAvailable
  • -
  • Last updated: @summary.Value.UpdatedAt
  • -
  • Synced: @summary.Value.Synced (@summary.Value.CurrentHeight / @summary.Value.TargetHeight)
  • -
- } - } -} diff --git a/BTCPayServer/Views/UIMoneroLikeStore/GetStoreMoneroLikePaymentMethod.cshtml b/BTCPayServer/Views/UIMoneroLikeStore/GetStoreMoneroLikePaymentMethod.cshtml deleted file mode 100644 index 343174464..000000000 --- a/BTCPayServer/Views/UIMoneroLikeStore/GetStoreMoneroLikePaymentMethod.cshtml +++ /dev/null @@ -1,148 +0,0 @@ -@using MoneroLikePaymentMethodViewModel = BTCPayServer.Services.Altcoins.Monero.UI.UIMoneroLikeStoreController.MoneroLikePaymentMethodViewModel -@using MoneroLikeSettlementThresholdChoice = BTCPayServer.Services.Altcoins.Monero.UI.UIMoneroLikeStoreController.MoneroLikeSettlementThresholdChoice; -@model MoneroLikePaymentMethodViewModel - -@{ - ViewData.SetActivePage(Model.CryptoCode, StringLocalizer["{0} Settings", Model.CryptoCode], Model.CryptoCode); -} - - - -
-
- @if (!ViewContext.ModelState.IsValid) - { -
- } - @if (Model.Summary != null) - { -
-
    -
  • Node available: @Model.Summary.DaemonAvailable
  • -
  • Wallet available: @Model.Summary.WalletAvailable (@(Model.WalletFileFound ? "Wallet file present" : "Wallet file not found"))
  • -
  • Last updated: @Model.Summary.UpdatedAt
  • -
  • Synced: @Model.Summary.Synced (@Model.Summary.CurrentHeight / @Model.Summary.TargetHeight)
  • -
-
- } - - @if (!Model.WalletFileFound || Model.Summary.WalletHeight == default) - { -
- -
-

Upload Wallet

-
- - - -
-
- - - -
-
- - - -
- -
-
- } -
- - - @if (!Model.WalletFileFound || Model.Summary.WalletHeight == default) - { - - } - else - { -
- - @if (@Model.Accounts != null && Model.Accounts.Any()) - { - - - } - else - { - No accounts available on the current wallet - - } -
-
-
- - -
-
- } - -
- - - -
- -
- - - - - - - -
- - - -
- - - - Back to list - -
-
-
-
- -@section PageFootContent { - @await Html.PartialAsync("_ValidationScriptsPartial") -} diff --git a/BTCPayServer/Views/UIMoneroLikeStore/GetStoreMoneroLikePaymentMethods.cshtml b/BTCPayServer/Views/UIMoneroLikeStore/GetStoreMoneroLikePaymentMethods.cshtml deleted file mode 100644 index 67a64a5dd..000000000 --- a/BTCPayServer/Views/UIMoneroLikeStore/GetStoreMoneroLikePaymentMethods.cshtml +++ /dev/null @@ -1,57 +0,0 @@ -@model BTCPayServer.Services.Altcoins.Monero.UI.UIMoneroLikeStoreController.MoneroLikePaymentMethodListViewModel - -@{ - ViewData.SetActivePage("Monero Settings", StringLocalizer["{0} Settings", "Monero"], "Monero Settings"); -} - -
-
- @if (!ViewContext.ModelState.IsValid) - { -
- } -
- - - - - - - - - - - @foreach (var item in Model.Items) - { - - - - - - - } - -
CryptoAccount IndexEnabledActions
@item.CryptoCode@item.AccountIndex - @if (item.Enabled) - { - - } - else - { - - } - - - Modify - -
-
-
-
- -@section PageFootContent { - @await Html.PartialAsync("_ValidationScriptsPartial") -} diff --git a/BTCPayServer/Views/UIZcashLikeStore/GetStoreZcashLikePaymentMethod.cshtml b/BTCPayServer/Views/UIZcashLikeStore/GetStoreZcashLikePaymentMethod.cshtml deleted file mode 100644 index 20351be06..000000000 --- a/BTCPayServer/Views/UIZcashLikeStore/GetStoreZcashLikePaymentMethod.cshtml +++ /dev/null @@ -1,112 +0,0 @@ -@using BTCPayServer.Views.Stores -@model BTCPayServer.Services.Altcoins.Zcash.UI.UIZcashLikeStoreController.ZcashLikePaymentMethodViewModel - -@{ - ViewData.SetActivePage(StoreNavPages.OnchainSettings, StringLocalizer["{0} Settings", Model.CryptoCode], $"{Context.GetStoreData().Id}-{Model.CryptoCode}"); -} - -
-
- @if (!ViewContext.ModelState.IsValid) - { -
- } - @if (Model.Summary != null) - { -
-
    -
  • Node available: @Model.Summary.DaemonAvailable
  • -
  • Wallet available: @Model.Summary.WalletAvailable (@(Model.WalletFileFound ? "Wallet file present" : "Wallet file not found"))
  • -
  • Last updated: @Model.Summary.UpdatedAt
  • -
  • Synced: @Model.Summary.Synced (@Model.Summary.CurrentHeight / @Model.Summary.TargetHeight)
  • -
-
- } - - @if (!Model.WalletFileFound || Model.Summary.WalletHeight == default) - { -
- -
-

Upload Wallet

-
- - - -
-
- - - -
-
- - - -
- -
-
- } -
- - - @if (!Model.WalletFileFound || Model.Summary.WalletHeight == default) - { - - } - else - { -
- - @if (@Model.Accounts != null && Model.Accounts.Any()) - { - - - } - else - { - No accounts available on the current wallet - - } -
-
-
- - -
-
- } - -
- - - -
- -
- - - - Back to list - -
-
-
-
- -@section PageFootContent { - @await Html.PartialAsync("_ValidationScriptsPartial") -} diff --git a/BTCPayServer/Views/UIZcashLikeStore/GetStoreZcashLikePaymentMethods.cshtml b/BTCPayServer/Views/UIZcashLikeStore/GetStoreZcashLikePaymentMethods.cshtml deleted file mode 100644 index 870469965..000000000 --- a/BTCPayServer/Views/UIZcashLikeStore/GetStoreZcashLikePaymentMethods.cshtml +++ /dev/null @@ -1,58 +0,0 @@ -@using BTCPayServer.Views.Stores -@model BTCPayServer.Services.Altcoins.Zcash.UI.UIZcashLikeStoreController.ZcashLikePaymentMethodListViewModel - -@{ - ViewData.SetActivePage(StoreNavPages.OnchainSettings, StringLocalizer["{0} Settings", "Zcash"], $"{Context.GetStoreData().Id}-ZEC"); -} - -
-
- @if (!ViewContext.ModelState.IsValid) - { -
- } -
- - - - - - - - - - - @foreach (var item in Model.Items) - { - - - - - - - } - -
CryptoAccount IndexEnabledActions
@item.CryptoCode@item.AccountIndex - @if (item.Enabled) - { - - } - else - { - - } - - - Modify - -
-
-
-
- -@section PageFootContent { - @await Html.PartialAsync("_ValidationScriptsPartial") -} diff --git a/BTCPayServer/wwwroot/imlegacy/monero.svg b/BTCPayServer/wwwroot/imlegacy/monero.svg deleted file mode 100644 index 05d80151e..000000000 --- a/BTCPayServer/wwwroot/imlegacy/monero.svg +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/BTCPayServer/wwwroot/imlegacy/zcash.png b/BTCPayServer/wwwroot/imlegacy/zcash.png deleted file mode 100644 index 82de5b7ac..000000000 Binary files a/BTCPayServer/wwwroot/imlegacy/zcash.png and /dev/null differ