mirror of
https://github.com/aljazceru/BTCPayServerPlugins.git
synced 2025-12-17 07:34:24 +01:00
update ss
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net;
|
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -11,7 +10,6 @@ using BTCPayServer.Data;
|
|||||||
using BTCPayServer.HostedServices;
|
using BTCPayServer.HostedServices;
|
||||||
using BTCPayServer.Payments;
|
using BTCPayServer.Payments;
|
||||||
using BTCPayServer.Services;
|
using BTCPayServer.Services;
|
||||||
using BTCPayServer.Services.Stores;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
@@ -26,29 +24,24 @@ namespace BTCPayServer.Plugins.SideShift
|
|||||||
[Route("plugins/{storeId}/SideShift")]
|
[Route("plugins/{storeId}/SideShift")]
|
||||||
public class SideShiftController : Controller
|
public class SideShiftController : Controller
|
||||||
{
|
{
|
||||||
private readonly BTCPayServerClient _btcPayServerClient;
|
|
||||||
private readonly SideShiftService _sideShiftService;
|
private readonly SideShiftService _sideShiftService;
|
||||||
private readonly IHttpClientFactory _httpClientFactory;
|
private readonly IHttpClientFactory _httpClientFactory;
|
||||||
private readonly IEnumerable<IPayoutHandler> _payoutHandlers;
|
private readonly IEnumerable<IPayoutHandler> _payoutHandlers;
|
||||||
private readonly PullPaymentHostedService _pullPaymentHostedService;
|
private readonly PullPaymentHostedService _pullPaymentHostedService;
|
||||||
private readonly StoreRepository _storeRepository;
|
|
||||||
private readonly BTCPayNetworkJsonSerializerSettings _serializerSettings;
|
private readonly BTCPayNetworkJsonSerializerSettings _serializerSettings;
|
||||||
private readonly ApplicationDbContextFactory _dbContextFactory;
|
private readonly ApplicationDbContextFactory _dbContextFactory;
|
||||||
|
|
||||||
public SideShiftController(BTCPayServerClient btcPayServerClient,
|
public SideShiftController(
|
||||||
SideShiftService sideShiftService,
|
SideShiftService sideShiftService,
|
||||||
IHttpClientFactory httpClientFactory,
|
IHttpClientFactory httpClientFactory,
|
||||||
IEnumerable<IPayoutHandler> payoutHandlers,
|
IEnumerable<IPayoutHandler> payoutHandlers,
|
||||||
PullPaymentHostedService pullPaymentHostedService,
|
PullPaymentHostedService pullPaymentHostedService,
|
||||||
StoreRepository storeRepository,
|
|
||||||
BTCPayNetworkJsonSerializerSettings serializerSettings, ApplicationDbContextFactory dbContextFactory)
|
BTCPayNetworkJsonSerializerSettings serializerSettings, ApplicationDbContextFactory dbContextFactory)
|
||||||
{
|
{
|
||||||
_btcPayServerClient = btcPayServerClient;
|
|
||||||
_sideShiftService = sideShiftService;
|
_sideShiftService = sideShiftService;
|
||||||
_httpClientFactory = httpClientFactory;
|
_httpClientFactory = httpClientFactory;
|
||||||
_payoutHandlers = payoutHandlers;
|
_payoutHandlers = payoutHandlers;
|
||||||
_pullPaymentHostedService = pullPaymentHostedService;
|
_pullPaymentHostedService = pullPaymentHostedService;
|
||||||
_storeRepository = storeRepository;
|
|
||||||
_serializerSettings = serializerSettings;
|
_serializerSettings = serializerSettings;
|
||||||
_dbContextFactory = dbContextFactory;
|
_dbContextFactory = dbContextFactory;
|
||||||
}
|
}
|
||||||
@@ -56,10 +49,6 @@ namespace BTCPayServer.Plugins.SideShift
|
|||||||
[HttpGet("")]
|
[HttpGet("")]
|
||||||
public async Task<IActionResult> UpdateSideShiftSettings(string storeId)
|
public async Task<IActionResult> UpdateSideShiftSettings(string storeId)
|
||||||
{
|
{
|
||||||
var store = await _btcPayServerClient.GetStore(storeId);
|
|
||||||
|
|
||||||
UpdateSideShiftSettingsViewModel vm = new UpdateSideShiftSettingsViewModel();
|
|
||||||
vm.StoreName = store.Name;
|
|
||||||
SideShiftSettings SideShift = null;
|
SideShiftSettings SideShift = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -70,19 +59,12 @@ namespace BTCPayServer.Plugins.SideShift
|
|||||||
// ignored
|
// ignored
|
||||||
}
|
}
|
||||||
|
|
||||||
SetExistingValues(SideShift, vm);
|
return View(SideShift??new SideShiftSettings());
|
||||||
return View(vm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetExistingValues(SideShiftSettings existing, UpdateSideShiftSettingsViewModel vm)
|
|
||||||
{
|
|
||||||
if (existing == null)
|
|
||||||
return;
|
|
||||||
vm.Enabled = existing.Enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPost("")]
|
[HttpPost("")]
|
||||||
public async Task<IActionResult> UpdateSideShiftSettings(string storeId, UpdateSideShiftSettingsViewModel vm,
|
public async Task<IActionResult> UpdateSideShiftSettings(string storeId, SideShiftSettings vm,
|
||||||
string command)
|
string command)
|
||||||
{
|
{
|
||||||
if (vm.Enabled)
|
if (vm.Enabled)
|
||||||
@@ -93,15 +75,11 @@ namespace BTCPayServer.Plugins.SideShift
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var sideShiftSettings = new SideShiftSettings()
|
|
||||||
{
|
|
||||||
Enabled = vm.Enabled,
|
|
||||||
};
|
|
||||||
|
|
||||||
switch (command)
|
switch (command)
|
||||||
{
|
{
|
||||||
case "save":
|
case "save":
|
||||||
await _sideShiftService.SetSideShiftForStore(storeId, sideShiftSettings);
|
await _sideShiftService.SetSideShiftForStore(storeId, vm);
|
||||||
TempData["SuccessMessage"] = "SideShift settings modified";
|
TempData["SuccessMessage"] = "SideShift settings modified";
|
||||||
return RedirectToAction(nameof(UpdateSideShiftSettings), new {storeId});
|
return RedirectToAction(nameof(UpdateSideShiftSettings), new {storeId});
|
||||||
|
|
||||||
@@ -223,7 +201,7 @@ namespace BTCPayServer.Plugins.SideShift
|
|||||||
if (claim.Result == ClaimRequest.ClaimResult.Ok)
|
if (claim.Result == ClaimRequest.ClaimResult.Ok)
|
||||||
{
|
{
|
||||||
await using var ctx = _dbContextFactory.CreateContext();
|
await using var ctx = _dbContextFactory.CreateContext();
|
||||||
ppBlob.Description += $"The payout of {claim.PayoutData.Destination} will be forwarded to SideShift.ai for further conversion. Please go to <a href=\"https://sideshift.ai/orders/{shift.id}\">the order page</a> for support.";
|
ppBlob.Description += $"The payout of {claim.PayoutData.Destination} will be forwarded to SideShift.ai for further conversion. Please go to <a href=\"https://sideshift.ai/orders/{shift.id}?openSupport=true\">the order page</a> for support.";
|
||||||
pp.SetBlob(ppBlob);
|
pp.SetBlob(ppBlob);
|
||||||
ctx.Attach(pp).State = EntityState.Modified;
|
ctx.Attach(pp).State = EntityState.Modified;
|
||||||
await ctx.SaveChangesAsync();
|
await ctx.SaveChangesAsync();
|
||||||
|
|||||||
@@ -148,5 +148,6 @@ namespace BTCPayServer.Plugins.SideShift
|
|||||||
public bool hasMemo { get; set; }
|
public bool hasMemo { get; set; }
|
||||||
public JToken fixedOnly { get; set; }
|
public JToken fixedOnly { get; set; }
|
||||||
public JToken variableOnly { get; set; }
|
public JToken variableOnly { get; set; }
|
||||||
|
public JToken settleOffline { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,13 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Abstractions.Contracts;
|
using BTCPayServer.Abstractions.Contracts;
|
||||||
using BTCPayServer.Client;
|
using BTCPayServer.Client;
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace BTCPayServer.Plugins.SideShift
|
namespace BTCPayServer.Plugins.SideShift
|
||||||
{
|
{
|
||||||
@@ -11,12 +16,14 @@ namespace BTCPayServer.Plugins.SideShift
|
|||||||
private readonly ISettingsRepository _settingsRepository;
|
private readonly ISettingsRepository _settingsRepository;
|
||||||
private readonly IMemoryCache _memoryCache;
|
private readonly IMemoryCache _memoryCache;
|
||||||
private readonly IStoreRepository _storeRepository;
|
private readonly IStoreRepository _storeRepository;
|
||||||
|
private readonly IHttpClientFactory _httpClientFactory;
|
||||||
|
|
||||||
public SideShiftService(ISettingsRepository settingsRepository, IMemoryCache memoryCache, IStoreRepository storeRepository)
|
public SideShiftService(ISettingsRepository settingsRepository, IMemoryCache memoryCache, IStoreRepository storeRepository, IHttpClientFactory httpClientFactory)
|
||||||
{
|
{
|
||||||
_settingsRepository = settingsRepository;
|
_settingsRepository = settingsRepository;
|
||||||
_memoryCache = memoryCache;
|
_memoryCache = memoryCache;
|
||||||
_storeRepository = storeRepository;
|
_storeRepository = storeRepository;
|
||||||
|
_httpClientFactory = httpClientFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<SideShiftSettings> GetSideShiftForStore(string storeId)
|
public async Task<SideShiftSettings> GetSideShiftForStore(string storeId)
|
||||||
@@ -45,5 +52,144 @@ namespace BTCPayServer.Plugins.SideShift
|
|||||||
await _storeRepository.UpdateSetting(storeId, nameof(SideShiftSettings), SideShiftSettings);
|
await _storeRepository.UpdateSetting(storeId, nameof(SideShiftSettings), SideShiftSettings);
|
||||||
_memoryCache.Set(k, SideShiftSettings);
|
_memoryCache.Set(k, SideShiftSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<List<SideshiftSettleCoin>> GetSettleCoins()
|
||||||
|
{
|
||||||
|
return await _memoryCache.GetOrCreateAsync<List<SideshiftSettleCoin>>("sideshift-coins", async entry =>
|
||||||
|
{
|
||||||
|
var client = _httpClientFactory.CreateClient("sideshift");
|
||||||
|
var request = new HttpRequestMessage(HttpMethod.Get, "https://sideshift.ai/api/v2/coins");
|
||||||
|
var response = await client.SendAsync(request);
|
||||||
|
var result = new List<SideshiftSettleCoin>();
|
||||||
|
if (!response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(2);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
var coins = await response.Content.ReadAsStringAsync().ContinueWith(t => JsonConvert.DeserializeObject<List<SideShiftAvailableCoin>>(t.Result));
|
||||||
|
|
||||||
|
coins.ForEach(coin =>
|
||||||
|
{
|
||||||
|
Array.ForEach (coin.networks,network =>
|
||||||
|
{
|
||||||
|
if(coin.settleOffline.Type == JTokenType.Boolean && coin.settleOffline.Value<bool>())
|
||||||
|
return;
|
||||||
|
if (coin.settleOffline is JArray settleOfflineArray &&
|
||||||
|
settleOfflineArray.Any(v => v.Value<string>() == network))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var coinType = CoinType.Both;
|
||||||
|
if (coin.fixedOnly.Type == JTokenType.Boolean && coin.fixedOnly.Value<bool>())
|
||||||
|
{
|
||||||
|
coinType = CoinType.FixedOnly;
|
||||||
|
}
|
||||||
|
else if (coin.fixedOnly is JArray fixedOnlyArray &&
|
||||||
|
fixedOnlyArray.Any(v => v.Value<string>() == network))
|
||||||
|
{
|
||||||
|
coinType = CoinType.FixedOnly;
|
||||||
|
}
|
||||||
|
else if (coin.variableOnly.Type == JTokenType.Boolean && coin.variableOnly.Value<bool>())
|
||||||
|
{
|
||||||
|
coinType = CoinType.VariableOnly;
|
||||||
|
}
|
||||||
|
else if (coin.variableOnly is JArray variableOnlyArray &&
|
||||||
|
variableOnlyArray.Any(v => v.Value<string>() == network))
|
||||||
|
{
|
||||||
|
coinType = CoinType.VariableOnly;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Add(new SideshiftSettleCoin()
|
||||||
|
{
|
||||||
|
Id = $"{coin.coin}_{network}",
|
||||||
|
CryptoCode = coin.coin,
|
||||||
|
Network = network,
|
||||||
|
DisplayName = coin.name,
|
||||||
|
HasMemo = coin.hasMemo,
|
||||||
|
Type = coinType,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5);
|
||||||
|
entry.Value = result;
|
||||||
|
return entry.Value as List<SideshiftSettleCoin>;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum CoinType
|
||||||
|
{
|
||||||
|
FixedOnly,
|
||||||
|
VariableOnly,
|
||||||
|
Both
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SideshiftSettleCoin:SideshiftDepositCoin
|
||||||
|
{
|
||||||
|
public bool HasMemo { get; set; }
|
||||||
|
}
|
||||||
|
public class SideshiftDepositCoin
|
||||||
|
{
|
||||||
|
public string DisplayName { get; set; }
|
||||||
|
public string Id { get; set; }
|
||||||
|
public CoinType Type { get; set; }
|
||||||
|
public string CryptoCode { get; set; }
|
||||||
|
public string Network { get; set; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"{DisplayName} {(DisplayName.Equals(Network, StringComparison.InvariantCultureIgnoreCase)? string.Empty: $"({Network})")}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public async Task<List<SideshiftDepositCoin>> GetDepositOptions()
|
||||||
|
{
|
||||||
|
return (List<SideshiftDepositCoin>) await _memoryCache.GetOrCreateAsync("sideshift-deposit", async entry =>
|
||||||
|
{
|
||||||
|
var client = _httpClientFactory.CreateClient("sideshift");
|
||||||
|
var request = new HttpRequestMessage(HttpMethod.Get, "https://sideshift.ai/api/v1/facts");
|
||||||
|
var response = await client.SendAsync(request);
|
||||||
|
var result = new List<SideshiftDepositCoin>();
|
||||||
|
if (!response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(2);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
var coins = await response.Content.ReadAsStringAsync().ContinueWith(t => JsonConvert.DeserializeObject<JObject>(t.Result));
|
||||||
|
|
||||||
|
foreach (var asset in coins["depositMethods"].Children<JProperty>())
|
||||||
|
{
|
||||||
|
if (asset.Value["enabled"].Value<bool>() is not true)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var id = asset.Name;
|
||||||
|
var displayName = asset.Value["displayName"].Value<string>();
|
||||||
|
var coinType = asset.Value["fixedOnly"].Value<bool>() ? CoinType.FixedOnly : asset.Value["variableOnly"].Value<bool>()? CoinType.VariableOnly : CoinType.Both;
|
||||||
|
var network = asset.Value["network"].Value<string>();
|
||||||
|
var cryptoCode = asset.Value["asset"].Value<string>();
|
||||||
|
result.Add(new SideshiftDepositCoin()
|
||||||
|
{
|
||||||
|
Id = id,
|
||||||
|
DisplayName = displayName,
|
||||||
|
Type = coinType,
|
||||||
|
Network = network,
|
||||||
|
CryptoCode = cryptoCode,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5);
|
||||||
|
entry.Value = result;
|
||||||
|
return entry.Value;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,5 +4,11 @@ namespace BTCPayServer.Plugins.SideShift
|
|||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
public decimal AmountMarkupPercentage { get; set; } = 0;
|
public decimal AmountMarkupPercentage { get; set; } = 0;
|
||||||
|
|
||||||
|
public string? PreferredTargetPaymentMethodId { get; set; }
|
||||||
|
public string[] ExplicitMethods { get; set; }
|
||||||
|
public bool OnlyShowExplicitMethods { get; set; } = false;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
namespace BTCPayServer.Plugins.SideShift
|
|
||||||
{
|
|
||||||
public class UpdateSideShiftSettingsViewModel
|
|
||||||
{
|
|
||||||
public bool Enabled { get; set; }
|
|
||||||
public string StoreName { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,9 +3,12 @@
|
|||||||
@using Newtonsoft.Json.Linq
|
@using Newtonsoft.Json.Linq
|
||||||
@inject BTCPayServer.Security.ContentSecurityPolicies csp
|
@inject BTCPayServer.Security.ContentSecurityPolicies csp
|
||||||
@inject SideShiftService SideShiftService
|
@inject SideShiftService SideShiftService
|
||||||
|
@model BTCPayServer.Models.InvoicingModels.PaymentModel
|
||||||
@{
|
@{
|
||||||
var storeId = ((JObject)JObject.Parse(JsonConvert.SerializeObject(Model)))["StoreId"].Value<string>();
|
var storeId = Model.StoreId;
|
||||||
var settings = await SideShiftService.GetSideShiftForStore(storeId);
|
var settings = await SideShiftService.GetSideShiftForStore(storeId);
|
||||||
|
var preferredTargetPaymentMethodId = string.IsNullOrEmpty(settings?.PreferredTargetPaymentMethodId) ? null : Model.AvailableCryptos.Any(crypto => crypto.PaymentMethodId == settings.PreferredTargetPaymentMethodId) ? settings.PreferredTargetPaymentMethodId : null;
|
||||||
|
|
||||||
}
|
}
|
||||||
@if (settings?.Enabled is true)
|
@if (settings?.Enabled is true)
|
||||||
{
|
{
|
||||||
@@ -22,6 +25,21 @@
|
|||||||
Vue.component("SideShiftCheckout", {
|
Vue.component("SideShiftCheckout", {
|
||||||
template: "#side-shift-checkout-template",
|
template: "#side-shift-checkout-template",
|
||||||
props: ["model"],
|
props: ["model"],
|
||||||
|
data: function() {
|
||||||
|
return {
|
||||||
|
explicitId: "",
|
||||||
|
preferredToCurrency: @Json.Serialize(preferredTargetPaymentMethodId),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
const self = this;
|
||||||
|
setInterval(function() {
|
||||||
|
if ( self.explicitId === window.ssExplicitId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.explicitId = window.ssExplicitId;
|
||||||
|
},200)
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
content () {
|
content () {
|
||||||
return this.$i18n.i18next.t("conversion_body", this.model).replace(/\n/ig, '<br>');
|
return this.$i18n.i18next.t("conversion_body", this.model).replace(/\n/ig, '<br>');
|
||||||
@@ -55,13 +73,20 @@
|
|||||||
openDialog () {
|
openDialog () {
|
||||||
window.__SIDESHIFT__ = {
|
window.__SIDESHIFT__ = {
|
||||||
parentAffiliateId: "qg0OrfHJV",
|
parentAffiliateId: "qg0OrfHJV",
|
||||||
|
defaultDepositMethodId: this.explicitId || undefined,
|
||||||
defaultSettleMethodId: this.settleMethodId,
|
defaultSettleMethodId: this.settleMethodId,
|
||||||
settleAddress: this.model.btcAddress,
|
settleAddress: this.model.btcAddress,
|
||||||
settleAmount: this.amountDue,
|
settleAmount: this.amountDue,
|
||||||
type: this.type
|
type: this.type
|
||||||
};
|
};
|
||||||
|
console.log(window.__SIDESHIFT__);
|
||||||
window.sideshift.show();
|
window.sideshift.show();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
explicitId (val) {
|
||||||
|
this.openDialog();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,15 +1,36 @@
|
|||||||
@using BTCPayServer.Plugins.SideShift
|
@using BTCPayServer.Plugins.SideShift
|
||||||
@using Newtonsoft.Json
|
|
||||||
@using Newtonsoft.Json.Linq
|
|
||||||
@inject SideShiftService SideShiftService
|
@inject SideShiftService SideShiftService
|
||||||
|
@model BTCPayServer.Models.InvoicingModels.PaymentModel
|
||||||
@{
|
@{
|
||||||
const string id = "SideShift";
|
const string id = "SideShift";
|
||||||
var storeId = ((JObject)JObject.Parse(JsonConvert.SerializeObject(Model)))["StoreId"].Value<string>();
|
var storeId = Model.StoreId;
|
||||||
var settings = await SideShiftService.GetSideShiftForStore(storeId);
|
var settings = await SideShiftService.GetSideShiftForStore(storeId);
|
||||||
if (settings?.Enabled is true)
|
if (settings?.Enabled is true)
|
||||||
{
|
{
|
||||||
<a href="#@id" class="btcpay-pill m-0 payment-method" :class="{ active: pmId === '@id' }" v-on:click.prevent="changePaymentMethod('@id')">
|
|
||||||
@id
|
var coins = await SideShiftService.GetDepositOptions();
|
||||||
|
if (settings.ExplicitMethods?.Any() is true)
|
||||||
|
{
|
||||||
|
foreach (var explicitMethod in settings.ExplicitMethods)
|
||||||
|
{
|
||||||
|
var s = explicitMethod.Split("_");
|
||||||
|
var coin = s[0];
|
||||||
|
var network = s[1];
|
||||||
|
var coinInfo = coins.FirstOrDefault(c => c.CryptoCode == coin && c.Network == network);
|
||||||
|
if(coinInfo is null)
|
||||||
|
continue;
|
||||||
|
<a href="#@id" class="btcpay-pill m-0 payment-method" :class="{ active: pmId === '@id' && window.ssExplicitId === '@coinInfo.Id'}" v-on:click.prevent="()=>{ window.ssExplicitId = '@coinInfo.Id'; changePaymentMethod('@id'); }">
|
||||||
|
@coinInfo.DisplayName @(coinInfo.DisplayName.Equals(coinInfo.Network, StringComparison.InvariantCultureIgnoreCase)? string.Empty: $"({coinInfo.Network})")
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!settings.OnlyShowExplicitMethods || settings.ExplicitMethods?.Any() is not true)
|
||||||
|
{
|
||||||
|
<a href="#@id" class="btcpay-pill m-0 payment-method" :class="{ active: pmId === '@id' && !window.ssExplicitId }" v-on:click.prevent="()=>{ window.ssExplicitId = null; changePaymentMethod('@id'); }">
|
||||||
|
@id
|
||||||
|
</a>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,31 +1,24 @@
|
|||||||
@using System.Net.Http
|
@using BTCPayServer.Abstractions.TagHelpers
|
||||||
@using BTCPayServer.Abstractions.TagHelpers
|
|
||||||
@using BTCPayServer.Plugins.SideShift
|
@using BTCPayServer.Plugins.SideShift
|
||||||
@using Microsoft.AspNetCore.Mvc.TagHelpers
|
@using Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
@using Newtonsoft.Json
|
@inject SideShiftService SideShiftService
|
||||||
@using Newtonsoft.Json.Linq
|
|
||||||
@inject IHttpClientFactory HttpClientFactory
|
|
||||||
@{
|
@{
|
||||||
var client = HttpClientFactory.CreateClient("sideshift");
|
|
||||||
var request = new HttpRequestMessage(HttpMethod.Get, "https://sideshift.ai/api/v2/coins");
|
var coins = await SideShiftService.GetSettleCoins();
|
||||||
var response = await client.SendAsync(request);
|
coins = coins.Where(tuple => new[] {SideShiftService.CoinType.VariableOnly, SideShiftService.CoinType.Both}.Contains(tuple.Type)).ToList();
|
||||||
if (!response.IsSuccessStatusCode)
|
if(coins.Any() is not true)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var coins = await response.Content.ReadAsStringAsync().ContinueWith(t => JsonConvert.DeserializeObject<List<SideShiftAvailableCoin>>(t.Result));
|
|
||||||
var availableCoins = coins.SelectMany(coin => coin.networks.Select(s => (Coin: coin, Network: s)))
|
|
||||||
.Where(tuple => (tuple.Coin.fixedOnly.Type == JTokenType.Boolean && !tuple.Coin.fixedOnly.Value<bool>()) || (
|
|
||||||
tuple.Coin.fixedOnly is JArray varOnlyArray && varOnlyArray.All(v => v.Value<string>() != tuple.Network))).ToList();
|
|
||||||
}
|
}
|
||||||
<button type="button" class="btn btn-primary btn-sm mt-4" data-bs-toggle="modal" data-bs-target="#sideshiftModal" >Generate SideShift destination</button>
|
<button type="button" class="btn btn-primary btn-sm mt-4" data-bs-toggle="modal" data-bs-target="#sideshiftModal" >Generate SideShift destination</button>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
const ssAvailableCoins = @Json.Serialize(availableCoins.ToDictionary(tuple=> $"{tuple.Coin.coin}_{tuple.Network}",tuple =>
|
const ssAvailableCoins = @Json.Serialize(coins.ToDictionary(tuple=> $"{tuple.CryptoCode}_{tuple.Network}",tuple =>
|
||||||
new {
|
new {
|
||||||
coin = tuple.Coin.name,
|
coin = tuple.DisplayName,
|
||||||
code = tuple.Coin.coin,
|
code = tuple.CryptoCode,
|
||||||
memo = tuple.Coin.hasMemo,
|
memo = tuple.HasMemo,
|
||||||
network = tuple.Network
|
network = tuple.Network
|
||||||
}));
|
}));
|
||||||
document.addEventListener('DOMContentLoaded', (event) => {
|
document.addEventListener('DOMContentLoaded', (event) => {
|
||||||
@@ -156,9 +149,9 @@ document.addEventListener('DOMContentLoaded', (event) => {
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">Which coin should Sideshift send you</label>
|
<label class="form-label">Which coin should Sideshift send you</label>
|
||||||
<select id="sscoin" class="form-select">
|
<select id="sscoin" class="form-select">
|
||||||
@foreach (var opt in availableCoins)
|
@foreach (var opt in coins)
|
||||||
{
|
{
|
||||||
<option value="@(opt.Coin.coin)_@(opt.Network)">@opt.Coin.name (@opt.Network)</option>
|
<option value="@($"{opt.CryptoCode}_{opt.Network}")">@opt.ToString()</option>
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
@using System.Net.Http
|
@using System.Net.Http
|
||||||
@using BTCPayServer.Plugins.SideShift
|
@using BTCPayServer.Plugins.SideShift
|
||||||
@using Newtonsoft.Json
|
|
||||||
@using Newtonsoft.Json.Linq
|
|
||||||
@model BTCPayServer.Models.ViewPullPaymentModel
|
@model BTCPayServer.Models.ViewPullPaymentModel
|
||||||
@inject IHttpClientFactory HttpClientFactory
|
@inject IHttpClientFactory HttpClientFactory
|
||||||
@inject SideShiftService SideShiftService
|
@inject SideShiftService SideShiftService
|
||||||
@@ -11,28 +9,23 @@
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var client = HttpClientFactory.CreateClient("sideshift");
|
var coins = await SideShiftService.GetSettleCoins();
|
||||||
var request = new HttpRequestMessage(HttpMethod.Get, "https://sideshift.ai/api/v2/coins");
|
coins = coins.Where(tuple => new[] {SideShiftService.CoinType.FixedOnly, SideShiftService.CoinType.Both}.Contains(tuple.Type)).ToList();
|
||||||
var response = await client.SendAsync(request);
|
if(coins.Any() is not true)
|
||||||
if (!response.IsSuccessStatusCode)
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var coins = await response.Content.ReadAsStringAsync().ContinueWith(t => JsonConvert.DeserializeObject<List<SideShiftAvailableCoin>>(t.Result));
|
|
||||||
var availableCoins = coins.SelectMany(coin => coin.networks.Select(s => (Coin: coin, Network: s)))
|
|
||||||
.Where(tuple => (tuple.Coin.fixedOnly.Type == JTokenType.Boolean && !tuple.Coin.fixedOnly.Value<bool>()) || (
|
|
||||||
tuple.Coin.fixedOnly is JArray varOnlyArray && varOnlyArray.All(v => v.Value<string>() != tuple.Network))).ToList();
|
|
||||||
|
|
||||||
var potentialPaymentMethods = Model.PaymentMethods;//.Where(id => id.CryptoCode.Equals(Model.Currency, StringComparison.OrdinalIgnoreCase)).ToList();
|
var potentialPaymentMethods = Model.PaymentMethods;//.Where(id => id.CryptoCode.Equals(Model.Currency, StringComparison.OrdinalIgnoreCase)).ToList();
|
||||||
if (Model.IsPending && potentialPaymentMethods.Any() && availableCoins.Any())
|
if (Model.IsPending && potentialPaymentMethods.Any())
|
||||||
{
|
{
|
||||||
<script>
|
<script>
|
||||||
const url = @Json.Serialize(Url.Action("CreatePayout", "SideShift", new {pullPaymentId = Model.Id }))
|
const url = @Json.Serialize(Url.Action("CreatePayout", "SideShift", new {pullPaymentId = Model.Id }))
|
||||||
const ssAvailableCoins = @Json.Serialize(availableCoins.ToDictionary(tuple=> $"{tuple.Coin.coin}_{tuple.Network}",tuple =>
|
const ssAvailableCoins = @Json.Serialize(coins.ToDictionary(tuple=> $"{tuple.CryptoCode}_{tuple.Network}",tuple =>
|
||||||
new {
|
new {
|
||||||
coin = tuple.Coin.name,
|
coin = tuple.DisplayName,
|
||||||
code = tuple.Coin.coin,
|
code = tuple.CryptoCode,
|
||||||
memo = tuple.Coin.hasMemo,
|
memo = tuple.HasMemo,
|
||||||
network = tuple.Network
|
network = tuple.Network
|
||||||
}));
|
}));
|
||||||
const ssPaymentMethods = @Json.Serialize(potentialPaymentMethods.Select(id => new { id = id.ToString(), name= id.ToPrettyString()}));
|
const ssPaymentMethods = @Json.Serialize(potentialPaymentMethods.Select(id => new { id = id.ToString(), name= id.ToPrettyString()}));
|
||||||
@@ -159,9 +152,9 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">Which coin should Sideshift send you</label>
|
<label class="form-label">Which coin should Sideshift send you</label>
|
||||||
<select id="sscoin" class="form-select">
|
<select id="sscoin" class="form-select">
|
||||||
@foreach (var opt in availableCoins)
|
@foreach (var opt in coins)
|
||||||
{
|
{
|
||||||
<option value="@(opt.Coin.coin)_@(opt.Network)">@opt.Coin.name (@opt.Network)</option>
|
<option value="@($"{opt.CryptoCode}_{opt.Network}")">@opt.ToString()</option>
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,8 +1,19 @@
|
|||||||
@using BTCPayServer.Abstractions.Extensions
|
@using BTCPayServer
|
||||||
|
@using BTCPayServer.Abstractions.Extensions
|
||||||
|
@using BTCPayServer.Data
|
||||||
|
@using BTCPayServer.Plugins.SideShift
|
||||||
@using Microsoft.AspNetCore.Mvc.TagHelpers
|
@using Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
@model BTCPayServer.Plugins.SideShift.UpdateSideShiftSettingsViewModel
|
@model BTCPayServer.Plugins.SideShift.SideShiftSettings
|
||||||
|
@inject BTCPayNetworkProvider BTCPayNetworkProvider
|
||||||
|
@inject SideShiftService SideShiftService
|
||||||
@{
|
@{
|
||||||
ViewData.SetActivePage("SideShift", "SideShift", "SideShift");
|
ViewData.SetActivePage("SideShift", "SideShift", "SideShift");
|
||||||
|
var store = Context.GetStoreData();
|
||||||
|
var allowedPaymentMethods = store.GetEnabledPaymentIds(BTCPayNetworkProvider)
|
||||||
|
.Select(pmi => new SelectListItem(pmi.ToPrettyString(), pmi.ToString()))
|
||||||
|
.Prepend(new SelectListItem("Any", ""));
|
||||||
|
var coins = await SideShiftService.GetDepositOptions();
|
||||||
|
var allowedCoins = coins.OrderBy(coin => coin.ToString()).Select(c => new SelectListItem(c.ToString(), $"{c.CryptoCode}_{c.Network}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
<partial name="_StatusMessage" />
|
<partial name="_StatusMessage" />
|
||||||
@@ -22,6 +33,21 @@
|
|||||||
<label asp-for="Enabled" class="form-label mb-0 me-1"></label>
|
<label asp-for="Enabled" class="form-label mb-0 me-1"></label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label asp-for="PreferredTargetPaymentMethodId" class="form-label" data-required>Convert always to this payment method, if possible</label>
|
||||||
|
<select asp-for="PreferredTargetPaymentMethodId" asp-items="allowedPaymentMethods" class="form-select"></select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label asp-for="ExplicitMethods" class="form-label" data-required>Show these conversion options as individual payment methods</label>
|
||||||
|
<select style="min-height: 300px;" multiple asp-for="ExplicitMethods" asp-items="@allowedCoins" class="form-select"></select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<input asp-for="OnlyShowExplicitMethods" type="checkbox" class="btcpay-toggle me-2"/>
|
||||||
|
<label asp-for="OnlyShowExplicitMethods" class="form-label mb-0 me-1">Only show explicit methods</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<button name="command" type="submit" value="save" class="btn btn-primary">Submit</button>
|
<button name="command" type="submit" value="save" class="btn btn-primary">Submit</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user