diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
index f025bc0..403be6a 100644
--- a/.github/workflows/dotnet.yml
+++ b/.github/workflows/dotnet.yml
@@ -31,7 +31,7 @@ jobs:
run: dotnet clean
- name: Build projects
- run: dotnet build -c Release --no-restore
+ run: dotnet build -maxcpucount:1 -c Release --no-restore
- name: Deterministic build check
run: |
diff --git a/BTCPayServer.Plugins.IntegrationTests/BTCPayServer.Plugins.IntegrationTests.csproj b/BTCPayServer.Plugins.IntegrationTests/BTCPayServer.Plugins.IntegrationTests.csproj
index 5487a18..b0e1029 100644
--- a/BTCPayServer.Plugins.IntegrationTests/BTCPayServer.Plugins.IntegrationTests.csproj
+++ b/BTCPayServer.Plugins.IntegrationTests/BTCPayServer.Plugins.IntegrationTests.csproj
@@ -8,9 +8,10 @@
-
-
-
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -26,8 +27,8 @@
-
-
+
+
diff --git a/BTCPayServer.Plugins.IntegrationTests/Monero/MoneroPluginIntegrationTest.cs b/BTCPayServer.Plugins.IntegrationTests/Monero/MoneroPluginIntegrationTest.cs
index 670e03b..ae2aec3 100644
--- a/BTCPayServer.Plugins.IntegrationTests/Monero/MoneroPluginIntegrationTest.cs
+++ b/BTCPayServer.Plugins.IntegrationTests/Monero/MoneroPluginIntegrationTest.cs
@@ -1,5 +1,9 @@
+using System.Diagnostics;
+
+using BTCPayServer.Plugins.Monero.Services;
using BTCPayServer.Rating;
using BTCPayServer.Services.Rates;
+using BTCPayServer.Tests;
using BTCPayServer.Tests.Mocks;
using Xunit;
@@ -36,20 +40,25 @@ public class MoneroPluginIntegrationTest(ITestOutputHelper helper) : MoneroAndBi
await s.RegisterNewUser(true);
await s.CreateNewStore(preferredExchange: "Kraken");
await s.Page.Locator("a.nav-link[href*='monerolike/XMR']").ClickAsync();
- await s.Page.Locator("input#PrimaryAddress").FillAsync("43Pnj6ZKGFTJhaLhiecSFfLfr64KPJZw7MyGH73T6PTDekBBvsTAaWEUSM4bmJqDuYLizhA13jQkMRPpz9VXBCBqQQb6y5L");
- await s.Page.Locator("input#PrivateViewKey").FillAsync("1bfa03b0c78aa6bc8292cf160ec9875657d61e889c41d0ebe5c54fd3a2c4b40e");
+ await s.Page.Locator("input#PrimaryAddress")
+ .FillAsync(
+ "43Pnj6ZKGFTJhaLhiecSFfLfr64KPJZw7MyGH73T6PTDekBBvsTAaWEUSM4bmJqDuYLizhA13jQkMRPpz9VXBCBqQQb6y5L");
+ await s.Page.Locator("input#PrivateViewKey")
+ .FillAsync("1bfa03b0c78aa6bc8292cf160ec9875657d61e889c41d0ebe5c54fd3a2c4b40e");
await s.Page.Locator("input#RestoreHeight").FillAsync("0");
await s.Page.Locator("input#WalletPassword").FillAsync("pass123");
await s.Page.ClickAsync("button[name='command'][value='set-wallet-details']");
await s.Page.CheckAsync("#Enabled");
await s.Page.SelectOptionAsync("#SettlementConfirmationThresholdChoice", "2");
await s.Page.ClickAsync("#SaveButton");
- var classList = await s.Page.Locator("svg.icon-checkmark").GetAttributeAsync("class");
+ var classList = await s.Page
+ .Locator("svg.icon-checkmark")
+ .GetAttributeAsync("class");
Assert.Contains("text-success", classList);
// Set rate provider
- await s.Page.Locator("#StoreNav-General").ClickAsync();
- await s.Page.Locator("#mainNav #StoreNav-Rates").ClickAsync();
+ await s.Page.Locator("#menu-item-General").ClickAsync();
+ await s.Page.Locator("#menu-item-Rates").ClickAsync();
await s.Page.FillAsync("#DefaultCurrencyPairs", "BTC_USD,XMR_USD,XMR_BTC");
await s.Page.SelectOptionAsync("#PrimarySource_PreferredExchange", "kraken");
await s.Page.Locator("#page-primary").ClickAsync();
@@ -69,7 +78,9 @@ public class MoneroPluginIntegrationTest(ITestOutputHelper helper) : MoneroAndBi
await s.Page.ClickAsync("#DetailsToggle");
// Verify the total fiat amount is $4.20
- var totalFiat = await s.Page.Locator("#PaymentDetails-TotalFiat dd.clipboard-button").InnerTextAsync();
+ var totalFiat = await s.Page
+ .Locator("#PaymentDetails-TotalFiat dd.clipboard-button")
+ .InnerTextAsync();
Assert.Equal("$4.20", totalFiat);
await s.Page.GoBackAsync();
@@ -92,5 +103,90 @@ public class MoneroPluginIntegrationTest(ITestOutputHelper helper) : MoneroAndBi
// Select confirmation time to 0
await s.Page.SelectOptionAsync("#SettlementConfirmationThresholdChoice", "3");
await s.Page.ClickAsync("#SaveButton");
+
+ await CleanUp(s);
+ }
+
+ [Fact]
+ public async Task ShouldFailWhenWrongPrimaryAddress()
+ {
+ await using var s = CreatePlaywrightTester();
+ await s.StartAsync();
+
+ await s.RegisterNewUser(true);
+ await s.CreateNewStore();
+ await s.Page.Locator("a.nav-link[href*='monerolike/XMR']").ClickAsync();
+ await s.Page.Locator("input#PrimaryAddress")
+ .FillAsync("wrongprimaryaddressfSF6ZKGFT7MyGH73T6PTDekBBvsTAaWEUSM4bmJqDuYLizhA13jQkMRPpz9VXBCBqQQb6y5L");
+ await s.Page.Locator("input#PrivateViewKey")
+ .FillAsync("1bfa03b0c78aa6bc8292cf160ec9875657d61e889c41d0ebe5c54fd3a2c4b40e");
+ await s.Page.Locator("input#RestoreHeight").FillAsync("0");
+ await s.Page.Locator("input#WalletPassword").FillAsync("pass123");
+ await s.Page.ClickAsync("button[name='command'][value='set-wallet-details']");
+ var errorText = await s.Page
+ .Locator("div.validation-summary-errors li")
+ .InnerTextAsync();
+
+ Assert.Equal("Could not generate view wallet from keys: Failed to parse public address", errorText);
+
+ await CleanUp(s);
+ }
+
+ private static async Task CleanUp(PlaywrightTester playwrightTester)
+ {
+ MoneroRPCProvider moneroRpcProvider = playwrightTester.Server.PayTester.GetService();
+ if (moneroRpcProvider.IsAvailable("XMR"))
+ {
+ await moneroRpcProvider.CloseWallet("XMR");
+ await moneroRpcProvider.UpdateSummary("XMR");
+ }
+
+ if (playwrightTester.Server.PayTester.InContainer)
+ {
+ moneroRpcProvider.DeleteWallet();
+ }
+ else
+ {
+ await RemoveWalletFromLocalDocker();
+ }
+ }
+
+ static async Task RemoveWalletFromLocalDocker()
+ {
+ try
+ {
+ var removeWalletFromDocker = new ProcessStartInfo
+ {
+ FileName = "docker",
+ Arguments = "exec xmr_wallet sh -c \"rm -rf /wallet/*\"",
+ RedirectStandardOutput = true,
+ RedirectStandardError = true
+ };
+
+ using var process = Process.Start(removeWalletFromDocker);
+ if (process is null)
+ {
+ return;
+ }
+
+ var stdout = await process.StandardOutput.ReadToEndAsync();
+ var stderr = await process.StandardError.ReadToEndAsync();
+
+ await process.WaitForExitAsync();
+
+ if (!string.IsNullOrWhiteSpace(stdout))
+ {
+ Console.WriteLine(stdout);
+ }
+
+ if (!string.IsNullOrWhiteSpace(stderr))
+ {
+ Console.WriteLine(stderr);
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"Cleanup failed: {ex}");
+ }
}
}
\ No newline at end of file
diff --git a/BTCPayServer.Plugins.IntegrationTests/docker-compose.yml b/BTCPayServer.Plugins.IntegrationTests/docker-compose.yml
index 64e1d79..cc69d76 100644
--- a/BTCPayServer.Plugins.IntegrationTests/docker-compose.yml
+++ b/BTCPayServer.Plugins.IntegrationTests/docker-compose.yml
@@ -22,6 +22,7 @@ services:
- "tests:127.0.0.1"
volumes:
- ../coverage:/coverage
+ - xmr_wallet:/wallet
# The dev container is not used, it is just handy to run `docker-compose up dev` to start all services
dev:
@@ -89,7 +90,7 @@ services:
- "bitcoin_datadir:/data"
monerod:
- image: btcpayserver/monero:0.18.4.2
+ image: btcpayserver/monero:0.18.4.3
restart: unless-stopped
container_name: monerod
command: monerod --fixed-difficulty 1 --log-level=2 --rpc-bind-ip=0.0.0.0 --confirm-external-bind --rpc-bind-port=18081 --block-notify="/bin/sh ./scripts/notifier.sh -k -X GET https://host.docker.internal:14142/monerolikedaemoncallback/block?cryptoCode=xmr&hash=%s" --regtest --no-igd --hide-my-port --offline --non-interactive
@@ -99,7 +100,7 @@ services:
- "18081:18081"
xmr_wallet:
- image: btcpayserver/monero:0.18.4.2
+ image: btcpayserver/monero:0.18.4.3
restart: unless-stopped
container_name: xmr_wallet
command: monero-wallet-rpc --log-level 2 --allow-mismatched-daemon-version --rpc-bind-ip=0.0.0.0 --disable-rpc-login --confirm-external-bind --rpc-bind-port=18082 --non-interactive --trusted-daemon --daemon-address=monerod:18081 --wallet-dir=/wallet --tx-notify="/bin/sh ./scripts/notifier.sh -k -X GET https://host.docker.internal:14142/monerolikedaemoncallback/tx?cryptoCode=xmr&hash=%s"
diff --git a/Plugins/Monero/BTCPayServer.Plugins.Monero.csproj b/Plugins/Monero/BTCPayServer.Plugins.Monero.csproj
index 3287596..4a848b8 100644
--- a/Plugins/Monero/BTCPayServer.Plugins.Monero.csproj
+++ b/Plugins/Monero/BTCPayServer.Plugins.Monero.csproj
@@ -39,10 +39,7 @@
-
-
-