From 52dbc03dda545cb1d870661abd2f003c3967cde6 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Tue, 30 Apr 2019 19:43:08 -0700 Subject: [PATCH] lndclient: add NewBasicClient function --- go.mod | 2 +- lndclient/basic_client.go | 71 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 lndclient/basic_client.go diff --git a/go.mod b/go.mod index 64a6d8e..6e7679f 100644 --- a/go.mod +++ b/go.mod @@ -15,5 +15,5 @@ require ( golang.org/x/net v0.0.0-20190313220215-9f648a60d977 google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19 google.golang.org/grpc v1.19.0 - gopkg.in/macaroon.v2 v2.1.0 // indirect + gopkg.in/macaroon.v2 v2.1.0 ) diff --git a/lndclient/basic_client.go b/lndclient/basic_client.go new file mode 100644 index 0000000..989b053 --- /dev/null +++ b/lndclient/basic_client.go @@ -0,0 +1,71 @@ +package lndclient + +import ( + "fmt" + "io/ioutil" + "path/filepath" + + "github.com/lightningnetwork/lnd/lncfg" + "github.com/lightningnetwork/lnd/lnrpc" + "github.com/lightningnetwork/lnd/macaroons" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + macaroon "gopkg.in/macaroon.v2" +) + +// NewBasicClient creates a new basic gRPC client to lnd. We call this client +// "basic" as it uses a global macaroon (by default the admin macaroon) for the +// entire connection, and falls back to expected defaults if the arguments +// aren't provided. +func NewBasicClient(lndHost, tlsPath, macPath, network string) (lnrpc.LightningClient, error) { + if tlsPath == "" { + tlsPath = defaultTLSCertPath + } + + // Load the specified TLS certificate and build transport credentials + creds, err := credentials.NewClientTLSFromFile(tlsPath, "") + if err != nil { + return nil, err + } + + // Create a dial options array. + opts := []grpc.DialOption{ + grpc.WithTransportCredentials(creds), + } + + if macPath == "" { + macPath = filepath.Join( + defaultLndDir, defaultDataDir, defaultChainSubDir, + "bitcoin", network, defaultAdminMacaroonFilename, + ) + } + + // Load the specified macaroon file. + macBytes, err := ioutil.ReadFile(macPath) + if err == nil { + // Only if file is found + mac := &macaroon.Macaroon{} + if err = mac.UnmarshalBinary(macBytes); err != nil { + return nil, fmt.Errorf("unable to decode macaroon: %v", + err) + } + + // Now we append the macaroon credentials to the dial options. + cred := macaroons.NewMacaroonCredential(mac) + opts = append(opts, grpc.WithPerRPCCredentials(cred)) + } + + // We need to use a custom dialer so we can also connect to unix sockets + // and not just TCP addresses. + opts = append( + opts, grpc.WithDialer( + lncfg.ClientAddressDialer(defaultRPCPort), + ), + ) + conn, err := grpc.Dial(lndHost, opts...) + if err != nil { + return nil, fmt.Errorf("unable to connect to RPC server: %v", err) + } + + return lnrpc.NewLightningClient(conn), nil +}