package alchemy import ( "context" "fmt" "gitea.pena/PenaSide/treasurer/internal/errors" "gitea.pena/PenaSide/treasurer/internal/models" "gitea.pena/PenaSide/treasurer/internal/models/alchemy" "gitea.pena/PenaSide/treasurer/internal/repository" "github.com/gofiber/fiber/v2" "go.uber.org/zap" ) const ProviderName = "alchemy" type Config struct { WalletAddress string `json:"walletAddress"` } type Provider struct { repository *repository.PaymentRepository logger *zap.Logger config *Config } type Deps struct { Repository *repository.PaymentRepository Logger *zap.Logger Config *Config } func New(deps Deps) *Provider { return &Provider{ logger: deps.Logger, config: deps.Config, } } func (p *Provider) GetName() string { return ProviderName } func (p *Provider) GetSupportedPaymentMethods() []models.PaymentType { return []models.PaymentType{models.PaymentTypeAlchemy} } // todo func (p *Provider) CreateInvoice(ctx context.Context, req map[string]string) (string, errors.Error) { return "", nil } func (p *Provider) RegisterWebhookHandlers(router fiber.Router) { router.Post("/webhook/alchemy", p.handleWebhook) } func (p *Provider) handleWebhook(ctx *fiber.Ctx) error { var payload alchemy.AlchemyAddressActivityWebhook if err := ctx.BodyParser(&payload); err != nil { return ctx.Status(fiber.StatusBadRequest).SendString(fmt.Sprintf("failed to parse Alchemy webhook: %s", err.Error())) } for _, act := range payload.Event.Activity { if act.ToAddress != p.config.WalletAddress { continue } payment, err := p.repository.FindByWalletAddressAndAmount(ctx.Context(), act.FromAddress, act.Value) if err != nil { if err.Type() == errors.ErrNotFound { return ctx.Status(fiber.StatusNotFound).SendString(fmt.Sprintf("payment not found: %s", err.Error())) } return ctx.Status(fiber.StatusInternalServerError).SendString(fmt.Sprintf("internal error while searching payment: %s", err.Error())) } _, err = p.repository.SetPaymentComplete(ctx.Context(), payment.PaymentID) if err != nil { return ctx.Status(fiber.StatusInternalServerError).SendString(fmt.Sprintf("failed to set payment complete: %s", err.Error())) } } return ctx.SendStatus(fiber.StatusOK) }