pay_invoice_controller.go raw
1 package controllers
2
3 import (
4 "context"
5 "fmt"
6 "strings"
7
8 "github.com/getAlby/go-nostr"
9 "github.com/getAlby/hub/constants"
10 "github.com/getAlby/hub/db"
11 "github.com/getAlby/hub/logger"
12 "github.com/getAlby/hub/nip47/models"
13 decodepay "github.com/nbd-wtf/ln-decodepay"
14 "github.com/sirupsen/logrus"
15 )
16
17 type payInvoiceParams struct {
18 Invoice string `json:"invoice"`
19 Amount *uint64 `json:"amount"`
20 Metadata map[string]interface{} `json:"metadata,omitempty"`
21 }
22
23 func (controller *nip47Controller) HandlePayInvoiceEvent(ctx context.Context, nip47Request *models.Request, requestEventId uint, app *db.App, publishResponse publishFunc, tags nostr.Tags) {
24 payParams := &payInvoiceParams{}
25 resp := decodeRequest(nip47Request, payParams)
26 if resp != nil {
27 publishResponse(resp, tags)
28 return
29 }
30
31 bolt11 := payParams.Invoice
32 // Convert invoice to lowercase string
33 bolt11 = strings.ToLower(bolt11)
34 paymentRequest, err := decodepay.Decodepay(bolt11)
35 if err != nil {
36 logger.Logger.WithFields(logrus.Fields{
37 "request_event_id": requestEventId,
38 "app_id": app.ID,
39 "bolt11": bolt11,
40 }).WithError(err).Error("Failed to decode bolt11 invoice")
41
42 publishResponse(&models.Response{
43 ResultType: nip47Request.Method,
44 Error: &models.Error{
45 Code: constants.ERROR_BAD_REQUEST,
46 Message: fmt.Sprintf("Failed to decode bolt11 invoice: %s", err.Error()),
47 },
48 }, tags)
49 return
50 }
51
52 controller.pay(bolt11, payParams.Amount, payParams.Metadata, &paymentRequest, nip47Request, requestEventId, app, publishResponse, tags)
53 }
54
55 func (controller *nip47Controller) pay(bolt11 string, amount *uint64, metadata map[string]interface{}, paymentRequest *decodepay.Bolt11, nip47Request *models.Request, requestEventId uint, app *db.App, publishResponse publishFunc, tags nostr.Tags) {
56 logger.Logger.WithFields(logrus.Fields{
57 "request_event_id": requestEventId,
58 "app_id": app.ID,
59 "bolt11": bolt11,
60 }).Info("Sending payment")
61
62 transaction, err := controller.transactionsService.SendPaymentSync(bolt11, amount, metadata, controller.lnClient, &app.ID, &requestEventId)
63 if err != nil {
64 logger.Logger.WithFields(logrus.Fields{
65 "request_event_id": requestEventId,
66 "app_id": app.ID,
67 "bolt11": bolt11,
68 }).WithError(err).Error("Failed to send payment")
69 publishResponse(&models.Response{
70 ResultType: nip47Request.Method,
71 Error: mapNip47Error(err),
72 }, tags)
73 return
74 }
75
76 publishResponse(&models.Response{
77 ResultType: nip47Request.Method,
78 Result: payResponse{
79 Preimage: *transaction.Preimage,
80 FeesPaid: transaction.FeeMsat,
81 },
82 }, tags)
83 }
84