Fix: Nostr Lighthning Client was always failing

This commit is contained in:
nicolas.dorier
2024-11-08 21:08:22 +09:00
parent beda7741a3
commit d5f664ad9b

View File

@@ -63,7 +63,7 @@ public class NostrWalletConnectLightningClient : ILightningClient
var expired = !isPaid && expiresAt < DateTimeOffset.UtcNow; var expired = !isPaid && expiresAt < DateTimeOffset.UtcNow;
var s = tx.SettledAt is not null var s = tx.SettledAt is not null
? DateTimeOffset.FromUnixTimeSeconds(tx.SettledAt.Value) ? DateTimeOffset.FromUnixTimeSeconds(tx.SettledAt.Value)
: (DateTimeOffset?) null; : (DateTimeOffset?)null;
return new LightningInvoice() return new LightningInvoice()
{ {
PaymentHash = tx.PaymentHash, PaymentHash = tx.PaymentHash,
@@ -118,7 +118,7 @@ public class NostrWalletConnectLightningClient : ILightningClient
new NIP47.ListTransactionsRequest() new NIP47.ListTransactionsRequest()
{ {
Type = "incoming", Type = "incoming",
Offset = (int) (request.OffsetIndex ?? 0), Offset = (int)(request.OffsetIndex ?? 0),
Unpaid = request.PendingOnly ?? false, Unpaid = request.PendingOnly ?? false,
}, cts.Token); }, cts.Token);
@@ -144,7 +144,7 @@ public class NostrWalletConnectLightningClient : ILightningClient
var expired = !isPaid && expiresAt < DateTimeOffset.UtcNow; var expired = !isPaid && expiresAt < DateTimeOffset.UtcNow;
var s = tx.SettledAt is not null var s = tx.SettledAt is not null
? DateTimeOffset.FromUnixTimeSeconds(tx.SettledAt.Value) ? DateTimeOffset.FromUnixTimeSeconds(tx.SettledAt.Value)
: (DateTimeOffset?) null; : (DateTimeOffset?)null;
return new LightningPayment() return new LightningPayment()
{ {
PaymentHash = tx.PaymentHash, PaymentHash = tx.PaymentHash,
@@ -169,11 +169,21 @@ public class NostrWalletConnectLightningClient : ILightningClient
var (nostrClient, usage) = await _nostrClientPool.GetClientAndConnect(_connectParams.relays, cts.Token); var (nostrClient, usage) = await _nostrClientPool.GetClientAndConnect(_connectParams.relays, cts.Token);
using (usage) using (usage)
{ {
var tx = await nostrClient.SendNIP47Request<NIP47.Nip47Transaction>(_connectParams.pubkey, _connectParams.secret, NIP47.Nip47Transaction tx;
try
{
tx = await nostrClient.SendNIP47Request<NIP47.Nip47Transaction>(_connectParams.pubkey, _connectParams.secret,
new NIP47.LookupInvoiceRequest() new NIP47.LookupInvoiceRequest()
{ {
PaymentHash = paymentHash PaymentHash = paymentHash
}, cts.Token); }, cts.Token);
}
// The standard says it returns NOT_FOUND error, but
// Alby returns INTERNAL error... Probably safer to catch all
catch (Exception)
{
return null;
}
return ToLightningPayment(tx)!; return ToLightningPayment(tx)!;
} }
} }
@@ -197,7 +207,7 @@ public class NostrWalletConnectLightningClient : ILightningClient
new NIP47.ListTransactionsRequest() new NIP47.ListTransactionsRequest()
{ {
Type = "outgoing", Type = "outgoing",
Offset = (int) (request.OffsetIndex ?? 0), Offset = (int)(request.OffsetIndex ?? 0),
Unpaid = request.IncludePending ?? false, Unpaid = request.IncludePending ?? false,
}, cts.Token); }, cts.Token);
return response.Transactions.Select(ToLightningPayment).Where(i => i is not null).ToArray()!; return response.Transactions.Select(ToLightningPayment).Where(i => i is not null).ToArray()!;
@@ -229,7 +239,7 @@ public class NostrWalletConnectLightningClient : ILightningClient
? null ? null
: createInvoiceRequest.Description, : createInvoiceRequest.Description,
DescriptionHash = createInvoiceRequest.DescriptionHash?.ToString(), DescriptionHash = createInvoiceRequest.DescriptionHash?.ToString(),
ExpirySeconds = (int) createInvoiceRequest.Expiry.TotalSeconds, ExpirySeconds = (int)createInvoiceRequest.Expiry.TotalSeconds,
}, cts.Token); }, cts.Token);
return ToLightningInvoice(response, _network)!; return ToLightningInvoice(response, _network)!;
} }
@@ -327,7 +337,7 @@ public class NostrWalletConnectLightningClient : ILightningClient
// Unpaid = true, //seems like this is ignored... so we only get paid ones // Unpaid = true, //seems like this is ignored... so we only get paid ones
Limit = 300 Limit = 300
}, cancellationToken: cts.Token); }, cancellationToken: cts.Token);
paid.Transactions = paid.Transactions.Where(i => i is {Type: "incoming", SettledAt: not null}).ToArray(); paid.Transactions = paid.Transactions.Where(i => i is { Type: "incoming", SettledAt: not null }).ToArray();
if (_lastPaid is not null) if (_lastPaid is not null)
{ {
@@ -342,7 +352,7 @@ public class NostrWalletConnectLightningClient : ILightningClient
// .Select(i => ToLightningInvoice(i, _network)!); // .Select(i => ToLightningInvoice(i, _network)!);
foreach (var invoice in paidInvoicesSinceLastPoll) foreach (var invoice in paidInvoicesSinceLastPoll)
{ {
await queue.Writer.WriteAsync(invoice,_cts.Token); await queue.Writer.WriteAsync(invoice, _cts.Token);
} }
} }
@@ -405,19 +415,16 @@ public class NostrWalletConnectLightningClient : ILightningClient
public async Task<PayResponse> Pay(string bolt11, PayInvoiceParams payParams, public async Task<PayResponse> Pay(string bolt11, PayInvoiceParams payParams,
CancellationToken cancellation = new()) CancellationToken cancellation = new())
{ {
try
{
var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellation); var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellation);
cts.CancelAfter(TimeSpan.FromSeconds(10)); cts.CancelAfter(TimeSpan.FromSeconds(10));
var (client, usage) = await _nostrClientPool.GetClientAndConnect(_connectParams.relays, cts.Token); var (client, usage) = await _nostrClientPool.GetClientAndConnect(_connectParams.relays, cts.Token);
using (usage) using (usage)
{ {
var response = await client.SendNIP47Request<NIP47.PayInvoiceResponse>(_connectParams.pubkey, NIP47.INIP47Request request;
_connectParams.secret, if (bolt11 is null)
bolt11 is null {
? new NIP47.PayKeysendRequest() request = new NIP47.PayKeysendRequest()
{ {
Amount = Convert.ToDecimal(payParams.Amount.MilliSatoshi), Amount = Convert.ToDecimal(payParams.Amount.MilliSatoshi),
Pubkey = payParams.Destination.ToHex(), Pubkey = payParams.Destination.ToHex(),
@@ -426,22 +433,27 @@ public class NostrWalletConnectLightningClient : ILightningClient
Type = kv.Key.ToString(), Type = kv.Key.ToString(),
Value = kv.Value Value = kv.Value
}).ToArray() }).ToArray()
};
} }
: new NIP47.PayInvoiceRequest() else
{
request = new NIP47.PayInvoiceRequest()
{ {
Invoice = bolt11, Invoice = bolt11,
Amount = payParams.Amount?.MilliSatoshi is not null Amount = payParams.Amount?.MilliSatoshi is not null
? Convert.ToDecimal(payParams.Amount.MilliSatoshi) ? Convert.ToDecimal(payParams.Amount.MilliSatoshi)
: null, : null,
}, cts.Token); };
var payHash = payParams?.PaymentHash?.ToString()?? }
(response.Preimage is not null? var response = await client.SendNIP47Request<NIP47.PayInvoiceResponse>(_connectParams.pubkey, _connectParams.secret, request, cts.Token);
ConvertHelper.ToHexString(SHA256.HashData(Convert.FromHexString(response.Preimage))): var payHash = ConvertHelper.ToHexString(SHA256.HashData(Convert.FromHexString(response.Preimage)));
BOLT11PaymentRequest.Parse(bolt11, _network).PaymentHash.ToString());
try
{
var tx = await client.SendNIP47Request<NIP47.Nip47Transaction>(_connectParams.pubkey, _connectParams.secret, var tx = await client.SendNIP47Request<NIP47.Nip47Transaction>(_connectParams.pubkey, _connectParams.secret,
new NIP47 .LookupInvoiceRequest() new NIP47.LookupInvoiceRequest()
{ {
PaymentHash = payHash PaymentHash = payHash
}, cts.Token); }, cts.Token);
@@ -456,17 +468,20 @@ public class NostrWalletConnectLightningClient : ILightningClient
FeeAmount = lp.Fee FeeAmount = lp.Fee
}); });
} }
}
catch (Exception e) catch (Exception e)
{ {
return new PayResponse() return new PayResponse(PayResult.Ok, new PayDetails()
{ {
Result = PayResult.Error, Status = LightningPaymentStatus.Complete,
ErrorDetail = e.Message PaymentHash = new uint256(payHash),
}; Preimage = new uint256(response.Preimage),
})
{ ErrorDetail = e.Message };
} }
} }
}
public async Task<PayResponse> Pay(string bolt11, CancellationToken cancellation = new()) public async Task<PayResponse> Pay(string bolt11, CancellationToken cancellation = new())
{ {
return await Pay(bolt11, new PayInvoiceParams(), cancellation); return await Pay(bolt11, new PayInvoiceParams(), cancellation);