diff --git a/README.md b/README.md index cb07470a..853927d5 100644 --- a/README.md +++ b/README.md @@ -135,11 +135,9 @@ You can also contribute to our [bounty program](https://github.com/getAlby/light ✅ `pay_keysend` -⚠️ `make_invoice` -- ⚠️ does not match spec +✅ `make_invoice` -⚠️ `lookup_invoice` -- ⚠️ does not match spec +✅ `lookup_invoice` ✅ `list_transactions` - ⚠️ from and until in request not supported @@ -165,12 +163,11 @@ You can also contribute to our [bounty program](https://github.com/getAlby/light ✅ `pay_keysend` - ⚠️ preimage in request not supported -⚠️ `make_invoice` +✅ `make_invoice` - ⚠️ expiry in request not supported -- ⚠️ does not match spec -⚠️ `lookup_invoice` -- ⚠️ does not match spec +✅ `lookup_invoice` +- ⚠️ fees_paid in response not supported ✅ `list_transactions` - ⚠️ offset and unpaid in request not supported diff --git a/alby.go b/alby.go index ca63a1f1..7a0e0f9d 100644 --- a/alby.go +++ b/alby.go @@ -79,7 +79,7 @@ func (svc *AlbyOAuthService) FetchUserToken(ctx context.Context, app App) (token return tok, nil } -func (svc *AlbyOAuthService) MakeInvoice(ctx context.Context, senderPubkey string, amount int64, description string, descriptionHash string, expiry int64) (invoice string, paymentHash string, err error) { +func (svc *AlbyOAuthService) MakeInvoice(ctx context.Context, senderPubkey string, amount int64, description string, descriptionHash string, expiry int64) (transaction *Nip47Transaction, err error) { // TODO: move to a shared function app := App{} err = svc.db.Preload("User").First(&app, &App{ @@ -93,7 +93,7 @@ func (svc *AlbyOAuthService) MakeInvoice(ctx context.Context, senderPubkey strin "descriptionHash": descriptionHash, "expiry": expiry, }).Errorf("App not found: %v", err) - return "", "", err + return nil, err } // amount provided in msat, but Alby API currently only supports sats. Will get truncated to a whole sat value @@ -107,7 +107,7 @@ func (svc *AlbyOAuthService) MakeInvoice(ctx context.Context, senderPubkey strin "descriptionHash": descriptionHash, "expiry": expiry, }).Errorf("amount must be 1000 msat or greater") - return "", "", errors.New("amount must be 1000 msat or greater") + return nil, errors.New("amount must be 1000 msat or greater") } svc.Logger.WithFields(logrus.Fields{ @@ -121,7 +121,7 @@ func (svc *AlbyOAuthService) MakeInvoice(ctx context.Context, senderPubkey strin }).Info("Processing make invoice request") tok, err := svc.FetchUserToken(ctx, app) if err != nil { - return "", "", err + return nil, err } client := svc.oauthConf.Client(ctx, tok) @@ -138,7 +138,7 @@ func (svc *AlbyOAuthService) MakeInvoice(ctx context.Context, senderPubkey strin req, err := http.NewRequest("POST", fmt.Sprintf("%s/invoices", svc.cfg.AlbyAPIURL), body) if err != nil { svc.Logger.WithError(err).Error("Error creating request /invoices") - return "", "", err + return nil, err } // TODO: move to creation of HTTP client @@ -156,14 +156,14 @@ func (svc *AlbyOAuthService) MakeInvoice(ctx context.Context, senderPubkey strin "appId": app.ID, "userId": app.User.ID, }).Errorf("Failed to make invoice: %v", err) - return "", "", err + return nil, err } if resp.StatusCode < 300 { - responsePayload := &MakeInvoiceResponse{} + responsePayload := &AlbyInvoice{} err = json.NewDecoder(resp.Body).Decode(responsePayload) if err != nil { - return "", "", err + return nil, err } svc.Logger.WithFields(logrus.Fields{ "senderPubkey": senderPubkey, @@ -176,7 +176,9 @@ func (svc *AlbyOAuthService) MakeInvoice(ctx context.Context, senderPubkey strin "paymentRequest": responsePayload.PaymentRequest, "paymentHash": responsePayload.PaymentHash, }).Info("Make invoice successful") - return responsePayload.PaymentRequest, responsePayload.PaymentHash, nil + + transaction := albyInvoiceToTransaction(responsePayload) + return transaction, nil } errorPayload := &ErrorResponse{} @@ -191,10 +193,10 @@ func (svc *AlbyOAuthService) MakeInvoice(ctx context.Context, senderPubkey strin "userId": app.User.ID, "APIHttpStatus": resp.StatusCode, }).Errorf("Make invoice failed %s", string(errorPayload.Message)) - return "", "", errors.New(errorPayload.Message) + return nil, errors.New(errorPayload.Message) } -func (svc *AlbyOAuthService) LookupInvoice(ctx context.Context, senderPubkey string, paymentHash string) (invoice string, paid bool, err error) { +func (svc *AlbyOAuthService) LookupInvoice(ctx context.Context, senderPubkey string, paymentHash string) (transaction *Nip47Transaction, err error) { // TODO: move to a shared function app := App{} err = svc.db.Preload("User").First(&app, &App{ @@ -205,7 +207,7 @@ func (svc *AlbyOAuthService) LookupInvoice(ctx context.Context, senderPubkey str "senderPubkey": senderPubkey, "paymentHash": paymentHash, }).Errorf("App not found: %v", err) - return "", false, err + return nil, err } svc.Logger.WithFields(logrus.Fields{ @@ -216,7 +218,7 @@ func (svc *AlbyOAuthService) LookupInvoice(ctx context.Context, senderPubkey str }).Info("Processing lookup invoice request") tok, err := svc.FetchUserToken(ctx, app) if err != nil { - return "", false, err + return nil, err } client := svc.oauthConf.Client(ctx, tok) @@ -226,7 +228,7 @@ func (svc *AlbyOAuthService) LookupInvoice(ctx context.Context, senderPubkey str req, err := http.NewRequest("GET", fmt.Sprintf("%s/invoices/%s", svc.cfg.AlbyAPIURL, paymentHash), body) if err != nil { svc.Logger.WithError(err).Errorf("Error creating request /invoices/%s", paymentHash) - return "", false, err + return nil, err } req.Header.Set("User-Agent", "NWC") @@ -240,14 +242,14 @@ func (svc *AlbyOAuthService) LookupInvoice(ctx context.Context, senderPubkey str "appId": app.ID, "userId": app.User.ID, }).Errorf("Failed to lookup invoice: %v", err) - return "", false, err + return nil, err } if resp.StatusCode < 300 { - responsePayload := &LookupInvoiceResponse{} + responsePayload := &AlbyInvoice{} err = json.NewDecoder(resp.Body).Decode(responsePayload) if err != nil { - return "", false, err + return nil, err } svc.Logger.WithFields(logrus.Fields{ "senderPubkey": senderPubkey, @@ -257,7 +259,9 @@ func (svc *AlbyOAuthService) LookupInvoice(ctx context.Context, senderPubkey str "paymentRequest": responsePayload.PaymentRequest, "settled": responsePayload.Settled, }).Info("Lookup invoice successful") - return responsePayload.PaymentRequest, responsePayload.Settled, nil + + transaction = albyInvoiceToTransaction(responsePayload) + return transaction, nil } errorPayload := &ErrorResponse{} @@ -269,7 +273,7 @@ func (svc *AlbyOAuthService) LookupInvoice(ctx context.Context, senderPubkey str "userId": app.User.ID, "APIHttpStatus": resp.StatusCode, }).Errorf("Lookup invoice failed %s", string(errorPayload.Message)) - return "", false, errors.New(errorPayload.Message) + return nil, errors.New(errorPayload.Message) } func (svc *AlbyOAuthService) GetInfo(ctx context.Context, senderPubkey string) (info *NodeInfo, err error) { @@ -437,27 +441,9 @@ func (svc *AlbyOAuthService) ListTransactions(ctx context.Context, senderPubkey transactions = []Nip47Transaction{} for _, invoice := range invoices { - description := invoice.Comment - if description == "" { - description = invoice.Memo - } - - transaction := Nip47Transaction{ - Type: invoice.Type, - Invoice: invoice.PaymentRequest, - Description: description, - DescriptionHash: invoice.DescriptionHash, - Preimage: invoice.Preimage, - PaymentHash: invoice.PaymentHash, - Amount: invoice.Amount * 1000, - FeesPaid: 0, // TODO: support fees - CreatedAt: invoice.CreatedAt, - ExpiresAt: invoice.ExpiresAt, - SettledAt: invoice.SettledAt, - Metadata: invoice.Metadata, - } - - transactions = append(transactions, transaction) + transaction := albyInvoiceToTransaction(&invoice) + + transactions = append(transactions, *transaction) } svc.Logger.WithFields(logrus.Fields{ @@ -712,3 +698,29 @@ func (svc *AlbyOAuthService) CallbackHandler(c echo.Context) error { sess.Save(c.Request(), c.Response()) return c.Redirect(302, "/") } + +func albyInvoiceToTransaction(invoice *AlbyInvoice) *Nip47Transaction { + description := invoice.Comment + if description == "" { + description = invoice.Memo + } + var preimage string + if invoice.SettledAt != nil { + preimage = invoice.Preimage + } + + return &Nip47Transaction{ + Type: invoice.Type, + Invoice: invoice.PaymentRequest, + Description: description, + DescriptionHash: invoice.DescriptionHash, + Preimage: preimage, + PaymentHash: invoice.PaymentHash, + Amount: invoice.Amount * 1000, + FeesPaid: 0, // TODO: support fees + CreatedAt: invoice.CreatedAt, + ExpiresAt: invoice.ExpiresAt, + SettledAt: invoice.SettledAt, + Metadata: invoice.Metadata, + } +} diff --git a/handle_lookup_invoice_request.go b/handle_lookup_invoice_request.go index 428fb77d..9217bfe4 100644 --- a/handle_lookup_invoice_request.go +++ b/handle_lookup_invoice_request.go @@ -84,7 +84,7 @@ func (svc *Service) HandleLookupInvoiceEvent(ctx context.Context, request *Nip47 paymentHash = paymentRequest.PaymentHash } - invoice, paid, err := svc.lnClient.LookupInvoice(ctx, event.PubKey, paymentHash) + transaction, err := svc.lnClient.LookupInvoice(ctx, event.PubKey, paymentHash) if err != nil { svc.Logger.WithFields(logrus.Fields{ "eventId": event.ID, @@ -105,8 +105,7 @@ func (svc *Service) HandleLookupInvoiceEvent(ctx context.Context, request *Nip47 } responsePayload := &Nip47LookupInvoiceResponse{ - Invoice: invoice, - Paid: paid, + Nip47Transaction: *transaction, } nostrEvent.State = NOSTR_EVENT_STATE_HANDLER_EXECUTED diff --git a/handle_make_invoice_request.go b/handle_make_invoice_request.go index 6a84dc5b..5269c694 100644 --- a/handle_make_invoice_request.go +++ b/handle_make_invoice_request.go @@ -81,7 +81,7 @@ func (svc *Service) HandleMakeInvoiceEvent(ctx context.Context, request *Nip47Re "expiry": makeInvoiceParams.Expiry, }).Info("Making invoice") - invoice, paymentHash, err := svc.lnClient.MakeInvoice(ctx, event.PubKey, makeInvoiceParams.Amount, makeInvoiceParams.Description, makeInvoiceParams.DescriptionHash, makeInvoiceParams.Expiry) + transaction, err := svc.lnClient.MakeInvoice(ctx, event.PubKey, makeInvoiceParams.Amount, makeInvoiceParams.Description, makeInvoiceParams.DescriptionHash, makeInvoiceParams.Expiry) if err != nil { svc.Logger.WithFields(logrus.Fields{ "eventId": event.ID, @@ -104,8 +104,7 @@ func (svc *Service) HandleMakeInvoiceEvent(ctx context.Context, request *Nip47Re } responsePayload := &Nip47MakeInvoiceResponse{ - Invoice: invoice, - PaymentHash: paymentHash, + Nip47Transaction: *transaction, } nostrEvent.State = NOSTR_EVENT_STATE_HANDLER_EXECUTED diff --git a/lnd.go b/lnd.go index f18a9139..9de5e334 100644 --- a/lnd.go +++ b/lnd.go @@ -25,9 +25,9 @@ type LNClient interface { SendKeysend(ctx context.Context, senderPubkey string, amount int64, destination, preimage string, custom_records []TLVRecord) (preImage string, err error) GetBalance(ctx context.Context, senderPubkey string) (balance int64, err error) GetInfo(ctx context.Context, senderPubkey string) (info *NodeInfo, err error) - MakeInvoice(ctx context.Context, senderPubkey string, amount int64, description string, descriptionHash string, expiry int64) (invoice string, paymentHash string, err error) - LookupInvoice(ctx context.Context, senderPubkey string, paymentHash string) (invoice string, paid bool, err error) - ListTransactions(ctx context.Context, senderPubkey string, from, until, limit, offset uint64, unpaid bool, invoiceType string) (invoices []Nip47Transaction, err error) + MakeInvoice(ctx context.Context, senderPubkey string, amount int64, description string, descriptionHash string, expiry int64) (transaction *Nip47Transaction, err error) + LookupInvoice(ctx context.Context, senderPubkey string, paymentHash string) (transaction *Nip47Transaction, err error) + ListTransactions(ctx context.Context, senderPubkey string, from, until, limit, offset uint64, unpaid bool, invoiceType string) (transactions []Nip47Transaction, err error) } // wrap it again :sweat_smile: @@ -75,21 +75,8 @@ func (svc *LNDService) ListTransactions(ctx context.Context, senderPubkey string continue } - transaction := Nip47Transaction{ - Type: "incoming", - Invoice: invoice.PaymentRequest, - Description: invoice.Memo, - DescriptionHash: hex.EncodeToString(invoice.DescriptionHash), - Preimage: hex.EncodeToString(invoice.RPreimage), - PaymentHash: hex.EncodeToString(invoice.RHash), - Amount: invoice.ValueMsat, - FeesPaid: invoice.AmtPaidMsat, - CreatedAt: time.Unix(invoice.CreationDate, 0), - SettledAt: time.Unix(invoice.SettleDate, 0), - ExpiresAt: time.Unix(invoice.CreationDate+invoice.Expiry, 0), - // TODO: Metadata (e.g. keysend) - } - transactions = append(transactions, transaction) + transaction := lndInvoiceToTransaction(invoice) + transactions = append(transactions, *transaction) } // Fetch payments var payments []*lnrpc.Payment @@ -108,7 +95,7 @@ func (svc *LNDService) ListTransactions(ctx context.Context, senderPubkey string continue } var paymentRequest decodepay.Bolt11 - var expiresAt time.Time + var expiresAt *time.Time var description string var descriptionHash string if payment.PaymentRequest != "" { @@ -120,15 +107,17 @@ func (svc *LNDService) ListTransactions(ctx context.Context, senderPubkey string return nil, err } - expiresAt = time.UnixMilli(int64(paymentRequest.CreatedAt) * 1000).Add(time.Duration(paymentRequest.Expiry) * time.Second) + expiresAt = &time.Time{} + *expiresAt = time.UnixMilli(int64(paymentRequest.CreatedAt) * 1000).Add(time.Duration(paymentRequest.Expiry) * time.Second) description = paymentRequest.Description descriptionHash = paymentRequest.DescriptionHash } - var settledAt time.Time + var settledAt *time.Time if payment.Status == lnrpc.Payment_SUCCEEDED { // FIXME: how to get the actual settled at time? - settledAt = time.Unix(0, payment.CreationTimeNs) + settledAt = &time.Time{} + *settledAt = time.Unix(0, payment.CreationTimeNs) } transaction := Nip47Transaction{ @@ -171,7 +160,7 @@ func (svc *LNDService) GetInfo(ctx context.Context, senderPubkey string) (info * }, nil } -func (svc *LNDService) MakeInvoice(ctx context.Context, senderPubkey string, amount int64, description string, descriptionHash string, expiry int64) (invoice string, paymentHash string, err error) { +func (svc *LNDService) MakeInvoice(ctx context.Context, senderPubkey string, amount int64, description string, descriptionHash string, expiry int64) (transaction *Nip47Transaction, err error) { var descriptionHashBytes []byte if descriptionHash != "" { @@ -185,34 +174,41 @@ func (svc *LNDService) MakeInvoice(ctx context.Context, senderPubkey string, amo "descriptionHash": descriptionHash, "expiry": expiry, }).Errorf("Invalid description hash") - return "", "", errors.New("Description hash must be 32 bytes hex") + return nil, errors.New("Description hash must be 32 bytes hex") } } resp, err := svc.client.AddInvoice(ctx, &lnrpc.Invoice{ValueMsat: amount, Memo: description, DescriptionHash: descriptionHashBytes, Expiry: expiry}) if err != nil { - return "", "", err + return nil, err + } + + inv, err := svc.client.LookupInvoice(ctx, &lnrpc.PaymentHash{RHash: resp.RHash}) + if err != nil { + return nil, err } - return resp.GetPaymentRequest(), hex.EncodeToString(resp.GetRHash()), nil + transaction = lndInvoiceToTransaction(inv) + return transaction, nil } -func (svc *LNDService) LookupInvoice(ctx context.Context, senderPubkey string, paymentHash string) (invoice string, paid bool, err error) { +func (svc *LNDService) LookupInvoice(ctx context.Context, senderPubkey string, paymentHash string) (transaction *Nip47Transaction, err error) { paymentHashBytes, err := hex.DecodeString(paymentHash) if err != nil || len(paymentHashBytes) != 32 { svc.Logger.WithFields(logrus.Fields{ "paymentHash": paymentHash, }).Errorf("Invalid payment hash") - return "", false, errors.New("Payment hash must be 32 bytes hex") + return nil, errors.New("Payment hash must be 32 bytes hex") } lndInvoice, err := svc.client.LookupInvoice(ctx, &lnrpc.PaymentHash{RHash: paymentHashBytes}) if err != nil { - return "", false, err + return nil, err } - return lndInvoice.PaymentRequest, lndInvoice.State == *lnrpc.Invoice_SETTLED.Enum(), nil + transaction = lndInvoiceToTransaction(lndInvoice) + return transaction, nil } func (svc *LNDService) SendPaymentSync(ctx context.Context, senderPubkey, payReq string) (preimage string, err error) { @@ -358,3 +354,34 @@ func NewLNDService(ctx context.Context, svc *Service, e *echo.Echo) (result *LND return lndService, nil } + +func lndInvoiceToTransaction(invoice *lnrpc.Invoice) *Nip47Transaction { + var settledAt *time.Time + var preimage string + if invoice.State == lnrpc.Invoice_SETTLED { + settledAt = &time.Time{} + *settledAt = time.Unix(invoice.SettleDate, 0) + // only set preimage if invoice is settled + preimage = hex.EncodeToString(invoice.RPreimage) + } + var expiresAt *time.Time + if invoice.Expiry > 0 { + expiresAt = &time.Time{} + *expiresAt = time.Unix(invoice.SettleDate, 0) + } + + return &Nip47Transaction{ + Type: "incoming", + Invoice: invoice.PaymentRequest, + Description: invoice.Memo, + DescriptionHash: hex.EncodeToString(invoice.DescriptionHash), + Preimage: preimage, + PaymentHash: hex.EncodeToString(invoice.RHash), + Amount: invoice.ValueMsat, + FeesPaid: invoice.AmtPaidMsat, + CreatedAt: time.Unix(invoice.CreationDate, 0), + SettledAt: settledAt, + ExpiresAt: expiresAt, + // TODO: Metadata (e.g. keysend) + } +} diff --git a/models.go b/models.go index 7b0ebf52..4f56a251 100644 --- a/models.go +++ b/models.go @@ -136,8 +136,8 @@ type Nip47Transaction struct { Amount int64 `json:"amount"` FeesPaid int64 `json:"fees_paid"` CreatedAt time.Time `json:"created_at"` - ExpiresAt time.Time `json:"expires_at"` - SettledAt time.Time `json:"settled_at"` + ExpiresAt *time.Time `json:"expires_at"` + SettledAt *time.Time `json:"settled_at"` Metadata interface{} `json:"metadata,omitempty"` } @@ -150,9 +150,9 @@ type AlbyInvoice struct { // CreationDate uint64 `json:"creation_date"` Currency string `json:"currency"` // custom_records - DescriptionHash string `json:"description_hash"` - ExpiresAt time.Time `json:"expires_at"` - Expiry uint32 `json:"expiry"` + DescriptionHash string `json:"description_hash"` + ExpiresAt *time.Time `json:"expires_at"` + Expiry uint32 `json:"expiry"` // Identifier string KeysendMessage string `json:"keysend_message"` Memo string `json:"memo"` @@ -163,10 +163,10 @@ type AlbyInvoice struct { PaymentRequest string `json:"payment_request"` Preimage string `json:"preimage"` // r_hash_str - Settled bool `json:"settled"` - SettledAt time.Time `json:"settled_at"` - State string `json:"state"` - Type string `json:"type"` + Settled bool `json:"settled"` + SettledAt *time.Time `json:"settled_at"` + State string `json:"state"` + Type string `json:"type"` // value } @@ -198,18 +198,12 @@ type MakeInvoiceRequest struct { DescriptionHash string `json:"description_hash"` } -// TODO: this should have the same content as Nip47Transaction type MakeInvoiceResponse struct { - // Nip47Transaction - PaymentRequest string `json:"payment_request"` - PaymentHash string `json:"payment_hash"` + Nip47Transaction } -// TODO: this should have the same content as Nip47Transaction type LookupInvoiceResponse struct { - // Nip47Transaction - PaymentRequest string `json:"payment_request"` - Settled bool `json:"settled"` + Nip47Transaction } type ErrorResponse struct { @@ -293,8 +287,7 @@ type Nip47MakeInvoiceParams struct { Expiry int64 `json:"expiry"` } type Nip47MakeInvoiceResponse struct { - Invoice string `json:"invoice"` - PaymentHash string `json:"payment_hash"` + Nip47Transaction } type Nip47LookupInvoiceParams struct { @@ -303,8 +296,7 @@ type Nip47LookupInvoiceParams struct { } type Nip47LookupInvoiceResponse struct { - Invoice string `json:"invoice"` - Paid bool `json:"paid"` + Nip47Transaction } type Nip47ListTransactionsParams struct { diff --git a/service_test.go b/service_test.go index befaac36..fecefee3 100644 --- a/service_test.go +++ b/service_test.go @@ -110,6 +110,8 @@ var mockNodeInfo = NodeInfo{ BlockHash: "123blockhash", } +var mockTime = time.Unix(1693876963, 0) + var mockTransactions = []Nip47Transaction{ { Type: "incoming", @@ -120,7 +122,7 @@ var mockTransactions = []Nip47Transaction{ PaymentHash: "payment_hash_1", Amount: 1000, FeesPaid: 50, - SettledAt: time.Unix(1693876963, 0), + SettledAt: &mockTime, Metadata: map[string]interface{}{ "key1": "value1", "key2": 42, @@ -135,9 +137,10 @@ var mockTransactions = []Nip47Transaction{ PaymentHash: "payment_hash_2", Amount: 2000, FeesPaid: 75, - SettledAt: time.Unix(1693876965, 0), + SettledAt: &mockTime, }, } +var mockTransaction = &mockTransactions[0] // TODO: split up into individual tests func TestHandleEvent(t *testing.T) { @@ -480,8 +483,7 @@ func TestHandleEvent(t *testing.T) { } err = json.Unmarshal([]byte(decrypted), received) assert.NoError(t, err) - assert.Equal(t, mockInvoice, received.Result.(*Nip47MakeInvoiceResponse).Invoice) - assert.Equal(t, mockPaymentHash, received.Result.(*Nip47MakeInvoiceResponse).PaymentHash) + assert.Equal(t, mockTransaction.Preimage, received.Result.(*Nip47MakeInvoiceResponse).Preimage) // lookup_invoice: without permission newPayload, err = nip04.Encrypt(nip47LookupInvoiceJson, ss) @@ -520,8 +522,7 @@ func TestHandleEvent(t *testing.T) { } err = json.Unmarshal([]byte(decrypted), received) assert.NoError(t, err) - assert.Equal(t, mockInvoice, received.Result.(*Nip47LookupInvoiceResponse).Invoice) - assert.Equal(t, false, received.Result.(*Nip47LookupInvoiceResponse).Paid) + assert.Equal(t, mockTransaction.Preimage, received.Result.(*Nip47LookupInvoiceResponse).Preimage) // list_transactions: without permission newPayload, err = nip04.Encrypt(nip47ListTransactionsJson, ss) @@ -672,12 +673,12 @@ func (mln *MockLn) GetInfo(ctx context.Context, senderPubkey string) (info *Node return &mockNodeInfo, nil } -func (mln *MockLn) MakeInvoice(ctx context.Context, senderPubkey string, amount int64, description string, descriptionHash string, expiry int64) (invoice string, paymentHash string, err error) { - return mockInvoice, mockPaymentHash, nil +func (mln *MockLn) MakeInvoice(ctx context.Context, senderPubkey string, amount int64, description string, descriptionHash string, expiry int64) (transaction *Nip47Transaction, err error) { + return mockTransaction, nil } -func (mln *MockLn) LookupInvoice(ctx context.Context, senderPubkey string, paymentHash string) (invoice string, paid bool, err error) { - return mockInvoice, false, nil +func (mln *MockLn) LookupInvoice(ctx context.Context, senderPubkey string, paymentHash string) (transaction *Nip47Transaction, err error) { + return mockTransaction, nil } func (mln *MockLn) ListTransactions(ctx context.Context, senderPubkey string, from, until, limit, offset uint64, unpaid bool, invoiceType string) (invoices []Nip47Transaction, err error) {