Implement addinvoice call

This commit is contained in:
Michael Bumann
2022-01-19 19:43:29 +01:00
parent 818dd78c6f
commit f625ef7efc
3 changed files with 82 additions and 46 deletions

View File

@@ -1,12 +1,10 @@
package controllers
import (
"math/rand"
"net/http"
"github.com/getAlby/lndhub.go/lib/service"
"github.com/labstack/echo/v4"
"github.com/labstack/gommon/random"
)
// AddInvoiceController : Add invoice controller struct
@@ -22,7 +20,7 @@ func NewAddInvoiceController(svc *service.LndhubService) *AddInvoiceController {
func (controller *AddInvoiceController) AddInvoice(c echo.Context) error {
userID := c.Get("UserID").(int64)
type RequestBody struct {
Amt uint `json:"amt" validate:"required"`
Amt int64 `json:"amt" validate:"required,gte=0"` // amount in Satoshi
Memo string `json:"memo"`
DescriptionHash string `json:"description_hash"`
}
@@ -30,41 +28,41 @@ func (controller *AddInvoiceController) AddInvoice(c echo.Context) error {
var body RequestBody
if err := c.Bind(&body); err != nil {
c.Logger().Errorf("Failed to load addinvoice request body: %v", err)
return c.JSON(http.StatusBadRequest, echo.Map{
"message": "failed to bind json, amt field with positive value is required",
"error": true,
"code": 8,
"message": "Bad arguments",
})
}
if err := c.Validate(&body); err != nil {
c.Logger().Errorf("Invalid addinvoice request body: %v", err)
return c.JSON(http.StatusBadRequest, echo.Map{
"message": "amt with positive value is required",
"error": true,
"code": 8,
"message": "Bad arguments",
})
}
c.Logger().Infof("Adding invoice: user_id=%v memo=%s value=%v description_hash=%s", userID, body.Memo, body.Amt, body.DescriptionHash)
invoice, err := controller.svc.AddInvoice(userID, body.Amt, body.Memo, body.DescriptionHash)
if err != nil {
c.Logger().Errorf("error saving an invoice: %v", err)
c.Logger().Errorf("Error creating invoice: %v", err)
// TODO: sentry notification
return c.JSON(http.StatusInternalServerError, nil)
}
var responseBody struct {
RHash string `json:"r_hash"`
PaymentRequest string `json:"payment_request"`
PayReq string `json:"pay_req"`
}
//TODO
responseBody.PayReq = makePreimageHex()
responseBody.RHash = invoice.RHash
responseBody.PaymentRequest = invoice.PaymentRequest
responseBody.PayReq = invoice.PaymentRequest
return c.JSON(http.StatusOK, &responseBody)
}
const hexBytes = random.Hex
func makePreimageHex() string {
b := make([]byte, 32)
for i := range b {
b[i] = hexBytes[rand.Intn(len(hexBytes))]
}
return string(b)
}

View File

@@ -9,20 +9,20 @@ import (
// Invoice : Invoice Model
type Invoice struct {
ID uint `json:"id" bun:",pk,autoincrement"`
Type string `json:"type"`
UserID int64 `json:"user_id"`
User *User `bun:"rel:belongs-to,join:user_id=id"`
TransactionEntryID uint `json:"transaction_entry_id"`
Amount uint `json:"amount"`
Memo string `json:"memo"`
DescriptionHash string `json:"description_hash"`
PaymentRequest string `json:"payment_request"`
RHash string `json:"r_hash"`
State string `json:"state"`
CreatedAt time.Time `bun:",nullzero,notnull,default:current_timestamp"`
UpdatedAt bun.NullTime `json:"updated_at"`
SettledAt bun.NullTime `json:"settled_at"`
ID uint `json:"id" bun:",pk,autoincrement"`
Type string `json:"type"`
UserID int64 `json:"user_id"`
User *User `bun:"rel:belongs-to,join:user_id=id"`
Amount int64 `json:"amount"`
Memo string `json:"memo"`
DescriptionHash string `json:"description_hash"`
PaymentRequest string `json:"payment_request"`
RHash string `json:"r_hash"`
State string `json:"state"`
AddIndex uint64 `json:"add_index"`
CreatedAt time.Time `bun:",nullzero,notnull,default:current_timestamp"`
UpdatedAt bun.NullTime `json:"updated_at"`
SettledAt bun.NullTime `json:"settled_at"`
}
func (i *Invoice) BeforeAppendModel(ctx context.Context, query bun.Query) error {

View File

@@ -2,8 +2,12 @@ package service
import (
"context"
"encoding/hex"
"math/rand"
"github.com/getAlby/lndhub.go/db/models"
"github.com/labstack/gommon/random"
"github.com/lightningnetwork/lnd/lnrpc"
)
func (svc *LndhubService) Payinvoice(userId int64, invoice string) error {
@@ -27,23 +31,57 @@ func (svc *LndhubService) Payinvoice(userId int64, invoice string) error {
}
func (svc *LndhubService) AddInvoice(userID int64, amount uint, memo, descriptionHash string) (*models.Invoice, error) {
invoice := &models.Invoice{
Type: "",
UserID: userID,
TransactionEntryID: 0,
Amount: amount,
Memo: memo,
DescriptionHash: descriptionHash,
PaymentRequest: "",
RHash: "",
State: "",
func (svc *LndhubService) AddInvoice(userID int64, amount int64, memo, descriptionHash string) (*models.Invoice, error) {
// Initialize new DB invoice
invoice := models.Invoice{
Type: "incoming",
UserID: userID,
Amount: amount,
Memo: memo,
DescriptionHash: descriptionHash,
State: "initialized",
}
// TODO: move this to a service layer and call a method
_, err := svc.DB.NewInsert().Model(invoice).Exec(context.TODO())
// Save invoice - we save the invoice early to have a record in case the LN call fails
_, err := svc.DB.NewInsert().Model(&invoice).Exec(context.TODO())
if err != nil {
return nil, err
}
return invoice, nil
// Initialize lnrpc invoice
lnInvoice := lnrpc.Invoice{
Memo: memo,
Value: amount,
RPreimage: makePreimageHex(),
Expiry: 3600 * 24, // 24h
}
lndClient := *svc.LndClient
// Call LND
lnInvoiceResult, err := lndClient.AddInvoice(context.TODO(), &lnInvoice)
if err != nil {
return nil, err
}
// Update the DB invoice with the data from the LND gRPC call
invoice.PaymentRequest = lnInvoiceResult.PaymentRequest
invoice.RHash = hex.EncodeToString(lnInvoiceResult.RHash)
invoice.AddIndex = lnInvoiceResult.AddIndex
invoice.State = "created"
_, err = svc.DB.NewUpdate().Model(&invoice).WherePK().Exec(context.TODO())
if err != nil {
return nil, err
}
return &invoice, nil
}
const hexBytes = random.Hex
func makePreimageHex() []byte {
b := make([]byte, 32)
for i := range b {
b[i] = hexBytes[rand.Intn(len(hexBytes))]
}
return b
}