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; 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.Options; using NBitcoin; using NBXplorer.Models; using Newtonsoft.Json.Linq; using InvoiceData = BTCPayServer.Client.Models.InvoiceData; using Language = BTCPayServer.Client.Models.Language; using LightningAddressData = BTCPayServer.Client.Models.LightningAddressData; using NotificationData = BTCPayServer.Client.Models.NotificationData; using PaymentRequestData = BTCPayServer.Client.Models.PaymentRequestData; using PayoutData = BTCPayServer.Client.Models.PayoutData; using PayoutProcessorData = BTCPayServer.Client.Models.PayoutProcessorData; 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 UserManager _userManager; private readonly IServiceProvider _serviceProvider; public BTCPayServerClientFactory( StoreRepository storeRepository, IOptionsMonitor identityOptions, UserManager userManager, IServiceProvider serviceProvider) { _storeRepository = storeRepository; _identityOptions = identityOptions; _userManager = userManager; _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() { new(_identityOptions.CurrentValue.ClaimsIdentity.RoleClaimType, Roles.ServerAdmin) }, $"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 ActivatorUtilities.CreateInstance(_serviceProvider, new LocalHttpContextAccessor() { HttpContext = context }); } } public class LocalHttpContextAccessor : IHttpContextAccessor { public HttpContext HttpContext { get; set; } } public class LocalBTCPayServerClient : BTCPayServerClient { private readonly IHttpContextAccessor _httpContextAccessor; private readonly IServiceProvider _serviceProvider; public LocalBTCPayServerClient( IHttpContextAccessor httpContextAccessor, IServiceProvider serviceProvider) : base(new Uri("https://dummy.local"), "", "") { _httpContextAccessor = httpContextAccessor; _serviceProvider = serviceProvider; } private T GetController() where T : ControllerBase { var authoverride = new AuthorizationService(new GreenfieldAuthorizationHandler(_httpContextAccessor, _serviceProvider.GetService>(), _serviceProvider.GetService(), _serviceProvider.GetService())); var controller = _serviceProvider.GetService(); controller.ControllerContext.HttpContext = _httpContextAccessor.HttpContext; var authInterface = typeof(IAuthorizationService); var type = controller.GetType(); do { foreach (FieldInfo fieldInfo in type.GetFields(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static) .Where(info => authInterface == info.FieldType || authInterface.IsAssignableFrom(info.FieldType))) { fieldInfo.SetValue(controller, authoverride); } type = type.BaseType; } while (type is not null); return controller; } class AuthorizationService : IAuthorizationService { private readonly GreenfieldAuthorizationHandler _greenfieldAuthorizationHandler; public AuthorizationService(GreenfieldAuthorizationHandler greenfieldAuthorizationHandler) { _greenfieldAuthorizationHandler = greenfieldAuthorizationHandler; } public async Task AuthorizeAsync(ClaimsPrincipal user, object resource, IEnumerable requirements) { var withuser = user.Identity?.AuthenticationType == $"Local{GreenfieldConstants.AuthenticationType}WithUser"; if (withuser) { var newUser = new ClaimsPrincipal(new ClaimsIdentity(user.Claims, $"{GreenfieldConstants.AuthenticationType}")); var newContext = new AuthorizationHandlerContext(requirements, newUser, resource); await _greenfieldAuthorizationHandler.HandleAsync(newContext); if (newContext.HasSucceeded) { return AuthorizationResult.Success(); } return AuthorizationResult.Failed(); } var succeed = user.Identity.AuthenticationType == $"Local{GreenfieldConstants.AuthenticationType}"; if (succeed) { return AuthorizationResult.Success(); } return AuthorizationResult.Failed(); } public Task AuthorizeAsync(ClaimsPrincipal user, object resource, string policyName) { return AuthorizeAsync(user, resource, new List(new[] { new PolicyRequirement(policyName) })); } } 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 MarketTradeCustodianAccountAsset(string storeId, string accountId, TradeRequestData request, CancellationToken cancellationToken = default) { return GetFromActionResult( await GetController().MarketTradeCustodianAccountAsset(storeId, accountId, request, cancellationToken)); } public override async Task SimulateCustodianAccountWithdrawal(string storeId, string accountId, WithdrawRequestData request, CancellationToken cancellationToken = default) { return GetFromActionResult( await GetController().SimulateWithdrawal(storeId, accountId, request, cancellationToken)); } public override async Task CreateCustodianAccountWithdrawal(string storeId, string accountId, WithdrawRequestData request, CancellationToken cancellationToken = default) { return GetFromActionResult( await GetController().CreateWithdrawal(storeId, accountId, request, cancellationToken)); } public override async Task GetOnChainWalletObjects(string storeId, string cryptoCode, GetWalletObjectsRequest query = null, CancellationToken token = default) { return GetFromActionResult( await GetController().GetOnChainWalletObjects(storeId, cryptoCode, query?.Type, query?.Ids, query?.IncludeNeighbourData)); } public override async Task GetOnChainWalletObject(string storeId, string cryptoCode, OnChainWalletObjectId objectId, bool? includeNeighbourData = null, CancellationToken token = default) { return GetFromActionResult( await GetController().GetOnChainWalletObject(storeId, cryptoCode, objectId.Type, objectId.Id, includeNeighbourData)); } public override async Task AddOrUpdateOnChainWalletObject(string storeId, string cryptoCode, AddOnChainWalletObjectRequest request, CancellationToken token = default) { return GetFromActionResult( await GetController().AddOrUpdateOnChainWalletObject(storeId, cryptoCode, request)); } public override async Task RemoveOnChainWalletLinks(string storeId, string cryptoCode, OnChainWalletObjectId objectId, OnChainWalletObjectId link, CancellationToken token = default) { HandleActionResult(await GetController().RemoveOnChainWalletLink(storeId, cryptoCode, objectId.Type, objectId.Id, link.Type, link.Id)); } public override async Task RemoveOnChainWalletObject(string storeId, string cryptoCode, OnChainWalletObjectId objectId, CancellationToken token = default) { HandleActionResult(await GetController().RemoveOnChainWalletObject(storeId, cryptoCode, objectId.Type, objectId.Id)); } public override async Task AddOrUpdateOnChainWalletLink(string storeId, string cryptoCode, OnChainWalletObjectId objectId, AddOnChainWalletObjectLinkRequest request = null, CancellationToken token = default) { HandleActionResult(await GetController().AddOrUpdateOnChainWalletLinks(storeId, cryptoCode, objectId.Type, objectId.Id, request)); } public override async Task CreateWebhook(string storeId, CreateStoreWebhookRequest create, CancellationToken token = default) { return GetFromActionResult( await GetController().CreateWebhook(storeId, create)); } public override async Task GetWebhook(string storeId, string webhookId, CancellationToken token = default) { return GetFromActionResult( await GetController().ListWebhooks(storeId, webhookId)); } public override async Task UpdateWebhook(string storeId, string webhookId, UpdateStoreWebhookRequest update, CancellationToken token = default) { return GetFromActionResult( await GetController().UpdateWebhook(storeId, webhookId, update)); } public override async Task DeleteWebhook(string storeId, string webhookId, CancellationToken token = default) { HandleActionResult(await GetController().DeleteWebhook(storeId, webhookId)); return true; } public override async Task GetWebhooks(string storeId, CancellationToken token = default) { return GetFromActionResult( await GetController().ListWebhooks(storeId, null)); } public override async Task GetWebhookDeliveries(string storeId, string webhookId, CancellationToken token = default) { return GetFromActionResult( await GetController().ListDeliveries(storeId, webhookId, null)); } public override async Task GetWebhookDelivery(string storeId, string webhookId, string deliveryId, CancellationToken token = default) { return GetFromActionResult( await GetController().ListDeliveries(storeId, webhookId, deliveryId)); } public override async Task RedeliverWebhook(string storeId, string webhookId, string deliveryId, CancellationToken token = default) { return GetFromActionResult( await GetController().RedeliverWebhook(storeId, webhookId, deliveryId)); } public override async Task GetWebhookDeliveryRequest(string storeId, string webhookId, string deliveryId, CancellationToken token = default) { return GetFromActionResult( await GetController().GetDeliveryRequest(storeId, webhookId, deliveryId)); } public override async Task CreatePullPayment(string storeId, CreatePullPaymentRequest request, CancellationToken cancellationToken = default) { return GetFromActionResult( await GetController().CreatePullPayment(storeId, request)); } public override async Task GetPullPayment(string pullPaymentId, CancellationToken cancellationToken = default) { return GetFromActionResult( await GetController().GetPullPayment(pullPaymentId)); } public override async Task GetPullPayments(string storeId, bool includeArchived = false, CancellationToken cancellationToken = default) { return GetFromActionResult( await GetController().GetPullPayments(storeId, includeArchived)); } public override async Task ArchivePullPayment(string storeId, string pullPaymentId, CancellationToken cancellationToken = default) { HandleActionResult(await GetController().ArchivePullPayment(storeId, pullPaymentId)); } public override async Task GetPayouts(string pullPaymentId, bool includeCancelled = false, CancellationToken cancellationToken = default) { return GetFromActionResult( await GetController().GetPayouts(pullPaymentId, includeCancelled)); } public override async Task CreatePayout(string pullPaymentId, CreatePayoutRequest payoutRequest, CancellationToken cancellationToken = default) { return GetFromActionResult( await GetController().CreatePayout(pullPaymentId, payoutRequest, cancellationToken)); } public override async Task CancelPayout(string storeId, string payoutId, CancellationToken cancellationToken = default) { HandleActionResult(await GetController().CancelPayout(storeId, payoutId)); } public override async Task ApprovePayout(string storeId, string payoutId, ApprovePayoutRequest request, CancellationToken cancellationToken = default) { return GetFromActionResult( await GetController().ApprovePayout(storeId, payoutId, request, cancellationToken)); } public override async Task GetLightningNodeInfo(string storeId, string cryptoCode, CancellationToken token = default) { return GetFromActionResult( await GetController().GetInfo(cryptoCode, token)); } public override async Task GetLightningNodeBalance(string storeId, string cryptoCode, CancellationToken token = default) { return GetFromActionResult( await GetController().GetBalance(cryptoCode, token)); } public override async Task ConnectToLightningNode(string storeId, string cryptoCode, ConnectToNodeRequest request, CancellationToken token = default) { HandleActionResult(await GetController().ConnectToNode(cryptoCode, request, token)); } public override async Task> GetLightningNodeChannels(string storeId, string cryptoCode, CancellationToken token = default) { return GetFromActionResult>( await GetController().GetChannels(cryptoCode, token)); } public override async Task OpenLightningChannel(string storeId, string cryptoCode, OpenLightningChannelRequest request, CancellationToken token = default) { HandleActionResult(await GetController().OpenChannel(cryptoCode, request, token)); } public override async Task GetLightningDepositAddress(string storeId, string cryptoCode, CancellationToken token = default) { return GetFromActionResult( await GetController().GetDepositAddress(cryptoCode, token)); } public override async Task PayLightningInvoice(string storeId, string cryptoCode, PayLightningInvoiceRequest request, CancellationToken token = default) { return GetFromActionResult( await GetController().PayInvoice(cryptoCode, request, token)); } public override async Task GetLightningInvoice(string storeId, string cryptoCode, string invoiceId, CancellationToken token = default) { return GetFromActionResult( await GetController().GetInvoice(cryptoCode, invoiceId, token)); } public override async Task GetLightningInvoices(string storeId, string cryptoCode, bool? pendingOnly = null, long? offsetIndex = null, CancellationToken token = default) { return GetFromActionResult( await GetController().GetInvoices(cryptoCode, pendingOnly, offsetIndex, token)); } public override async Task GetLightningPayments(string storeId, string cryptoCode, bool? includePending = null, long? offsetIndex = null, CancellationToken token = default) { return GetFromActionResult( await GetController().GetPayments(cryptoCode, includePending, offsetIndex, token)); } public override async Task CreateLightningInvoice(string storeId, string cryptoCode, CreateLightningInvoiceRequest request, CancellationToken token = default) { return GetFromActionResult( await GetController().CreateInvoice(cryptoCode, request, token)); } public override async Task GetLightningNodeInfo(string cryptoCode, CancellationToken token = default) { return GetFromActionResult( await GetController().GetInfo(cryptoCode)); } public override async Task GetLightningNodeBalance(string cryptoCode, CancellationToken token = default) { return GetFromActionResult( await GetController().GetBalance(cryptoCode)); } public override async Task ConnectToLightningNode(string cryptoCode, ConnectToNodeRequest request, CancellationToken token = default) { HandleActionResult(await GetController().ConnectToNode(cryptoCode, request, token)); } public override async Task> GetLightningNodeChannels(string cryptoCode, CancellationToken token = default) { return GetFromActionResult>( await GetController().GetChannels(cryptoCode, token)); } public override async Task OpenLightningChannel(string cryptoCode, OpenLightningChannelRequest request, CancellationToken token = default) { HandleActionResult(await GetController().OpenChannel(cryptoCode, request, token)); } public override async Task GetLightningDepositAddress(string cryptoCode, CancellationToken token = default) { return GetFromActionResult( await GetController().GetDepositAddress(cryptoCode, token)); } public override async Task PayLightningInvoice(string cryptoCode, PayLightningInvoiceRequest request, CancellationToken token = default) { return GetFromActionResult( await GetController().PayInvoice(cryptoCode, request, token)); } public override async Task GetLightningInvoice(string cryptoCode, string invoiceId, CancellationToken token = default) { return GetFromActionResult( await GetController().GetInvoice(cryptoCode, invoiceId, token)); } public override async Task GetLightningInvoices(string cryptoCode, bool? pendingOnly = null, long? offsetIndex = null, CancellationToken token = default) { return GetFromActionResult( await GetController().GetInvoices(cryptoCode, pendingOnly, offsetIndex, token)); } public override async Task GetLightningPayments(string cryptoCode, bool? includePending = null, long? offsetIndex = null, CancellationToken token = default) { return GetFromActionResult( await GetController().GetPayments(cryptoCode, includePending, offsetIndex, token)); } public override async Task CreateLightningInvoice(string cryptoCode, CreateLightningInvoiceRequest request, CancellationToken token = default) { return GetFromActionResult( await GetController().CreateInvoice(cryptoCode, request, token)); } private T GetFromActionResult(IActionResult result) { HandleActionResult(result); return result switch { JsonResult jsonResult => (T)jsonResult.Value, OkObjectResult { Value: T res } => res, OkObjectResult { Value: JValue res } => res.Value(), _ => 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 ObjectResult { 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(GetController().GetOnChainPaymentMethods(storeId, enabled))); } public override Task GetStoreOnChainPaymentMethod(string storeId, string cryptoCode, CancellationToken token = default) { return Task.FromResult(GetFromActionResult( GetController().GetOnChainPaymentMethod(storeId, cryptoCode))); } public override async Task RemoveStoreOnChainPaymentMethod(string storeId, string cryptoCode, CancellationToken token = default) { HandleActionResult(await GetController().RemoveOnChainPaymentMethod(storeId, cryptoCode)); } public override async Task UpdateStoreOnChainPaymentMethod(string storeId, string cryptoCode, UpdateOnChainPaymentMethodRequest paymentMethod, CancellationToken token = default) { return GetFromActionResult( await GetController().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( GetController().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( GetController().GetOnChainPaymentMethodPreview(storeId, cryptoCode, offset, amount))); } public override Task GetHealth(CancellationToken token = default) { return Task.FromResult(GetFromActionResult(GetController().GetHealth())); } public override async Task> GetPaymentRequests(string storeId, bool includeArchived = false, CancellationToken token = default) { return GetFromActionResult(await GetController().GetPaymentRequests(storeId, includeArchived)); } public override async Task GetPaymentRequest(string storeId, string paymentRequestId, CancellationToken token = default) { return GetFromActionResult( await GetController().GetPaymentRequest(storeId, paymentRequestId)); } public override async Task ArchivePaymentRequest(string storeId, string paymentRequestId, CancellationToken token = default) { HandleActionResult(await GetController().ArchivePaymentRequest(storeId, paymentRequestId)); } public override async Task PayPaymentRequest(string storeId, string paymentRequestId, PayPaymentRequestRequest request, CancellationToken token = default) { return GetFromActionResult( await GetController().PayPaymentRequest(storeId, paymentRequestId, request, token)); } public override async Task CreatePaymentRequest(string storeId, CreatePaymentRequestRequest request, CancellationToken token = default) { return GetFromActionResult( await GetController().CreatePaymentRequest(storeId, request)); } public override async Task UpdatePaymentRequest(string storeId, string paymentRequestId, UpdatePaymentRequestRequest request, CancellationToken token = default) { return GetFromActionResult( await GetController().UpdatePaymentRequest(storeId, paymentRequestId, request)); } public override async Task GetCurrentAPIKeyInfo(CancellationToken token = default) { return GetFromActionResult(await GetController().GetKey()); } public override async Task CreateAPIKey(CreateApiKeyRequest request, CancellationToken token = default) { return GetFromActionResult(await GetController().CreateAPIKey(request)); } public override async Task RevokeCurrentAPIKeyInfo(CancellationToken token = default) { HandleActionResult(await GetController().RevokeCurrentKey()); } public override async Task RevokeAPIKey(string apikey, CancellationToken token = default) { HandleActionResult(await GetController().RevokeAPIKey(apikey)); } public override async Task> GetNotifications(bool? seen = null, int? skip = null, int? take = null, CancellationToken token = default) { return GetFromActionResult>( await GetController().GetNotifications(seen, skip, take)); } public override async Task GetNotification(string notificationId, CancellationToken token = default) { return GetFromActionResult( await GetController().GetNotification(notificationId)); } public override async Task UpdateNotification(string notificationId, bool? seen, CancellationToken token = default) { return GetFromActionResult( await GetController().UpdateNotification(notificationId, new UpdateNotification() { Seen = seen })); } public override async Task RemoveNotification(string notificationId, CancellationToken token = default) { HandleActionResult(await GetController().DeleteNotification(notificationId)); } public override async Task GetCurrentUser(CancellationToken token = default) { return GetFromActionResult(await GetController().GetCurrentUser()); } public override async Task CreateUser(CreateApplicationUserRequest request, CancellationToken token = default) { return GetFromActionResult(await GetController().CreateUser(request, token)); } public override async Task ShowOnChainWalletOverview(string storeId, string cryptoCode, CancellationToken token = default) { return GetFromActionResult( await GetController().ShowOnChainWalletOverview(storeId, cryptoCode)); } public override async Task GetOnChainWalletReceiveAddress(string storeId, string cryptoCode, bool forceGenerate = false, CancellationToken token = default) { return GetFromActionResult( await GetController().GetOnChainWalletReceiveAddress(storeId, cryptoCode, forceGenerate)); } public override async Task UnReserveOnChainWalletReceiveAddress(string storeId, string cryptoCode, CancellationToken token = default) { HandleActionResult( await GetController().UnReserveOnChainWalletReceiveAddress(storeId, cryptoCode)); } public override async Task> ShowOnChainWalletTransactions( string storeId, string cryptoCode, TransactionStatus[] statusFilter = null, string labelFilter = null, int skip = 0, CancellationToken token = default) { return GetFromActionResult>( await GetController().ShowOnChainWalletTransactions(storeId, cryptoCode, statusFilter)); } public override async Task GetOnChainWalletTransaction(string storeId, string cryptoCode, string transactionId, CancellationToken token = default) { return GetFromActionResult( await GetController().GetOnChainWalletTransaction(storeId, cryptoCode, transactionId)); } public override async Task> GetOnChainWalletUTXOs(string storeId, string cryptoCode, CancellationToken token = default) { return GetFromActionResult>( await GetController().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 GetController().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 GetController().CreateOnChainTransaction(storeId, cryptoCode, request)), network); } public override async Task> GetStores(CancellationToken token = default) { return GetFromActionResult(await GetController().GetStores()); } public override Task GetStore(string storeId, CancellationToken token = default) { return Task.FromResult(GetFromActionResult(GetController().GetStore(storeId))); } public override async Task RemoveStore(string storeId, CancellationToken token = default) { HandleActionResult(await GetController().RemoveStore(storeId)); } public override async Task CreateStore(CreateStoreRequest request, CancellationToken token = default) { return GetFromActionResult(await GetController().CreateStore(request)); } public override async Task UpdateStore(string storeId, UpdateStoreRequest request, CancellationToken token = default) { return GetFromActionResult(await GetController().UpdateStore(storeId, request)); } public override Task> GetStoreLNURLPayPaymentMethods(string storeId, bool? enabled, CancellationToken token = default) { return Task.FromResult(GetFromActionResult( GetController().GetLNURLPayPaymentMethods(storeId, enabled))); } public override Task GetStoreLNURLPayPaymentMethod( string storeId, string cryptoCode, CancellationToken token = default) { return Task.FromResult(GetFromActionResult( GetController().GetLNURLPayPaymentMethod(storeId, cryptoCode))); } public override async Task RemoveStoreLNURLPayPaymentMethod(string storeId, string cryptoCode, CancellationToken token = default) { HandleActionResult( await GetController().RemoveLNURLPayPaymentMethod(storeId, cryptoCode)); } public override async Task UpdateStoreLNURLPayPaymentMethod( string storeId, string cryptoCode, LNURLPayPaymentMethodData paymentMethod, CancellationToken token = default) { return GetFromActionResult(await GetController().UpdateLNURLPayPaymentMethod(storeId, cryptoCode, paymentMethod)); } public override Task> GetStoreLightningNetworkPaymentMethods(string storeId, bool? enabled, CancellationToken token = default) { return Task.FromResult(GetFromActionResult( GetController().GetLightningPaymentMethods(storeId, enabled))); } public override Task GetStoreLightningNetworkPaymentMethod( string storeId, string cryptoCode, CancellationToken token = default) { return Task.FromResult(GetFromActionResult( GetController().GetLightningNetworkPaymentMethod(storeId, cryptoCode))); } public override async Task RemoveStoreLightningNetworkPaymentMethod(string storeId, string cryptoCode, CancellationToken token = default) { HandleActionResult( await GetController().RemoveLightningNetworkPaymentMethod(storeId, cryptoCode)); } public override async Task UpdateStoreLightningNetworkPaymentMethod( string storeId, string cryptoCode, UpdateLightningNetworkPaymentMethodRequest paymentMethod, CancellationToken token = default) { return GetFromActionResult(await GetController().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 GetController().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 GetController().GetInvoice(storeId, invoiceId)); } public override async Task GetInvoicePaymentMethods(string storeId, string invoiceId, CancellationToken token = default) { return GetFromActionResult( await GetController().GetInvoicePaymentMethods(storeId, invoiceId)); } public override async Task ArchiveInvoice(string storeId, string invoiceId, CancellationToken token = default) { HandleActionResult(await GetController().ArchiveInvoice(storeId, invoiceId)); } public override async Task CreateInvoice(string storeId, CreateInvoiceRequest request, CancellationToken token = default) { return GetFromActionResult(await GetController().CreateInvoice(storeId, request)); } public override async Task UpdateInvoice(string storeId, string invoiceId, UpdateInvoiceRequest request, CancellationToken token = default) { return GetFromActionResult( await GetController().UpdateInvoice(storeId, invoiceId, request)); } public override async Task MarkInvoiceStatus(string storeId, string invoiceId, MarkInvoiceStatusRequest request, CancellationToken token = default) { return GetFromActionResult( await GetController().MarkInvoiceStatus(storeId, invoiceId, request)); } public override async Task UnarchiveInvoice(string storeId, string invoiceId, CancellationToken token = default) { return GetFromActionResult( await GetController().UnarchiveInvoice(storeId, invoiceId)); } public override Task GetServerInfo(CancellationToken token = default) { return Task.FromResult(GetFromActionResult(GetController().ServerInfo())); } public override async Task ActivateInvoicePaymentMethod(string storeId, string invoiceId, string paymentMethod, CancellationToken token = default) { HandleActionResult( await GetController().ActivateInvoicePaymentMethod(storeId, invoiceId, paymentMethod)); } public override async Task GetOnChainFeeRate(string storeId, string cryptoCode, int? blockTarget = null, CancellationToken token = default) { return GetFromActionResult( await GetController().GetOnChainFeeRate(storeId, cryptoCode, blockTarget)); } public override async Task DeleteCurrentUser(CancellationToken token = default) { HandleActionResult(await GetController().DeleteCurrentUser()); } public override async Task DeleteUser(string userId, CancellationToken token = default) { HandleActionResult(await GetController().DeleteUser(userId)); } public override Task GetAvailableLanguages(CancellationToken token = default) { return Task.FromResult(GetController().LanguageService.GetLanguages() .Select(language => new Language(language.Code, language.DisplayName)).ToArray()); } public override Task GetPermissionMetadata(CancellationToken token = default) { return Task.FromResult(GetFromActionResult(GetController().Permissions())); } public override async Task> GetStorePaymentMethods(string storeId, bool? enabled = null, CancellationToken token = default) { return GetFromActionResult(await GetController().GetStorePaymentMethods(storeId, enabled)); } public override async Task GenerateOnChainWallet(string storeId, string cryptoCode, GenerateOnChainWalletRequest request, CancellationToken token = default) { return GetFromActionResult( await GetController().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 GetController().SendEmailFromStore(storeId, request)); } public override Task GetStoreEmailSettings(string storeId, CancellationToken token = default) { return Task.FromResult( GetFromActionResult(GetController().GetStoreEmailSettings())); } public override async Task UpdateStoreEmailSettings(string storeId, EmailSettingsData request, CancellationToken token = default) { return GetFromActionResult( await GetController().UpdateStoreEmailSettings(storeId, JObject.FromObject(request).ToObject())); } public override async Task GetUsers(CancellationToken token = default) { return GetFromActionResult(await GetController().GetUsers()); } public override Task> GetStoreUsers(string storeId, CancellationToken token = default) { return Task.FromResult( GetFromActionResult>(GetController().GetStoreUsers())); } public override async Task AddStoreUser(string storeId, StoreUserData request, CancellationToken token = default) { HandleActionResult(await GetController().AddStoreUser(storeId, request)); } public override async Task RemoveStoreUser(string storeId, string userId, CancellationToken token = default) { HandleActionResult(await GetController().RemoveStoreUser(storeId, userId)); } public override async Task GetUserByIdOrEmail(string idOrEmail, CancellationToken token = default) { return GetFromActionResult(await GetController().GetUser(idOrEmail)); } public override async Task LockUser(string idOrEmail, bool disabled, CancellationToken token = default) { return GetFromActionResult( await GetController().LockUser(idOrEmail, new LockUserRequest { Locked = disabled })); } public override async Task PatchOnChainWalletTransaction(string storeId, string cryptoCode, string transactionId, PatchOnChainTransactionRequest request, bool force = false, CancellationToken token = default) { return GetFromActionResult( await GetController().PatchOnChainWalletTransaction(storeId, cryptoCode, transactionId, request, force)); } public override async Task GetLightningPayment(string cryptoCode, string paymentHash, CancellationToken token = default) { return GetFromActionResult( await GetController().GetPayment(cryptoCode, paymentHash, token)); } public override async Task GetLightningPayment(string storeId, string cryptoCode, string paymentHash, CancellationToken token = default) { return GetFromActionResult( await GetController().GetPayment(cryptoCode, paymentHash, token)); } public override async Task CreatePayout(string storeId, CreatePayoutThroughStoreRequest payoutRequest, CancellationToken cancellationToken = default) { return GetFromActionResult( await GetController().CreatePayoutThroughStore(storeId, payoutRequest)); } public override async Task> GetPayoutProcessors(string storeId, CancellationToken token = default) { return GetFromActionResult>( await GetController().GetStorePayoutProcessors(storeId)); } public override Task> GetPayoutProcessors(CancellationToken token = default) { return Task.FromResult( GetFromActionResult>(GetController() .GetPayoutProcessors())); } public override async Task RemovePayoutProcessor(string storeId, string processor, string paymentMethod, CancellationToken token = default) { HandleActionResult( await GetController().RemoveStorePayoutProcessor(storeId, processor, paymentMethod)); } public override async Task> GetStoreOnChainAutomatedPayoutProcessors(string storeId, string paymentMethod = null, CancellationToken token = default) { return GetFromActionResult>( await GetController() .GetStoreOnChainAutomatedPayoutProcessors(storeId, paymentMethod)); } public override async Task> GetStoreLightningAutomatedPayoutProcessors(string storeId, string paymentMethod = null, CancellationToken token = default) { return GetFromActionResult>( await GetController() .GetStoreLightningAutomatedPayoutProcessors(storeId, paymentMethod)); } public override async Task UpdateStoreOnChainAutomatedPayoutProcessors( string storeId, string paymentMethod, OnChainAutomatedPayoutSettings request, CancellationToken token = default) { return GetFromActionResult( await GetController() .UpdateStoreOnchainAutomatedPayoutProcessor(storeId, paymentMethod, request)); } public override async Task UpdateStoreLightningAutomatedPayoutProcessors( string storeId, string paymentMethod, LightningAutomatedPayoutSettings request, CancellationToken token = default) { return GetFromActionResult( await GetController() .UpdateStoreLightningAutomatedPayoutProcessor(storeId, paymentMethod, request)); } public override async Task GetStorePayouts(string storeId, bool includeCancelled = false, CancellationToken cancellationToken = default) { return GetFromActionResult( await GetController() .GetStorePayouts(storeId, includeCancelled)); } public override async Task CreatePointOfSaleApp( string storeId, CreatePointOfSaleAppRequest request, CancellationToken token = default) { return GetFromActionResult( await GetController().CreatePointOfSaleApp(storeId, request)); } public override async Task UpdatePointOfSaleApp( string appId, CreatePointOfSaleAppRequest request, CancellationToken token = default) { return GetFromActionResult( await GetController().UpdatePointOfSaleApp(appId, request)); } public override async Task CreateCrowdfundApp( string storeId, CreateCrowdfundAppRequest request, CancellationToken token = default) { return GetFromActionResult( await GetController().CreateCrowdfundApp(storeId, request)); } public override async Task GetApp(string appId, CancellationToken token = default) { return GetFromActionResult( await GetController().GetApp(appId)); } public override async Task GetAllApps(string storeId, CancellationToken token = default) { return GetFromActionResult( await GetController().GetAllApps(storeId)); } public override async Task GetAllApps(CancellationToken token = default) { return GetFromActionResult( await GetController().GetAllApps()); } public override async Task DeleteApp(string appId, CancellationToken token = default) { HandleActionResult(await GetController().DeleteApp(appId)); } public override Task> GetRateSources(CancellationToken token = default) { return Task.FromResult(GetFromActionResult(GetController().GetRateSources())); } public override Task GetStoreRateConfiguration(string storeId, CancellationToken token = default) { return Task.FromResult(GetFromActionResult(GetController().GetStoreRateConfiguration())); } public override async Task> GetStoreRates(string storeId, string[] currencyPair, CancellationToken token = default) { return GetFromActionResult>(await GetController().GetStoreRates(currencyPair)); } public override async Task> PreviewUpdateStoreRateConfiguration(string storeId, StoreRateConfiguration request, string[] currencyPair, CancellationToken token = default) { return GetFromActionResult>( await GetController().PreviewUpdateStoreRateConfiguration(request, currencyPair)); } public override async Task UpdateStoreRateConfiguration(string storeId, StoreRateConfiguration request, CancellationToken token = default) { return GetFromActionResult(await GetController().UpdateStoreRateConfiguration(request)); } public override async Task MarkPayoutPaid(string storeId, string payoutId, CancellationToken cancellationToken = default) { HandleActionResult(await GetController().MarkPayoutPaid(storeId, payoutId, cancellationToken)); } public override async Task MarkPayout(string storeId, string payoutId, MarkPayoutRequest request, CancellationToken cancellationToken = default) { HandleActionResult(await GetController().MarkPayout(storeId, payoutId, request)); } public override async Task GetPullPaymentPayout(string pullPaymentId, string payoutId, CancellationToken cancellationToken = default) { return GetFromActionResult(await GetController().GetPayout(pullPaymentId, payoutId)); } public override async Task GetPullPaymentLNURL(string pullPaymentId, CancellationToken cancellationToken = default) { return GetFromActionResult(await GetController().GetPullPaymentLNURL(pullPaymentId)); } public override async Task GetStorePayout(string storeId, string payoutId, CancellationToken cancellationToken = default) { return GetFromActionResult(await GetController().GetStorePayout(storeId, payoutId)); } public override async Task GetStoreLightningAddresses(string storeId, CancellationToken token = default) { return GetFromActionResult(await GetController().GetStoreLightningAddresses(storeId)); } public override async Task GetStoreLightningAddress(string storeId, string username, CancellationToken token = default) { return GetFromActionResult(await GetController().GetStoreLightningAddress(storeId, username)); } public override async Task AddOrUpdateStoreLightningAddress(string storeId, string username, LightningAddressData data, CancellationToken token = default) { return GetFromActionResult(await GetController().AddOrUpdateStoreLightningAddress(storeId, username, data)); } public override async Task RemoveStoreLightningAddress(string storeId, string username, CancellationToken token = default) { HandleActionResult(await GetController().RemoveStoreLightningAddress(storeId, username)); } public override async Task GetPosApp(string appId, CancellationToken cancellationToken = default) { return GetFromActionResult(await GetController().GetPosApp(appId)); } public override async Task GetCrowdfundApp(string appId, CancellationToken cancellationToken = default) { return GetFromActionResult(await GetController().GetCrowdfundApp(appId)); } public override async Task RefundInvoice(string storeId, string invoiceId, RefundInvoiceRequest request, CancellationToken token = default) { return GetFromActionResult(await GetController().RefundInvoice(storeId, invoiceId, request, token)); } public override async Task RevokeAPIKey(string userId, string apikey, CancellationToken token = default) { HandleActionResult(await GetController().RevokeAPIKey(userId, apikey)); } public override async Task CreateAPIKey(string userId, CreateApiKeyRequest request, CancellationToken token = default) { return GetFromActionResult(await GetController().CreateUserAPIKey(userId, request)); } public override async Task> GetServerRoles(CancellationToken token = default) { return GetFromActionResult>(await GetController().GetServerRoles()); } public override async Task> GetStoreRoles(string storeId, CancellationToken token = default) { return GetFromActionResult>(await GetController().GetStoreRoles(storeId)); } } }