127 lines
3.3 KiB
Go
127 lines
3.3 KiB
Go
package lnd
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"time"
|
|
|
|
"git.ekzyis.com/ekzyis/delphi.market/db"
|
|
"github.com/lightninglabs/lndclient"
|
|
"github.com/lightningnetwork/lnd/lnrpc/invoicesrpc"
|
|
"github.com/lightningnetwork/lnd/lntypes"
|
|
"github.com/lightningnetwork/lnd/lnwire"
|
|
)
|
|
|
|
func (lnd *LNDClient) CreateInvoice(d *db.DB, pubkey string, msats int64, description string) (*db.Invoice, error) {
|
|
var (
|
|
expiry time.Duration = time.Hour
|
|
preimage lntypes.Preimage
|
|
hash lntypes.Hash
|
|
paymentRequest string
|
|
lnInvoice *lndclient.Invoice
|
|
dbInvoice *db.Invoice
|
|
err error
|
|
)
|
|
if preimage, err = generateNewPreimage(); err != nil {
|
|
return nil, err
|
|
}
|
|
hash = preimage.Hash()
|
|
if paymentRequest, err = lnd.Invoices.AddHoldInvoice(context.TODO(), &invoicesrpc.AddInvoiceData{
|
|
Hash: &hash,
|
|
Value: lnwire.MilliSatoshi(msats),
|
|
Expiry: int64(expiry / time.Millisecond),
|
|
}); err != nil {
|
|
return nil, err
|
|
}
|
|
if lnInvoice, err = lnd.Client.LookupInvoice(context.TODO(), hash); err != nil {
|
|
return nil, err
|
|
}
|
|
dbInvoice = &db.Invoice{
|
|
Pubkey: pubkey,
|
|
Msats: msats,
|
|
Preimage: preimage.String(),
|
|
PaymentRequest: paymentRequest,
|
|
Hash: hash.String(),
|
|
CreatedAt: lnInvoice.CreationDate,
|
|
ExpiresAt: lnInvoice.CreationDate.Add(expiry),
|
|
Description: description,
|
|
}
|
|
if err := d.CreateInvoice(dbInvoice); err != nil {
|
|
return nil, err
|
|
}
|
|
return dbInvoice, nil
|
|
}
|
|
|
|
func (lnd *LNDClient) CheckInvoice(d *db.DB, hash lntypes.Hash) {
|
|
var (
|
|
pollInterval = 5 * time.Second
|
|
invoice db.Invoice
|
|
lnInvoice *lndclient.Invoice
|
|
preimage lntypes.Preimage
|
|
err error
|
|
)
|
|
|
|
if err = d.FetchInvoice(&db.FetchInvoiceWhere{Hash: hash.String()}, &invoice); err != nil {
|
|
log.Println(err)
|
|
return
|
|
}
|
|
|
|
handleLoopError := func(err error) {
|
|
log.Println(err)
|
|
time.Sleep(pollInterval)
|
|
}
|
|
|
|
for {
|
|
log.Printf("lookup invoice: hash=%s", hash)
|
|
if lnInvoice, err = lnd.Client.LookupInvoice(context.TODO(), hash); err != nil {
|
|
handleLoopError(err)
|
|
continue
|
|
}
|
|
if time.Now().After(invoice.ExpiresAt) {
|
|
// cancel invoices after expiration if no matching order found yet
|
|
if err = lnd.Invoices.CancelInvoice(context.TODO(), hash); err != nil {
|
|
handleLoopError(err)
|
|
continue
|
|
}
|
|
log.Printf("invoice expired: hash=%s", hash)
|
|
break
|
|
}
|
|
if lnInvoice.AmountPaid > 0 {
|
|
if preimage, err = lntypes.MakePreimageFromStr(invoice.Preimage); err != nil {
|
|
handleLoopError(err)
|
|
continue
|
|
}
|
|
// TODO settle invoice after matching order was found
|
|
if err = lnd.Invoices.SettleInvoice(context.TODO(), preimage); err != nil {
|
|
handleLoopError(err)
|
|
continue
|
|
}
|
|
if err = d.ConfirmInvoice(hash.String(), time.Now(), int(lnInvoice.AmountPaid)); err != nil {
|
|
handleLoopError(err)
|
|
continue
|
|
}
|
|
log.Printf("invoice confirmed: hash=%s", hash)
|
|
break
|
|
}
|
|
time.Sleep(pollInterval)
|
|
}
|
|
}
|
|
|
|
func (lnd *LNDClient) CheckInvoices(d *db.DB) error {
|
|
var (
|
|
invoices []db.Invoice
|
|
err error
|
|
hash lntypes.Hash
|
|
)
|
|
if err = d.FetchInvoices(&db.FetchInvoicesWhere{Unconfirmed: true}, &invoices); err != nil {
|
|
return err
|
|
}
|
|
for _, invoice := range invoices {
|
|
if hash, err = lntypes.MakeHashFromStr(invoice.Hash); err != nil {
|
|
return err
|
|
}
|
|
go lnd.CheckInvoice(d, hash)
|
|
}
|
|
return nil
|
|
}
|