This commit is contained in:
Kukks
2023-12-20 09:29:32 +01:00
parent d24f2b54f6
commit 028e58d438
14 changed files with 223 additions and 285 deletions

View File

@@ -81,8 +81,8 @@ Global
{B19C9F52-DC47-466D-8B5C-2D202B7B003F}.Altcoins-Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU {B19C9F52-DC47-466D-8B5C-2D202B7B003F}.Altcoins-Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU
{B19C9F52-DC47-466D-8B5C-2D202B7B003F}.Altcoins-Release|Any CPU.ActiveCfg = Altcoins-Release|Any CPU {B19C9F52-DC47-466D-8B5C-2D202B7B003F}.Altcoins-Release|Any CPU.ActiveCfg = Altcoins-Release|Any CPU
{B19C9F52-DC47-466D-8B5C-2D202B7B003F}.Altcoins-Release|Any CPU.Build.0 = Altcoins-Release|Any CPU {B19C9F52-DC47-466D-8B5C-2D202B7B003F}.Altcoins-Release|Any CPU.Build.0 = Altcoins-Release|Any CPU
{B19C9F52-DC47-466D-8B5C-2D202B7B003F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B19C9F52-DC47-466D-8B5C-2D202B7B003F}.Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU
{B19C9F52-DC47-466D-8B5C-2D202B7B003F}.Debug|Any CPU.Build.0 = Debug|Any CPU {B19C9F52-DC47-466D-8B5C-2D202B7B003F}.Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU
{AD9635BB-C70E-4676-BB04-900D51B01666}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {AD9635BB-C70E-4676-BB04-900D51B01666}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AD9635BB-C70E-4676-BB04-900D51B01666}.Debug|Any CPU.Build.0 = Debug|Any CPU {AD9635BB-C70E-4676-BB04-900D51B01666}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AD9635BB-C70E-4676-BB04-900D51B01666}.Release|Any CPU.ActiveCfg = Release|Any CPU {AD9635BB-C70E-4676-BB04-900D51B01666}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -97,48 +97,48 @@ Global
{8F158B88-0FEE-44FF-8552-7C0F17D5C508}.Altcoins-Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU {8F158B88-0FEE-44FF-8552-7C0F17D5C508}.Altcoins-Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU
{8F158B88-0FEE-44FF-8552-7C0F17D5C508}.Altcoins-Release|Any CPU.ActiveCfg = Altcoins-Release|Any CPU {8F158B88-0FEE-44FF-8552-7C0F17D5C508}.Altcoins-Release|Any CPU.ActiveCfg = Altcoins-Release|Any CPU
{8F158B88-0FEE-44FF-8552-7C0F17D5C508}.Altcoins-Release|Any CPU.Build.0 = Altcoins-Release|Any CPU {8F158B88-0FEE-44FF-8552-7C0F17D5C508}.Altcoins-Release|Any CPU.Build.0 = Altcoins-Release|Any CPU
{8F158B88-0FEE-44FF-8552-7C0F17D5C508}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8F158B88-0FEE-44FF-8552-7C0F17D5C508}.Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU
{8F158B88-0FEE-44FF-8552-7C0F17D5C508}.Debug|Any CPU.Build.0 = Debug|Any CPU {8F158B88-0FEE-44FF-8552-7C0F17D5C508}.Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU
{DF85EFA4-0EF5-4A99-853F-E6F9C88E3F8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DF85EFA4-0EF5-4A99-853F-E6F9C88E3F8C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DF85EFA4-0EF5-4A99-853F-E6F9C88E3F8C}.Release|Any CPU.ActiveCfg = Release|Any CPU {DF85EFA4-0EF5-4A99-853F-E6F9C88E3F8C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DF85EFA4-0EF5-4A99-853F-E6F9C88E3F8C}.Release|Any CPU.Build.0 = Release|Any CPU {DF85EFA4-0EF5-4A99-853F-E6F9C88E3F8C}.Release|Any CPU.Build.0 = Release|Any CPU
{DF85EFA4-0EF5-4A99-853F-E6F9C88E3F8C}.Altcoins-Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU {DF85EFA4-0EF5-4A99-853F-E6F9C88E3F8C}.Altcoins-Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU
{DF85EFA4-0EF5-4A99-853F-E6F9C88E3F8C}.Altcoins-Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU {DF85EFA4-0EF5-4A99-853F-E6F9C88E3F8C}.Altcoins-Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU
{DF85EFA4-0EF5-4A99-853F-E6F9C88E3F8C}.Altcoins-Release|Any CPU.ActiveCfg = Altcoins-Release|Any CPU {DF85EFA4-0EF5-4A99-853F-E6F9C88E3F8C}.Altcoins-Release|Any CPU.ActiveCfg = Altcoins-Release|Any CPU
{DF85EFA4-0EF5-4A99-853F-E6F9C88E3F8C}.Altcoins-Release|Any CPU.Build.0 = Altcoins-Release|Any CPU {DF85EFA4-0EF5-4A99-853F-E6F9C88E3F8C}.Altcoins-Release|Any CPU.Build.0 = Altcoins-Release|Any CPU
{DF85EFA4-0EF5-4A99-853F-E6F9C88E3F8C}.Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU
{DF85EFA4-0EF5-4A99-853F-E6F9C88E3F8C}.Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU
{2C5C4DF9-BA1F-4671-9F24-B22D7C9C3D21}.Release|Any CPU.ActiveCfg = Release|Any CPU {2C5C4DF9-BA1F-4671-9F24-B22D7C9C3D21}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2C5C4DF9-BA1F-4671-9F24-B22D7C9C3D21}.Release|Any CPU.Build.0 = Release|Any CPU {2C5C4DF9-BA1F-4671-9F24-B22D7C9C3D21}.Release|Any CPU.Build.0 = Release|Any CPU
{2C5C4DF9-BA1F-4671-9F24-B22D7C9C3D21}.Altcoins-Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU {2C5C4DF9-BA1F-4671-9F24-B22D7C9C3D21}.Altcoins-Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU
{2C5C4DF9-BA1F-4671-9F24-B22D7C9C3D21}.Altcoins-Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU {2C5C4DF9-BA1F-4671-9F24-B22D7C9C3D21}.Altcoins-Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU
{2C5C4DF9-BA1F-4671-9F24-B22D7C9C3D21}.Altcoins-Release|Any CPU.ActiveCfg = Altcoins-Release|Any CPU {2C5C4DF9-BA1F-4671-9F24-B22D7C9C3D21}.Altcoins-Release|Any CPU.ActiveCfg = Altcoins-Release|Any CPU
{2C5C4DF9-BA1F-4671-9F24-B22D7C9C3D21}.Altcoins-Release|Any CPU.Build.0 = Altcoins-Release|Any CPU {2C5C4DF9-BA1F-4671-9F24-B22D7C9C3D21}.Altcoins-Release|Any CPU.Build.0 = Altcoins-Release|Any CPU
{2C5C4DF9-BA1F-4671-9F24-B22D7C9C3D21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2C5C4DF9-BA1F-4671-9F24-B22D7C9C3D21}.Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU
{2C5C4DF9-BA1F-4671-9F24-B22D7C9C3D21}.Debug|Any CPU.Build.0 = Debug|Any CPU {2C5C4DF9-BA1F-4671-9F24-B22D7C9C3D21}.Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU
{D7E7309D-C4F4-496A-B2C8-BC5D3991B9C0}.Release|Any CPU.ActiveCfg = Release|Any CPU {D7E7309D-C4F4-496A-B2C8-BC5D3991B9C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D7E7309D-C4F4-496A-B2C8-BC5D3991B9C0}.Release|Any CPU.Build.0 = Release|Any CPU {D7E7309D-C4F4-496A-B2C8-BC5D3991B9C0}.Release|Any CPU.Build.0 = Release|Any CPU
{D7E7309D-C4F4-496A-B2C8-BC5D3991B9C0}.Altcoins-Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU {D7E7309D-C4F4-496A-B2C8-BC5D3991B9C0}.Altcoins-Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU
{D7E7309D-C4F4-496A-B2C8-BC5D3991B9C0}.Altcoins-Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU {D7E7309D-C4F4-496A-B2C8-BC5D3991B9C0}.Altcoins-Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU
{D7E7309D-C4F4-496A-B2C8-BC5D3991B9C0}.Altcoins-Release|Any CPU.ActiveCfg = Altcoins-Release|Any CPU {D7E7309D-C4F4-496A-B2C8-BC5D3991B9C0}.Altcoins-Release|Any CPU.ActiveCfg = Altcoins-Release|Any CPU
{D7E7309D-C4F4-496A-B2C8-BC5D3991B9C0}.Altcoins-Release|Any CPU.Build.0 = Altcoins-Release|Any CPU {D7E7309D-C4F4-496A-B2C8-BC5D3991B9C0}.Altcoins-Release|Any CPU.Build.0 = Altcoins-Release|Any CPU
{D7E7309D-C4F4-496A-B2C8-BC5D3991B9C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D7E7309D-C4F4-496A-B2C8-BC5D3991B9C0}.Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU
{D7E7309D-C4F4-496A-B2C8-BC5D3991B9C0}.Debug|Any CPU.Build.0 = Debug|Any CPU {D7E7309D-C4F4-496A-B2C8-BC5D3991B9C0}.Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU
{3F2E0BA0-9EA7-490F-894D-F9703F35B174}.Release|Any CPU.ActiveCfg = Release|Any CPU {3F2E0BA0-9EA7-490F-894D-F9703F35B174}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3F2E0BA0-9EA7-490F-894D-F9703F35B174}.Release|Any CPU.Build.0 = Release|Any CPU {3F2E0BA0-9EA7-490F-894D-F9703F35B174}.Release|Any CPU.Build.0 = Release|Any CPU
{3F2E0BA0-9EA7-490F-894D-F9703F35B174}.Altcoins-Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU {3F2E0BA0-9EA7-490F-894D-F9703F35B174}.Altcoins-Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU
{3F2E0BA0-9EA7-490F-894D-F9703F35B174}.Altcoins-Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU {3F2E0BA0-9EA7-490F-894D-F9703F35B174}.Altcoins-Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU
{3F2E0BA0-9EA7-490F-894D-F9703F35B174}.Altcoins-Release|Any CPU.ActiveCfg = Altcoins-Release|Any CPU {3F2E0BA0-9EA7-490F-894D-F9703F35B174}.Altcoins-Release|Any CPU.ActiveCfg = Altcoins-Release|Any CPU
{3F2E0BA0-9EA7-490F-894D-F9703F35B174}.Altcoins-Release|Any CPU.Build.0 = Altcoins-Release|Any CPU {3F2E0BA0-9EA7-490F-894D-F9703F35B174}.Altcoins-Release|Any CPU.Build.0 = Altcoins-Release|Any CPU
{3F2E0BA0-9EA7-490F-894D-F9703F35B174}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3F2E0BA0-9EA7-490F-894D-F9703F35B174}.Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU
{3F2E0BA0-9EA7-490F-894D-F9703F35B174}.Debug|Any CPU.Build.0 = Debug|Any CPU {3F2E0BA0-9EA7-490F-894D-F9703F35B174}.Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU
{6295533A-F941-40CA-B889-FE6C0432ED53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6295533A-F941-40CA-B889-FE6C0432ED53}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6295533A-F941-40CA-B889-FE6C0432ED53}.Release|Any CPU.ActiveCfg = Release|Any CPU {6295533A-F941-40CA-B889-FE6C0432ED53}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6295533A-F941-40CA-B889-FE6C0432ED53}.Release|Any CPU.Build.0 = Release|Any CPU {6295533A-F941-40CA-B889-FE6C0432ED53}.Release|Any CPU.Build.0 = Release|Any CPU
{6295533A-F941-40CA-B889-FE6C0432ED53}.Altcoins-Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU {6295533A-F941-40CA-B889-FE6C0432ED53}.Altcoins-Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU
{6295533A-F941-40CA-B889-FE6C0432ED53}.Altcoins-Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU {6295533A-F941-40CA-B889-FE6C0432ED53}.Altcoins-Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU
{6295533A-F941-40CA-B889-FE6C0432ED53}.Altcoins-Release|Any CPU.ActiveCfg = Altcoins-Release|Any CPU {6295533A-F941-40CA-B889-FE6C0432ED53}.Altcoins-Release|Any CPU.ActiveCfg = Altcoins-Release|Any CPU
{6295533A-F941-40CA-B889-FE6C0432ED53}.Altcoins-Release|Any CPU.Build.0 = Altcoins-Release|Any CPU {6295533A-F941-40CA-B889-FE6C0432ED53}.Altcoins-Release|Any CPU.Build.0 = Altcoins-Release|Any CPU
{6295533A-F941-40CA-B889-FE6C0432ED53}.Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU
{6295533A-F941-40CA-B889-FE6C0432ED53}.Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU
{58863D86-3C78-4BEC-ACB6-2F82CC141210}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {58863D86-3C78-4BEC-ACB6-2F82CC141210}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{58863D86-3C78-4BEC-ACB6-2F82CC141210}.Debug|Any CPU.Build.0 = Debug|Any CPU {58863D86-3C78-4BEC-ACB6-2F82CC141210}.Debug|Any CPU.Build.0 = Debug|Any CPU
{58863D86-3C78-4BEC-ACB6-2F82CC141210}.Release|Any CPU.ActiveCfg = Release|Any CPU {58863D86-3C78-4BEC-ACB6-2F82CC141210}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -149,12 +149,12 @@ Global
{58863D86-3C78-4BEC-ACB6-2F82CC141210}.Altcoins-Release|Any CPU.Build.0 = Release|Any CPU {58863D86-3C78-4BEC-ACB6-2F82CC141210}.Altcoins-Release|Any CPU.Build.0 = Release|Any CPU
{B4E2ED08-4AD3-4648-8BDB-3107200460B9}.Release|Any CPU.ActiveCfg = Release|Any CPU {B4E2ED08-4AD3-4648-8BDB-3107200460B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B4E2ED08-4AD3-4648-8BDB-3107200460B9}.Release|Any CPU.Build.0 = Release|Any CPU {B4E2ED08-4AD3-4648-8BDB-3107200460B9}.Release|Any CPU.Build.0 = Release|Any CPU
{B4E2ED08-4AD3-4648-8BDB-3107200460B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B4E2ED08-4AD3-4648-8BDB-3107200460B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B4E2ED08-4AD3-4648-8BDB-3107200460B9}.Altcoins-Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU {B4E2ED08-4AD3-4648-8BDB-3107200460B9}.Altcoins-Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU
{B4E2ED08-4AD3-4648-8BDB-3107200460B9}.Altcoins-Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU {B4E2ED08-4AD3-4648-8BDB-3107200460B9}.Altcoins-Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU
{B4E2ED08-4AD3-4648-8BDB-3107200460B9}.Altcoins-Release|Any CPU.ActiveCfg = Altcoins-Release|Any CPU {B4E2ED08-4AD3-4648-8BDB-3107200460B9}.Altcoins-Release|Any CPU.ActiveCfg = Altcoins-Release|Any CPU
{B4E2ED08-4AD3-4648-8BDB-3107200460B9}.Altcoins-Release|Any CPU.Build.0 = Altcoins-Release|Any CPU {B4E2ED08-4AD3-4648-8BDB-3107200460B9}.Altcoins-Release|Any CPU.Build.0 = Altcoins-Release|Any CPU
{B4E2ED08-4AD3-4648-8BDB-3107200460B9}.Debug|Any CPU.ActiveCfg = Altcoins-Debug|Any CPU
{B4E2ED08-4AD3-4648-8BDB-3107200460B9}.Debug|Any CPU.Build.0 = Altcoins-Debug|Any CPU
{5E1BAA06-7828-47BC-89D6-19C2A78EA427}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5E1BAA06-7828-47BC-89D6-19C2A78EA427}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5E1BAA06-7828-47BC-89D6-19C2A78EA427}.Debug|Any CPU.Build.0 = Debug|Any CPU {5E1BAA06-7828-47BC-89D6-19C2A78EA427}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5E1BAA06-7828-47BC-89D6-19C2A78EA427}.Release|Any CPU.ActiveCfg = Release|Any CPU {5E1BAA06-7828-47BC-89D6-19C2A78EA427}.Release|Any CPU.ActiveCfg = Release|Any CPU

View File

@@ -1,4 +1,4 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> <wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/UnloadedProject/UnloadedProjects/=b4e2ed08_002D4ad3_002D4648_002D8bdb_002D3107200460b9_0023BTCPayServer_002EPlugins_002ELiquidPlus/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Nostr/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary> <s:Boolean x:Key="/Default/UserDictionary/Words/=Nostr/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View File

@@ -1,23 +1,17 @@
#nullable enable #nullable enable
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq; using System.Linq;
using System.Net.Http; using System.Net.Http;
using System.Runtime.ExceptionServices;
using System.Threading; using System.Threading;
using System.Threading.Channels; using System.Threading.Channels;
using System.Threading.Tasks; using System.Threading.Tasks;
using BTCPayServer.HostedServices; using BTCPayServer.HostedServices;
using BTCPayServer.Lightning; using BTCPayServer.Lightning;
using BTCPayServer.Lightning.LndHub;
using GraphQL; using GraphQL;
using GraphQL.Client.Http; using GraphQL.Client.Http;
using GraphQL.Client.Serializer.Newtonsoft; using GraphQL.Client.Serializer.Newtonsoft;
using Microsoft.AspNetCore.OutputCaching;
using NBitcoin; using NBitcoin;
using NBitpayClient;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Network = NBitcoin.Network; using Network = NBitcoin.Network;
@@ -32,18 +26,20 @@ public class BlinkLightningClient : ILightningClient
public string? WalletCurrency { get; set; } public string? WalletCurrency { get; set; }
private readonly Network _network; private readonly Network _network;
private readonly NBXplorerDashboard _nbXplorerDashboard;
private readonly GraphQLHttpClient _client; private readonly GraphQLHttpClient _client;
public BlinkLightningClient(string apiKey, Uri apiEndpoint, string walletId, Network network, public BlinkLightningClient(string apiKey, Uri apiEndpoint, string walletId, Network network, HttpClient httpClient)
NBXplorerDashboard nbXplorerDashboard, HttpClient httpClient)
{ {
_apiKey = apiKey; _apiKey = apiKey;
_apiEndpoint = apiEndpoint; _apiEndpoint = apiEndpoint;
WalletId = walletId; WalletId = walletId;
_network = network; _network = network;
_nbXplorerDashboard = nbXplorerDashboard; _client = new GraphQLHttpClient(new GraphQLHttpClientOptions() {EndPoint = _apiEndpoint, WebSocketEndPoint = new Uri( "wss://" + _apiEndpoint.Host.Replace("api.", "ws.") + _apiEndpoint.PathAndQuery), ConfigureWebsocketOptions =
_client = new GraphQLHttpClient(new GraphQLHttpClientOptions() {EndPoint = _apiEndpoint}, new NewtonsoftJsonSerializer(), httpClient); options =>
{
options.SetRequestHeader("X-API-KEY", apiKey);
}}, new NewtonsoftJsonSerializer(), httpClient);
} }
@@ -301,23 +297,9 @@ query Transactions($walletId: WalletId!) {
public async Task<LightningInvoice> CreateInvoice(CreateInvoiceParams createInvoiceRequest, public async Task<LightningInvoice> CreateInvoice(CreateInvoiceParams createInvoiceRequest,
CancellationToken cancellation = new()) CancellationToken cancellation = new())
{ {
var query = @" string query;
mutation lnInvoiceCreate($input: LnInvoiceCreateOnBehalfOfRecipientInput!) {
lnInvoiceCreateOnBehalfOfRecipient(input: $input) {
invoice {
createdAt
paymentHash
paymentRequest
paymentSecret
paymentStatus
satoshis
}
}
}";
if (WalletCurrency?.Equals("btc", StringComparison.InvariantCultureIgnoreCase) is not true) query = WalletCurrency?.Equals("btc", StringComparison.InvariantCultureIgnoreCase) is not true ? @"
{
query = @"
mutation lnInvoiceCreate($input: LnUsdInvoiceBtcDenominatedCreateOnBehalfOfRecipientInput!) { mutation lnInvoiceCreate($input: LnUsdInvoiceBtcDenominatedCreateOnBehalfOfRecipientInput!) {
lnUsdInvoiceBtcDenominatedCreateOnBehalfOfRecipient(input: $input) { lnUsdInvoiceBtcDenominatedCreateOnBehalfOfRecipient(input: $input) {
invoice { invoice {
@@ -327,10 +309,27 @@ mutation lnInvoiceCreate($input: LnUsdInvoiceBtcDenominatedCreateOnBehalfOfRecip
paymentSecret paymentSecret
paymentStatus paymentStatus
satoshis satoshis
},
errors{
message
}
}
}" : @"
mutation lnInvoiceCreate($input: LnInvoiceCreateOnBehalfOfRecipientInput!) {
lnInvoiceCreateOnBehalfOfRecipient(input: $input) {
invoice {
createdAt
paymentHash
paymentRequest
paymentSecret
paymentStatus
satoshis
},
errors{
message
} }
} }
}"; }";
}
var reques = new GraphQLRequest var reques = new GraphQLRequest
{ {
@@ -350,142 +349,101 @@ expiresIn = (int)createInvoiceRequest.Expiry.TotalMinutes
} }
}; };
var response = await _client.SendQueryAsync<dynamic>(reques, cancellation); var response = await _client.SendQueryAsync<dynamic>(reques, cancellation);
var inv = (WalletCurrency?.Equals("btc", StringComparison.InvariantCultureIgnoreCase) is not true
? response.Data.lnUsdInvoiceBtcDenominatedCreateOnBehalfOfRecipient.invoice
: response.Data.lnInvoiceCreateOnBehalfOfRecipient.invoice)as JObject;
if (inv is null)
{
var errors = (WalletCurrency?.Equals("btc", StringComparison.InvariantCultureIgnoreCase) is not true
? response.Data.lnUsdInvoiceBtcDenominatedCreateOnBehalfOfRecipient.errors
: response.Data.lnInvoiceCreateOnBehalfOfRecipient.errors) as JArray;
return ToInvoice(response.Data.lnInvoiceCreate.invoice); if (errors.Any())
{
throw new Exception(errors.First()["message"].ToString());
}
}
return ToInvoice(inv);
} }
public async Task<ILightningInvoiceListener> Listen(CancellationToken cancellation = new CancellationToken()) public async Task<ILightningInvoiceListener> Listen(CancellationToken cancellation = new CancellationToken())
{ {
return new BlinkListener(this, cancellation); return new BlinkListener(_client, this);
} }
public class BlinkListener : ILightningInvoiceListener public class BlinkListener : ILightningInvoiceListener
{ {
private readonly ILightningClient _client; private readonly BlinkLightningClient _lightningClient;
private readonly Channel<LightningInvoice> _invoices = Channel.CreateUnbounded<LightningInvoice>(); private readonly Channel<LightningInvoice> _invoices = Channel.CreateUnbounded<LightningInvoice>();
private readonly CancellationTokenSource _cts; private readonly IDisposable _subscription;
private HttpClient _httpClient;
private HttpResponseMessage _response;
private Stream _body;
private StreamReader _reader;
private Task _listenLoop;
private readonly List<string> _paidInvoiceIds;
public BlinkListener(ILightningClient client, CancellationToken cancellation) public BlinkListener(GraphQLHttpClient httpClient, BlinkLightningClient lightningClient)
{ {
_cts = CancellationTokenSource.CreateLinkedTokenSource(cancellation); try
_client = client; {
_paidInvoiceIds = new List<string>();
_listenLoop = ListenLoop(); _lightningClient = lightningClient;
var stream = httpClient.CreateSubscriptionStream<dynamic>(new GraphQLRequest()
{
Query = @"subscription myUpdates {
myUpdates {
update {
... on LnUpdate {
transaction {
initiationVia {
... on InitiationViaLn {
paymentHash
}
}
direction
}
}
}
}
}
", OperationName = "myUpdates"
});
_subscription = stream.Subscribe(async response =>
{
try
{
var x = stream;
var y = _lightningClient;
if (response.Data.myUpdates.update.transaction.direction != "RECEIVE")
return;
if ((await _lightningClient.GetInvoice(response.Data.myUpdates.update.transaction.initiationVia
.paymentHash.ToString())) is LightningInvoice inv)
{
_invoices.Writer.TryWrite(inv);
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
});
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
public void Dispose()
{
_subscription.Dispose();
_invoices.Writer.TryComplete();
} }
public async Task<LightningInvoice> WaitInvoice(CancellationToken cancellation) public async Task<LightningInvoice> WaitInvoice(CancellationToken cancellation)
{
try
{ {
return await _invoices.Reader.ReadAsync(cancellation); return await _invoices.Reader.ReadAsync(cancellation);
} }
catch (ChannelClosedException ex) when (ex.InnerException == null)
{
throw new OperationCanceledException();
} }
catch (ChannelClosedException ex) public async Task<(Network Network, string DefaultWalletId, string DefaultWalletCurrency)> GetNetworkAndDefaultWallet(CancellationToken cancellation =default)
{
ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
throw;
}
}
public void Dispose()
{
Dispose(true);
}
static readonly AsyncDuplicateLock _locker = new();
static readonly ConcurrentDictionary<string, LightningInvoice[]> _activeListeners = new();
private async Task ListenLoop()
{
try
{
var releaser = await _locker.LockOrBustAsync(_client.ToString(), _cts.Token);
if (releaser is null)
{
while (!_cts.IsCancellationRequested && releaser is null)
{
if (_activeListeners.TryGetValue(_client.ToString(), out var invoicesData))
{
await HandleInvoicesData(invoicesData);
}
releaser = await _locker.LockOrBustAsync(_client.ToString(), _cts.Token);
if (releaser is null)
await Task.Delay(2500, _cts.Token);
}
}
using (releaser)
{
while (!_cts.IsCancellationRequested)
{
var invoicesData = await _client.ListInvoices(_cts.Token);
_activeListeners.AddOrReplace(_client.ToString(), invoicesData);
await HandleInvoicesData(invoicesData);
await Task.Delay(2500, _cts.Token);
}
}
}
catch when (_cts.IsCancellationRequested)
{
}
catch (Exception ex)
{
_invoices.Writer.TryComplete(ex);
}
finally
{
_activeListeners.TryRemove(_client.ToString(), out _);
Dispose(false);
}
}
private async Task HandleInvoicesData(IEnumerable<LightningInvoice> invoicesData)
{
foreach (var data in invoicesData)
{
var invoice = data;
if (invoice.PaidAt != null && !_paidInvoiceIds.Contains(invoice.Id))
{
await _invoices.Writer.WriteAsync(invoice, _cts.Token);
_paidInvoiceIds.Add(invoice.Id);
}
}
}
private void Dispose(bool waitLoop)
{
if (_cts.IsCancellationRequested)
return;
_cts.Cancel();
_reader?.Dispose();
_reader = null;
_body?.Dispose();
_body = null;
_response?.Dispose();
_response = null;
_httpClient?.Dispose();
_httpClient = null;
if (waitLoop)
_listenLoop?.Wait();
_invoices.Writer.TryComplete();
}
}
public async Task<(Network Network, string DefaultWalletId)> GetNetworkAndDefaultWallet(CancellationToken cancellation =default)
{ {
var reques = new GraphQLRequest var reques = new GraphQLRequest
@@ -497,7 +455,10 @@ query GetNetworkAndDefaultWallet {
} }
me { me {
defaultAccount { defaultAccount {
defaultWalletId defaultWallet{
id
currency
}
} }
} }
}", }",
@@ -506,7 +467,8 @@ query GetNetworkAndDefaultWallet {
var response = await _client.SendQueryAsync<dynamic>(reques, cancellation); var response = await _client.SendQueryAsync<dynamic>(reques, cancellation);
var defaultWalletId = (string) response.Data.me.defaultAccount.defaultWalletId; var defaultWalletId = (string) response.Data.me.defaultAccount.defaultWallet.id;
var defaultWalletCurrency = (string) response.Data.me.defaultAccount.defaultWallet.currency;
var network = response.Data.globals.network.ToString() switch var network = response.Data.globals.network.ToString() switch
{ {
"mainnet" => Network.Main, "mainnet" => Network.Main,
@@ -514,31 +476,13 @@ query GetNetworkAndDefaultWallet {
"regtest" => Network.RegTest, "regtest" => Network.RegTest,
_ => throw new ArgumentOutOfRangeException() _ => throw new ArgumentOutOfRangeException()
}; };
return (network, defaultWalletId); return (network, defaultWalletId, defaultWalletCurrency);
} }
public async Task<LightningNodeInformation> GetInfo(CancellationToken cancellation = new CancellationToken()) public Task<LightningNodeInformation> GetInfo(CancellationToken cancellation = new CancellationToken())
{ {
var reques = new GraphQLRequest throw new NotSupportedException();
{
Query = @"
query Globals {
globals {
nodesIds
}
}",
OperationName = "Globals"
};
var response = await _client.SendQueryAsync<dynamic>(reques, cancellation);
var result = new LightningNodeInformation()
{
BlockHeight = _nbXplorerDashboard.Get("BTC").Status.ChainHeight,
Alias = "Blink",
};
result.NodeInfoList.AddRange(((JArray)response.Data.globals.nodesIds).Select(s => new NodeInfo(new PubKey(s.Value<string>()), "galoy.com", 69)));
return result;
} }
public async Task<LightningNodeBalance> GetBalance(CancellationToken cancellation = new()) public async Task<LightningNodeBalance> GetBalance(CancellationToken cancellation = new())

View File

@@ -2,7 +2,6 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Net.Http; using System.Net.Http;
using BTCPayServer.HostedServices;
using BTCPayServer.Lightning; using BTCPayServer.Lightning;
using Network = NBitcoin.Network; using Network = NBitcoin.Network;
@@ -11,13 +10,10 @@ namespace BTCPayServer.Plugins.Blink;
public class BlinkLightningConnectionStringHandler : ILightningConnectionStringHandler public class BlinkLightningConnectionStringHandler : ILightningConnectionStringHandler
{ {
private readonly IHttpClientFactory _httpClientFactory; private readonly IHttpClientFactory _httpClientFactory;
private readonly NBXplorerDashboard _nbXplorerDashboard;
public BlinkLightningConnectionStringHandler(IHttpClientFactory httpClientFactory, public BlinkLightningConnectionStringHandler(IHttpClientFactory httpClientFactory)
NBXplorerDashboard nbXplorerDashboard)
{ {
_httpClientFactory = httpClientFactory; _httpClientFactory = httpClientFactory;
_nbXplorerDashboard = nbXplorerDashboard;
} }
@@ -32,8 +28,9 @@ public class BlinkLightningConnectionStringHandler : ILightningConnectionStringH
if (!kv.TryGetValue("server", out var server)) if (!kv.TryGetValue("server", out var server))
{ {
error = $"The key 'server' is mandatory for blink connection strings"; server = "https://api.blink.sv/graphql";
return null; // error = $"The key 'server' is mandatory for blink connection strings";
// return null;
} }
if (!Uri.TryCreate(server, UriKind.Absolute, out var uri) if (!Uri.TryCreate(server, UriKind.Absolute, out var uri)
@@ -77,8 +74,8 @@ public class BlinkLightningConnectionStringHandler : ILightningConnectionStringH
client.BaseAddress = uri; client.BaseAddress = uri;
kv.TryGetValue("wallet-id", out var walletId); kv.TryGetValue("wallet-id", out var walletId);
var bclient = new BlinkLightningClient(apiKey, uri, walletId, network, _nbXplorerDashboard, client); var bclient = new BlinkLightningClient(apiKey, uri, walletId, network, client);
(Network Network, string DefaultWalletId) res; (Network Network, string DefaultWalletId, string DefaultWalletCurrency) res;
try try
{ {
res = bclient.GetNetworkAndDefaultWallet().GetAwaiter().GetResult(); res = bclient.GetNetworkAndDefaultWallet().GetAwaiter().GetResult();
@@ -103,6 +100,7 @@ public class BlinkLightningConnectionStringHandler : ILightningConnectionStringH
if (walletId is null) if (walletId is null)
{ {
bclient.WalletId = res.DefaultWalletId; bclient.WalletId = res.DefaultWalletId;
bclient.WalletCurrency = res.DefaultWalletCurrency;
} }
else else
{ {

View File

@@ -32,7 +32,7 @@
<code><b>type=</b>blink;<b>server=</b>https://api.blink.sv/graphql;<b>api-key</b>=blink_...;<b>wallet-id=</b>xyz</code> <code><b>type=</b>blink;<b>server=</b>https://api.blink.sv/graphql;<b>api-key</b>=blink_...;<b>wallet-id=</b>xyz</code>
</li> </li>
</ul> </ul>
<p class="my-2">Head over to the Blink dashboard and create an api key. The wallet-id is optional and will use the default wallet otherwise.</p> <p class="my-2">Head over to the <a href="https://dashboard.blink.sv" target="_blank" rel="noreferrer noopener" >Blink dashboard</a> and create an api key. The server is optional and will use the default Blink instance.The wallet-id is optional and will use the default wallet otherwise.</p>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -5,6 +5,7 @@
<LangVersion>10</LangVersion> <LangVersion>10</LangVersion>
<Configurations>Debug;Release;Altcoins-Debug;Altcoins-Release</Configurations> <Configurations>Debug;Release;Altcoins-Debug;Altcoins-Release</Configurations>
<Platforms>AnyCPU</Platforms> <Platforms>AnyCPU</Platforms>
<DefineConstants>$(DefineConstants);ALTCOINS</DefineConstants>
</PropertyGroup> </PropertyGroup>
<!-- Plugin specific properties --> <!-- Plugin specific properties -->
@@ -31,18 +32,6 @@
</ProjectReference> </ProjectReference>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<Altcoins>true</Altcoins>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<Altcoins>true</Altcoins>
</PropertyGroup>
<PropertyGroup Condition="'$(Altcoins)' == 'true'">
<DefineConstants>$(DefineConstants);ALTCOINS</DefineConstants>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Resources\**" /> <EmbeddedResource Include="Resources\**" />
<ProjectReference Include="..\..\submodules\btcpayserver\BTCPayServer\BTCPayServer.csproj"> <ProjectReference Include="..\..\submodules\btcpayserver\BTCPayServer\BTCPayServer.csproj">

View File

@@ -10,6 +10,7 @@ using BTCPayServer.Abstractions.Extensions;
using BTCPayServer.Abstractions.Models; using BTCPayServer.Abstractions.Models;
using BTCPayServer.Client; using BTCPayServer.Client;
using BTCPayServer.Common; using BTCPayServer.Common;
using BTCPayServer.Plugins.Altcoins;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.AspNetCore.Mvc.ViewFeatures;

View File

@@ -1,14 +1,20 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
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.Configuration;
using BTCPayServer.Hosting;
using BTCPayServer.Payments;
using BTCPayServer.Plugins.Altcoins;
using BTCPayServer.Plugins.LiquidPlus.Services; using BTCPayServer.Plugins.LiquidPlus.Services;
using BTCPayServer.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options;
using NBitcoin; using NBitcoin;
using NBXplorer;
namespace BTCPayServer.Plugins.LiquidPlus namespace BTCPayServer.Plugins.LiquidPlus
{ {
@@ -16,35 +22,53 @@ namespace BTCPayServer.Plugins.LiquidPlus
{ {
public override IBTCPayServerPlugin.PluginDependency[] Dependencies { get; } = public override IBTCPayServerPlugin.PluginDependency[] Dependencies { get; } =
{ {
new() { Identifier = nameof(BTCPayServer), Condition = ">=1.12.0" } new() {Identifier = nameof(BTCPayServer), Condition = ">=1.12.0"}
}; };
public override void Execute(IServiceCollection services)
public override void Execute(IServiceCollection applicationBuilder)
{ {
var services = (PluginServiceCollection) applicationBuilder;
if (services.BootstrapServices.GetRequiredService<NBXplorerNetworkProvider>()
.GetFromCryptoCode("LBTC") is null || !services.BootstrapServices.GetRequiredService<SelectedChains>().Contains("LBTC"))
return;
services.AddSingleton<IUIExtension>(new UIExtension("LiquidNav", "store-integrations-nav")); services.AddSingleton<IUIExtension>(new UIExtension("LiquidNav", "store-integrations-nav"));
services.AddSingleton<IUIExtension>(new UIExtension("OnChainWalletSetupLiquidExtension", "onchain-wallet-setup-post-body")); services.AddSingleton<IUIExtension>(new UIExtension("OnChainWalletSetupLiquidExtension",
"onchain-wallet-setup-post-body"));
services.AddSingleton<IUIExtension>(new UIExtension("CustomLiquidAssetsNavExtension", "server-nav")); services.AddSingleton<IUIExtension>(new UIExtension("CustomLiquidAssetsNavExtension", "server-nav"));
services.AddSingleton<IUIExtension>(new UIExtension("StoreNavLiquidExtension", "store-nav")); services.AddSingleton<IUIExtension>(new UIExtension("StoreNavLiquidExtension", "store-nav"));
services.AddSingleton<CustomLiquidAssetsRepository>(); services.AddSingleton<CustomLiquidAssetsRepository>();
var originalImplementationFactory = services.Single(descriptor =>
descriptor.Lifetime == ServiceLifetime.Singleton && var config = services.BootstrapServices.GetRequiredService<IConfiguration>();
descriptor.ServiceType == typeof(BTCPayNetworkProvider)); DataDirectories dataDirectories = new DataDirectories();
services.Replace(ServiceDescriptor.Singleton(provider => dataDirectories.Configure(config);
var repo = new CustomLiquidAssetsRepository(new NullLogger<CustomLiquidAssetsRepository>(),
new OptionsWrapper<DataDirectories>(dataDirectories));
var settings = repo.Get();
var template = (ElementsBTCPayNetwork) services.Single(descriptor =>
descriptor.ServiceType == typeof(BTCPayNetworkBase) &&
descriptor.ImplementationInstance is ElementsBTCPayNetwork
{ {
var _customLiquidAssetsRepository = provider.GetService<CustomLiquidAssetsRepository>(); CryptoCode: "LBTC"
var _logger = provider.GetService<ILogger<LiquidPlusPlugin>>(); })
var networkProvider = .ImplementationInstance;
(originalImplementationFactory.ImplementationInstance ?? var tlProvider = (TransactionLinkProviders.Entry) services.Single(descriptor =>
originalImplementationFactory.ImplementationFactory.Invoke(provider)) as BTCPayNetworkProvider; descriptor.ServiceType == typeof(TransactionLinkProviders.Entry) &&
if (networkProvider.Support("LBTC")) descriptor.ImplementationInstance is TransactionLinkProviders.Entry
{ {
var settings = _customLiquidAssetsRepository.Get(); PaymentMethodId: {CryptoCode: "LBTC"}
var template = networkProvider.GetNetwork<ElementsBTCPayNetwork>("LBTC"); })
var additionalNetworks = settings.Items.Select(configuration => new ElementsBTCPayNetwork() .ImplementationInstance;
settings.Items.ForEach(configuration =>
{ {
CryptoCode = configuration.CryptoCode var code = configuration.CryptoCode
.Replace("-", "") .Replace("-", "")
.Replace("_", ""), .Replace("_", "");
services.AddBTCPayNetwork(new ElementsBTCPayNetwork()
{
CryptoCode = code,
DefaultRateRules = configuration.DefaultRateRules ?? Array.Empty<string>(), DefaultRateRules = configuration.DefaultRateRules ?? Array.Empty<string>(),
AssetId = uint256.Parse(configuration.AssetId), AssetId = uint256.Parse(configuration.AssetId),
Divisibility = configuration.Divisibility, Divisibility = configuration.Divisibility,
@@ -64,30 +88,9 @@ namespace BTCPayServer.Plugins.LiquidPlus
CoinType = template.CoinType, CoinType = template.CoinType,
VaultSupported = template.VaultSupported, VaultSupported = template.VaultSupported,
MaxTrackedConfirmation = template.MaxTrackedConfirmation, MaxTrackedConfirmation = template.MaxTrackedConfirmation,
BlockExplorerLinkDefault = template.BlockExplorerLinkDefault,
SupportRBF = template.SupportRBF SupportRBF = template.SupportRBF
}).AddTransactionLinkProvider(new PaymentMethodId(code, PaymentTypes.BTCLike), tlProvider.Provider);
}); });
var newCryptoCodes = settings.Items.Select(configuration => configuration.CryptoCode).ToArray();
_logger.LogInformation($"Loaded {newCryptoCodes.Length} " +
$"{(!newCryptoCodes.Any()?string.Empty: $"({string.Join(',', newCryptoCodes)})")} additional liquid assets");
var newSupportedChains = networkProvider.GetAll().Select(b => b.CryptoCode).Concat(newCryptoCodes).ToArray();
return new BTCPayNetworkProviderOverride(networkProvider.NetworkType, additionalNetworks).Filter(newSupportedChains);
}
return networkProvider;
}));
}
}
public class BTCPayNetworkProviderOverride : BTCPayNetworkProvider
{
public BTCPayNetworkProviderOverride(ChainName networkType,
IEnumerable<ElementsBTCPayNetwork> elementsBTCPayNetworks) : base(networkType)
{
foreach (ElementsBTCPayNetwork elementsBTCPayNetwork in elementsBTCPayNetworks)
{
_Networks.TryAdd(elementsBTCPayNetwork.CryptoCode.ToUpperInvariant(), elementsBTCPayNetwork);
}
} }
} }
} }

View File

@@ -1,6 +1,9 @@
@using BTCPayServer @using BTCPayServer
@using BTCPayServer.Abstractions.Contracts @using BTCPayServer.Abstractions.Contracts
@using BTCPayServer.Client
@using BTCPayServer.Plugins.Altcoins
@using BTCPayServer.Plugins.LiquidPlus.Controllers @using BTCPayServer.Plugins.LiquidPlus.Controllers
@using Microsoft.AspNetCore.Mvc.TagHelpers
@using Microsoft.AspNetCore.Routing @using Microsoft.AspNetCore.Routing
@inject BTCPayNetworkProvider BTCPayNetworkProvider; @inject BTCPayNetworkProvider BTCPayNetworkProvider;
@@ -13,7 +16,7 @@
} }
@if (!string.IsNullOrEmpty(storeId) && (BTCPayNetworkProvider.GetAll().OfType<ElementsBTCPayNetwork>().Any())) @if (!string.IsNullOrEmpty(storeId) && (BTCPayNetworkProvider.GetAll().OfType<ElementsBTCPayNetwork>().Any()))
{ {
<li class="nav-item"> <li class="nav-item" permission="@Policies.CanModifyStoreSettings">
<a asp-route-storeId="@storeId" asp-action="GenerateLiquidScript" asp-controller="StoreLiquid" class="nav-link js-scroll-trigger @(isActive ? "active" : string.Empty)"> <a asp-route-storeId="@storeId" asp-action="GenerateLiquidScript" asp-controller="StoreLiquid" class="nav-link js-scroll-trigger @(isActive ? "active" : string.Empty)">
<svg role="img" class="icon"> <svg role="img" class="icon">
</svg> </svg>

View File

@@ -2,6 +2,7 @@
@using BTCPayServer @using BTCPayServer
@using BTCPayServer.Abstractions.TagHelpers @using BTCPayServer.Abstractions.TagHelpers
@using BTCPayServer.Models.StoreViewModels @using BTCPayServer.Models.StoreViewModels
@using BTCPayServer.Plugins.Altcoins
@using NBitcoin @using NBitcoin
@using NBitcoin.Altcoins.Elements @using NBitcoin.Altcoins.Elements
@model dynamic @model dynamic

View File

@@ -1,6 +1,8 @@
@using BTCPayServer @using BTCPayServer
@using BTCPayServer.Abstractions.Contracts @using BTCPayServer.Abstractions.Contracts
@using BTCPayServer.Plugins.Altcoins
@using BTCPayServer.Plugins.LiquidPlus.Controllers @using BTCPayServer.Plugins.LiquidPlus.Controllers
@using Microsoft.AspNetCore.Mvc.TagHelpers
@using Microsoft.AspNetCore.Routing @using Microsoft.AspNetCore.Routing
@inject BTCPayNetworkProvider BTCPayNetworkProvider; @inject BTCPayNetworkProvider BTCPayNetworkProvider;
@inject IScopeProvider ScopeProvider @inject IScopeProvider ScopeProvider

View File

@@ -11,7 +11,7 @@
<PropertyGroup> <PropertyGroup>
<Product>Prism</Product> <Product>Prism</Product>
<Description>Automated value splits for Bitcoin.</Description> <Description>Automated value splits for Bitcoin.</Description>
<Version>1.2.1</Version> <Version>1.2.2</Version>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup> </PropertyGroup>
<!-- Plugin development properties --> <!-- Plugin development properties -->

View File

@@ -1,5 +1,4 @@
@using BTCPayServer.Abstractions.TagHelpers @using BTCPayServer.Abstractions.Extensions
@using BTCPayServer.Abstractions.Extensions
@using BTCPayServer.Components.UIExtensionPoint @using BTCPayServer.Components.UIExtensionPoint
@using BTCPayServer.Plugins.Prism.Components @using BTCPayServer.Plugins.Prism.Components
@using BTCPayServer.Abstractions.Contracts @using BTCPayServer.Abstractions.Contracts
@@ -15,6 +14,4 @@
{ {
StoreId = ScopeProvider.GetCurrentStoreId(), StoreId = ScopeProvider.GetCurrentStoreId(),
})) }))
<script src="_framework/blazor.server.js"></script>
<vc:ui-extension-point location="prism-edit" model="@Model"></vc:ui-extension-point> <vc:ui-extension-point location="prism-edit" model="@Model"></vc:ui-extension-point>