Bug fixes
This commit is contained in:
@ -1,9 +1,12 @@
|
|||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
using BTCPayServer.Lightning;
|
using BTCPayServer.Lightning;
|
||||||
using LNURL;
|
using LNURL;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Nostr.Client.Json;
|
using Nostr.Client.Json;
|
||||||
using Nostr.Client.Messages;
|
using Nostr.Client.Messages;
|
||||||
|
using Nostr.Client.Utils;
|
||||||
using NostrStreamer.Database;
|
using NostrStreamer.Database;
|
||||||
using NostrStreamer.Services;
|
using NostrStreamer.Services;
|
||||||
|
|
||||||
@ -41,10 +44,14 @@ public class LnurlController : Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("{key}")]
|
[HttpGet("{key}")]
|
||||||
public async Task<IActionResult> PayUserBalance([FromRoute] string key, [FromQuery] long amount, [FromQuery] string? nostr)
|
public async Task<IActionResult> PayUserBalance([FromRoute] string key, [FromQuery] ulong amount, [FromQuery] string? nostr)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
var user = await _userService.GetUser(key);
|
||||||
|
if (user == default) return LnurlError("User not found");
|
||||||
|
|
||||||
|
string? descHash;
|
||||||
if (!string.IsNullOrEmpty(nostr))
|
if (!string.IsNullOrEmpty(nostr))
|
||||||
{
|
{
|
||||||
var ev = JsonConvert.DeserializeObject<NostrEvent>(nostr, NostrSerializer.Settings);
|
var ev = JsonConvert.DeserializeObject<NostrEvent>(nostr, NostrSerializer.Settings);
|
||||||
@ -53,9 +60,16 @@ public class LnurlController : Controller
|
|||||||
{
|
{
|
||||||
throw new Exception("Invalid nostr event");
|
throw new Exception("Invalid nostr event");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
descHash = SHA256.HashData(Encoding.UTF8.GetBytes(nostr)).ToHex();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var metadata = GetMetadata(user);
|
||||||
|
descHash = SHA256.HashData(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(metadata))).ToHex();
|
||||||
}
|
}
|
||||||
|
|
||||||
var invoice = await _userService.CreateTopup(key, (ulong)(amount / 1000), nostr);
|
var invoice = await _userService.CreateTopup(key, amount, descHash, nostr);
|
||||||
return Json(new LNURLPayRequest.LNURLPayRequestCallbackResponse
|
return Json(new LNURLPayRequest.LNURLPayRequestCallbackResponse
|
||||||
{
|
{
|
||||||
Pr = invoice
|
Pr = invoice
|
||||||
|
@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Nostr.Client.Json;
|
using Nostr.Client.Json;
|
||||||
using Nostr.Client.Utils;
|
using Nostr.Client.Messages;
|
||||||
using NostrStreamer.ApiModel;
|
using NostrStreamer.ApiModel;
|
||||||
using NostrStreamer.Database;
|
using NostrStreamer.Database;
|
||||||
using NostrStreamer.Services;
|
using NostrStreamer.Services;
|
||||||
@ -19,14 +19,14 @@ public class NostrController : Controller
|
|||||||
private readonly StreamerContext _db;
|
private readonly StreamerContext _db;
|
||||||
private readonly Config _config;
|
private readonly Config _config;
|
||||||
private readonly StreamManagerFactory _streamManagerFactory;
|
private readonly StreamManagerFactory _streamManagerFactory;
|
||||||
private readonly LndNode _lnd;
|
private readonly UserService _userService;
|
||||||
|
|
||||||
public NostrController(StreamerContext db, Config config, StreamManagerFactory streamManager, LndNode lnd)
|
public NostrController(StreamerContext db, Config config, StreamManagerFactory streamManager, UserService userService)
|
||||||
{
|
{
|
||||||
_db = db;
|
_db = db;
|
||||||
_config = config;
|
_config = config;
|
||||||
_streamManagerFactory = streamManager;
|
_streamManagerFactory = streamManager;
|
||||||
_lnd = lnd;
|
_userService = userService;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("account")]
|
[HttpGet("account")]
|
||||||
@ -36,23 +36,24 @@ public class NostrController : Controller
|
|||||||
if (user == default)
|
if (user == default)
|
||||||
{
|
{
|
||||||
var pk = GetPubKey();
|
var pk = GetPubKey();
|
||||||
user = new()
|
user = await _userService.CreateAccount(pk);
|
||||||
{
|
|
||||||
PubKey = pk,
|
|
||||||
Balance = 1000_000,
|
|
||||||
StreamKey = Guid.NewGuid().ToString()
|
|
||||||
};
|
|
||||||
|
|
||||||
_db.Users.Add(user);
|
|
||||||
|
|
||||||
await _db.SaveChangesAsync();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var endpoints = await _db.Endpoints.ToListAsync();
|
var endpoints = await _db.Endpoints
|
||||||
|
.AsNoTracking()
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
var latestEvent = await _db.Streams
|
||||||
|
.AsNoTracking()
|
||||||
|
.Where(a => a.User.PubKey == user.PubKey)
|
||||||
|
.OrderByDescending(a => a.Starts)
|
||||||
|
.Select(a => a.Event)
|
||||||
|
.FirstOrDefaultAsync();
|
||||||
|
|
||||||
var account = new Account
|
var account = new Account
|
||||||
{
|
{
|
||||||
Event = null,
|
Event = !string.IsNullOrEmpty(latestEvent) ? JsonConvert.DeserializeObject<NostrEvent>(latestEvent) : null,
|
||||||
Endpoints = endpoints.Select(a => new AccountEndpoint()
|
Endpoints = endpoints.Select(a => new AccountEndpoint
|
||||||
{
|
{
|
||||||
Name = a.Name,
|
Name = a.Name,
|
||||||
Url = new Uri(_config.RtmpHost, a.App).ToString(),
|
Url = new Uri(_config.RtmpHost, a.App).ToString(),
|
||||||
@ -87,27 +88,17 @@ public class NostrController : Controller
|
|||||||
var pubkey = GetPubKey();
|
var pubkey = GetPubKey();
|
||||||
if (string.IsNullOrEmpty(pubkey)) return Unauthorized();
|
if (string.IsNullOrEmpty(pubkey)) return Unauthorized();
|
||||||
|
|
||||||
var invoice = await _lnd.AddInvoice(amount * 1000, TimeSpan.FromMinutes(10), $"Top up for {pubkey}");
|
var invoice = await _userService.CreateTopup(pubkey, amount * 1000, null, null);
|
||||||
_db.Payments.Add(new()
|
|
||||||
{
|
|
||||||
PubKey = pubkey,
|
|
||||||
Amount = amount,
|
|
||||||
Invoice = invoice.PaymentRequest,
|
|
||||||
PaymentHash = invoice.RHash.ToByteArray().ToHex()
|
|
||||||
});
|
|
||||||
|
|
||||||
await _db.SaveChangesAsync();
|
|
||||||
|
|
||||||
return Json(new
|
return Json(new
|
||||||
{
|
{
|
||||||
pr = invoice.PaymentRequest
|
pr = invoice
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<User?> GetUser()
|
private async Task<User?> GetUser()
|
||||||
{
|
{
|
||||||
var pk = GetPubKey();
|
var pk = GetPubKey();
|
||||||
return await _db.Users.FirstOrDefaultAsync(a => a.PubKey == pk);
|
return await _userService.GetUser(pk);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetPubKey()
|
private string GetPubKey()
|
||||||
|
@ -34,7 +34,7 @@ public class SrsController : Controller
|
|||||||
var streamManager = await _streamManagerFactory.ForStream(new StreamInfo
|
var streamManager = await _streamManagerFactory.ForStream(new StreamInfo
|
||||||
{
|
{
|
||||||
App = appSplit[0],
|
App = appSplit[0],
|
||||||
Variant = appSplit.Length > 1 ? appSplit[1] : "source",
|
Variant = appSplit.Length > 1 ? appSplit[1] : "",
|
||||||
ClientId = req.ClientId!,
|
ClientId = req.ClientId!,
|
||||||
StreamKey = req.Stream
|
StreamKey = req.Stream
|
||||||
});
|
});
|
||||||
@ -42,15 +42,23 @@ public class SrsController : Controller
|
|||||||
if (req.Action == "on_forward")
|
if (req.Action == "on_forward")
|
||||||
{
|
{
|
||||||
var urls = await streamManager.OnForward();
|
var urls = await streamManager.OnForward();
|
||||||
return new SrsForwardHookReply
|
if (urls.Count > 0)
|
||||||
{
|
{
|
||||||
Data = new()
|
return new SrsForwardHookReply
|
||||||
{
|
{
|
||||||
Urls = urls
|
Data = new()
|
||||||
}
|
{
|
||||||
|
Urls = urls
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return new()
|
||||||
|
{
|
||||||
|
Code = 2 // invalid request
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req.App.EndsWith("/source"))
|
if (req.App.EndsWith("/source"))
|
||||||
{
|
{
|
||||||
if (req.Action == "on_publish")
|
if (req.Action == "on_publish")
|
||||||
@ -78,7 +86,7 @@ public class SrsController : Controller
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogWarning(ex, "Failed to start stream");
|
_logger.LogWarning("Failed to start stream: {message}", ex.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new()
|
return new()
|
||||||
|
@ -84,23 +84,27 @@ public class StreamManagerFactory
|
|||||||
|
|
||||||
if (ep == default) throw new Exception("No endpoint found");
|
if (ep == default) throw new Exception("No endpoint found");
|
||||||
|
|
||||||
stream = new()
|
// create new stream entry for source only
|
||||||
|
if (info.Variant == "source")
|
||||||
{
|
{
|
||||||
EndpointId = ep.Id,
|
stream = new()
|
||||||
PubKey = user.PubKey,
|
{
|
||||||
ClientId = info.ClientId,
|
EndpointId = ep.Id,
|
||||||
State = UserStreamState.Planned
|
PubKey = user.PubKey,
|
||||||
};
|
ClientId = info.ClientId,
|
||||||
|
State = UserStreamState.Planned
|
||||||
|
};
|
||||||
|
|
||||||
|
var ev = _eventBuilder.CreateStreamEvent(user, stream);
|
||||||
|
stream.Event = JsonConvert.SerializeObject(ev, NostrSerializer.Settings);
|
||||||
|
_db.Streams.Add(stream);
|
||||||
|
await _db.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
var ev = _eventBuilder.CreateStreamEvent(user, stream);
|
|
||||||
stream.Event = JsonConvert.SerializeObject(ev, NostrSerializer.Settings);
|
|
||||||
_db.Streams.Add(stream);
|
|
||||||
await _db.SaveChangesAsync();
|
|
||||||
|
|
||||||
// replace again with new values
|
// replace again with new values
|
||||||
stream = new()
|
stream = new()
|
||||||
{
|
{
|
||||||
Id = stream.Id,
|
Id = stream?.Id ?? Guid.NewGuid(),
|
||||||
User = user,
|
User = user,
|
||||||
Endpoint = ep,
|
Endpoint = ep,
|
||||||
ClientId = info.ClientId,
|
ClientId = info.ClientId,
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
using System.Security.Cryptography;
|
|
||||||
using System.Text;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Nostr.Client.Utils;
|
using Nostr.Client.Utils;
|
||||||
using NostrStreamer.Database;
|
using NostrStreamer.Database;
|
||||||
@ -17,17 +15,44 @@ public class UserService
|
|||||||
_lnd = lnd;
|
_lnd = lnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> CreateTopup(string pubkey, ulong amount, string? nostr)
|
/// <summary>
|
||||||
|
/// Create new user account
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pubkey"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<User> CreateAccount(string pubkey)
|
||||||
|
{
|
||||||
|
var user = new User()
|
||||||
|
{
|
||||||
|
PubKey = pubkey,
|
||||||
|
Balance = 1000_000,
|
||||||
|
StreamKey = Guid.NewGuid().ToString()
|
||||||
|
};
|
||||||
|
|
||||||
|
_db.Users.Add(user);
|
||||||
|
await _db.SaveChangesAsync();
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create topup for a user
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pubkey"></param>
|
||||||
|
/// <param name="amount">milli-sats amount</param>
|
||||||
|
/// <param name="descHash"></param>
|
||||||
|
/// <param name="nostr"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <exception cref="Exception"></exception>
|
||||||
|
public async Task<string> CreateTopup(string pubkey, ulong amount, string? descHash, string? nostr)
|
||||||
{
|
{
|
||||||
var user = await GetUser(pubkey);
|
var user = await GetUser(pubkey);
|
||||||
if (user == default) throw new Exception("No user found");
|
if (user == default) throw new Exception("No user found");
|
||||||
|
|
||||||
var descHash = string.IsNullOrEmpty(nostr) ? null : SHA256.HashData(Encoding.UTF8.GetBytes(nostr)).ToHex();
|
var invoice = await _lnd.AddInvoice(amount, TimeSpan.FromMinutes(10), $"Top up for {pubkey}", descHash);
|
||||||
var invoice = await _lnd.AddInvoice(amount * 1000, TimeSpan.FromMinutes(10), $"Top up for {pubkey}", descHash);
|
|
||||||
_db.Payments.Add(new()
|
_db.Payments.Add(new()
|
||||||
{
|
{
|
||||||
PubKey = pubkey,
|
PubKey = pubkey,
|
||||||
Amount = amount,
|
Amount = amount / 1000,
|
||||||
Invoice = invoice.PaymentRequest,
|
Invoice = invoice.PaymentRequest,
|
||||||
PaymentHash = invoice.RHash.ToByteArray().ToHex(),
|
PaymentHash = invoice.RHash.ToByteArray().ToHex(),
|
||||||
Nostr = nostr,
|
Nostr = nostr,
|
Reference in New Issue
Block a user