diff --git a/controllers/keysend.ctrl.go b/controllers/keysend.ctrl.go index 99350b4..8d80371 100644 --- a/controllers/keysend.ctrl.go +++ b/controllers/keysend.ctrl.go @@ -72,7 +72,7 @@ func (controller *KeySendController) KeySend(c echo.Context) error { } } - if reqBody.Destination == controller.svc.IdentityPubkey && reqBody.CustomRecords[strconv.Itoa(service.TLV_WALLET_ID)] == "" { + if controller.svc.LndClient.IsIdentityPubkey(reqBody.Destination) && reqBody.CustomRecords[strconv.Itoa(service.TLV_WALLET_ID)] == "" { return c.JSON(http.StatusBadRequest, &responses.ErrorResponse{ Error: true, Code: 8, diff --git a/controllers_v2/keysend.ctrl.go b/controllers_v2/keysend.ctrl.go index 4ed2dbc..df01fb5 100644 --- a/controllers_v2/keysend.ctrl.go +++ b/controllers_v2/keysend.ctrl.go @@ -162,7 +162,7 @@ func (controller *KeySendController) SingleKeySend(c echo.Context, reqBody *KeyS if reqBody.CustomRecords != nil { customRecords = reqBody.CustomRecords } - if reqBody.Destination == controller.svc.IdentityPubkey && customRecords[strconv.Itoa(service.TLV_WALLET_ID)] == "" { + if controller.svc.LndClient.IsIdentityPubkey(reqBody.Destination) && customRecords[strconv.Itoa(service.TLV_WALLET_ID)] == "" { return nil, &responses.ErrorResponse{ Error: true, Code: 8, diff --git a/integration_tests/internal_payment_test.go b/integration_tests/internal_payment_test.go index e1edb64..986eeb5 100644 --- a/integration_tests/internal_payment_test.go +++ b/integration_tests/internal_payment_test.go @@ -283,7 +283,7 @@ func (suite *PaymentTestSuite) TestInternalPaymentKeysend() { var buf bytes.Buffer assert.NoError(suite.T(), json.NewEncoder(&buf).Encode(ExpectedKeySendRequestBody{ Amount: int64(bobAmt), - Destination: suite.service.IdentityPubkey, + Destination: suite.service.LndClient.GetMainPubkey(), Memo: memo, //add memo as WHATSAT_MESSAGE custom record CustomRecords: map[string]string{fmt.Sprint(service.TLV_WHATSAT_MESSAGE): memo, diff --git a/integration_tests/lnd_mock.go b/integration_tests/lnd_mock.go index c7571c4..47a758d 100644 --- a/integration_tests/lnd_mock.go +++ b/integration_tests/lnd_mock.go @@ -248,6 +248,15 @@ func (mlnd *MockLND) DecodeBolt11(ctx context.Context, bolt11 string, options .. } return result, nil } + +func (mlnd *MockLND) IsIdentityPubkey(pubkey string) (isOurPubkey bool) { + return pubkey == hex.EncodeToString(mlnd.pubKey.SerializeCompressed()) +} + +func (mlnd *MockLND) GetMainPubkey() (pubkey string) { + return hex.EncodeToString(mlnd.pubKey.SerializeCompressed()) +} + func makePreimageHex() ([]byte, error) { return randBytesFromStr(32, random.Hex) } diff --git a/integration_tests/subscription_start_test.go b/integration_tests/subscription_start_test.go index 01683dd..aea1ee4 100644 --- a/integration_tests/subscription_start_test.go +++ b/integration_tests/subscription_start_test.go @@ -144,3 +144,10 @@ func (mock *lndSubscriptionStartMockClient) DecodeBolt11(ctx context.Context, bo func (mlnd *lndSubscriptionStartMockClient) TrackPayment(ctx context.Context, hash []byte, options ...grpc.CallOption) (*lnrpc.Payment, error) { return nil, nil } +func (mlnd *lndSubscriptionStartMockClient) IsIdentityPubkey(pubkey string) (isOurPubkey bool) { + panic("not implemented") // TODO: Implement +} + +func (mlnd *lndSubscriptionStartMockClient) GetMainPubkey() (pubkey string) { + panic("not implemented") // TODO: Implement +} diff --git a/integration_tests/util.go b/integration_tests/util.go index c322047..3297ada 100644 --- a/integration_tests/util.go +++ b/integration_tests/util.go @@ -19,7 +19,6 @@ import ( "github.com/getAlby/lndhub.go/rabbitmq" "github.com/golang-jwt/jwt" "github.com/labstack/echo/v4" - "github.com/lightningnetwork/lnd/lnrpc" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "github.com/uptrace/bun/migrate" @@ -66,10 +65,10 @@ func LndHubTestServiceInit(lndClientMock lnd.LightningClientWrapper) (svc *servi c.RabbitMQLndhubInvoiceExchange = "test_lndhub_invoices" c.RabbitMQLndInvoiceExchange = "test_lnd_invoices" - amqpClient, err := rabbitmq.DialAMQP(c.RabbitMQUri) - if err != nil { - return nil, err - } + amqpClient, err := rabbitmq.DialAMQP(c.RabbitMQUri) + if err != nil { + return nil, err + } rabbitmqClient, err = rabbitmq.NewClient(amqpClient, rabbitmq.WithLndInvoiceExchange(c.RabbitMQLndInvoiceExchange), @@ -105,11 +104,6 @@ func LndHubTestServiceInit(lndClientMock lnd.LightningClientWrapper) (svc *servi Logger: logger, RabbitMQClient: rabbitmqClient, } - getInfo, err := lndClientMock.GetInfo(ctx, &lnrpc.GetInfoRequest{}) - if err != nil { - logger.Fatalf("Error getting node info: %v", err) - } - svc.IdentityPubkey = getInfo.IdentityPubkey svc.InvoicePubSub = service.NewPubsub() return svc, nil diff --git a/lib/service/invoices.go b/lib/service/invoices.go index f1d5cc9..ba3fc0b 100644 --- a/lib/service/invoices.go +++ b/lib/service/invoices.go @@ -217,7 +217,7 @@ func (svc *LndhubService) PayInvoice(ctx context.Context, invoice *models.Invoic // Check the destination pubkey if it is an internal invoice and going to our node // Here we start using context.Background because we want to complete these calls // regardless of if the request's context is canceled or not. - if svc.IdentityPubkey == invoice.DestinationPubkeyHex { + if svc.LndClient.IsIdentityPubkey(invoice.DestinationPubkeyHex) { paymentResponse, err = svc.SendInternalPayment(context.Background(), invoice) if err != nil { svc.HandleFailedPayment(context.Background(), invoice, entry, err) @@ -408,7 +408,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.IdentityPubkey // Our node pubkey for incoming invoices + invoice.DestinationPubkeyHex = svc.LndClient.GetMainPubkey() // Our node pubkey for incoming invoices invoice.State = common.InvoiceStateOpen _, err = svc.DB.NewUpdate().Model(&invoice).WherePK().Exec(ctx) diff --git a/lib/service/invoicesubscription.go b/lib/service/invoicesubscription.go index 909e7b8..85ffbe4 100644 --- a/lib/service/invoicesubscription.go +++ b/lib/service/invoicesubscription.go @@ -46,7 +46,7 @@ func (svc *LndhubService) HandleInternalKeysendPayment(ctx context.Context, invo RHash: hex.EncodeToString(pHash.Sum(nil)), Preimage: hex.EncodeToString(preImage), DestinationCustomRecords: invoice.DestinationCustomRecords, - DestinationPubkeyHex: svc.IdentityPubkey, + DestinationPubkeyHex: svc.LndClient.GetMainPubkey(), AddIndex: invoice.AddIndex, } //persist the incoming invoice @@ -212,7 +212,7 @@ func (svc *LndhubService) createKeysendInvoice(ctx context.Context, rawInvoice * RHash: hex.EncodeToString(rawInvoice.RHash), Preimage: hex.EncodeToString(rawInvoice.RPreimage), DestinationCustomRecords: rawInvoice.Htlcs[0].CustomRecords, - DestinationPubkeyHex: svc.IdentityPubkey, + DestinationPubkeyHex: svc.LndClient.GetMainPubkey(), AddIndex: rawInvoice.AddIndex, } return result, nil diff --git a/lib/service/service.go b/lib/service/service.go index b7d3feb..b4278ff 100644 --- a/lib/service/service.go +++ b/lib/service/service.go @@ -25,7 +25,6 @@ type LndhubService struct { LndClient lnd.LightningClientWrapper RabbitMQClient rabbitmq.Client Logger *lecho.Logger - IdentityPubkey string InvoicePubSub *Pubsub } diff --git a/lib/service/user.go b/lib/service/user.go index 0c04435..45e6a3f 100644 --- a/lib/service/user.go +++ b/lib/service/user.go @@ -135,7 +135,7 @@ func (svc *LndhubService) BalanceCheck(ctx context.Context, lnpayReq *lnd.LNPayR } func (svc *LndhubService) CalcFeeLimit(destination string, amount int64) int64 { - if destination == svc.IdentityPubkey { + if svc.LndClient.IsIdentityPubkey(destination) { return 0 } limit := int64(10) diff --git a/lnd/interface.go b/lnd/interface.go index e7de050..15fdf5a 100644 --- a/lnd/interface.go +++ b/lnd/interface.go @@ -16,6 +16,8 @@ type LightningClientWrapper interface { SubscribePayment(ctx context.Context, req *routerrpc.TrackPaymentRequest, options ...grpc.CallOption) (SubscribePaymentWrapper, 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) + IsIdentityPubkey(pubkey string) (isOurPubkey bool) + GetMainPubkey() (pubkey string) } type SubscribeInvoicesWrapper interface { diff --git a/lnd/lnd.go b/lnd/lnd.go index a95b444..0261a93 100644 --- a/lnd/lnd.go +++ b/lnd/lnd.go @@ -31,11 +31,12 @@ type LNDoptions struct { } type LNDWrapper struct { - client lnrpc.LightningClient - routerClient routerrpc.RouterClient + client lnrpc.LightningClient + routerClient routerrpc.RouterClient + IdentityPubkey string } -func NewLNDclient(lndOptions LNDoptions) (result *LNDWrapper, err error) { +func NewLNDclient(lndOptions LNDoptions, ctx context.Context) (result *LNDWrapper, err error) { // Get credentials either from a hex string, a file or the system's certificate store var creds credentials.TransportCredentials // if a hex string is provided @@ -92,10 +93,15 @@ func NewLNDclient(lndOptions LNDoptions) (result *LNDWrapper, err error) { if err != nil { return nil, err } - + lnClient := lnrpc.NewLightningClient(conn) + getInfo, err := lnClient.GetInfo(ctx, &lnrpc.GetInfoRequest{}) + if err != nil { + return nil, err + } return &LNDWrapper{ - client: lnrpc.NewLightningClient(conn), - routerClient: routerrpc.NewRouterClient(conn), + client: lnClient, + routerClient: routerrpc.NewRouterClient(conn), + IdentityPubkey: getInfo.IdentityPubkey, }, nil } @@ -128,3 +134,11 @@ func (wrapper *LNDWrapper) DecodeBolt11(ctx context.Context, bolt11 string, opti func (wrapper *LNDWrapper) SubscribePayment(ctx context.Context, req *routerrpc.TrackPaymentRequest, options ...grpc.CallOption) (SubscribePaymentWrapper, error) { return wrapper.routerClient.TrackPaymentV2(ctx, req, options...) } + +func (wrapper *LNDWrapper) IsIdentityPubkey(pubkey string) (isOurPubkey bool) { + return pubkey == wrapper.IdentityPubkey +} + +func (wrapper *LNDWrapper) GetMainPubkey() (pubkey string) { + return wrapper.IdentityPubkey +} diff --git a/main.go b/main.go index 0760e83..f28deb9 100644 --- a/main.go +++ b/main.go @@ -24,7 +24,6 @@ import ( "github.com/joho/godotenv" "github.com/kelseyhightower/envconfig" "github.com/labstack/echo/v4" - "github.com/lightningnetwork/lnd/lnrpc" echoSwagger "github.com/swaggo/echo-swagger" "github.com/uptrace/bun/migrate" ) @@ -105,15 +104,12 @@ func main() { MacaroonHex: c.LNDMacaroonHex, CertFile: c.LNDCertFile, CertHex: c.LNDCertHex, - }) + }, startupCtx) if err != nil { logger.Fatalf("Error initializing the LND connection: %v", err) } - getInfo, err := lndClient.GetInfo(startupCtx, &lnrpc.GetInfoRequest{}) - if err != nil { - logger.Fatalf("Error getting node info: %v", err) - } - logger.Infof("Connected to LND: %s - %s", getInfo.Alias, getInfo.IdentityPubkey) + + logger.Infof("Connected to LND: %s ", lndClient.GetMainPubkey()) // If no RABBITMQ_URI was provided we will not attempt to create a client // No rabbitmq features will be available in this case. @@ -147,7 +143,6 @@ func main() { DB: dbConn, LndClient: lndClient, Logger: logger, - IdentityPubkey: getInfo.IdentityPubkey, InvoicePubSub: service.NewPubsub(), RabbitMQClient: rabbitmqClient, } diff --git a/reconciliation_lost_invoices/main.go b/reconciliation_lost_invoices/main.go index 0ce27aa..bdd41ec 100644 --- a/reconciliation_lost_invoices/main.go +++ b/reconciliation_lost_invoices/main.go @@ -13,7 +13,6 @@ import ( "github.com/joho/godotenv" "github.com/kelseyhightower/envconfig" "github.com/labstack/echo/v4" - "github.com/lightningnetwork/lnd/lnrpc" ) // script to reconcile pending payments between the backup node and the database @@ -54,23 +53,18 @@ func main() { MacaroonHex: c.LNDMacaroonHex, CertFile: c.LNDCertFile, CertHex: c.LNDCertHex, - }) + }, startupCtx) if err != nil { e.Logger.Fatalf("Error initializing the LND connection: %v", err) } - getInfo, err := lndClient.GetInfo(startupCtx, &lnrpc.GetInfoRequest{}) - if err != nil { - e.Logger.Fatalf("Error getting node info: %v", err) - } - logger.Infof("Connected to LND: %s - %s", getInfo.Alias, getInfo.IdentityPubkey) + logger.Infof("Connected to LND: %s ", lndClient.GetMainPubkey()) svc := &service.LndhubService{ - Config: c, - DB: dbConn, - LndClient: lndClient, - Logger: logger, - IdentityPubkey: getInfo.IdentityPubkey, - InvoicePubSub: service.NewPubsub(), + Config: c, + DB: dbConn, + LndClient: lndClient, + Logger: logger, + InvoicePubSub: service.NewPubsub(), } err = svc.CheckAllPendingOutgoingPayments(startupCtx)