using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Reflection; using System.Security.Claims; using System.Threading; using System.Threading.Tasks; using BTCPayServer.Abstractions.Contracts; using BTCPayServer.Client; using BTCPayServer.Client.Models; using BTCPayServer.Controllers.GreenField; using BTCPayServer.Data; using BTCPayServer.Security.Greenfield; using BTCPayServer.Services.Mails; using BTCPayServer.Services.Stores; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using NBitcoin; using NBXplorer.Models; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using InvoiceData = BTCPayServer.Client.Models.InvoiceData; using Language = BTCPayServer.Client.Models.Language; using NotificationData = BTCPayServer.Client.Models.NotificationData; using PaymentRequestData = BTCPayServer.Client.Models.PaymentRequestData; using PayoutData = BTCPayServer.Client.Models.PayoutData; using PullPaymentData = BTCPayServer.Client.Models.PullPaymentData; using StoreData = BTCPayServer.Client.Models.StoreData; using StoreWebhookData = BTCPayServer.Client.Models.StoreWebhookData; using WebhookDeliveryData = BTCPayServer.Client.Models.WebhookDeliveryData; namespace BTCPayServer.Controllers.Greenfield { public class BTCPayServerClientFactory : IBTCPayServerClientFactory { private readonly StoreRepository _storeRepository; private readonly IOptionsMonitor _identityOptions; private readonly GreenfieldStoreOnChainPaymentMethodsController _chainPaymentMethodsController; private readonly GreenfieldStoreOnChainWalletsController _storeOnChainWalletsController; private readonly GreenfieldStoreLightningNetworkPaymentMethodsController _storeLightningNetworkPaymentMethodsController; private readonly GreenfieldStoreLNURLPayPaymentMethodsController _storeLnurlPayPaymentMethodsController; private readonly GreenfieldHealthController _healthController; private readonly GreenfieldPaymentRequestsController _paymentRequestController; private readonly GreenfieldApiKeysController _apiKeysController; private readonly GreenfieldNotificationsController _notificationsController; private readonly GreenfieldUsersController _usersController; private readonly GreenfieldStoresController _storesController; private readonly GreenfieldInternalLightningNodeApiController _internalLightningNodeApiController; private readonly GreenfieldStoreLightningNodeApiController _storeLightningNodeApiController; private readonly GreenfieldInvoiceController _greenFieldInvoiceController; private readonly UserManager _userManager; private readonly GreenfieldServerInfoController _greenFieldServerInfoController; private readonly GreenfieldStoreWebhooksController _storeWebhooksController; private readonly GreenfieldPullPaymentController _greenfieldPullPaymentController; private readonly UIHomeController _homeController; private readonly GreenfieldStorePaymentMethodsController _storePaymentMethodsController; private readonly GreenfieldStoreEmailController _greenfieldStoreEmailController; private readonly GreenfieldStoreUsersController _greenfieldStoreUsersController; private readonly GreenfieldStorePayoutProcessorsController _greenfieldStorePayoutProcessorsController; private readonly GreenfieldPayoutProcessorsController _greenfieldPayoutProcessorsController; private readonly GreenfieldStoreAutomatedOnChainPayoutProcessorsController _greenfieldStoreAutomatedOnChainPayoutProcessorsController; private readonly GreenfieldStoreAutomatedLightningPayoutProcessorsController _greenfieldStoreAutomatedLightningPayoutProcessorsController; private readonly IServiceProvider _serviceProvider; public BTCPayServerClientFactory(StoreRepository storeRepository, IOptionsMonitor identityOptions, GreenfieldStoreOnChainPaymentMethodsController chainPaymentMethodsController, GreenfieldStoreOnChainWalletsController storeOnChainWalletsController, GreenfieldStoreLightningNetworkPaymentMethodsController storeLightningNetworkPaymentMethodsController, GreenfieldStoreLNURLPayPaymentMethodsController storeLnurlPayPaymentMethodsController, GreenfieldHealthController healthController, GreenfieldPaymentRequestsController paymentRequestController, GreenfieldApiKeysController apiKeysController, GreenfieldNotificationsController notificationsController, GreenfieldUsersController usersController, GreenfieldStoresController storesController, GreenfieldInternalLightningNodeApiController internalLightningNodeApiController, GreenfieldStoreLightningNodeApiController storeLightningNodeApiController, GreenfieldInvoiceController greenFieldInvoiceController, UserManager userManager, GreenfieldServerInfoController greenFieldServerInfoController, GreenfieldStoreWebhooksController storeWebhooksController, GreenfieldPullPaymentController greenfieldPullPaymentController, UIHomeController homeController, GreenfieldStorePaymentMethodsController storePaymentMethodsController, GreenfieldStoreEmailController greenfieldStoreEmailController, GreenfieldStoreUsersController greenfieldStoreUsersController, GreenfieldStorePayoutProcessorsController greenfieldStorePayoutProcessorsController, GreenfieldPayoutProcessorsController greenfieldPayoutProcessorsController, GreenfieldStoreAutomatedOnChainPayoutProcessorsController greenfieldStoreAutomatedOnChainPayoutProcessorsController, GreenfieldStoreAutomatedLightningPayoutProcessorsController greenfieldStoreAutomatedLightningPayoutProcessorsController, IServiceProvider serviceProvider) { _storeRepository = storeRepository; _identityOptions = identityOptions; _chainPaymentMethodsController = chainPaymentMethodsController; _storeOnChainWalletsController = storeOnChainWalletsController; _storeLightningNetworkPaymentMethodsController = storeLightningNetworkPaymentMethodsController; _storeLnurlPayPaymentMethodsController = storeLnurlPayPaymentMethodsController; _healthController = healthController; _paymentRequestController = paymentRequestController; _apiKeysController = apiKeysController; _notificationsController = notificationsController; _usersController = usersController; _storesController = storesController; _internalLightningNodeApiController = internalLightningNodeApiController; _storeLightningNodeApiController = storeLightningNodeApiController; _greenFieldInvoiceController = greenFieldInvoiceController; _userManager = userManager; _greenFieldServerInfoController = greenFieldServerInfoController; _storeWebhooksController = storeWebhooksController; _greenfieldPullPaymentController = greenfieldPullPaymentController; _homeController = homeController; _storePaymentMethodsController = storePaymentMethodsController; _greenfieldStoreEmailController = greenfieldStoreEmailController; _greenfieldStoreUsersController = greenfieldStoreUsersController; _greenfieldStorePayoutProcessorsController = greenfieldStorePayoutProcessorsController; _greenfieldPayoutProcessorsController = greenfieldPayoutProcessorsController; _greenfieldStoreAutomatedOnChainPayoutProcessorsController = greenfieldStoreAutomatedOnChainPayoutProcessorsController; _greenfieldStoreAutomatedLightningPayoutProcessorsController = greenfieldStoreAutomatedLightningPayoutProcessorsController; _serviceProvider = serviceProvider; } public Task Create(string userId, params string[] storeIds) { return Create(userId, storeIds, new DefaultHttpContext() { Request = { Scheme = "https", Host = new HostString("dummy.com"), Path = new PathString(), PathBase = new PathString(), } }); } public async Task Create(string userId, string[] storeIds, HttpContext context) { if (!string.IsNullOrEmpty(userId)) { var user = await _userManager.FindByIdAsync(userId); List claims = new List { new Claim(_identityOptions.CurrentValue.ClaimsIdentity.UserIdClaimType, userId), new Claim(GreenfieldConstants.ClaimTypes.Permission, Permission.Create(Policies.Unrestricted).ToString()) }; claims.AddRange((await _userManager.GetRolesAsync(user)).Select(s => new Claim(_identityOptions.CurrentValue.ClaimsIdentity.RoleClaimType, s))); context.User = new ClaimsPrincipal(new ClaimsIdentity(claims, $"Local{GreenfieldConstants.AuthenticationType}WithUser")); } else { context.User = new ClaimsPrincipal(new ClaimsIdentity(new List(), $"Local{GreenfieldConstants.AuthenticationType}")); } if (storeIds?.Any() is true) { context.SetStoreData(await _storeRepository.FindStore(storeIds.First())); context.SetStoresData(await _storeRepository.GetStoresByUserId(userId, storeIds)); } else { context.SetStoresData(await _storeRepository.GetStoresByUserId(userId)); } return new LocalBTCPayServerClient( _serviceProvider, _chainPaymentMethodsController, _storeOnChainWalletsController, _healthController, _paymentRequestController, _apiKeysController, _notificationsController, _usersController, _storesController, _storeLightningNodeApiController, _internalLightningNodeApiController, _storeLightningNetworkPaymentMethodsController, _storeLnurlPayPaymentMethodsController, _greenFieldInvoiceController, _greenFieldServerInfoController, _storeWebhooksController, _greenfieldPullPaymentController, _homeController, _storePaymentMethodsController, _greenfieldStoreEmailController, _greenfieldStoreUsersController, _greenfieldStorePayoutProcessorsController, _greenfieldPayoutProcessorsController, _greenfieldStoreAutomatedOnChainPayoutProcessorsController, _greenfieldStoreAutomatedLightningPayoutProcessorsController, new LocalHttpContextAccessor() { HttpContext = context } ); } } public class LocalHttpContextAccessor : IHttpContextAccessor { public HttpContext HttpContext { get; set; } } public class LocalBTCPayServerClient : BTCPayServerClient { private readonly GreenfieldStoreOnChainPaymentMethodsController _chainPaymentMethodsController; private readonly GreenfieldStoreOnChainWalletsController _storeOnChainWalletsController; private readonly GreenfieldHealthController _healthController; private readonly GreenfieldPaymentRequestsController _paymentRequestController; private readonly GreenfieldApiKeysController _apiKeysController; private readonly GreenfieldNotificationsController _notificationsController; private readonly GreenfieldUsersController _usersController; private readonly GreenfieldStoresController _storesController; private readonly GreenfieldStoreLightningNodeApiController _storeLightningNodeApiController; private readonly GreenfieldInternalLightningNodeApiController _lightningNodeApiController; private readonly GreenfieldStoreLightningNetworkPaymentMethodsController _storeLightningNetworkPaymentMethodsController; private readonly GreenfieldStoreLNURLPayPaymentMethodsController _storeLnurlPayPaymentMethodsController; private readonly GreenfieldInvoiceController _greenFieldInvoiceController; private readonly GreenfieldServerInfoController _greenFieldServerInfoController; private readonly GreenfieldStoreWebhooksController _storeWebhooksController; private readonly GreenfieldPullPaymentController _greenfieldPullPaymentController; private readonly UIHomeController _homeController; private readonly GreenfieldStorePaymentMethodsController _storePaymentMethodsController; private readonly GreenfieldStoreEmailController _greenfieldStoreEmailController; private readonly GreenfieldStorePayoutProcessorsController _greenfieldStorePayoutProcessorsController; private readonly GreenfieldPayoutProcessorsController _greenfieldPayoutProcessorsController; private readonly GreenfieldStoreAutomatedOnChainPayoutProcessorsController _greenfieldStoreAutomatedOnChainPayoutProcessorsController; private readonly GreenfieldStoreAutomatedLightningPayoutProcessorsController _greenfieldStoreAutomatedLightningPayoutProcessorsController; private readonly GreenfieldStoreUsersController _greenfieldStoreUsersController; public LocalBTCPayServerClient( IServiceProvider serviceProvider, GreenfieldStoreOnChainPaymentMethodsController chainPaymentMethodsController, GreenfieldStoreOnChainWalletsController storeOnChainWalletsController, GreenfieldHealthController healthController, GreenfieldPaymentRequestsController paymentRequestController, GreenfieldApiKeysController apiKeysController, GreenfieldNotificationsController notificationsController, GreenfieldUsersController usersController, GreenfieldStoresController storesController, GreenfieldStoreLightningNodeApiController storeLightningNodeApiController, GreenfieldInternalLightningNodeApiController lightningNodeApiController, GreenfieldStoreLightningNetworkPaymentMethodsController storeLightningNetworkPaymentMethodsController, GreenfieldStoreLNURLPayPaymentMethodsController storeLnurlPayPaymentMethodsController, GreenfieldInvoiceController greenFieldInvoiceController, GreenfieldServerInfoController greenFieldServerInfoController, GreenfieldStoreWebhooksController storeWebhooksController, GreenfieldPullPaymentController greenfieldPullPaymentController, UIHomeController homeController, GreenfieldStorePaymentMethodsController storePaymentMethodsController, GreenfieldStoreEmailController greenfieldStoreEmailController, GreenfieldStoreUsersController greenfieldStoreUsersController, GreenfieldStorePayoutProcessorsController greenfieldStorePayoutProcessorsController, GreenfieldPayoutProcessorsController greenfieldPayoutProcessorsController, GreenfieldStoreAutomatedOnChainPayoutProcessorsController greenfieldStoreAutomatedOnChainPayoutProcessorsController, GreenfieldStoreAutomatedLightningPayoutProcessorsController greenfieldStoreAutomatedLightningPayoutProcessorsController, IHttpContextAccessor httpContextAccessor) : base(new Uri("https://dummy.local"), "", "") { _chainPaymentMethodsController = chainPaymentMethodsController; _storeOnChainWalletsController = storeOnChainWalletsController; _healthController = healthController; _paymentRequestController = paymentRequestController; _apiKeysController = apiKeysController; _notificationsController = notificationsController; _usersController = usersController; _storesController = storesController; _storeLightningNodeApiController = storeLightningNodeApiController; _lightningNodeApiController = lightningNodeApiController; _storeLightningNetworkPaymentMethodsController = storeLightningNetworkPaymentMethodsController; _storeLnurlPayPaymentMethodsController = storeLnurlPayPaymentMethodsController; _greenFieldInvoiceController = greenFieldInvoiceController; _greenFieldServerInfoController = greenFieldServerInfoController; _storeWebhooksController = storeWebhooksController; _greenfieldPullPaymentController = greenfieldPullPaymentController; _homeController = homeController; _storePaymentMethodsController = storePaymentMethodsController; _greenfieldStoreEmailController = greenfieldStoreEmailController; _greenfieldStoreUsersController = greenfieldStoreUsersController; _greenfieldStorePayoutProcessorsController = greenfieldStorePayoutProcessorsController; _greenfieldPayoutProcessorsController = greenfieldPayoutProcessorsController; _greenfieldStoreAutomatedOnChainPayoutProcessorsController = greenfieldStoreAutomatedOnChainPayoutProcessorsController; _greenfieldStoreAutomatedLightningPayoutProcessorsController = greenfieldStoreAutomatedLightningPayoutProcessorsController; var controllers = new[] { chainPaymentMethodsController, storeOnChainWalletsController, healthController, paymentRequestController, apiKeysController, notificationsController, usersController, storeLightningNetworkPaymentMethodsController, greenFieldInvoiceController, storeWebhooksController, greenFieldServerInfoController, greenfieldPullPaymentController, storesController, homeController, lightningNodeApiController, storeLightningNodeApiController as ControllerBase, storePaymentMethodsController, greenfieldStoreEmailController, greenfieldStoreUsersController, lightningNodeApiController, storeLightningNodeApiController as ControllerBase, storePaymentMethodsController, greenfieldStoreEmailController, greenfieldStorePayoutProcessorsController, greenfieldPayoutProcessorsController, greenfieldStoreAutomatedOnChainPayoutProcessorsController, greenfieldStoreAutomatedLightningPayoutProcessorsController, }; var authoverride = new DefaultAuthorizationService( serviceProvider.GetRequiredService(), new AuthHandlerProvider( serviceProvider.GetRequiredService(), serviceProvider.GetRequiredService>(), httpContextAccessor ), serviceProvider.GetRequiredService>(), serviceProvider.GetRequiredService(), serviceProvider.GetRequiredService(), serviceProvider.GetRequiredService>() ); foreach (var controller in controllers) { controller.ControllerContext.HttpContext = httpContextAccessor.HttpContext; var authInterface = typeof(IAuthorizationService); foreach (FieldInfo fieldInfo in controller.GetType().GetFields() .Where(info => authInterface.IsAssignableFrom(info.FieldType))) { fieldInfo.SetValue(controller, authoverride); } } } class AuthHandlerProvider : IAuthorizationHandlerProvider { private readonly IHttpContextAccessor _httpContextAccessor; private readonly UserManager _userManager; private readonly StoreRepository _storeRepository; public AuthHandlerProvider(StoreRepository storeRepository, UserManager userManager, IHttpContextAccessor httpContextAccessor) { _storeRepository = storeRepository; _userManager = userManager; _httpContextAccessor = httpContextAccessor; } public Task> GetHandlersAsync(AuthorizationHandlerContext context) { return Task.FromResult>(new IAuthorizationHandler[] { new LocalGreenfieldAuthorizationHandler(_httpContextAccessor, _userManager, _storeRepository) }); } } protected override HttpRequestMessage CreateHttpRequest(string path, Dictionary queryPayload = null, HttpMethod method = null) { throw new NotSupportedException("This method is not supported by the LocalBTCPayServerClient."); } public override async Task CreateWebhook(string storeId, CreateStoreWebhookRequest create, CancellationToken token = default) { return GetFromActionResult( await _storeWebhooksController.CreateWebhook(storeId, create)); } public override async Task GetWebhook(string storeId, string webhookId, CancellationToken token = default) { return GetFromActionResult( await _storeWebhooksController.ListWebhooks(storeId, webhookId)); } public override async Task UpdateWebhook(string storeId, string webhookId, UpdateStoreWebhookRequest update, CancellationToken token = default) { return GetFromActionResult( await _storeWebhooksController.UpdateWebhook(storeId, webhookId, update)); } public override async Task DeleteWebhook(string storeId, string webhookId, CancellationToken token = default) { HandleActionResult(await _storeWebhooksController.DeleteWebhook(storeId, webhookId)); return true; } public override async Task GetWebhooks(string storeId, CancellationToken token = default) { return GetFromActionResult( await _storeWebhooksController.ListWebhooks(storeId, null)); } public override async Task GetWebhookDeliveries(string storeId, string webhookId, CancellationToken token = default) { return GetFromActionResult( await _storeWebhooksController.ListDeliveries(storeId, webhookId, null)); } public override async Task GetWebhookDelivery(string storeId, string webhookId, string deliveryId, CancellationToken token = default) { return GetFromActionResult( await _storeWebhooksController.ListDeliveries(storeId, webhookId, deliveryId)); } public override async Task RedeliverWebhook(string storeId, string webhookId, string deliveryId, CancellationToken token = default) { return GetFromActionResult( await _storeWebhooksController.RedeliverWebhook(storeId, webhookId, deliveryId)); } public override async Task GetWebhookDeliveryRequest(string storeId, string webhookId, string deliveryId, CancellationToken token = default) { return GetFromActionResult( await _storeWebhooksController.GetDeliveryRequest(storeId, webhookId, deliveryId)); } public override async Task CreatePullPayment(string storeId, CreatePullPaymentRequest request, CancellationToken cancellationToken = default) { return GetFromActionResult( await _greenfieldPullPaymentController.CreatePullPayment(storeId, request)); } public override async Task GetPullPayment(string pullPaymentId, CancellationToken cancellationToken = default) { return GetFromActionResult( await _greenfieldPullPaymentController.GetPullPayment(pullPaymentId)); } public override async Task GetPullPayments(string storeId, bool includeArchived = false, CancellationToken cancellationToken = default) { return GetFromActionResult( await _greenfieldPullPaymentController.GetPullPayments(storeId, includeArchived)); } public override async Task ArchivePullPayment(string storeId, string pullPaymentId, CancellationToken cancellationToken = default) { HandleActionResult(await _greenfieldPullPaymentController.ArchivePullPayment(storeId, pullPaymentId)); } public override async Task GetPayouts(string pullPaymentId, bool includeCancelled = false, CancellationToken cancellationToken = default) { return GetFromActionResult( await _greenfieldPullPaymentController.GetPayouts(pullPaymentId, includeCancelled)); } public override async Task CreatePayout(string pullPaymentId, CreatePayoutRequest payoutRequest, CancellationToken cancellationToken = default) { return GetFromActionResult( await _greenfieldPullPaymentController.CreatePayout(pullPaymentId, payoutRequest)); } public override async Task CancelPayout(string storeId, string payoutId, CancellationToken cancellationToken = default) { HandleActionResult(await _greenfieldPullPaymentController.CancelPayout(storeId, payoutId)); } public override async Task ApprovePayout(string storeId, string payoutId, ApprovePayoutRequest request, CancellationToken cancellationToken = default) { return GetFromActionResult( await _greenfieldPullPaymentController.ApprovePayout(storeId, payoutId, request, cancellationToken)); } public override async Task GetLightningNodeInfo(string storeId, string cryptoCode, CancellationToken token = default) { return GetFromActionResult( await _storeLightningNodeApiController.GetInfo(cryptoCode, token)); } public override async Task ConnectToLightningNode(string storeId, string cryptoCode, ConnectToNodeRequest request, CancellationToken token = default) { HandleActionResult(await _storeLightningNodeApiController.ConnectToNode(cryptoCode, request, token)); } public override async Task> GetLightningNodeChannels(string storeId, string cryptoCode, CancellationToken token = default) { return GetFromActionResult>( await _storeLightningNodeApiController.GetChannels(cryptoCode, token)); } public override async Task OpenLightningChannel(string storeId, string cryptoCode, OpenLightningChannelRequest request, CancellationToken token = default) { HandleActionResult(await _storeLightningNodeApiController.OpenChannel(cryptoCode, request, token)); } public override async Task GetLightningDepositAddress(string storeId, string cryptoCode, CancellationToken token = default) { return GetFromActionResult( await _storeLightningNodeApiController.GetDepositAddress(cryptoCode, token)); } public override async Task PayLightningInvoice(string storeId, string cryptoCode, PayLightningInvoiceRequest request, CancellationToken token = default) { HandleActionResult(await _storeLightningNodeApiController.PayInvoice(cryptoCode, request, token)); } public override async Task GetLightningInvoice(string storeId, string cryptoCode, string invoiceId, CancellationToken token = default) { return GetFromActionResult( await _storeLightningNodeApiController.GetInvoice(cryptoCode, invoiceId, token)); } public override async Task CreateLightningInvoice(string storeId, string cryptoCode, CreateLightningInvoiceRequest request, CancellationToken token = default) { return GetFromActionResult( await _storeLightningNodeApiController.CreateInvoice(cryptoCode, request, token)); } public override async Task GetLightningNodeInfo(string cryptoCode, CancellationToken token = default) { return GetFromActionResult( await _lightningNodeApiController.GetInfo(cryptoCode)); } public override async Task ConnectToLightningNode(string cryptoCode, ConnectToNodeRequest request, CancellationToken token = default) { HandleActionResult(await _lightningNodeApiController.ConnectToNode(cryptoCode, request, token)); } public override async Task> GetLightningNodeChannels(string cryptoCode, CancellationToken token = default) { return GetFromActionResult>( await _lightningNodeApiController.GetChannels(cryptoCode, token)); } public override async Task OpenLightningChannel(string cryptoCode, OpenLightningChannelRequest request, CancellationToken token = default) { HandleActionResult(await _lightningNodeApiController.OpenChannel(cryptoCode, request, token)); } public override async Task GetLightningDepositAddress(string cryptoCode, CancellationToken token = default) { return GetFromActionResult( await _lightningNodeApiController.GetDepositAddress(cryptoCode, token)); } public override async Task PayLightningInvoice(string cryptoCode, PayLightningInvoiceRequest request, CancellationToken token = default) { return GetFromActionResult( await _lightningNodeApiController.PayInvoice(cryptoCode, request, token)); } public override async Task GetLightningInvoice(string cryptoCode, string invoiceId, CancellationToken token = default) { return GetFromActionResult( await _lightningNodeApiController.GetInvoice(cryptoCode, invoiceId, token)); } public override async Task CreateLightningInvoice(string cryptoCode, CreateLightningInvoiceRequest request, CancellationToken token = default) { return GetFromActionResult( await _lightningNodeApiController.CreateInvoice(cryptoCode, request, token)); } private T GetFromActionResult(IActionResult result) { HandleActionResult(result); return result switch { JsonResult jsonResult => (T)jsonResult.Value, OkObjectResult { Value: T res } => res, _ => default }; } private void HandleActionResult(IActionResult result) { switch (result) { case UnprocessableEntityObjectResult {Value: List validationErrors}: throw new GreenfieldValidationException(validationErrors.ToArray()); case BadRequestObjectResult {Value: GreenfieldAPIError error}: throw new GreenfieldAPIException(400, error); case NotFoundResult _: throw new GreenfieldAPIException(404, new GreenfieldAPIError("not-found", "")); default: return; } } private T GetFromActionResult(ActionResult result) { return GetFromActionResult((IActionResult)result); } private T GetFromActionResult(ActionResult result) { return result.Value ?? GetFromActionResult(result.Result); } public override Task> GetStoreOnChainPaymentMethods(string storeId, bool? enabled, CancellationToken token = default) { return Task.FromResult( GetFromActionResult(_chainPaymentMethodsController.GetOnChainPaymentMethods(storeId, enabled))); } public override Task GetStoreOnChainPaymentMethod(string storeId, string cryptoCode, CancellationToken token = default) { return Task.FromResult(GetFromActionResult( _chainPaymentMethodsController.GetOnChainPaymentMethod(storeId, cryptoCode))); } public override async Task RemoveStoreOnChainPaymentMethod(string storeId, string cryptoCode, CancellationToken token = default) { HandleActionResult(await _chainPaymentMethodsController.RemoveOnChainPaymentMethod(storeId, cryptoCode)); } public override async Task UpdateStoreOnChainPaymentMethod(string storeId, string cryptoCode, UpdateOnChainPaymentMethodRequest paymentMethod, CancellationToken token = default) { return GetFromActionResult( await _chainPaymentMethodsController.UpdateOnChainPaymentMethod(storeId, cryptoCode, new UpdateOnChainPaymentMethodRequest( enabled: paymentMethod.Enabled, label: paymentMethod.Label, accountKeyPath: paymentMethod.AccountKeyPath, derivationScheme: paymentMethod.DerivationScheme ))); } public override Task PreviewProposedStoreOnChainPaymentMethodAddresses( string storeId, string cryptoCode, UpdateOnChainPaymentMethodRequest paymentMethod, int offset = 0, int amount = 10, CancellationToken token = default) { return Task.FromResult(GetFromActionResult( _chainPaymentMethodsController.GetProposedOnChainPaymentMethodPreview(storeId, cryptoCode, paymentMethod, offset, amount))); } public override Task PreviewStoreOnChainPaymentMethodAddresses( string storeId, string cryptoCode, int offset = 0, int amount = 10, CancellationToken token = default) { return Task.FromResult(GetFromActionResult( _chainPaymentMethodsController.GetOnChainPaymentMethodPreview(storeId, cryptoCode, offset, amount))); } public override Task GetHealth(CancellationToken token = default) { return Task.FromResult(GetFromActionResult(_healthController.GetHealth())); } public override async Task> GetPaymentRequests(string storeId, bool includeArchived = false, CancellationToken token = default) { return GetFromActionResult(await _paymentRequestController.GetPaymentRequests(storeId, includeArchived)); } public override async Task GetPaymentRequest(string storeId, string paymentRequestId, CancellationToken token = default) { return GetFromActionResult( await _paymentRequestController.GetPaymentRequest(storeId, paymentRequestId)); } public override async Task ArchivePaymentRequest(string storeId, string paymentRequestId, CancellationToken token = default) { HandleActionResult(await _paymentRequestController.ArchivePaymentRequest(storeId, paymentRequestId)); } public override async Task CreatePaymentRequest(string storeId, CreatePaymentRequestRequest request, CancellationToken token = default) { return GetFromActionResult( await _paymentRequestController.CreatePaymentRequest(storeId, request)); } public override async Task UpdatePaymentRequest(string storeId, string paymentRequestId, UpdatePaymentRequestRequest request, CancellationToken token = default) { return GetFromActionResult( await _paymentRequestController.UpdatePaymentRequest(storeId, paymentRequestId, request)); } public override async Task GetCurrentAPIKeyInfo(CancellationToken token = default) { return GetFromActionResult(await _apiKeysController.GetKey()); } public override async Task CreateAPIKey(CreateApiKeyRequest request, CancellationToken token = default) { return GetFromActionResult(await _apiKeysController.CreateKey(request)); } public override async Task RevokeCurrentAPIKeyInfo(CancellationToken token = default) { HandleActionResult(await _apiKeysController.RevokeCurrentKey()); } public override async Task RevokeAPIKey(string apikey, CancellationToken token = default) { HandleActionResult(await _apiKeysController.RevokeKey(apikey)); } public override async Task> GetNotifications(bool? seen = null, int? skip = null, int? take = null, CancellationToken token = default) { return GetFromActionResult>( await _notificationsController.GetNotifications(seen, skip, take)); } public override async Task GetNotification(string notificationId, CancellationToken token = default) { return GetFromActionResult( await _notificationsController.GetNotification(notificationId)); } public override async Task UpdateNotification(string notificationId, bool? seen, CancellationToken token = default) { return GetFromActionResult( await _notificationsController.UpdateNotification(notificationId, new UpdateNotification() {Seen = seen})); } public override async Task RemoveNotification(string notificationId, CancellationToken token = default) { HandleActionResult(await _notificationsController.DeleteNotification(notificationId)); } public override async Task GetCurrentUser(CancellationToken token = default) { return GetFromActionResult(await _usersController.GetCurrentUser()); } public override async Task CreateUser(CreateApplicationUserRequest request, CancellationToken token = default) { return GetFromActionResult(await _usersController.CreateUser(request, token)); } public override async Task ShowOnChainWalletOverview(string storeId, string cryptoCode, CancellationToken token = default) { return GetFromActionResult( await _storeOnChainWalletsController.ShowOnChainWalletOverview(storeId, cryptoCode)); } public override async Task GetOnChainWalletReceiveAddress(string storeId, string cryptoCode, bool forceGenerate = false, CancellationToken token = default) { return GetFromActionResult( await _storeOnChainWalletsController.GetOnChainWalletReceiveAddress(storeId, cryptoCode, forceGenerate)); } public override async Task UnReserveOnChainWalletReceiveAddress(string storeId, string cryptoCode, CancellationToken token = default) { HandleActionResult( await _storeOnChainWalletsController.UnReserveOnChainWalletReceiveAddress(storeId, cryptoCode)); } public override async Task> ShowOnChainWalletTransactions( string storeId, string cryptoCode, TransactionStatus[] statusFilter = null, string labelFilter = null, CancellationToken token = default) { return GetFromActionResult>( await _storeOnChainWalletsController.ShowOnChainWalletTransactions(storeId, cryptoCode, statusFilter)); } public override async Task GetOnChainWalletTransaction(string storeId, string cryptoCode, string transactionId, CancellationToken token = default) { return GetFromActionResult( await _storeOnChainWalletsController.GetOnChainWalletTransaction(storeId, cryptoCode, transactionId)); } public override async Task> GetOnChainWalletUTXOs(string storeId, string cryptoCode, CancellationToken token = default) { return GetFromActionResult>( await _storeOnChainWalletsController.GetOnChainWalletUTXOs(storeId, cryptoCode)); } public override async Task CreateOnChainTransaction(string storeId, string cryptoCode, CreateOnChainTransactionRequest request, CancellationToken token = default) { if (!request.ProceedWithBroadcast) { throw new ArgumentOutOfRangeException(nameof(request.ProceedWithBroadcast), "Please use CreateOnChainTransactionButDoNotBroadcast when wanting to only create the transaction"); } return GetFromActionResult( await _storeOnChainWalletsController.CreateOnChainTransaction(storeId, cryptoCode, request)); } public override async Task CreateOnChainTransactionButDoNotBroadcast(string storeId, string cryptoCode, CreateOnChainTransactionRequest request, Network network, CancellationToken token = default) { if (request.ProceedWithBroadcast) { throw new ArgumentOutOfRangeException(nameof(request.ProceedWithBroadcast), "Please use CreateOnChainTransaction when wanting to also broadcast the transaction"); } return Transaction.Parse( GetFromActionResult( await _storeOnChainWalletsController.CreateOnChainTransaction(storeId, cryptoCode, request)), network); } public override async Task> GetStores(CancellationToken token = default) { return GetFromActionResult(await _storesController.GetStores()); } public override Task GetStore(string storeId, CancellationToken token = default) { return Task.FromResult(GetFromActionResult(_storesController.GetStore(storeId))); } public override async Task RemoveStore(string storeId, CancellationToken token = default) { HandleActionResult(await _storesController.RemoveStore(storeId)); } public override async Task CreateStore(CreateStoreRequest request, CancellationToken token = default) { return GetFromActionResult(await _storesController.CreateStore(request)); } public override async Task UpdateStore(string storeId, UpdateStoreRequest request, CancellationToken token = default) { return GetFromActionResult(await _storesController.UpdateStore(storeId, request)); } public override Task> GetStoreLNURLPayPaymentMethods(string storeId, bool? enabled, CancellationToken token = default) { return Task.FromResult(GetFromActionResult( _storeLnurlPayPaymentMethodsController.GetLNURLPayPaymentMethods(storeId, enabled))); } public override Task GetStoreLNURLPayPaymentMethod( string storeId, string cryptoCode, CancellationToken token = default) { return Task.FromResult(GetFromActionResult( _storeLnurlPayPaymentMethodsController.GetLNURLPayPaymentMethod(storeId, cryptoCode))); } public override async Task RemoveStoreLNURLPayPaymentMethod(string storeId, string cryptoCode, CancellationToken token = default) { HandleActionResult( await _storeLnurlPayPaymentMethodsController.RemoveLNURLPayPaymentMethod(storeId, cryptoCode)); } public override async Task UpdateStoreLNURLPayPaymentMethod( string storeId, string cryptoCode, LNURLPayPaymentMethodData paymentMethod, CancellationToken token = default) { return GetFromActionResult(await _storeLnurlPayPaymentMethodsController.UpdateLNURLPayPaymentMethod(storeId, cryptoCode, paymentMethod)); } public override Task> GetStoreLightningNetworkPaymentMethods(string storeId, bool? enabled, CancellationToken token = default) { return Task.FromResult(GetFromActionResult( _storeLightningNetworkPaymentMethodsController.GetLightningPaymentMethods(storeId, enabled))); } public override Task GetStoreLightningNetworkPaymentMethod( string storeId, string cryptoCode, CancellationToken token = default) { return Task.FromResult(GetFromActionResult( _storeLightningNetworkPaymentMethodsController.GetLightningNetworkPaymentMethod(storeId, cryptoCode))); } public override async Task RemoveStoreLightningNetworkPaymentMethod(string storeId, string cryptoCode, CancellationToken token = default) { HandleActionResult( await _storeLightningNetworkPaymentMethodsController.RemoveLightningNetworkPaymentMethod(storeId, cryptoCode)); } public override async Task UpdateStoreLightningNetworkPaymentMethod( string storeId, string cryptoCode, UpdateLightningNetworkPaymentMethodRequest paymentMethod, CancellationToken token = default) { return GetFromActionResult(await _storeLightningNetworkPaymentMethodsController.UpdateLightningNetworkPaymentMethod(storeId, cryptoCode, new UpdateLightningNetworkPaymentMethodRequest(paymentMethod.ConnectionString, paymentMethod.Enabled))); } public override async Task> GetInvoices(string storeId, string[] orderId = null, InvoiceStatus[] status = null, DateTimeOffset? startDate = null, DateTimeOffset? endDate = null, string textSearch = null, bool includeArchived = false, int? skip = null, int? take = null, CancellationToken token = default ) { return GetFromActionResult>( await _greenFieldInvoiceController.GetInvoices(storeId, orderId, status?.Select(invoiceStatus => invoiceStatus.ToString())?.ToArray(), startDate, endDate, textSearch, includeArchived, skip, take)); } public override async Task GetInvoice(string storeId, string invoiceId, CancellationToken token = default) { return GetFromActionResult(await _greenFieldInvoiceController.GetInvoice(storeId, invoiceId)); } public override async Task GetInvoicePaymentMethods(string storeId, string invoiceId, CancellationToken token = default) { return GetFromActionResult( await _greenFieldInvoiceController.GetInvoicePaymentMethods(storeId, invoiceId)); } public override async Task ArchiveInvoice(string storeId, string invoiceId, CancellationToken token = default) { HandleActionResult(await _greenFieldInvoiceController.ArchiveInvoice(storeId, invoiceId)); } public override async Task CreateInvoice(string storeId, CreateInvoiceRequest request, CancellationToken token = default) { return GetFromActionResult(await _greenFieldInvoiceController.CreateInvoice(storeId, request)); } public override async Task UpdateInvoice(string storeId, string invoiceId, UpdateInvoiceRequest request, CancellationToken token = default) { return GetFromActionResult( await _greenFieldInvoiceController.UpdateInvoice(storeId, invoiceId, request)); } public override async Task MarkInvoiceStatus(string storeId, string invoiceId, MarkInvoiceStatusRequest request, CancellationToken token = default) { return GetFromActionResult( await _greenFieldInvoiceController.MarkInvoiceStatus(storeId, invoiceId, request)); } public override async Task UnarchiveInvoice(string storeId, string invoiceId, CancellationToken token = default) { return GetFromActionResult( await _greenFieldInvoiceController.UnarchiveInvoice(storeId, invoiceId)); } public override Task GetServerInfo(CancellationToken token = default) { return Task.FromResult(GetFromActionResult(_greenFieldServerInfoController.ServerInfo())); } public override async Task ActivateInvoicePaymentMethod(string storeId, string invoiceId, string paymentMethod, CancellationToken token = default) { HandleActionResult( await _greenFieldInvoiceController.ActivateInvoicePaymentMethod(storeId, invoiceId, paymentMethod)); } public override async Task GetOnChainFeeRate(string storeId, string cryptoCode, int? blockTarget = null, CancellationToken token = default) { return GetFromActionResult( await _storeOnChainWalletsController.GetOnChainFeeRate(storeId, cryptoCode, blockTarget)); } public override async Task DeleteCurrentUser(CancellationToken token = default) { HandleActionResult(await _usersController.DeleteCurrentUser()); } public override async Task DeleteUser(string userId, CancellationToken token = default) { HandleActionResult(await _usersController.DeleteUser(userId)); } public override Task GetAvailableLanguages(CancellationToken token = default) { return Task.FromResult(_homeController.LanguageService.GetLanguages() .Select(language => new Language(language.Code, language.DisplayName)).ToArray()); } public override Task GetPermissionMetadata(CancellationToken token = default) { return Task.FromResult(GetFromActionResult(_homeController.Permissions())); } public override async Task> GetStorePaymentMethods(string storeId, bool? enabled = null, CancellationToken token = default) { return GetFromActionResult(await _storePaymentMethodsController.GetStorePaymentMethods(storeId, enabled)); } public override async Task GenerateOnChainWallet(string storeId, string cryptoCode, GenerateOnChainWalletRequest request, CancellationToken token = default) { return GetFromActionResult( await _chainPaymentMethodsController.GenerateOnChainWallet(storeId, cryptoCode, new GenerateWalletRequest() { Passphrase = request.Passphrase, AccountNumber = request.AccountNumber, ExistingMnemonic = request.ExistingMnemonic?.ToString(), WordCount = request.WordCount, WordList = request.WordList, SavePrivateKeys = request.SavePrivateKeys, ScriptPubKeyType = request.ScriptPubKeyType, ImportKeysToRPC = request.ImportKeysToRPC })); } public override async Task SendEmail(string storeId, SendEmailRequest request, CancellationToken token = default) { HandleActionResult(await _greenfieldStoreEmailController.SendEmailFromStore(storeId, request)); } public override Task GetStoreEmailSettings(string storeId, CancellationToken token = default) { return Task.FromResult( GetFromActionResult(_greenfieldStoreEmailController.GetStoreEmailSettings())); } public override async Task UpdateStoreEmailSettings(string storeId, EmailSettingsData request, CancellationToken token = default) { return GetFromActionResult( await _greenfieldStoreEmailController.UpdateStoreEmailSettings(storeId, JObject.FromObject(request).ToObject())); } public override async Task GetUsers(CancellationToken token = default) { return GetFromActionResult(await _usersController.GetUsers()); } public override Task> GetStoreUsers(string storeId, CancellationToken token = default) { return Task.FromResult( GetFromActionResult>(_greenfieldStoreUsersController.GetStoreUsers())); } public override async Task AddStoreUser(string storeId, StoreUserData request, CancellationToken token = default) { HandleActionResult(await _greenfieldStoreUsersController.AddStoreUser(storeId, request)); } public override async Task RemoveStoreUser(string storeId, string userId, CancellationToken token = default) { HandleActionResult(await _greenfieldStoreUsersController.RemoveStoreUser(storeId, userId)); } public override async Task GetUserByIdOrEmail(string idOrEmail, CancellationToken token = default) { return GetFromActionResult(await _usersController.GetUser(idOrEmail)); } public override async Task LockUser(string idOrEmail, bool disabled, CancellationToken token = default) { HandleActionResult(await _usersController.LockUser(idOrEmail, new LockUserRequest() { Locked = disabled })); } public override async Task PatchOnChainWalletTransaction(string storeId, string cryptoCode, string transactionId, PatchOnChainTransactionRequest request, CancellationToken token = default) { return GetFromActionResult(await _storeOnChainWalletsController.PatchOnChainWalletTransaction(storeId, cryptoCode, transactionId, request)); } public override async Task GetLightningPayment(string cryptoCode, string paymentHash, CancellationToken token = default) { return GetFromActionResult(await _lightningNodeApiController.GetPayment(cryptoCode, paymentHash, token)); } public override async Task GetLightningPayment(string storeId, string cryptoCode, string paymentHash, CancellationToken token = default) { return GetFromActionResult(await _storeLightningNodeApiController.GetPayment(cryptoCode, paymentHash, token)); } public override async Task CreatePayout(string storeId, CreatePayoutThroughStoreRequest payoutRequest, CancellationToken cancellationToken = default) { return GetFromActionResult( await _greenfieldPullPaymentController.CreatePayoutThroughStore(storeId, payoutRequest)); } public override async Task> GetPayoutProcessors(string storeId, CancellationToken token = default) { return GetFromActionResult>(await _greenfieldStorePayoutProcessorsController.GetStorePayoutProcessors(storeId)); } public override Task> GetPayoutProcessors(CancellationToken token = default) { return Task.FromResult(GetFromActionResult>(_greenfieldPayoutProcessorsController.GetPayoutProcessors())); } public override async Task RemovePayoutProcessor(string storeId, string processor, string paymentMethod, CancellationToken token = default) { HandleActionResult(await _greenfieldStorePayoutProcessorsController.RemoveStorePayoutProcessor(storeId, processor, paymentMethod)); } public override async Task> GetStoreOnChainAutomatedPayoutProcessors(string storeId, string paymentMethod = null, CancellationToken token = default) { return GetFromActionResult>( await _greenfieldStoreAutomatedOnChainPayoutProcessorsController .GetStoreOnChainAutomatedPayoutProcessors(storeId, paymentMethod)); } public override async Task> GetStoreLightningAutomatedPayoutProcessors(string storeId, string paymentMethod = null, CancellationToken token = default) { return GetFromActionResult>( await _greenfieldStoreAutomatedLightningPayoutProcessorsController .GetStoreLightningAutomatedPayoutProcessors(storeId, paymentMethod)); } public override async Task UpdateStoreOnChainAutomatedPayoutProcessors(string storeId, string paymentMethod, OnChainAutomatedPayoutSettings request, CancellationToken token = default) { return GetFromActionResult( await _greenfieldStoreAutomatedOnChainPayoutProcessorsController .UpdateStoreOnchainAutomatedPayoutProcessor(storeId, paymentMethod, request)); } public override async Task UpdateStoreLightningAutomatedPayoutProcessors(string storeId, string paymentMethod, LightningAutomatedPayoutSettings request, CancellationToken token = default) { return GetFromActionResult( await _greenfieldStoreAutomatedLightningPayoutProcessorsController .UpdateStoreLightningAutomatedPayoutProcessor(storeId, paymentMethod, request)); } public override async Task GetStorePayouts(string storeId, bool includeCancelled = false, CancellationToken cancellationToken = default) { return GetFromActionResult( await _greenfieldPullPaymentController .GetStorePayouts(storeId,includeCancelled)); } } }