2023-09-10 15:39:34 +00:00
|
|
|
package lnd
|
|
|
|
|
|
|
|
import (
|
2024-07-15 10:57:51 +00:00
|
|
|
"context"
|
|
|
|
"database/sql"
|
2023-09-10 15:39:34 +00:00
|
|
|
"log"
|
2024-07-15 10:57:51 +00:00
|
|
|
"time"
|
2023-09-10 15:39:34 +00:00
|
|
|
|
2024-07-15 10:57:51 +00:00
|
|
|
"git.ekzyis.com/ekzyis/delphi.market/db"
|
2023-09-10 15:39:34 +00:00
|
|
|
"github.com/lightninglabs/lndclient"
|
2024-07-15 10:57:51 +00:00
|
|
|
"github.com/lightningnetwork/lnd/invoices"
|
|
|
|
"github.com/lightningnetwork/lnd/lntypes"
|
2023-09-10 15:39:34 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type LNDClient struct {
|
2023-10-04 11:36:54 +00:00
|
|
|
*lndclient.GrpcLndServices
|
2023-09-10 15:39:34 +00:00
|
|
|
}
|
|
|
|
|
2023-10-04 11:36:54 +00:00
|
|
|
type LNDConfig = lndclient.LndServicesConfig
|
|
|
|
|
|
|
|
func New(config *LNDConfig) (*LNDClient, error) {
|
2023-09-10 15:39:34 +00:00
|
|
|
var (
|
2023-10-04 11:36:54 +00:00
|
|
|
rcpLndServices *lndclient.GrpcLndServices
|
|
|
|
lnd *LNDClient
|
2023-09-10 15:39:34 +00:00
|
|
|
err error
|
|
|
|
)
|
2023-10-04 11:36:54 +00:00
|
|
|
if rcpLndServices, err = lndclient.NewLndServices(config); err != nil {
|
|
|
|
return nil, err
|
2023-09-10 15:39:34 +00:00
|
|
|
}
|
2023-10-04 11:36:54 +00:00
|
|
|
lnd = &LNDClient{GrpcLndServices: rcpLndServices}
|
|
|
|
log.Printf("Connected to %s running LND v%s", config.LndAddress, lnd.Version.Version)
|
|
|
|
return lnd, nil
|
2023-09-10 15:39:34 +00:00
|
|
|
}
|
2024-07-15 10:57:51 +00:00
|
|
|
|
|
|
|
func (lnd *LNDClient) CheckInvoices(db *db.DB) {
|
|
|
|
var (
|
|
|
|
pending bool
|
|
|
|
rows *sql.Rows
|
|
|
|
hash lntypes.Hash
|
|
|
|
inv *lndclient.Invoice
|
|
|
|
err error
|
|
|
|
)
|
|
|
|
for {
|
|
|
|
// fetch all pending invoices
|
|
|
|
if rows, err = db.Query("" +
|
|
|
|
"SELECT hash, expires_at " +
|
|
|
|
"FROM invoices " +
|
|
|
|
"WHERE confirmed_at IS NULL AND expires_at > CURRENT_TIMESTAMP"); err != nil {
|
|
|
|
log.Printf("error checking invoices: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
pending = false
|
|
|
|
|
|
|
|
for rows.Next() {
|
|
|
|
pending = true
|
|
|
|
|
|
|
|
var (
|
|
|
|
h string
|
|
|
|
expiresAt time.Time
|
|
|
|
)
|
|
|
|
rows.Scan(&h, &expiresAt)
|
|
|
|
|
|
|
|
if hash, err = lntypes.MakeHashFromStr(h); err != nil {
|
|
|
|
log.Printf("error parsing hash: %v", err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
if inv, err = lnd.Client.LookupInvoice(context.TODO(), hash); err != nil {
|
|
|
|
log.Printf("error looking up invoice: %v", err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
if !inv.State.IsFinal() {
|
2024-08-26 10:34:43 +00:00
|
|
|
log.Printf("invoice pending: %s expiry=%s", h, time.Until(expiresAt))
|
2024-07-15 10:57:51 +00:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
if inv.State == invoices.ContractSettled {
|
|
|
|
if _, err = db.Exec(
|
|
|
|
"UPDATE invoices SET msats_received = $1, confirmed_at = $2 WHERE hash = $3",
|
|
|
|
inv.AmountPaid, inv.SettleDate, h); err != nil {
|
|
|
|
log.Printf("error updating invoice %s: %v", h, err)
|
|
|
|
}
|
|
|
|
log.Printf("invoice confirmed: %s", h)
|
|
|
|
} else if inv.State == invoices.ContractCanceled {
|
|
|
|
log.Printf("invoice expired: %s", h)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// poll faster if there are pending invoices
|
|
|
|
if pending {
|
|
|
|
time.Sleep(1 * time.Second)
|
|
|
|
} else {
|
|
|
|
time.Sleep(5 * time.Second)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|