added LND backend
This commit is contained in:
parent
8bb29d4b6e
commit
cc124317ea
|
@ -0,0 +1,8 @@
|
||||||
|
package backends
|
||||||
|
|
||||||
|
type Backend interface {
|
||||||
|
Connect() error
|
||||||
|
|
||||||
|
// Value in satoshis and expiry in seconds
|
||||||
|
GetInvoice(description string, value int64, expiry int64) (invoice string, err error)
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
package backends
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/hex"
|
||||||
|
"github.com/lightningnetwork/lnd/lnrpc"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
"google.golang.org/grpc/credentials"
|
||||||
|
"google.golang.org/grpc/metadata"
|
||||||
|
"io/ioutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LND struct {
|
||||||
|
RPCHost string `long:"rpchost" Description:"Host that the gRPC interface of LND is listening to"`
|
||||||
|
CertFile string `long:"certfile" Description:"TLS certificate for LND gRPC and REST services"`
|
||||||
|
MacaroonFile string `long:"macaroonfile" Description:"Admin macaroon file for LND authentication. Set to an empty string for no macaroon"`
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
con, err := grpc.Dial(lnd.RPCHost, grpc.WithTransportCredentials(creds))
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lnd *LND) GetInvoice(description string, value int64, expiry int64) (invoice string, err error) {
|
||||||
|
response, err := lnd.client.AddInvoice(lnd.ctx, &lnrpc.Invoice{
|
||||||
|
Memo: description,
|
||||||
|
Value: value,
|
||||||
|
Expiry: expiry,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.PaymentRequest, err
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package backends
|
||||||
|
|
||||||
|
import "github.com/op/go-logging"
|
||||||
|
|
||||||
|
var log logging.Logger
|
||||||
|
|
||||||
|
func UseLogger(logger logging.Logger) {
|
||||||
|
log = logger
|
||||||
|
}
|
48
config.go
48
config.go
|
@ -2,7 +2,11 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/jessevdk/go-flags"
|
"github.com/jessevdk/go-flags"
|
||||||
|
"github.com/michael1011/lightningtip/backends"
|
||||||
"github.com/op/go-logging"
|
"github.com/op/go-logging"
|
||||||
|
"os/user"
|
||||||
|
"path"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -11,23 +15,40 @@ const (
|
||||||
|
|
||||||
defaultLogFile = "lightningTip.log"
|
defaultLogFile = "lightningTip.log"
|
||||||
defaultLogLevel = "debug"
|
defaultLogLevel = "debug"
|
||||||
|
|
||||||
|
defaultLndRPCHost = "localhost:10009"
|
||||||
|
defaultLndCertFile = "tls.cert"
|
||||||
|
defaultMacaroonFile = "admin.macaroon"
|
||||||
)
|
)
|
||||||
|
|
||||||
type config struct {
|
type config struct {
|
||||||
ConfigFile string `long:"config" Description:"Config file location"`
|
ConfigFile string `long:"config" Description:"Config file location"`
|
||||||
|
|
||||||
LogFile string `long:"logfile" Description:"Log file location"`
|
LogFile string `long:"logfile" Description:"Log file location"`
|
||||||
LogLevel string `long:"loglevel" Description:"Log level: debug, info, warning, error"`
|
LogLevel string `long:"loglevel" Description:"Log level: debug, info, warning, error"`
|
||||||
|
|
||||||
|
LND *backends.LND `group:"LND" namespace:"lnd"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var cfg config
|
var cfg config
|
||||||
|
|
||||||
|
var backend backends.Backend
|
||||||
|
var backendName string
|
||||||
|
|
||||||
func initConfig() {
|
func initConfig() {
|
||||||
|
lndDir := getDefaultLndDir()
|
||||||
|
|
||||||
cfg = config{
|
cfg = config{
|
||||||
ConfigFile: defaultConfigFile,
|
ConfigFile: defaultConfigFile,
|
||||||
|
|
||||||
LogFile: defaultLogFile,
|
LogFile: defaultLogFile,
|
||||||
LogLevel: defaultLogLevel,
|
LogLevel: defaultLogLevel,
|
||||||
|
|
||||||
|
LND: &backends.LND{
|
||||||
|
RPCHost: defaultLndRPCHost,
|
||||||
|
CertFile: path.Join(lndDir, defaultLndCertFile),
|
||||||
|
MacaroonFile: path.Join(lndDir, defaultMacaroonFile),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := flags.Parse(&cfg)
|
_, err := flags.Parse(&cfg)
|
||||||
|
@ -58,7 +79,30 @@ func initConfig() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if errFile != nil {
|
if errFile != nil {
|
||||||
log.Infof("Could not parse config file: %v", errFile)
|
log.Infof("Failed to parse config file: %v", errFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: add more backend options like for example c-lighting
|
||||||
|
backend = cfg.LND
|
||||||
|
backendName = "LND"
|
||||||
|
}
|
||||||
|
|
||||||
|
func getDefaultLndDir() (dir string) {
|
||||||
|
usr, err := user.Current()
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "windows":
|
||||||
|
dir = path.Join(usr.HomeDir, "AppData/Local/Lnd")
|
||||||
|
|
||||||
|
case "darwin":
|
||||||
|
dir = path.Join(usr.HomeDir, "Library/Application Support/Lnd/tls.cert")
|
||||||
|
|
||||||
|
default:
|
||||||
|
dir = path.Join(usr.HomeDir, ".lnd")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return dir
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,21 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
initLog()
|
initLog()
|
||||||
|
|
||||||
initConfig()
|
initConfig()
|
||||||
|
|
||||||
|
err := backend.Connect()
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
log.Info("Successfully connected to " + backendName)
|
||||||
|
|
||||||
|
invoice, err := backend.GetInvoice("Just a test", 1, 3600)
|
||||||
|
|
||||||
|
log.Info("Got invoice " + invoice)
|
||||||
|
log.Info(fmt.Sprint(err))
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue