first commit
This commit is contained in:
109
internal/http/handlers/invoices.go
Normal file
109
internal/http/handlers/invoices.go
Normal file
@@ -0,0 +1,109 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/noderunners/nip05api/internal/invoice"
|
||||
"github.com/noderunners/nip05api/internal/nostr"
|
||||
"github.com/noderunners/nip05api/internal/user"
|
||||
)
|
||||
|
||||
type Invoices struct {
|
||||
Service *invoice.Service
|
||||
LightningEnabled bool
|
||||
}
|
||||
|
||||
type createInvoiceReq struct {
|
||||
Username string `json:"username"`
|
||||
Pubkey string `json:"pubkey"`
|
||||
SubscriptionType string `json:"subscription_type"`
|
||||
Years int `json:"years"`
|
||||
}
|
||||
|
||||
func (h *Invoices) Create(w http.ResponseWriter, r *http.Request) {
|
||||
if !h.LightningEnabled {
|
||||
WriteError(w, http.StatusServiceUnavailable, "LightningDisabled", "lightning payments are disabled")
|
||||
return
|
||||
}
|
||||
var body createInvoiceReq
|
||||
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
||||
WriteError(w, http.StatusBadRequest, "ValidationError", "invalid JSON")
|
||||
return
|
||||
}
|
||||
hexpk, err := nostr.NormalizePubkey(body.Pubkey)
|
||||
if err != nil {
|
||||
WriteError(w, http.StatusBadRequest, "ValidationError", "Invalid pubkey format")
|
||||
return
|
||||
}
|
||||
subStr := strings.TrimSpace(body.SubscriptionType)
|
||||
if subStr == "" {
|
||||
subStr = string(user.SubLifetime)
|
||||
}
|
||||
sub := user.SubscriptionType(subStr)
|
||||
if !sub.Valid() {
|
||||
WriteError(w, http.StatusBadRequest, "ValidationError", "invalid subscription_type")
|
||||
return
|
||||
}
|
||||
years := body.Years
|
||||
if sub == user.SubYearly && years <= 0 {
|
||||
years = 1
|
||||
}
|
||||
p, err := h.Service.Create(r.Context(), invoice.CreateRequest{
|
||||
Username: body.Username,
|
||||
Pubkey: hexpk,
|
||||
SubscriptionType: sub,
|
||||
Years: years,
|
||||
})
|
||||
if err != nil {
|
||||
switch {
|
||||
case errors.Is(err, invoice.ErrLifetimeAccess):
|
||||
WriteError(w, http.StatusForbidden, "User already has lifetime access", "")
|
||||
case errors.Is(err, invoice.ErrPendingInvoiceExists):
|
||||
WriteError(w, http.StatusConflict, "Conflict", err.Error())
|
||||
case errors.Is(err, invoice.ErrUsernameTaken),
|
||||
errors.Is(err, user.ErrUsernameTaken):
|
||||
WriteError(w, http.StatusConflict, "Conflict", "username unavailable")
|
||||
case errors.Is(err, invoice.ErrUsernameMismatch):
|
||||
WriteError(w, http.StatusConflict, "Conflict", err.Error())
|
||||
case errors.Is(err, user.ErrInvalidUsername),
|
||||
errors.Is(err, invoice.ErrInvalidYears):
|
||||
WriteError(w, http.StatusBadRequest, "ValidationError", err.Error())
|
||||
case errors.Is(err, invoice.ErrLNbits):
|
||||
WriteError(w, http.StatusServiceUnavailable, "LightningError", err.Error())
|
||||
default:
|
||||
WriteError(w, http.StatusInternalServerError, "InternalError", err.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
WriteJSON(w, http.StatusOK, map[string]any{
|
||||
"payment_hash": p.PaymentHash,
|
||||
"payment_request": p.PaymentRequest,
|
||||
"amount_sats": p.AmountSats,
|
||||
"expires_at": p.ExpiresAt.UTC().Format(time.RFC3339),
|
||||
"username": p.Username,
|
||||
"is_renewal": p.IsRenewal,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *Invoices) Get(w http.ResponseWriter, r *http.Request) {
|
||||
hash := chi.URLParam(r, "payment_hash")
|
||||
p, err := h.Service.Repo().Get(r.Context(), hash)
|
||||
if errors.Is(err, invoice.ErrInvoiceNotFound) {
|
||||
WriteError(w, http.StatusNotFound, "NotFound", "invoice not found")
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
WriteError(w, http.StatusInternalServerError, "InternalError", err.Error())
|
||||
return
|
||||
}
|
||||
WriteJSON(w, http.StatusOK, map[string]any{
|
||||
"payment_hash": p.PaymentHash,
|
||||
"status": string(p.Status()),
|
||||
"username": p.Username,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user