diff --git a/controllers/payinvoice.ctrl.go b/controllers/payinvoice.ctrl.go index eaa07ba..36c4e7e 100644 --- a/controllers/payinvoice.ctrl.go +++ b/controllers/payinvoice.ctrl.go @@ -51,7 +51,7 @@ func (controller *PayInvoiceController) PayInvoice(c echo.Context) error { } paymentRequest := reqBody.Invoice - decodedPaymentRequest, err := controller.svc.DecodePaymentRequest(paymentRequest) + decodedPaymentRequest, err := controller.svc.DecodePaymentRequest(c.Request().Context(), paymentRequest) if err != nil { c.Logger().Errorf("Invalid payment request: %v", err) sentry.CaptureException(err) diff --git a/db/models/invoice.go b/db/models/invoice.go index 2b5d86c..ebb0aa5 100644 --- a/db/models/invoice.go +++ b/db/models/invoice.go @@ -2,10 +2,8 @@ package models import ( "context" - "encoding/hex" "time" - "github.com/btcsuite/btcd/btcec" "github.com/uptrace/bun" ) @@ -31,18 +29,6 @@ type Invoice struct { SettledAt bun.NullTime `json:"settled_at"` } -func (i *Invoice) DestinationPubkey() (*btcec.PublicKey, error) { - hexPubkey, err := hex.DecodeString(i.DestinationPubkeyHex) - if err != nil { - return nil, err - } - pubkey, err := btcec.ParsePubKey(hexPubkey[:], btcec.S256()) - if err != nil { - return nil, err - } - return pubkey, nil -} - func (i *Invoice) BeforeAppendModel(ctx context.Context, query bun.Query) error { switch query.(type) { case *bun.UpdateQuery: diff --git a/integration_tests/util.go b/integration_tests/util.go index 9e4e41a..38f5cd8 100644 --- a/integration_tests/util.go +++ b/integration_tests/util.go @@ -3,13 +3,11 @@ package integration_tests import ( "bytes" "context" - "encoding/hex" "encoding/json" "fmt" "net/http" "net/http/httptest" - "github.com/btcsuite/btcd/btcec" "github.com/getAlby/lndhub.go/controllers" "github.com/getAlby/lndhub.go/db" "github.com/getAlby/lndhub.go/db/migrations" @@ -71,15 +69,7 @@ func LndHubTestServiceInit() (svc *service.LndhubService, err error) { if err != nil { logger.Fatalf("Error getting node info: %v", err) } - hexPubkey, err := hex.DecodeString(getInfo.IdentityPubkey) - if err != nil { - logger.Fatalf("Failed to decode IdentityPubkey: %v", err) - } - identityPubKey, err := btcec.ParsePubKey(hexPubkey[:], btcec.S256()) - if err != nil { - logger.Fatalf("Failed to parse node IdentityPubkey: %v", err) - } - svc.IdentityPubkey = identityPubKey + svc.IdentityPubkey = getInfo.IdentityPubkey return svc, nil } diff --git a/lib/service/invoices.go b/lib/service/invoices.go index 35af77f..2ab6f5a 100644 --- a/lib/service/invoices.go +++ b/lib/service/invoices.go @@ -6,15 +6,12 @@ import ( "encoding/hex" "errors" "math/rand" - "strings" "time" - "github.com/btcsuite/btcd/chaincfg" "github.com/getAlby/lndhub.go/common" "github.com/getAlby/lndhub.go/db/models" "github.com/labstack/gommon/random" "github.com/lightningnetwork/lnd/lnrpc" - "github.com/lightningnetwork/lnd/zpay32" "github.com/uptrace/bun" "github.com/uptrace/bun/schema" ) @@ -181,12 +178,7 @@ func (svc *LndhubService) PayInvoice(ctx context.Context, invoice *models.Invoic var paymentResponse SendPaymentResponse // Check the destination pubkey if it is an internal invoice and going to our node - destinationPubkey, err := invoice.DestinationPubkey() - if err != nil { - // TODO: logging - return nil, err - } - if svc.IdentityPubkey.IsEqual(destinationPubkey) { + if svc.IdentityPubkey == invoice.DestinationPubkeyHex { paymentResponse, err = svc.SendInternalPayment(ctx, &tx, invoice) if err != nil { tx.Rollback() @@ -223,32 +215,19 @@ func (svc *LndhubService) PayInvoice(ctx context.Context, invoice *models.Invoic return &paymentResponse, err } -func (svc *LndhubService) AddOutgoingInvoice(ctx context.Context, userID int64, paymentRequest string, decodedInvoice *zpay32.Invoice) (*models.Invoice, error) { +func (svc *LndhubService) AddOutgoingInvoice(ctx context.Context, userID int64, paymentRequest string, decodedInvoice *lnrpc.PayReq) (*models.Invoice, error) { // Initialize new DB invoice - destinationPubkeyHex := hex.EncodeToString(decodedInvoice.Destination.SerializeCompressed()) - expiresAt := decodedInvoice.Timestamp.Add(decodedInvoice.Expiry()) invoice := models.Invoice{ Type: common.InvoiceTypeOutgoing, UserID: userID, PaymentRequest: paymentRequest, + RHash: decodedInvoice.PaymentHash, + Amount: decodedInvoice.NumSatoshis, State: common.InvoiceStateInitialized, - DestinationPubkeyHex: destinationPubkeyHex, - ExpiresAt: bun.NullTime{Time: expiresAt}, - } - if decodedInvoice.Description != nil { - invoice.Memo = *decodedInvoice.Description - } - if decodedInvoice.DescriptionHash != nil { - dh := *decodedInvoice.DescriptionHash - invoice.DescriptionHash = hex.EncodeToString(dh[:]) - } - if decodedInvoice.PaymentHash != nil { - ph := *decodedInvoice.PaymentHash - invoice.RHash = hex.EncodeToString(ph[:]) - } - if decodedInvoice.MilliSat != nil { - msat := decodedInvoice.MilliSat - invoice.Amount = int64(msat.ToSatoshis()) + DestinationPubkeyHex: decodedInvoice.Destination, + DescriptionHash: decodedInvoice.DescriptionHash, + Memo: decodedInvoice.Description, + ExpiresAt: bun.NullTime{Time: time.Unix(decodedInvoice.Timestamp, 0).Add(time.Duration(decodedInvoice.Expiry) * time.Second)}, } // Save invoice @@ -302,7 +281,7 @@ func (svc *LndhubService) AddIncomingInvoice(ctx context.Context, userID int64, invoice.RHash = hex.EncodeToString(lnInvoiceResult.RHash) invoice.Preimage = hex.EncodeToString(preimage) invoice.AddIndex = lnInvoiceResult.AddIndex - invoice.DestinationPubkeyHex = svc.GetIdentPubKeyHex() // Our node pubkey for incoming invoices + invoice.DestinationPubkeyHex = svc.IdentityPubkey // Our node pubkey for incoming invoices invoice.State = common.InvoiceStateOpen _, err = svc.DB.NewUpdate().Model(&invoice).WherePK().Exec(ctx) @@ -313,8 +292,8 @@ func (svc *LndhubService) AddIncomingInvoice(ctx context.Context, userID int64, return &invoice, nil } -func (svc *LndhubService) DecodePaymentRequest(bolt11 string) (*zpay32.Invoice, error) { - return zpay32.Decode(bolt11, ChainFromCurrency(bolt11[2:])) +func (svc *LndhubService) DecodePaymentRequest(ctx context.Context, bolt11 string) (*lnrpc.PayReq, error) { + return svc.LndClient.DecodeBolt11(ctx, bolt11) } const hexBytes = random.Hex @@ -326,15 +305,3 @@ func makePreimageHex() []byte { } return b } - -func ChainFromCurrency(currency string) *chaincfg.Params { - if strings.HasPrefix(currency, "bcrt") { - return &chaincfg.RegressionNetParams - } else if strings.HasPrefix(currency, "tb") { - return &chaincfg.TestNet3Params - } else if strings.HasPrefix(currency, "sb") { - return &chaincfg.SimNetParams - } else { - return &chaincfg.MainNetParams - } -} diff --git a/lib/service/ln.go b/lib/service/ln.go index 2a7bf52..a9f609a 100644 --- a/lib/service/ln.go +++ b/lib/service/ln.go @@ -2,7 +2,6 @@ package service import ( "context" - "encoding/hex" "github.com/lightningnetwork/lnd/lnrpc" ) @@ -10,7 +9,3 @@ import ( func (svc *LndhubService) GetInfo(ctx context.Context) (*lnrpc.GetInfoResponse, error) { return svc.LndClient.GetInfo(ctx, &lnrpc.GetInfoRequest{}) } - -func (svc *LndhubService) GetIdentPubKeyHex() string { - return hex.EncodeToString(svc.IdentityPubkey.SerializeCompressed()) -} diff --git a/lib/service/service.go b/lib/service/service.go index aac2cb6..86d4f5e 100644 --- a/lib/service/service.go +++ b/lib/service/service.go @@ -5,7 +5,6 @@ import ( "fmt" "strconv" - "github.com/btcsuite/btcd/btcec" "github.com/getAlby/lndhub.go/db/models" "github.com/getAlby/lndhub.go/lib/tokens" "github.com/getAlby/lndhub.go/lnd" @@ -22,7 +21,7 @@ type LndhubService struct { DB *bun.DB LndClient lnd.LightningClientWrapper Logger *lecho.Logger - IdentityPubkey *btcec.PublicKey + IdentityPubkey string } func (svc *LndhubService) GenerateToken(ctx context.Context, login, password, inRefreshToken string) (accessToken, refreshToken string, err error) { diff --git a/lnd/interface.go b/lnd/interface.go index c5a39a7..0c3733b 100644 --- a/lnd/interface.go +++ b/lnd/interface.go @@ -13,6 +13,7 @@ type LightningClientWrapper interface { AddInvoice(ctx context.Context, req *lnrpc.Invoice, options ...grpc.CallOption) (*lnrpc.AddInvoiceResponse, error) SubscribeInvoices(ctx context.Context, req *lnrpc.InvoiceSubscription, options ...grpc.CallOption) (SubscribeInvoicesWrapper, error) GetInfo(ctx context.Context, req *lnrpc.GetInfoRequest, options ...grpc.CallOption) (*lnrpc.GetInfoResponse, error) + DecodeBolt11(ctx context.Context, bolt11 string, options ...grpc.CallOption) (*lnrpc.PayReq, error) } type SubscribeInvoicesWrapper interface { diff --git a/lnd/lnd.go b/lnd/lnd.go index d62bd6e..dbfe8c8 100644 --- a/lnd/lnd.go +++ b/lnd/lnd.go @@ -110,3 +110,9 @@ func (wrapper *LNDWrapper) SubscribeInvoices(ctx context.Context, req *lnrpc.Inv func (wrapper *LNDWrapper) GetInfo(ctx context.Context, req *lnrpc.GetInfoRequest, options ...grpc.CallOption) (*lnrpc.GetInfoResponse, error) { return wrapper.client.GetInfo(ctx, req, options...) } + +func (wrapper *LNDWrapper) DecodeBolt11(ctx context.Context, bolt11 string, options ...grpc.CallOption) (*lnrpc.PayReq, error) { + return wrapper.client.DecodePayReq(ctx, &lnrpc.PayReqString{ + PayReq: bolt11, + }) +} diff --git a/main.go b/main.go index af659fc..c67ff7e 100644 --- a/main.go +++ b/main.go @@ -3,7 +3,6 @@ package main import ( "context" "embed" - "encoding/hex" "fmt" "log" "net/http" @@ -11,7 +10,6 @@ import ( "os/signal" "time" - "github.com/btcsuite/btcd/btcec" "github.com/getAlby/lndhub.go/controllers" "github.com/getAlby/lndhub.go/db" "github.com/getAlby/lndhub.go/db/migrations" @@ -113,14 +111,6 @@ func main() { if err != nil { e.Logger.Fatalf("Error getting node info: %v", err) } - hexPubkey, err := hex.DecodeString(getInfo.IdentityPubkey) - if err != nil { - logger.Fatalf("Failed to decode IdentityPubkey: %v", err) - } - identityPubKey, err := btcec.ParsePubKey(hexPubkey[:], btcec.S256()) - if err != nil { - logger.Fatalf("Failed to parse node IdentityPubkey: %v", err) - } logger.Infof("Connected to LND: %s - %s", getInfo.Alias, getInfo.IdentityPubkey) svc := &service.LndhubService{ @@ -128,7 +118,7 @@ func main() { DB: dbConn, LndClient: lndClient, Logger: logger, - IdentityPubkey: identityPubKey, + IdentityPubkey: getInfo.IdentityPubkey, } // Public endpoints for account creation and authentication