mirror of
https://github.com/aljazceru/BTCPayServerPlugins.git
synced 2025-12-17 07:34:24 +01:00
Make sideshift extend prism in a better way
This commit is contained in:
84
Plugins/BTCPayServer.Plugins.SideShift/PrismClaimCreate.cs
Normal file
84
Plugins/BTCPayServer.Plugins.SideShift/PrismClaimCreate.cs
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
using System;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using BTCPayServer.Abstractions.Contracts;
|
||||||
|
using BTCPayServer.Data.Payouts.LightningLike;
|
||||||
|
using BTCPayServer.HostedServices;
|
||||||
|
using BTCPayServer.Lightning;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Plugins.SideShift;
|
||||||
|
|
||||||
|
public class PrismClaimCreate : IPluginHookFilter
|
||||||
|
{
|
||||||
|
private readonly IHttpClientFactory _httpClientFactory;
|
||||||
|
private readonly BTCPayNetworkProvider _networkProvider;
|
||||||
|
public string Hook => "prism-claim-create";
|
||||||
|
|
||||||
|
public PrismClaimCreate(IHttpClientFactory httpClientFactory, BTCPayNetworkProvider networkProvider)
|
||||||
|
{
|
||||||
|
_httpClientFactory = httpClientFactory;
|
||||||
|
_networkProvider = networkProvider;
|
||||||
|
}
|
||||||
|
public async Task<object> Execute(object args)
|
||||||
|
{
|
||||||
|
var network = _networkProvider.GetNetwork<BTCPayNetwork>("BTC");
|
||||||
|
if (args is not ClaimRequest claimRequest || network is null)
|
||||||
|
{
|
||||||
|
return Task.FromResult(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (claimRequest.Destination?.ToString() is not { } args1 || !args1.StartsWith("sideshift:")) return args;
|
||||||
|
var request = JObject.Parse(args1.Substring("sideshift:".Length)).ToObject<PrismSideshiftDestination>();
|
||||||
|
if (!request.Valid())
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var client = _httpClientFactory.CreateClient("sideshift");
|
||||||
|
|
||||||
|
|
||||||
|
var shiftResponse = await client.PostAsJsonAsync("https://sideshift.ai/api/v2/shifts/variable", new
|
||||||
|
{
|
||||||
|
settleAddress = request.ShiftDestination,
|
||||||
|
affiliateId = "qg0OrfHJV",
|
||||||
|
settleMemo = request.ShiftMemo,
|
||||||
|
depositCoin = "BTC",
|
||||||
|
depositNetwork = "lightning",
|
||||||
|
settleCoin = request.ShiftCoin,
|
||||||
|
settleNetwork = request.ShiftNetwork,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (!shiftResponse.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var shift = await shiftResponse.Content.ReadAsAsync<SideShiftController.ShiftResponse>();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
LNURL.LNURL.Parse(shift.depositAddress, out _);
|
||||||
|
claimRequest.Destination = new LNURLPayClaimDestinaton(shift.depositAddress);
|
||||||
|
claimRequest.Metadata = JObject.FromObject(new
|
||||||
|
{
|
||||||
|
Source = $"Prism->Sideshift",
|
||||||
|
SourceLink = $"https://sideshift.ai/orders/{shift.id}?openSupport=true",
|
||||||
|
});
|
||||||
|
return claimRequest;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
if (BOLT11PaymentRequest.TryParse(shift.depositAddress, out var bolt11, network.NBitcoinNetwork))
|
||||||
|
{
|
||||||
|
claimRequest.Destination = new BoltInvoiceClaimDestination(shift.depositAddress, bolt11);
|
||||||
|
claimRequest.Metadata = JObject.FromObject(new
|
||||||
|
{
|
||||||
|
Source = $"Prism->Sideshift",
|
||||||
|
SourceLink = $"https://sideshift.ai/orders/{shift.id}?openSupport=true",
|
||||||
|
});
|
||||||
|
return claimRequest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using BTCPayServer.Abstractions.Contracts;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Plugins.SideShift;
|
||||||
|
|
||||||
|
public class PrismDestinationValidate : IPluginHookFilter
|
||||||
|
{
|
||||||
|
public string Hook => "prism-destination-validate";
|
||||||
|
public async Task<object> Execute(object args)
|
||||||
|
{
|
||||||
|
if (args is not string args1 || !args1.StartsWith("sideshift:")) return args;
|
||||||
|
var json = JObject.Parse(args1.Substring("sideshift:".Length)).ToObject<PrismSideshiftDestination>();
|
||||||
|
return json.Valid();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
15
Plugins/BTCPayServer.Plugins.SideShift/PrismEditFiltercs.cs
Normal file
15
Plugins/BTCPayServer.Plugins.SideShift/PrismEditFiltercs.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using BTCPayServer.Abstractions.Contracts;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Plugins.SideShift;
|
||||||
|
|
||||||
|
public class PrismEditFilter : IPluginHookFilter
|
||||||
|
{
|
||||||
|
public string Hook => "prism-edit-buttons";
|
||||||
|
|
||||||
|
public Task<object> Execute(object args)
|
||||||
|
{
|
||||||
|
return Task.FromResult<object>(( args??"") + "<button type='button' class=\"btn btn-primary\" data-bs-toggle=\"modal\" data-bs-target=\"#sideshiftModal\">Generate SideShift destination</button>");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
namespace BTCPayServer.Plugins.SideShift;
|
||||||
|
|
||||||
|
public class PrismSideshiftDestination
|
||||||
|
{
|
||||||
|
public string ShiftCoin { get; set; }
|
||||||
|
public string ShiftNetwork { get; set; }
|
||||||
|
public string ShiftDestination { get; set; }
|
||||||
|
public string ShiftMemo { get; set; }
|
||||||
|
|
||||||
|
public bool Valid()
|
||||||
|
{
|
||||||
|
return !string.IsNullOrEmpty(ShiftCoin) && !string.IsNullOrEmpty(ShiftNetwork) &&
|
||||||
|
!string.IsNullOrEmpty(ShiftDestination);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Plugins.SideShift;
|
||||||
|
|
||||||
|
public class SideShiftAvailableCoin
|
||||||
|
{
|
||||||
|
public string coin { get; set; }
|
||||||
|
public string[] networks { get; set; }
|
||||||
|
public string name { get; set; }
|
||||||
|
public bool hasMemo { get; set; }
|
||||||
|
public JToken fixedOnly { get; set; }
|
||||||
|
public JToken variableOnly { get; set; }
|
||||||
|
public JToken settleOffline { get; set; }
|
||||||
|
}
|
||||||
@@ -201,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}?openSupport=true\">the order page</a> for support.";
|
ppBlob.Description += $"<br/>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();
|
||||||
|
|||||||
@@ -1,14 +1,7 @@
|
|||||||
using System;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using BTCPayServer.Abstractions.Contracts;
|
using BTCPayServer.Abstractions.Contracts;
|
||||||
using BTCPayServer.Abstractions.Models;
|
using BTCPayServer.Abstractions.Models;
|
||||||
using BTCPayServer.Abstractions.Services;
|
using BTCPayServer.Abstractions.Services;
|
||||||
using BTCPayServer.Data;
|
|
||||||
using BTCPayServer.Data.Payouts.LightningLike;
|
|
||||||
using BTCPayServer.Lightning;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
|
|
||||||
namespace BTCPayServer.Plugins.SideShift
|
namespace BTCPayServer.Plugins.SideShift
|
||||||
{
|
{
|
||||||
@@ -47,107 +40,9 @@ namespace BTCPayServer.Plugins.SideShift
|
|||||||
applicationBuilder.AddSingleton<IUIExtension>(new UIExtension("SideShift/PrismEnhance",
|
applicationBuilder.AddSingleton<IUIExtension>(new UIExtension("SideShift/PrismEnhance",
|
||||||
"prism-edit"));
|
"prism-edit"));
|
||||||
applicationBuilder.AddSingleton<IPluginHookFilter, PrismDestinationValidate>();
|
applicationBuilder.AddSingleton<IPluginHookFilter, PrismDestinationValidate>();
|
||||||
applicationBuilder.AddSingleton<IPluginHookFilter, PrismClaimDestination>();
|
applicationBuilder.AddSingleton<IPluginHookFilter, PrismClaimCreate>();
|
||||||
|
applicationBuilder.AddSingleton<IPluginHookFilter, PrismEditFilter>();
|
||||||
base.Execute(applicationBuilder);
|
base.Execute(applicationBuilder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class PrismSideshiftDestination
|
|
||||||
{
|
|
||||||
public string ShiftCoin { get; set; }
|
|
||||||
public string ShiftNetwork { get; set; }
|
|
||||||
public string ShiftDestination { get; set; }
|
|
||||||
public string ShiftMemo { get; set; }
|
|
||||||
|
|
||||||
public bool Valid()
|
|
||||||
{
|
|
||||||
return !string.IsNullOrEmpty(ShiftCoin) && !string.IsNullOrEmpty(ShiftNetwork) &&
|
|
||||||
!string.IsNullOrEmpty(ShiftDestination);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PrismDestinationValidate : IPluginHookFilter
|
|
||||||
{
|
|
||||||
public string Hook => "prism-destination-validate";
|
|
||||||
public async Task<object> Execute(object args)
|
|
||||||
{
|
|
||||||
if (args is not string args1 || !args1.StartsWith("sideshift:")) return args;
|
|
||||||
var json = JObject.Parse(args1.Substring("sideshift:".Length)).ToObject<PrismSideshiftDestination>();
|
|
||||||
return json.Valid();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PrismClaimDestination : IPluginHookFilter
|
|
||||||
{
|
|
||||||
private readonly IHttpClientFactory _httpClientFactory;
|
|
||||||
private readonly BTCPayNetworkProvider _networkProvider;
|
|
||||||
public string Hook => "prism-claim-destination";
|
|
||||||
|
|
||||||
public PrismClaimDestination(IHttpClientFactory httpClientFactory, BTCPayNetworkProvider networkProvider)
|
|
||||||
{
|
|
||||||
_httpClientFactory = httpClientFactory;
|
|
||||||
_networkProvider = networkProvider;
|
|
||||||
}
|
|
||||||
public async Task<object> Execute(object args)
|
|
||||||
{
|
|
||||||
var network = _networkProvider.GetNetwork<BTCPayNetwork>("BTC");
|
|
||||||
if (args is not string s || network is null)
|
|
||||||
{
|
|
||||||
return Task.FromResult(args);
|
|
||||||
}
|
|
||||||
if (args is not string args1 || !args1.StartsWith("sideshift:")) return args;
|
|
||||||
var request = JObject.Parse(args1.Substring("sideshift:".Length)).ToObject<PrismSideshiftDestination>();
|
|
||||||
if (!request.Valid())
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
var client = _httpClientFactory.CreateClient("sideshift");
|
|
||||||
|
|
||||||
|
|
||||||
var shiftResponse = await client.PostAsJsonAsync("https://sideshift.ai/api/v2/shifts/variable", new
|
|
||||||
{
|
|
||||||
settleAddress = request.ShiftDestination,
|
|
||||||
affiliateId = "qg0OrfHJV",
|
|
||||||
settleMemo = request.ShiftMemo,
|
|
||||||
depositCoin = "BTC",
|
|
||||||
depositNetwork = "lightning",
|
|
||||||
settleCoin = request.ShiftCoin,
|
|
||||||
settleNetwork = request.ShiftNetwork,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
if (!shiftResponse.IsSuccessStatusCode)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
var shift = await shiftResponse.Content.ReadAsAsync<SideShiftController.ShiftResponse>();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
LNURL.LNURL.Parse(shift.depositAddress, out var lnurl);
|
|
||||||
return new LNURLPayClaimDestinaton(shift.depositAddress);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
if (BOLT11PaymentRequest.TryParse(shift.depositAddress, out var bolt11, network.NBitcoinNetwork))
|
|
||||||
{
|
|
||||||
return new BoltInvoiceClaimDestination(shift.depositAddress, bolt11);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SideShiftAvailableCoin
|
|
||||||
{
|
|
||||||
public string coin { get; set; }
|
|
||||||
public string[] networks { get; set; }
|
|
||||||
public string name { get; set; }
|
|
||||||
public bool hasMemo { get; set; }
|
|
||||||
public JToken fixedOnly { get; set; }
|
|
||||||
public JToken variableOnly { get; set; }
|
|
||||||
public JToken settleOffline { get; set; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -11,7 +11,6 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
<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(coins.ToDictionary(tuple=> $"{tuple.CryptoCode}_{tuple.Network}",tuple =>
|
const ssAvailableCoins = @Json.Serialize(coins.ToDictionary(tuple=> $"{tuple.CryptoCode}_{tuple.Network}",tuple =>
|
||||||
@@ -76,7 +75,6 @@ document.addEventListener('DOMContentLoaded', (event) => {
|
|||||||
document.getElementById("ss-result-additional-info").value = "";
|
document.getElementById("ss-result-additional-info").value = "";
|
||||||
if (isValid()){
|
if (isValid()){
|
||||||
shiftButton.setAttribute("disabled", "disabled");
|
shiftButton.setAttribute("disabled", "disabled");
|
||||||
const type = "permanent";
|
|
||||||
|
|
||||||
if (type ==="permanent"){
|
if (type ==="permanent"){
|
||||||
fetch("https://sideshift.ai/api/v2/shifts/variable",{
|
fetch("https://sideshift.ai/api/v2/shifts/variable",{
|
||||||
@@ -171,9 +169,15 @@ document.addEventListener('DOMContentLoaded', (event) => {
|
|||||||
|
|
||||||
<div id="ss-result" class="form-group mt-4" style="display: none;">
|
<div id="ss-result" class="form-group mt-4" style="display: none;">
|
||||||
<label class="form-label">Generated code</label>
|
<label class="form-label">Generated code</label>
|
||||||
<input type="text" id="ss-result-txt" class="form-control" readonly="readonly"/>
|
<div class="input-group">
|
||||||
|
<input type="text" id="ss-result-txt" class="form-control" readonly="readonly"/>
|
||||||
|
<button type="button" class="btn btn-secondary" data-clipboard-target="#ss-result-txt">
|
||||||
|
<vc:icon symbol="copy"/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<p id="ss-result-additional-info"></p>
|
<p id="ss-result-additional-info"></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,2 +1,5 @@
|
|||||||
@addTagHelper *, BTCPayServer.Abstractions
|
@using BTCPayServer.Abstractions.Services
|
||||||
|
@inject Safe Safe
|
||||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
|
@addTagHelper *, BTCPayServer
|
||||||
|
@addTagHelper *, BTCPayServer.Abstractions
|
||||||
Submodule submodules/btcpayserver updated: 3fb5e85369...ac4b49ff98
Reference in New Issue
Block a user