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