lightningtip/backends/lnd.go

126 lines
2.5 KiB
Go
Raw Normal View History

2018-03-23 16:08:03 -07:00
package backends
import (
"context"
"encoding/hex"
2018-03-24 15:03:55 -07:00
"errors"
"github.com/donovanhide/eventsource"
2018-03-23 16:08:03 -07:00
"github.com/lightningnetwork/lnd/lnrpc"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/metadata"
2018-03-24 15:03:55 -07:00
"io"
2018-03-23 16:08:03 -07:00
"io/ioutil"
)
type LND struct {
2018-03-29 06:01:28 -07:00
GRPCHost string `long:"grpchost" Description:"Host of the gRPC interface of LND"`
CertFile string `long:"certfile" Description:"TLS certificate for the LND gRPC and REST services"`
MacaroonFile string `long:"macaroonfile" Description:"Admin macaroon file for authentication. Set to an empty string for no macaroon"`
2018-03-23 16:08:03 -07:00
client lnrpc.LightningClient
ctx context.Context
}
func (lnd *LND) Connect() error {
creds, err := credentials.NewClientTLSFromFile(lnd.CertFile, "")
if err != nil {
log.Error("Failed to read certificate for LND gRPC")
return err
}
2018-03-29 06:01:28 -07:00
con, err := grpc.Dial(lnd.GRPCHost, grpc.WithTransportCredentials(creds))
2018-03-23 16:08:03 -07:00
if err != nil {
log.Error("Failed to connect to LND gRPC server")
return err
}
lnd.ctx = context.Background()
if lnd.MacaroonFile != "" {
macaroon, err := getMacaroon(lnd.MacaroonFile)
if macaroon == nil && err != nil {
log.Error("Failed to read admin macaroon file of LND")
}
lnd.ctx = metadata.NewOutgoingContext(lnd.ctx, macaroon)
}
lnd.client = lnrpc.NewLightningClient(con)
return err
}
2018-03-25 08:45:42 -07:00
func (lnd *LND) GetInvoice(message string, amount int64, expiry int64) (invoice string, err error) {
var response *lnrpc.AddInvoiceResponse
2018-04-01 08:21:55 -07:00
response, err = lnd.client.AddInvoice(lnd.ctx, &lnrpc.Invoice{
Memo: message,
Value: amount,
Expiry: expiry,
})
2018-03-23 16:08:03 -07:00
if err != nil {
return "", err
}
return response.PaymentRequest, err
}
2018-03-24 15:03:55 -07:00
func (lnd *LND) SubscribeInvoices(callback PublishInvoiceSettled, eventSrv *eventsource.Server) error {
2018-03-24 15:03:55 -07:00
stream, err := lnd.client.SubscribeInvoices(lnd.ctx, &lnrpc.InvoiceSubscription{})
if err != nil {
return err
}
wait := make(chan struct{})
go func() {
for {
invoice, streamErr := stream.Recv()
2018-03-24 15:03:55 -07:00
if streamErr == io.EOF {
err = errors.New("lost connection to LND gRPC")
close(wait)
return
}
if streamErr != nil {
err = streamErr
close(wait)
return
}
if invoice.Settled {
callback(invoice.PaymentRequest, eventSrv)
}
2018-03-24 15:03:55 -07:00
}
2018-03-24 15:03:55 -07:00
}()
<-wait
return err
}
2018-03-31 07:11:25 -07:00
func getMacaroon(macaroonFile string) (macaroon metadata.MD, err error) {
data, err := ioutil.ReadFile(macaroonFile)
if err == nil {
macaroon = metadata.Pairs("macaroon", hex.EncodeToString(data))
}
return macaroon, err
2018-04-01 06:51:40 -07:00
}