get_budget_controller.go raw

   1  package controllers
   2  
   3  import (
   4  	"context"
   5  	"errors"
   6  
   7  	"github.com/getAlby/go-nostr"
   8  	"github.com/getAlby/hub/db/queries"
   9  	"gorm.io/gorm"
  10  
  11  	"github.com/getAlby/hub/constants"
  12  	"github.com/getAlby/hub/db"
  13  	"github.com/getAlby/hub/logger"
  14  	"github.com/getAlby/hub/nip47/models"
  15  	"github.com/sirupsen/logrus"
  16  )
  17  
  18  type getBudgetResponse struct {
  19  	UsedBudget    uint64  `json:"used_budget"`
  20  	TotalBudget   uint64  `json:"total_budget"`
  21  	RenewsAt      *uint64 `json:"renews_at,omitempty"`
  22  	RenewalPeriod string  `json:"renewal_period"`
  23  }
  24  
  25  func (controller *nip47Controller) HandleGetBudgetEvent(ctx context.Context, nip47Request *models.Request, requestEventId uint, app *db.App, publishResponse publishFunc) {
  26  
  27  	logger.Logger.WithFields(logrus.Fields{
  28  		"request_event_id": requestEventId,
  29  	}).Debug("Getting budget")
  30  
  31  	appPermission := db.AppPermission{}
  32  	result := controller.db.Where("app_id = ? AND scope = ?", app.ID, constants.PAY_INVOICE_SCOPE).First(&appPermission)
  33  	if result.Error != nil && !errors.Is(result.Error, gorm.ErrRecordNotFound) {
  34  		logger.Logger.WithFields(logrus.Fields{
  35  			"request_event_id": requestEventId,
  36  		}).WithError(result.Error).Error("Failed to fetch pay_invoice permission")
  37  		publishResponse(&models.Response{
  38  			ResultType: nip47Request.Method,
  39  			Error:      mapNip47Error(result.Error),
  40  		}, nostr.Tags{})
  41  		return
  42  	}
  43  
  44  	// On ErrRecordNotFound appPermission stays zero-valued and maxAmountSat == 0,
  45  	// which returns the same empty "no budget" response as a permission with no
  46  	// budget set.
  47  	maxAmountSat := appPermission.MaxAmountSat
  48  	if maxAmountSat == 0 {
  49  		publishResponse(&models.Response{
  50  			ResultType: nip47Request.Method,
  51  			Result:     struct{}{},
  52  		}, nostr.Tags{})
  53  		return
  54  	}
  55  
  56  	usedBudgetMsat, err := queries.GetBudgetUsageMsat(controller.db, &appPermission)
  57  	if err != nil {
  58  		logger.Logger.WithFields(logrus.Fields{
  59  			"request_event_id": requestEventId,
  60  		}).WithError(err).Error("Failed to fetch budget usage")
  61  		publishResponse(&models.Response{
  62  			ResultType: nip47Request.Method,
  63  			Error:      mapNip47Error(err),
  64  		}, nostr.Tags{})
  65  		return
  66  	}
  67  
  68  	responsePayload := &getBudgetResponse{
  69  		TotalBudget:   uint64(maxAmountSat * 1000),
  70  		UsedBudget:    usedBudgetMsat,
  71  		RenewalPeriod: appPermission.BudgetRenewal,
  72  		RenewsAt:      queries.GetBudgetRenewsAt(appPermission.BudgetRenewal),
  73  	}
  74  
  75  	publishResponse(&models.Response{
  76  		ResultType: nip47Request.Method,
  77  		Result:     responsePayload,
  78  	}, nostr.Tags{})
  79  }
  80