mirror of
https://github.com/aljazceru/BTCPayServerPlugins.git
synced 2025-12-17 07:34:24 +01:00
update bring
This commit is contained in:
@@ -20,6 +20,30 @@ public class BringinClient
|
|||||||
private HttpClient HttpClient { get; set; }
|
private HttpClient HttpClient { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public static HttpClient CreateClient(IHttpClientFactory httpClientFactory, string? apiKey = null)
|
||||||
|
{
|
||||||
|
var httpClient = httpClientFactory.CreateClient("bringin");
|
||||||
|
httpClient.BaseAddress = new Uri("https://dev.bringin.xyz");
|
||||||
|
if(apiKey != null)
|
||||||
|
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("api-key", apiKey);
|
||||||
|
return httpClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<Uri> OnboardUri(HttpClient httpClient, Uri callback)
|
||||||
|
{
|
||||||
|
|
||||||
|
var content = new StringContent(JsonConvert.SerializeObject(new
|
||||||
|
{
|
||||||
|
callback
|
||||||
|
}), Encoding.UTF8, "application/json");
|
||||||
|
var response = await httpClient.PostAsync($"/api/v0/application/btcpay/signup-url", content);
|
||||||
|
var responseContent = await response.Content.ReadAsStringAsync();
|
||||||
|
if (response.IsSuccessStatusCode) return new Uri(JObject.Parse(responseContent)["signupURL"].ToString());
|
||||||
|
return new Uri("https://dev-app.bringin.xyz");
|
||||||
|
var error = JObject.Parse(responseContent).ToObject<BringinErrorResponse>();
|
||||||
|
throw new BringinException(error);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<string> GetUserId()
|
public async Task<string> GetUserId()
|
||||||
{
|
{
|
||||||
var response = await HttpClient.GetAsync($"/api/v0/user/user-id");
|
var response = await HttpClient.GetAsync($"/api/v0/user/user-id");
|
||||||
|
|||||||
96
Plugins/BTCPayServer.Plugins.Bringin/BringinController.cs
Normal file
96
Plugins/BTCPayServer.Plugins.Bringin/BringinController.cs
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
using System;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using BTCPayServer.Abstractions.Constants;
|
||||||
|
using BTCPayServer.Client;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Plugins.Bringin;
|
||||||
|
|
||||||
|
[Authorize(AuthenticationSchemes = AuthenticationSchemes.Cookie)]
|
||||||
|
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
|
||||||
|
[Route("plugins/{storeId}/Bringin")]
|
||||||
|
public class BringinController : Controller
|
||||||
|
{
|
||||||
|
private readonly BringinService _bringinService;
|
||||||
|
private readonly IHttpClientFactory _httpClientFactory;
|
||||||
|
|
||||||
|
public BringinController(BringinService bringinService, IHttpClientFactory httpClientFactory)
|
||||||
|
{
|
||||||
|
_bringinService = bringinService;
|
||||||
|
_httpClientFactory = httpClientFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("onboard")]
|
||||||
|
public async Task<IActionResult> Onboard(string storeId)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
var vm = await _bringinService.Update(storeId);
|
||||||
|
|
||||||
|
var callbackUri = Url.Action("Callback", "Bringin", new
|
||||||
|
{
|
||||||
|
code = vm.Code,
|
||||||
|
storeId
|
||||||
|
}, Request.Scheme);
|
||||||
|
|
||||||
|
var httpClient = BringinClient.CreateClient(_httpClientFactory);
|
||||||
|
var onboardUri = await BringinClient.OnboardUri(httpClient, new Uri(callbackUri));
|
||||||
|
return Redirect(onboardUri.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("")]
|
||||||
|
public async Task<IActionResult> Edit()
|
||||||
|
{
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("callback")]
|
||||||
|
[HttpGet("callback")]
|
||||||
|
public async Task<IActionResult> Callback(string storeId, string code, [FromBody]BringinVerificationUpdate content)
|
||||||
|
{
|
||||||
|
var vm = await _bringinService.Update(storeId);
|
||||||
|
if(vm.Code != code) return BadRequest();
|
||||||
|
if(content.verificationStatus != "APPROVED") return BadRequest("Verification not approved");
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(vm.ApiKey) && !string.IsNullOrEmpty(content.apikey))
|
||||||
|
{
|
||||||
|
vm.ApiKey = content.apikey;
|
||||||
|
await _bringinService.Update(storeId, vm);
|
||||||
|
|
||||||
|
}
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BringinVerificationUpdate
|
||||||
|
{
|
||||||
|
public string userId { get; set; }
|
||||||
|
public string apikey { get; set; }
|
||||||
|
public string verificationStatus { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// [HttpGet("callback")]
|
||||||
|
// public async Task<IActionResult> Callback(string storeId, string apiKey, string code)
|
||||||
|
// {
|
||||||
|
// //truncate with showing only first 3 letters on start ond end
|
||||||
|
//
|
||||||
|
// var truncatedApikey = apiKey.Substring(0, 3) + "***" + apiKey.Substring(apiKey.Length - 3);
|
||||||
|
//
|
||||||
|
// return View("Confirm",
|
||||||
|
// new ConfirmModel("Confirm Bringin API Key",
|
||||||
|
// $"You are about to set your Bringin API key to {truncatedApikey}", "Set", "btn-primary"));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// [HttpPost("callback")]
|
||||||
|
// public async Task<IActionResult> CallbackConfirm(string storeId, string apiKey)
|
||||||
|
// {
|
||||||
|
// var vm = await _bringinService.Update(storeId);
|
||||||
|
// vm.ApiKey = apiKey;
|
||||||
|
// await _bringinService.Update(storeId, vm);
|
||||||
|
// return RedirectToAction("Edit", new {storeId});
|
||||||
|
// }
|
||||||
|
}
|
||||||
@@ -1,12 +1,7 @@
|
|||||||
using System.Threading.Tasks;
|
using BTCPayServer.Abstractions.Contracts;
|
||||||
using BTCPayServer.Abstractions.Constants;
|
|
||||||
using BTCPayServer.Abstractions.Contracts;
|
|
||||||
using BTCPayServer.Abstractions.Extensions;
|
using BTCPayServer.Abstractions.Extensions;
|
||||||
using BTCPayServer.Abstractions.Models;
|
using BTCPayServer.Abstractions.Models;
|
||||||
using BTCPayServer.Abstractions.Services;
|
using BTCPayServer.Abstractions.Services;
|
||||||
using BTCPayServer.Client;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
|
|
||||||
@@ -27,44 +22,4 @@ public class BringinPlugin : BaseBTCPayServerPlugin
|
|||||||
applicationBuilder.AddSingleton<IUIExtension>(new UIExtension("Bringin/Nav",
|
applicationBuilder.AddSingleton<IUIExtension>(new UIExtension("Bringin/Nav",
|
||||||
"store-integrations-nav"));
|
"store-integrations-nav"));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
[Authorize(AuthenticationSchemes = AuthenticationSchemes.Cookie)]
|
|
||||||
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
|
|
||||||
[Route("plugins/{storeId}/Bringin")]
|
|
||||||
public class BringinController : Controller
|
|
||||||
{
|
|
||||||
private readonly BringinService _bringinService;
|
|
||||||
|
|
||||||
public BringinController(BringinService bringinService)
|
|
||||||
{
|
|
||||||
_bringinService = bringinService;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("")]
|
|
||||||
public async Task<IActionResult> Edit()
|
|
||||||
{
|
|
||||||
return View();
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("callback")]
|
|
||||||
public async Task<IActionResult> Callback(string storeId, string apiKey)
|
|
||||||
{
|
|
||||||
//truncate with showing only first 3 letters on start ond end
|
|
||||||
|
|
||||||
var truncatedApikey = apiKey.Substring(0, 3) + "***" + apiKey.Substring(apiKey.Length - 3);
|
|
||||||
|
|
||||||
return View("Confirm",
|
|
||||||
new ConfirmModel("Confirm Bringin API Key",
|
|
||||||
$"You are about to set your Bringin API key to {truncatedApikey}", "Set", "btn-primary"));
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPost("callback")]
|
|
||||||
public async Task<IActionResult> CallbackConfirm(string storeId, string apiKey)
|
|
||||||
{
|
|
||||||
var vm = await _bringinService.Update(storeId);
|
|
||||||
vm.ApiKey = apiKey;
|
|
||||||
await _bringinService.Update(storeId, vm);
|
|
||||||
return RedirectToAction("Edit", new {storeId});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -197,56 +197,34 @@ public class BringinService : EventHostedServiceBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (SupportedMethods.All(supportedMethod => supportedMethod.PaymentMethod != pmi))
|
try
|
||||||
{
|
{
|
||||||
//only LN is supported for now
|
var bringinClient = bringinStoreSetting.CreateClient(_httpClientFactory);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var supportedMethod = SupportedMethods.First(supportedMethod => supportedMethod.PaymentMethod == pmi);
|
var thresholdAmount = methodSetting.Value.Threshold;
|
||||||
var bringinClient = bringinStoreSetting.CreateClient(_httpClientFactory);
|
if (methodSetting.Value.FiatThreshold)
|
||||||
|
|
||||||
var host = await Dns.GetHostEntryAsync(Dns.GetHostName(), CancellationToken.None);
|
|
||||||
var ipToUse = host.AddressList
|
|
||||||
.FirstOrDefault(address => address.AddressFamily == AddressFamily.InterNetwork)?.ToString();
|
|
||||||
|
|
||||||
var thresholdAmount = methodSetting.Value.Threshold;
|
|
||||||
if (methodSetting.Value.FiatThreshold)
|
|
||||||
{
|
|
||||||
var rate = await bringinClient.GetRate();
|
|
||||||
thresholdAmount = methodSetting.Value.Threshold / rate.BringinPrice;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (methodSetting.Value.CurrentBalance >= thresholdAmount)
|
|
||||||
{
|
|
||||||
var request = new BringinClient.CreateOrderRequest()
|
|
||||||
{
|
{
|
||||||
SourceAmount = Money.Coins(methodSetting.Value.CurrentBalance).Satoshi,
|
var rate = await bringinClient.GetRate();
|
||||||
IP = ipToUse,
|
thresholdAmount = methodSetting.Value.Threshold / rate.BringinPrice;
|
||||||
PaymentMethod = supportedMethod.bringinMethod
|
}
|
||||||
};
|
|
||||||
var order = await bringinClient.PlaceOrder(request);
|
if (methodSetting.Value.CurrentBalance >= thresholdAmount)
|
||||||
var orderMoney = Money.Satoshis(order.Amount);
|
|
||||||
var network = _btcPayNetworkProvider.GetNetwork<BTCPayNetwork>(pmi.CryptoCode);
|
|
||||||
var claim = await _pullPaymentHostedService.Claim(new ClaimRequest()
|
|
||||||
{
|
{
|
||||||
PaymentMethodId = pmi,
|
var payoutId = await CreateOrder(storeId, pmi, Money.Coins(methodSetting.Value.CurrentBalance)
|
||||||
StoreId = storeId,
|
, true);
|
||||||
Destination = new BoltInvoiceClaimDestination(order.Invoice, BOLT11PaymentRequest.Parse(order.Invoice, network.NBitcoinNetwork)),
|
if (payoutId is not null)
|
||||||
Value = orderMoney.ToUnit(MoneyUnit.BTC),
|
|
||||||
PreApprove = true,
|
|
||||||
Metadata = JObject.FromObject(new
|
|
||||||
{
|
{
|
||||||
Source = "Bringin"
|
methodSetting.Value.CurrentBalance -= methodSetting.Value.CurrentBalance;
|
||||||
})
|
methodSetting.Value.PendingPayouts.Add(payoutId);
|
||||||
});
|
result = true;
|
||||||
if (claim.Result == ClaimRequest.ClaimResult.Ok)
|
}
|
||||||
{
|
|
||||||
methodSetting.Value.CurrentBalance -= orderMoney.ToUnit(MoneyUnit.BTC);
|
|
||||||
methodSetting.Value.PendingPayouts.Add(claim.PayoutData.Id);
|
|
||||||
result = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_logger.LogError(e, "Could not create payout");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
@@ -259,11 +237,11 @@ var network = _btcPayNetworkProvider.GetNetwork<BTCPayNetwork>(pmi.CryptoCode);
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> CreateOrder(string storeId, PaymentMethodId paymentMethodId, Money amountBtc, bool payout)
|
public async Task<string?> CreateOrder(string storeId, PaymentMethodId paymentMethodId, Money amountBtc, bool payout)
|
||||||
{
|
{
|
||||||
if (SupportedMethods.All(supportedMethod => supportedMethod.PaymentMethod != paymentMethodId))
|
if (SupportedMethods.All(supportedMethod => supportedMethod.PaymentMethod != paymentMethodId))
|
||||||
{
|
{
|
||||||
throw new NotSupportedException("Only LN is supported for now");
|
throw new NotSupportedException($"{paymentMethodId.ToPrettyString()} Payment method not supported");
|
||||||
|
|
||||||
}
|
}
|
||||||
var settings = _settings[storeId];
|
var settings = _settings[storeId];
|
||||||
@@ -397,7 +375,7 @@ var network = _btcPayNetworkProvider.GetNetwork<BTCPayNetwork>(pmi.CryptoCode);
|
|||||||
|
|
||||||
public static readonly SupportedMethodOptions[] SupportedMethods = new[]
|
public static readonly SupportedMethodOptions[] SupportedMethods = new[]
|
||||||
{
|
{
|
||||||
new SupportedMethodOptions(new PaymentMethodId("BTC", LightningPaymentType.Instance), true, 100m, "LIGHTNING")
|
new SupportedMethodOptions(new PaymentMethodId("BTC", LightningPaymentType.Instance), true, 15, "LIGHTNING")
|
||||||
};
|
};
|
||||||
|
|
||||||
private ConcurrentDictionary<string, (IDisposable, BringinStoreSettings, DateTimeOffset Expiry)> _editModes = new();
|
private ConcurrentDictionary<string, (IDisposable, BringinStoreSettings, DateTimeOffset Expiry)> _editModes = new();
|
||||||
@@ -472,6 +450,7 @@ var network = _btcPayNetworkProvider.GetNetwork<BTCPayNetwork>(pmi.CryptoCode);
|
|||||||
public const string BringinSettings = "BringinSettings";
|
public const string BringinSettings = "BringinSettings";
|
||||||
public bool Enabled { get; set; } = true;
|
public bool Enabled { get; set; } = true;
|
||||||
public string ApiKey { get; set; }
|
public string ApiKey { get; set; }
|
||||||
|
public string Code { get; set; } = Guid.NewGuid().ToString();
|
||||||
public Dictionary<string, PaymentMethodSettings> MethodSettings { get; set; } = new();
|
public Dictionary<string, PaymentMethodSettings> MethodSettings { get; set; } = new();
|
||||||
|
|
||||||
public class PaymentMethodSettings
|
public class PaymentMethodSettings
|
||||||
@@ -485,11 +464,21 @@ var network = _btcPayNetworkProvider.GetNetwork<BTCPayNetwork>(pmi.CryptoCode);
|
|||||||
|
|
||||||
public BringinClient CreateClient(IHttpClientFactory httpClientFactory)
|
public BringinClient CreateClient(IHttpClientFactory httpClientFactory)
|
||||||
{
|
{
|
||||||
var backend = new Uri("https://dev.bringin.xyz");
|
var httpClient = BringinClient.CreateClient(httpClientFactory, ApiKey);
|
||||||
var httpClient = httpClientFactory.CreateClient("bringin");
|
|
||||||
httpClient.BaseAddress = backend;
|
|
||||||
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("api-key", ApiKey);
|
|
||||||
return new BringinClient(ApiKey, httpClient);
|
return new BringinClient(ApiKey, httpClient);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ResetBalance(string storeId, PaymentMethodId pmi)
|
||||||
|
{
|
||||||
|
_ = HandleStoreAction(storeId, async bringinStoreSettings =>
|
||||||
|
{
|
||||||
|
if (bringinStoreSettings.MethodSettings.TryGetValue(pmi.ToString(), out var methodSettings) && methodSettings.CurrentBalance > 0)
|
||||||
|
{
|
||||||
|
methodSettings.CurrentBalance = 0;
|
||||||
|
await _storeRepository.UpdateSetting(storeId, BringinStoreSettings.BringinSettings, bringinStoreSettings);
|
||||||
|
_settings.AddOrReplace(storeId, bringinStoreSettings);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -71,9 +71,10 @@
|
|||||||
{
|
{
|
||||||
if (firstRender)
|
if (firstRender)
|
||||||
{
|
{
|
||||||
|
OnboardLink = LinkGenerator.GetUriByAction(HttpContextAccessor.HttpContext, "Onboard", "Bringin", new {StoreId});
|
||||||
PmiLink = $"A payout processor has not been configured for this payment method. Payouts generated by Bringin will not be automatically handled. <a href=\"{LinkGenerator.GetUriByAction(HttpContextAccessor.HttpContext, "ConfigureStorePayoutProcessors", "UIPayoutProcessors", new {StoreId})}\">Configure now</a>";
|
PmiLink = $"A payout processor has not been configured for this payment method. Payouts generated by Bringin will not be automatically handled. <a href=\"{LinkGenerator.GetUriByAction(HttpContextAccessor.HttpContext, "ConfigureStorePayoutProcessors", "UIPayoutProcessors", new {StoreId})}\">Configure now</a>";
|
||||||
_callbackLink = LinkGenerator.GetUriByAction(HttpContextAccessor.HttpContext, "Callback", "Bringin", new {StoreId});
|
_callbackLink = LinkGenerator.GetUriByAction(HttpContextAccessor.HttpContext, "Callback", "Bringin", new {StoreId});
|
||||||
_settings = BringinService.IsInEditMode(StoreId)? await BringinService.Update(StoreId): await BringinService.Get(StoreId);
|
_settings = BringinService.IsInEditMode(StoreId) ? await BringinService.Update(StoreId) : await BringinService.Get(StoreId);
|
||||||
_pms = (await StoreRepository.FindStore(StoreId)).GetSupportedPaymentMethods(BTCPayNetworkProvider).Select(method => method.PaymentId).Where(id => id.CryptoCode == "BTC").ToArray();
|
_pms = (await StoreRepository.FindStore(StoreId)).GetSupportedPaymentMethods(BTCPayNetworkProvider).Select(method => method.PaymentId).Where(id => id.CryptoCode == "BTC").ToArray();
|
||||||
_pps = (await PayoutProcessorService.GetProcessors(new PayoutProcessorService.PayoutProcessorQuery()
|
_pps = (await PayoutProcessorService.GetProcessors(new PayoutProcessorService.PayoutProcessorQuery()
|
||||||
{
|
{
|
||||||
@@ -150,17 +151,23 @@
|
|||||||
{
|
{
|
||||||
if (_saving)
|
if (_saving)
|
||||||
return;
|
return;
|
||||||
_saving = true;
|
try
|
||||||
await TestApiKey();
|
{
|
||||||
if (ApiKeyError)
|
_saving = true;
|
||||||
return;
|
await TestApiKey();
|
||||||
SaveError = null;
|
if (ApiKeyError)
|
||||||
if (!EditMode)
|
return;
|
||||||
return;
|
SaveError = null;
|
||||||
await BringinService.Update(StoreId, _settings);
|
if (!EditMode)
|
||||||
EditMode = false;
|
return;
|
||||||
_saving = false;
|
await BringinService.Update(StoreId, _settings);
|
||||||
fetcherCTS?.Cancel();
|
EditMode = false;
|
||||||
|
fetcherCTS?.Cancel();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_saving = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CancellationTokenSource fetcherCTS;
|
CancellationTokenSource fetcherCTS;
|
||||||
@@ -250,7 +257,7 @@
|
|||||||
public async Task SubmitOrder()
|
public async Task SubmitOrder()
|
||||||
{
|
{
|
||||||
_saving = true;
|
_saving = true;
|
||||||
|
|
||||||
await InvokeAsync(StateHasChanged);
|
await InvokeAsync(StateHasChanged);
|
||||||
var pm = PaymentMethodId.TryParse(ManualOrderPaymentMethod);
|
var pm = PaymentMethodId.TryParse(ManualOrderPaymentMethod);
|
||||||
if (pm is null)
|
if (pm is null)
|
||||||
@@ -269,6 +276,7 @@
|
|||||||
SaveError = e.Message;
|
SaveError = e.Message;
|
||||||
_saving = false;
|
_saving = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
await InvokeAsync(StateHasChanged);
|
await InvokeAsync(StateHasChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,10 +289,18 @@
|
|||||||
// private bool ManualOrderPayout = true;
|
// private bool ManualOrderPayout = true;
|
||||||
|
|
||||||
public string PmiLink;
|
public string PmiLink;
|
||||||
|
|
||||||
|
public string OnboardLink;
|
||||||
|
|
||||||
|
private void ResetBalance(PaymentMethodId pmi)
|
||||||
|
{
|
||||||
|
BringinService.ResetBalance(StoreId, pmi);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
<div class="widget store-numbers" id="Bringin-Info" style="grid-column-start: 1; grid-column-end: 9;">
|
<div class="widget store-wallet-balance" id="Bringin-Info">
|
||||||
@if (!IsLoaded)
|
@if (!IsLoaded)
|
||||||
{
|
{
|
||||||
<h2 class="text-muted">Loading Bringin offramp</h2>
|
<h2 class="text-muted">Loading Bringin offramp</h2>
|
||||||
@@ -354,6 +370,10 @@
|
|||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xxl-constrain">
|
<div class="col-xxl-constrain">
|
||||||
|
|
||||||
|
<p class="text-secondary my-3">
|
||||||
|
Create an order irrespective of the current balance tracked by the plugin.
|
||||||
|
</p>
|
||||||
@if (!string.IsNullOrEmpty(SaveError))
|
@if (!string.IsNullOrEmpty(SaveError))
|
||||||
{
|
{
|
||||||
<div class="alert alert-danger">@SaveError</div>
|
<div class="alert alert-danger">@SaveError</div>
|
||||||
@@ -362,7 +382,7 @@
|
|||||||
@if (!string.IsNullOrEmpty(ManualOrderResult))
|
@if (!string.IsNullOrEmpty(ManualOrderResult))
|
||||||
{
|
{
|
||||||
<div class="alert alert-success">Payout created: @ManualOrderResult</div>
|
<div class="alert alert-success">Payout created: @ManualOrderResult</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<button class="btn btn-primary" @onclick="CancelManual">Go back</button>
|
<button class="btn btn-primary" @onclick="CancelManual">Go back</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -455,8 +475,15 @@
|
|||||||
<h3 class="d-inline-block me-1" data-balance="@method.Value.CurrentBalance" data-sensitive>@DisplayFormatter.Currency(method.Value.CurrentBalance, "BTC", DisplayFormatter.CurrencyFormat.None)</h3>
|
<h3 class="d-inline-block me-1" data-balance="@method.Value.CurrentBalance" data-sensitive>@DisplayFormatter.Currency(method.Value.CurrentBalance, "BTC", DisplayFormatter.CurrencyFormat.None)</h3>
|
||||||
<span class="text-secondary fw-semibold currency">BTC</span>
|
<span class="text-secondary fw-semibold currency">BTC</span>
|
||||||
<span class="text-secondary"> (@DisplayFormatter.Currency(balanceInFiat.Value, "EUR", DisplayFormatter.CurrencyFormat.Code)) pending to forward once @DisplayFormatter.Currency(thresholdinBtc.Value, "BTC", DisplayFormatter.CurrencyFormat.Code) (@DisplayFormatter.Currency(method.Value.Threshold, "EUR")) is reached.</span>
|
<span class="text-secondary"> (@DisplayFormatter.Currency(balanceInFiat.Value, "EUR", DisplayFormatter.CurrencyFormat.Code)) pending to forward once @DisplayFormatter.Currency(thresholdinBtc.Value, "BTC", DisplayFormatter.CurrencyFormat.Code) (@DisplayFormatter.Currency(method.Value.Threshold, "EUR")) is reached.</span>
|
||||||
</div>
|
@if (method.Value.CurrentBalance > 0)
|
||||||
|
{
|
||||||
|
<button class="btn btn-link" @onclick="() => ResetBalance(pmi)">Reset balance</button>
|
||||||
|
//Clear balance
|
||||||
|
|
||||||
|
}
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (method.Value.PendingPayouts.Any())
|
@if (method.Value.PendingPayouts.Any())
|
||||||
{
|
{
|
||||||
<div class="balance d-flex align-items-baseline gap-1">
|
<div class="balance d-flex align-items-baseline gap-1">
|
||||||
@@ -466,7 +493,7 @@
|
|||||||
}
|
}
|
||||||
@if (!_pps.Contains(pmi) && PmiLink is not null)
|
@if (!_pps.Contains(pmi) && PmiLink is not null)
|
||||||
{
|
{
|
||||||
<p class="text-warning">@((MarkupString)PmiLink)</p>
|
<p class="text-warning">@((MarkupString) PmiLink)</p>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@@ -485,9 +512,12 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
||||||
<label class="form-label">API Key</label>
|
<label class="form-label">API Key</label>
|
||||||
<input type="password" class="form-control" @oninput="() => InvokeAsync(StateHasChanged)" @bind="ApiKey"/>
|
<input type="password" class="form-control" @bind:event="oninput" @bind="ApiKey"/>
|
||||||
<p class="my-2">You can get one <a href="https://dev-app.bringin.xyz/" target="_blank">here</a></p>
|
<p class="my-2">You can get one <a href="@OnboardLink" target="_blank">here</a></p>
|
||||||
|
@if (ApiKeyError)
|
||||||
|
{
|
||||||
|
<div class="text-danger">Invalid API Key</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -500,7 +530,7 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">API Key</label>
|
<label class="form-label">API Key</label>
|
||||||
<input type="password" class="form-control" @bind="_settings.ApiKey"/>
|
<input type="password" class="form-control" @bind="_settings.ApiKey"/>
|
||||||
<p class="my-2">You can get one <a href="https://dev-app.bringin.xyz/" target="_blank">here</a></p>
|
<p class="my-2">You can get one <a href="@OnboardLink" target="_blank">here</a></p>
|
||||||
@if (ApiKeyError)
|
@if (ApiKeyError)
|
||||||
{
|
{
|
||||||
<div class="text-danger">Invalid API Key</div>
|
<div class="text-danger">Invalid API Key</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user