87 lines
2.6 KiB
C#
87 lines
2.6 KiB
C#
using BTCPayServer.Lightning;
|
|
using LNURL;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Newtonsoft.Json;
|
|
using Nostr.Client.Json;
|
|
using Nostr.Client.Messages;
|
|
using NostrStreamer.Database;
|
|
using NostrStreamer.Services;
|
|
|
|
namespace NostrStreamer.Controllers;
|
|
|
|
[Route("/api/pay")]
|
|
public class LnurlController : Controller
|
|
{
|
|
private readonly Config _config;
|
|
private readonly UserService _userService;
|
|
|
|
public LnurlController(Config config, UserService userService)
|
|
{
|
|
_config = config;
|
|
_userService = userService;
|
|
}
|
|
|
|
[HttpGet("/.well-known/lnurlp/{key}")]
|
|
public async Task<IActionResult> GetPayService([FromRoute] string key)
|
|
{
|
|
var user = await _userService.GetUser(key);
|
|
if (user == default) return LnurlError("User not found");
|
|
|
|
var metadata = GetMetadata(user);
|
|
var pubKey = _config.GetPubKey();
|
|
return Json(new LNURLPayRequest
|
|
{
|
|
Callback = new Uri(_config.ApiHost, $"/api/pay/{key}"),
|
|
Metadata = JsonConvert.SerializeObject(metadata),
|
|
MinSendable = LightMoney.Satoshis(1),
|
|
MaxSendable = LightMoney.Coins(1),
|
|
Tag = "payRequest",
|
|
NostrPubkey = pubKey
|
|
});
|
|
}
|
|
|
|
[HttpGet("{key}")]
|
|
public async Task<IActionResult> PayUserBalance([FromRoute] string key, [FromQuery] long amount, [FromQuery] string? nostr)
|
|
{
|
|
try
|
|
{
|
|
if (!string.IsNullOrEmpty(nostr))
|
|
{
|
|
var ev = JsonConvert.DeserializeObject<NostrEvent>(nostr, NostrSerializer.Settings);
|
|
if (ev?.Kind != NostrKind.ZapRequest || ev.Tags?.FindFirstTagValue("amount") != amount.ToString() ||
|
|
!ev.IsSignatureValid())
|
|
{
|
|
throw new Exception("Invalid nostr event");
|
|
}
|
|
}
|
|
|
|
var invoice = await _userService.CreateTopup(key, (ulong)(amount / 1000), nostr);
|
|
return Json(new LNURLPayRequest.LNURLPayRequestCallbackResponse
|
|
{
|
|
Pr = invoice
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return LnurlError($"Failed to create invoice (${ex.Message})");
|
|
}
|
|
}
|
|
|
|
private List<KeyValuePair<string, string>> GetMetadata(User u)
|
|
{
|
|
return new List<KeyValuePair<string, string>>()
|
|
{
|
|
new("text/plain", $"Topup for {u.PubKey}")
|
|
};
|
|
}
|
|
|
|
private IActionResult LnurlError(string reason)
|
|
{
|
|
return Json(new LNUrlStatusResponse()
|
|
{
|
|
Reason = reason,
|
|
Status = "ERROR"
|
|
});
|
|
}
|
|
}
|