mirror of
https://github.com/aljazceru/BTCPayServerPlugins.git
synced 2025-12-18 16:14:25 +01:00
update bringin
This commit is contained in:
@@ -117,6 +117,71 @@ public class BringinClient
|
|||||||
[JsonConverter(typeof(NumericStringJsonConverter))]
|
[JsonConverter(typeof(NumericStringJsonConverter))]
|
||||||
public decimal Balance { get; set; }
|
public decimal Balance { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task<GetTransactionListResponse> GetTransactions()
|
||||||
|
{
|
||||||
|
var content = new StringContent(JsonConvert.SerializeObject(new
|
||||||
|
{
|
||||||
|
startDate = DateTimeOffset.UtcNow.AddDays(-30).ToUnixTimeMilliseconds(),
|
||||||
|
endDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
|
||||||
|
}), Encoding.UTF8, "application/json");
|
||||||
|
var response = await HttpClient.PostAsync($"/api/v0/account/transactions", content);
|
||||||
|
var responseContent = await response.Content.ReadAsStringAsync();
|
||||||
|
if (response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
return JObject.Parse(responseContent).ToObject<GetTransactionListResponse>();
|
||||||
|
}
|
||||||
|
|
||||||
|
var error = JObject.Parse(responseContent).ToObject<BringinErrorResponse>();
|
||||||
|
throw new BringinException(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GetTransactionListResponse
|
||||||
|
{
|
||||||
|
[JsonProperty("transactions")]
|
||||||
|
public BringinTransaction[] Transactions { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class BringinTransaction
|
||||||
|
{
|
||||||
|
// {
|
||||||
|
// "orderId": "3521154c-30b4-480c-834d-38f80d507963",
|
||||||
|
// "type": "OFFRAMP_WITHOUT_FIAT_WITHDRAWAL",
|
||||||
|
// "subType": "LIGHTNING",
|
||||||
|
// "sourceAmount": "100000",
|
||||||
|
// "sourceCurrency": "BTC",
|
||||||
|
// "destinationAmount": "3816",
|
||||||
|
// "destinationAddress": "b0a4c862-c941-4d3c-8727-18e5097a3b5a",
|
||||||
|
// "destinationCurrency": "EUR",
|
||||||
|
// "status": "SUCCESSFUL",
|
||||||
|
// "createdAt": "2024-01-18T14:02:59.709Z",
|
||||||
|
// }
|
||||||
|
[JsonProperty("orderId")]
|
||||||
|
public string OrderId { get; set; }
|
||||||
|
[JsonProperty("type")]
|
||||||
|
public string Type { get; set; }
|
||||||
|
[JsonProperty("subType")]
|
||||||
|
public string SubType { get; set; }
|
||||||
|
[JsonProperty("sourceAmount")]
|
||||||
|
[JsonConverter(typeof(NumericStringJsonConverter))]
|
||||||
|
public decimal SourceAmount { get; set; }
|
||||||
|
[JsonProperty("sourceCurrency")]
|
||||||
|
public string SourceCurrency { get; set; }
|
||||||
|
[JsonProperty("destinationAmount")]
|
||||||
|
[JsonConverter(typeof(NumericStringJsonConverter))]
|
||||||
|
public decimal DestinationAmount { get; set; }
|
||||||
|
[JsonProperty("destinationCurrency")]
|
||||||
|
public string DestinationCurrency { get; set; }
|
||||||
|
[JsonProperty("destinationAddress")]
|
||||||
|
public string DestinationAddress { get; set; }
|
||||||
|
[JsonProperty("status")]
|
||||||
|
public string Status { get; set; }
|
||||||
|
[JsonProperty("createdAt")]
|
||||||
|
public DateTimeOffset CreatedAt { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
//
|
//
|
||||||
// public class GetOrderResponse
|
// public class GetOrderResponse
|
||||||
// {
|
// {
|
||||||
@@ -154,6 +219,7 @@ public class BringinClient
|
|||||||
public decimal Amount { get; set; }
|
public decimal Amount { get; set; }
|
||||||
|
|
||||||
[JsonProperty("invoice")] public string Invoice { get; set; }
|
[JsonProperty("invoice")] public string Invoice { get; set; }
|
||||||
|
[JsonProperty("depositAddress")] public string DepositAddress { get; set; }
|
||||||
|
|
||||||
[JsonProperty("expiresAt")] public long Expiry { get; set; }
|
[JsonProperty("expiresAt")] public long Expiry { get; set; }
|
||||||
}
|
}
|
||||||
@@ -188,6 +254,7 @@ public class BringinClient
|
|||||||
public string Message { get; set; }
|
public string Message { get; set; }
|
||||||
public string StatusCode { get; set; }
|
public string StatusCode { get; set; }
|
||||||
public string ErrorCode { get; set; }
|
public string ErrorCode { get; set; }
|
||||||
public JObject ErrorDetails { get; set; }
|
public string ErrorMessage { get; set; }
|
||||||
|
public JToken ErrorDetails { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,7 +6,7 @@ public class BringinException : Exception
|
|||||||
{
|
{
|
||||||
private readonly BringinClient.BringinErrorResponse _error;
|
private readonly BringinClient.BringinErrorResponse _error;
|
||||||
|
|
||||||
public BringinException(BringinClient.BringinErrorResponse error)
|
public BringinException(BringinClient.BringinErrorResponse error):base(error.Message?? error.ErrorMessage)
|
||||||
{
|
{
|
||||||
_error = error;
|
_error = error;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
@@ -27,6 +28,15 @@ using PayoutData = BTCPayServer.Data.PayoutData;
|
|||||||
|
|
||||||
namespace BTCPayServer.Plugins.Bringin;
|
namespace BTCPayServer.Plugins.Bringin;
|
||||||
|
|
||||||
|
public static class StringExtensions
|
||||||
|
{
|
||||||
|
|
||||||
|
public static string ToHumanReadable(this string str)
|
||||||
|
{
|
||||||
|
return string.Join(' ', str.Split('_', '-').Select(part =>
|
||||||
|
CultureInfo.CurrentCulture.TextInfo.ToTitleCase(part.ToLower(CultureInfo.CurrentCulture))));
|
||||||
|
}
|
||||||
|
}
|
||||||
public class BringinService : EventHostedServiceBase
|
public class BringinService : EventHostedServiceBase
|
||||||
{
|
{
|
||||||
private readonly ILogger<BringinService> _logger;
|
private readonly ILogger<BringinService> _logger;
|
||||||
@@ -265,7 +275,7 @@ public class BringinService : EventHostedServiceBase
|
|||||||
|
|
||||||
var rate = await bringinClient.GetRate();
|
var rate = await bringinClient.GetRate();
|
||||||
var thresholdAmount = supportedMethod.FiatMinimumAmount / rate.BringinPrice;
|
var thresholdAmount = supportedMethod.FiatMinimumAmount / rate.BringinPrice;
|
||||||
if (amountBtc.ToDecimal(MoneyUnit.BTC) < thresholdAmount)
|
if (amountBtc.ToDecimal(MoneyUnit.BTC) <= thresholdAmount)
|
||||||
{
|
{
|
||||||
throw new Exception($"Amount is too low. Minimum amount is {Money.Coins(thresholdAmount)} BTC");
|
throw new Exception($"Amount is too low. Minimum amount is {Money.Coins(thresholdAmount)} BTC");
|
||||||
}
|
}
|
||||||
@@ -283,15 +293,17 @@ public class BringinService : EventHostedServiceBase
|
|||||||
|
|
||||||
if (!payout)
|
if (!payout)
|
||||||
{
|
{
|
||||||
return order.Invoice;
|
return order.Invoice?? order.DepositAddress;
|
||||||
}
|
}
|
||||||
var network = _btcPayNetworkProvider.GetNetwork<BTCPayNetwork>(paymentMethodId.CryptoCode);
|
var network = _btcPayNetworkProvider.GetNetwork<BTCPayNetwork>(paymentMethodId.CryptoCode);
|
||||||
|
|
||||||
|
var destination = !string.IsNullOrEmpty(order.Invoice)? (IClaimDestination) new BoltInvoiceClaimDestination(order.Invoice, BOLT11PaymentRequest.Parse(order.Invoice, network.NBitcoinNetwork)):
|
||||||
|
new AddressClaimDestination(BitcoinAddress.Create(order.DepositAddress, network.NBitcoinNetwork));
|
||||||
var claim = await _pullPaymentHostedService.Claim(new ClaimRequest()
|
var claim = await _pullPaymentHostedService.Claim(new ClaimRequest()
|
||||||
{
|
{
|
||||||
PaymentMethodId = paymentMethodId,
|
PaymentMethodId = paymentMethodId,
|
||||||
StoreId = storeId,
|
StoreId = storeId,
|
||||||
Destination = new BoltInvoiceClaimDestination(order.Invoice, BOLT11PaymentRequest.Parse(order.Invoice, network.NBitcoinNetwork)),
|
Destination = destination,
|
||||||
Value = orderMoney.ToUnit(MoneyUnit.BTC),
|
Value = orderMoney.ToUnit(MoneyUnit.BTC),
|
||||||
PreApprove = true,
|
PreApprove = true,
|
||||||
Metadata = JObject.FromObject(new
|
Metadata = JObject.FromObject(new
|
||||||
@@ -379,7 +391,8 @@ public class BringinService : EventHostedServiceBase
|
|||||||
|
|
||||||
public static readonly SupportedMethodOptions[] SupportedMethods = new[]
|
public static readonly SupportedMethodOptions[] SupportedMethods = new[]
|
||||||
{
|
{
|
||||||
new SupportedMethodOptions(new PaymentMethodId("BTC", LightningPaymentType.Instance), true, 15, "LIGHTNING")
|
new SupportedMethodOptions(new PaymentMethodId("BTC", LightningPaymentType.Instance), true, 15, "LIGHTNING"),
|
||||||
|
new SupportedMethodOptions(new PaymentMethodId("BTC", BitcoinPaymentType.Instance), true, 20, "ON_CHAIN"),
|
||||||
};
|
};
|
||||||
|
|
||||||
private ConcurrentDictionary<string, (IDisposable, BringinStoreSettings, DateTimeOffset Expiry)> _editModes = new();
|
private ConcurrentDictionary<string, (IDisposable, BringinStoreSettings, DateTimeOffset Expiry)> _editModes = new();
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
@using NBitcoin
|
@using NBitcoin
|
||||||
@implements IAsyncDisposable;
|
@implements IAsyncDisposable;
|
||||||
|
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private BringinService.BringinStoreSettings? _settings;
|
private BringinService.BringinStoreSettings? _settings;
|
||||||
private bool _isLoaded = false;
|
private bool _isLoaded = false;
|
||||||
@@ -194,6 +193,7 @@
|
|||||||
LastFiatBalance = await client.GetFiatBalance();
|
LastFiatBalance = await client.GetFiatBalance();
|
||||||
LastFiatRate = (await client.GetRate()).BringinPrice;
|
LastFiatRate = (await client.GetRate()).BringinPrice;
|
||||||
LastDataFetch = DateTimeOffset.UtcNow;
|
LastDataFetch = DateTimeOffset.UtcNow;
|
||||||
|
LastTxs = await client.GetTransactions();
|
||||||
_ = InvokeAsync(StateHasChanged);
|
_ = InvokeAsync(StateHasChanged);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@@ -210,6 +210,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BringinClient.GetTransactionListResponse LastTxs { get; set; }
|
||||||
|
|
||||||
|
|
||||||
private void UpdateDestinationValue(BringinService.BringinStoreSettings.PaymentMethodSettings settings, object eValue)
|
private void UpdateDestinationValue(BringinService.BringinStoreSettings.PaymentMethodSettings settings, object eValue)
|
||||||
{
|
{
|
||||||
@@ -417,9 +419,9 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@* <label class="form-label">Payment method</label> *@
|
@* <label class="form-label">Payment method</label> *@
|
||||||
<select @bind="ManualOrderPaymentMethod" class="form-select">
|
<select @bind="ManualOrderPaymentMethod" class="form-select">
|
||||||
|
<option value="">Select a payment method</option>
|
||||||
@foreach (var opt in items)
|
@foreach (var opt in items)
|
||||||
{
|
{
|
||||||
<option value="">Select a payment method</option>
|
|
||||||
<option value="@opt.ToString()">@opt.ToPrettyString()</option>
|
<option value="@opt.ToString()">@opt.ToPrettyString()</option>
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
@@ -569,15 +571,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="container">
|
||||||
@foreach (var method in _settings.MethodSettings)
|
<div class="row gx-5">
|
||||||
|
@for (int i = 0; i < _settings.MethodSettings.Count; i++)
|
||||||
{
|
{
|
||||||
|
var method = _settings.MethodSettings.ElementAt(i);
|
||||||
var pmId = PaymentMethodId.TryParse(method.Key);
|
var pmId = PaymentMethodId.TryParse(method.Key);
|
||||||
if (pmId is null)
|
if (pmId is null)
|
||||||
continue;
|
continue;
|
||||||
var supportedMethod = BringinService.SupportedMethods.FirstOrDefault(s => s.PaymentMethod.ToString() == method.Key);
|
var supportedMethod = BringinService.SupportedMethods.FirstOrDefault(s => s.PaymentMethod.ToString() == method.Key);
|
||||||
<div class="card col-xxl-constrain col-12 @(_settings.MethodSettings.Count > 1 ? "col-xl-6" : "")">
|
<div class="col-xxl-constrain col-12 @(_settings.MethodSettings.Count > 1 ? $"col-xl-6 {(i == 0 ? "border-end" : "")}" : "")">
|
||||||
<h5 class="card-header border-bottom-0 text-muted">@pmId.ToPrettyString()</h5>
|
<h5 class=" border-bottom-0 text-muted mb-4">@pmId.ToPrettyString()</h5>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">Percentage</label>
|
<label class="form-label">Percentage</label>
|
||||||
@@ -611,7 +615,52 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
@if (LastTxs is not null)
|
||||||
|
{
|
||||||
|
<div class="widget store-numbers">
|
||||||
|
<header>
|
||||||
|
<h4 class="text-muted">Bringin Transactions</h4>
|
||||||
|
</header>
|
||||||
|
@if (LastTxs.Transactions.Any())
|
||||||
|
{
|
||||||
|
<div class="table-responsive my-0 " style=" max-height: 400px;">
|
||||||
|
<table class="table table-hover mt-3 mb-0">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Date</th>
|
||||||
|
<th>Type</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th class="text-end">Amount</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach (var tx in LastTxs.Transactions.OrderByDescending(transaction => transaction.CreatedAt))
|
||||||
|
{
|
||||||
|
<tr>
|
||||||
|
<td>@tx.CreatedAt.ToTimeAgo()</td>
|
||||||
|
<td>@tx.SubType.ToHumanReadable()</td>
|
||||||
|
<td>
|
||||||
|
@tx.Status.ToHumanReadable()
|
||||||
|
</td>
|
||||||
|
<td class="amount-col">
|
||||||
|
<span data-sensitive>@(tx.SourceCurrency == "BTC" ? Money.Satoshis(tx.SourceAmount).ToDecimal(MoneyUnit.BTC): tx.SourceAmount)@tx.SourceCurrency -> @tx.DestinationAmount @tx.DestinationCurrency </span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<p class="text-secondary mt-3 mb-0">
|
||||||
|
There are no recent transactions.
|
||||||
|
</p>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user