btcpayserver / btcTransmuter

A self-hosted ,modular IFTTT-inspired system for bitcoin services written in C#
https://btcpayserver.org
77 stars 22 forks source link

Pairing does not work #96

Closed yapishu closed 2 years ago

yapishu commented 2 years ago

Hello,

I've run into an issue setting up Transmuter with my instance. Everything else seems to be working fine, but when I try to pair it, I get an error about it not being able to establish a connection.

I am using the Docker setup, following the instructions from the primary documentation. I haven't done anything unusual, except that my BTCPay server subdomain is served with https via a reverse proxy on the edge of my network, and https is disabled on the docker instance itself. Not sure if that's relevant, but it's the only place I really diverged from an otherwise vanilla setup.

An unhandled exception occurred while processing the request.
BitPayException: Error: System.Net.Http.HttpRequestException: Connection refused
---> System.Net.Sockets.SocketException (111): Connection refused
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at NBitpayClient.Bitpay.PostAsync(String path, String json, Boolean signatureRequired)
NBitpayClient.Bitpay.PostAsync(string path, string json, bool signatureRequired)

Stack Query Cookies Headers Routing
BitPayException: Error: System.Net.Http.HttpRequestException: Connection refused ---> System.Net.Sockets.SocketException (111): Connection refused at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken) --- End of inner exception stack trace --- at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken) at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts) at NBitpayClient.Bitpay.PostAsync(String path, String json, Boolean signatureRequired)
NBitpayClient.Bitpay.PostAsync(string path, string json, bool signatureRequired)
NBitpayClient.Bitpay.AuthorizeClient(PairingCode pairingCode)
BtcTransmuter.Extension.BtcPayServer.ExternalServices.BtcPayServer.BtcPayServerController.BuildModel(EditBtcPayServerDataViewModel viewModel, ExternalServiceData mainModel) in BtcPayServerController.cs
BtcTransmuter.Abstractions.ExternalServices.BaseExternalServiceController<TViewModel>.EditData(string identifier, TViewModel data) in BaseExternalServiceController.cs
Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor+TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, object controller, object[] arguments)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask<IActionResult> actionResultValueTask)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Builder.Extensions.UsePathBaseMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.MigrationsEndPointMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Show raw exception details
NBitpayClient.BitPayException: Error: System.Net.Http.HttpRequestException: Connection refused
 ---> System.Net.Sockets.SocketException (111): Connection refused
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at NBitpayClient.Bitpay.PostAsync(String path, String json, Boolean signatureRequired)
   at NBitpayClient.Bitpay.PostAsync(String path, String json, Boolean signatureRequired)
   at NBitpayClient.Bitpay.AuthorizeClient(PairingCode pairingCode)
   at BtcTransmuter.Extension.BtcPayServer.ExternalServices.BtcPayServer.BtcPayServerController.BuildModel(EditBtcPayServerDataViewModel viewModel, ExternalServiceData mainModel) in /src/BtcTransmuter.Extension.BtcPayServer/ExternalServices/BtcPayServer/BtcPayServerController.cs:line 100
   at BtcTransmuter.Abstractions.ExternalServices.BaseExternalServiceController`1.EditData(String identifier, TViewModel data) in /src/BtcTransmuter.Abstractions/ExternalServices/BaseExternalServiceController.cs:line 58
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Builder.Extensions.UsePathBaseMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.MigrationsEndPointMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.DatabaseErrorPageMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Thank you for any help you can provide

yapishu commented 2 years ago

Fixed this a few minutes later -- instead of using the subdomain as the base URL, I gave it the container's interface IP

BitizenOne commented 2 years ago

Fixed this a few minutes later -- instead of using the subdomain as the base URL, I gave it the container's interface IP @yapishu Could you elaborate on how you set this up? I'm trying to get the IP using: docker container inspect <container_id> | grep IP

but this IP did not work. I am also running it on docker through nginx.

Thanks

yapishu commented 2 years ago

@BitizenOne Are you able to load the web UI through that IP? That's all I did

BitizenOne commented 2 years ago

@yapishu no, the IP doesn't seem to work. I am able to access the IP on the host through curl, which is a headless ubuntu, but cannot use that IP for access from the internet. I am running nginx in a container as well as btcpay. I assume you were running nginx on your host machine without docker and running btcpay through docker?

I'm still digging on how to solve this issue. Thanks for the reply

yapishu commented 2 years ago

@BitizenOne so you're trying to connect Transmuter from a different device across the internet? If Btcpay and Transmuter are on the same host they should be able to talk via the local interface. If they're on separate devices, you will need to expose the port or configure a reverse proxy that forwards to Transmuter's local IP.

I was running all three (btcpay/transmuter/nginx) on the same host using the standard Docker setup. I had HTTPS disabled on nginx and used a separate reverse proxy with HTTPS outside of my docker setup to expose it to the internet.

BitizenOne commented 2 years ago

For the record: Ok I managed to solve this. So first I went through the standard "Create external service" on BTCTransmuter and initiated the server-side pairing through the btcpay public url, got the access token for the store on the btcpay side, then before you procede (here is the tricky park) changed the "BTCPay Host URL" to http://(btcpay docker IP):(btcpayserver container port number) with the pairing code. I figured I needed to enter a url that the docker container would recognize since nothing seemed to work on the public facing internet.

eko2one commented 1 year ago

then before you procede (here is the tricky park) changed the "BTCPay Host URL" to http://(btcpay docker IP):(btcpayserver container port number) with the pairing code.

Thanks, I could resolve the issue in this way. It feels unsafe though to not beeing able to use SSL. Here the summarized solution for others:

First grab the IP and Port of the BTCPayServer Container: docker container inspect <container_id> | grep IP docker container inspect <container_id> | grep VIRTUAL_PORT

Then enter as Server Host: http://<container_ip>:<container_port>