multi_pay_invoice_controller.go raw

   1  package controllers
   2  
   3  import (
   4  	"context"
   5  	"fmt"
   6  	"strings"
   7  	"sync"
   8  
   9  	"github.com/getAlby/go-nostr"
  10  	"github.com/getAlby/hub/constants"
  11  	"github.com/getAlby/hub/db"
  12  	"github.com/getAlby/hub/logger"
  13  	"github.com/getAlby/hub/nip47/models"
  14  	decodepay "github.com/nbd-wtf/ln-decodepay"
  15  	"github.com/sirupsen/logrus"
  16  )
  17  
  18  type multiPayInvoiceElement struct {
  19  	payInvoiceParams
  20  	Id string `json:"id"`
  21  }
  22  
  23  type multiPayInvoiceParams struct {
  24  	Invoices []multiPayInvoiceElement `json:"invoices"`
  25  }
  26  
  27  func (controller *nip47Controller) HandleMultiPayInvoiceEvent(ctx context.Context, nip47Request *models.Request, requestEventId uint, app *db.App, publishResponse publishFunc) {
  28  	multiPayParams := &multiPayInvoiceParams{}
  29  	resp := decodeRequest(nip47Request, multiPayParams)
  30  	if resp != nil {
  31  		publishResponse(resp, nostr.Tags{})
  32  		return
  33  	}
  34  	logger.Logger.WithField("multiPayParams", multiPayParams).Debug("sending multi payment")
  35  
  36  	var wg sync.WaitGroup
  37  	wg.Add(len(multiPayParams.Invoices))
  38  	for _, invoiceInfo := range multiPayParams.Invoices {
  39  		go func(invoiceInfo multiPayInvoiceElement) {
  40  			defer wg.Done()
  41  			bolt11 := invoiceInfo.Invoice
  42  			metadata := invoiceInfo.Metadata
  43  			// Convert invoice to lowercase string
  44  			bolt11 = strings.ToLower(bolt11)
  45  			paymentRequest, err := decodepay.Decodepay(bolt11)
  46  			if err != nil {
  47  				logger.Logger.WithFields(logrus.Fields{
  48  					"request_event_id": requestEventId,
  49  					"appId":            app.ID,
  50  					"bolt11":           bolt11,
  51  				}).Errorf("Failed to decode bolt11 invoice: %v", err)
  52  
  53  				// TODO: Decide what to do if id is empty
  54  				dTag := []string{"d", invoiceInfo.Id}
  55  				publishResponse(&models.Response{
  56  					ResultType: nip47Request.Method,
  57  					Error: &models.Error{
  58  						Code:    constants.ERROR_BAD_REQUEST,
  59  						Message: fmt.Sprintf("Failed to decode bolt11 invoice: %s", err.Error()),
  60  					},
  61  				}, nostr.Tags{dTag})
  62  				return
  63  			}
  64  
  65  			invoiceDTagValue := invoiceInfo.Id
  66  			if invoiceDTagValue == "" {
  67  				invoiceDTagValue = paymentRequest.PaymentHash
  68  			}
  69  			dTag := []string{"d", invoiceDTagValue}
  70  
  71  			controller.
  72  				pay(bolt11, invoiceInfo.Amount, metadata, &paymentRequest, nip47Request, requestEventId, app, publishResponse, nostr.Tags{dTag})
  73  		}(invoiceInfo)
  74  	}
  75  
  76  	wg.Wait()
  77  }
  78