mirror of
https://github.com/aljazceru/BTCPayServerPlugins.git
synced 2025-12-18 08:04:26 +01:00
fixes
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -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
|
||||||
return ToInvoice(response.Data.lnInvoiceCreate.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;
|
||||||
|
|
||||||
|
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)
|
|
||||||
{
|
|
||||||
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, string DefaultWalletCurrency)> GetNetworkAndDefaultWallet(CancellationToken cancellation =default)
|
||||||
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())
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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,78 +22,75 @@ 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 _customLiquidAssetsRepository = provider.GetService<CustomLiquidAssetsRepository>();
|
var repo = new CustomLiquidAssetsRepository(new NullLogger<CustomLiquidAssetsRepository>(),
|
||||||
var _logger = provider.GetService<ILogger<LiquidPlusPlugin>>();
|
new OptionsWrapper<DataDirectories>(dataDirectories));
|
||||||
var networkProvider =
|
var settings = repo.Get();
|
||||||
(originalImplementationFactory.ImplementationInstance ??
|
var template = (ElementsBTCPayNetwork) services.Single(descriptor =>
|
||||||
originalImplementationFactory.ImplementationFactory.Invoke(provider)) as BTCPayNetworkProvider;
|
descriptor.ServiceType == typeof(BTCPayNetworkBase) &&
|
||||||
if (networkProvider.Support("LBTC"))
|
descriptor.ImplementationInstance is ElementsBTCPayNetwork
|
||||||
{
|
|
||||||
var settings = _customLiquidAssetsRepository.Get();
|
|
||||||
var template = networkProvider.GetNetwork<ElementsBTCPayNetwork>("LBTC");
|
|
||||||
var additionalNetworks = settings.Items.Select(configuration => new ElementsBTCPayNetwork()
|
|
||||||
{
|
{
|
||||||
CryptoCode = configuration.CryptoCode
|
CryptoCode: "LBTC"
|
||||||
.Replace("-", "")
|
})
|
||||||
.Replace("_", ""),
|
.ImplementationInstance;
|
||||||
DefaultRateRules = configuration.DefaultRateRules ?? Array.Empty<string>(),
|
var tlProvider = (TransactionLinkProviders.Entry) services.Single(descriptor =>
|
||||||
AssetId = uint256.Parse(configuration.AssetId),
|
descriptor.ServiceType == typeof(TransactionLinkProviders.Entry) &&
|
||||||
Divisibility = configuration.Divisibility,
|
descriptor.ImplementationInstance is TransactionLinkProviders.Entry
|
||||||
DisplayName = configuration.DisplayName,
|
{
|
||||||
CryptoImagePath = configuration.CryptoImagePath,
|
PaymentMethodId: {CryptoCode: "LBTC"}
|
||||||
NetworkCryptoCode = template.NetworkCryptoCode,
|
})
|
||||||
DefaultSettings = template.DefaultSettings,
|
.ImplementationInstance;
|
||||||
ElectrumMapping = template.ElectrumMapping,
|
settings.Items.ForEach(configuration =>
|
||||||
BlockExplorerLink = template.BlockExplorerLink,
|
|
||||||
ReadonlyWallet = template.ReadonlyWallet,
|
|
||||||
SupportLightning = false,
|
|
||||||
SupportPayJoin = false,
|
|
||||||
ShowSyncSummary = false,
|
|
||||||
WalletSupported = template.WalletSupported,
|
|
||||||
LightningImagePath = "",
|
|
||||||
NBXplorerNetwork = template.NBXplorerNetwork,
|
|
||||||
CoinType = template.CoinType,
|
|
||||||
VaultSupported = template.VaultSupported,
|
|
||||||
MaxTrackedConfirmation = template.MaxTrackedConfirmation,
|
|
||||||
BlockExplorerLinkDefault = template.BlockExplorerLinkDefault,
|
|
||||||
SupportRBF = template.SupportRBF
|
|
||||||
});
|
|
||||||
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);
|
var code = configuration.CryptoCode
|
||||||
}
|
.Replace("-", "")
|
||||||
|
.Replace("_", "");
|
||||||
|
services.AddBTCPayNetwork(new ElementsBTCPayNetwork()
|
||||||
|
{
|
||||||
|
CryptoCode = code,
|
||||||
|
DefaultRateRules = configuration.DefaultRateRules ?? Array.Empty<string>(),
|
||||||
|
AssetId = uint256.Parse(configuration.AssetId),
|
||||||
|
Divisibility = configuration.Divisibility,
|
||||||
|
DisplayName = configuration.DisplayName,
|
||||||
|
CryptoImagePath = configuration.CryptoImagePath,
|
||||||
|
NetworkCryptoCode = template.NetworkCryptoCode,
|
||||||
|
DefaultSettings = template.DefaultSettings,
|
||||||
|
ElectrumMapping = template.ElectrumMapping,
|
||||||
|
BlockExplorerLink = template.BlockExplorerLink,
|
||||||
|
ReadonlyWallet = template.ReadonlyWallet,
|
||||||
|
SupportLightning = false,
|
||||||
|
SupportPayJoin = false,
|
||||||
|
ShowSyncSummary = false,
|
||||||
|
WalletSupported = template.WalletSupported,
|
||||||
|
LightningImagePath = "",
|
||||||
|
NBXplorerNetwork = template.NBXplorerNetwork,
|
||||||
|
CoinType = template.CoinType,
|
||||||
|
VaultSupported = template.VaultSupported,
|
||||||
|
MaxTrackedConfirmation = template.MaxTrackedConfirmation,
|
||||||
|
SupportRBF = template.SupportRBF
|
||||||
|
}).AddTransactionLinkProvider(new PaymentMethodId(code, PaymentTypes.BTCLike), tlProvider.Provider);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 -->
|
||||||
|
|||||||
@@ -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>
|
||||||
Submodule submodules/btcpayserver updated: 3f344f2c0c...cb54f8f6d1
Reference in New Issue
Block a user