mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2024-11-19 09:54:30 +01:00
130 lines
4.1 KiB
C#
130 lines
4.1 KiB
C#
#nullable enable
|
|
using System;
|
|
using System.Net.WebSockets;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Amazon.S3.Model.Internal.MarshallTransformations;
|
|
using ExchangeSharp;
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
namespace BTCPayServer
|
|
{
|
|
public enum VaultMessageType
|
|
{
|
|
Ok,
|
|
Error,
|
|
Processing
|
|
}
|
|
public enum VaultServices
|
|
{
|
|
HWI,
|
|
NFC
|
|
}
|
|
|
|
public class VaultNotConnectedException : VaultException
|
|
{
|
|
public VaultNotConnectedException() : base("BTCPay Vault isn't connected")
|
|
{
|
|
|
|
}
|
|
}
|
|
public class VaultException : Exception
|
|
{
|
|
public VaultException(string message) : base(message)
|
|
{
|
|
|
|
}
|
|
}
|
|
public class VaultClient
|
|
{
|
|
public VaultClient(WebSocket websocket)
|
|
{
|
|
Websocket = new WebSocketHelper(websocket);
|
|
}
|
|
|
|
public WebSocketHelper Websocket { get; }
|
|
|
|
public async Task<string> GetNextCommand(CancellationToken cancellationToken)
|
|
{
|
|
return await Websocket.NextMessageAsync(cancellationToken);
|
|
}
|
|
|
|
public async Task SendMessage(JObject mess, CancellationToken cancellationToken)
|
|
{
|
|
await Websocket.Send(mess.ToString(), cancellationToken);
|
|
}
|
|
|
|
public Task Show(VaultMessageType type, string message, CancellationToken cancellationToken)
|
|
{
|
|
return Show(type, message, null, cancellationToken);
|
|
}
|
|
public async Task Show(VaultMessageType type, string message, string? debug, CancellationToken cancellationToken)
|
|
{
|
|
|
|
await SendMessage(new JObject()
|
|
{
|
|
["command"] = "showMessage",
|
|
["message"] = message,
|
|
["type"] = type.ToString(),
|
|
["debug"] = debug
|
|
}, cancellationToken);
|
|
}
|
|
|
|
string? _ServiceUri;
|
|
public async Task<bool?> AskPermission(VaultServices service, CancellationToken cancellationToken)
|
|
{
|
|
var uri = service switch
|
|
{
|
|
VaultServices.HWI => "http://127.0.0.1:65092/hwi-bridge/v1",
|
|
VaultServices.NFC => "http://127.0.0.1:65092/nfc-bridge/v1",
|
|
_ => throw new NotSupportedException()
|
|
};
|
|
|
|
await this.SendMessage(new JObject()
|
|
{
|
|
["command"] = "sendRequest",
|
|
["uri"] = uri + "/request-permission"
|
|
}, cancellationToken);
|
|
var result = await GetNextMessage(cancellationToken);
|
|
if (result["httpCode"] is { } p)
|
|
{
|
|
var ok = p.Value<int>() == 200;
|
|
if (ok)
|
|
_ServiceUri = uri;
|
|
return ok;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public async Task<JToken?> SendVaultRequest(string? path, JObject? body, CancellationToken cancellationToken)
|
|
{
|
|
var isAbsolute = path is not null && Uri.IsWellFormedUriString(path, UriKind.Absolute);
|
|
var query = new JObject()
|
|
{
|
|
["command"] = "sendRequest",
|
|
["uri"] = isAbsolute ? path : _ServiceUri + path
|
|
};
|
|
if (body is not null)
|
|
query["body"] = body;
|
|
await this.SendMessage(query, cancellationToken);
|
|
var resp = await GetNextMessage(cancellationToken);
|
|
if (resp["httpCode"] is not { } p)
|
|
throw new VaultNotConnectedException();
|
|
if (p.Value<int>() != 200)
|
|
throw new VaultException($"Unexpected response code from vault {p.Value<int>()}");
|
|
return resp["body"] as JToken;
|
|
}
|
|
|
|
public async Task<JObject> GetNextMessage(CancellationToken cancellationToken)
|
|
{
|
|
return JObject.Parse(await this.Websocket.NextMessageAsync(cancellationToken));
|
|
}
|
|
|
|
public Task SendSimpleMessage(string command, CancellationToken cancellationToken)
|
|
{
|
|
return SendMessage(new JObject() { ["command"] = command }, cancellationToken);
|
|
}
|
|
}
|
|
}
|