lndclient: add new macaroonPouch struct

In this commit, we add a new struct, the `macaroonPouch`. This struct
bundles all the macaroons we need for each sub-server. Along the way, we
also export the set of default* paths for lnd, and add a new set of
variables that store the default file names of each of the macaroons for
each sub-server.

The `WithMacaroonAuth` method on the `serializedMacaroon` type will
allow us to attach a macaroon for each call rather than attaching it at
the connection level. This slight change will allow us to use multiple
macaroons over a single RPC connection, rather than a single global
macaroon.
pull/45/head
Olaoluwa Osuntokun 5 years ago
parent 3d0d73348d
commit ee6191f844

@ -122,11 +122,17 @@ var (
defaultRPCPort = "10009"
defaultLndDir = btcutil.AppDataDir("lnd", false)
defaultTLSCertFilename = "tls.cert"
defaultTLSCertPath = filepath.Join(defaultLndDir,
defaultTLSCertFilename)
defaultDataDir = "data"
defaultChainSubDir = "chain"
defaultMacaroonFilename = "admin.macaroon"
defaultTLSCertPath = filepath.Join(
defaultLndDir, defaultTLSCertFilename,
)
defaultDataDir = "data"
defaultChainSubDir = "chain"
defaultAdminMacaroonFilename = "admin.macaroon"
defaultInvoiceMacaroonFilename = "invoices.macaroon"
defaultChainMacaroonFilename = "chainnotifier.macaroon"
defaultWalletKitMacaroonFilename = "walletkit.macaroon"
defaultSignerFilename = "signer.macaroon"
)
func getClientConn(address string, network string, macPath, tlsPath string) (
@ -151,7 +157,7 @@ func getClientConn(address string, network string, macPath, tlsPath string) (
if macPath == "" {
macPath = filepath.Join(
defaultLndDir, defaultDataDir, defaultChainSubDir,
"bitcoin", network, defaultMacaroonFilename,
"bitcoin", network, defaultAdminMacaroonFilename,
)
}

@ -0,0 +1,98 @@
package lndclient
import (
"context"
"encoding/hex"
"io/ioutil"
"path/filepath"
"google.golang.org/grpc/metadata"
)
// serializedMacaroon is a type that represents a hex-encoded macaroon. We'll
// use this primarily vs the raw binary format as the gRPC metadata feature
// requires that all keys and values be strings.
type serializedMacaroon string
// newSerializedMacaroon reads a new serializedMacaroon from that target
// macaroon path. If the file can't be found, then an error is returned.
func newSerializedMacaroon(macaroonPath string) (serializedMacaroon, error) {
macBytes, err := ioutil.ReadFile(macaroonPath)
if err != nil {
return "", err
}
return serializedMacaroon(hex.EncodeToString(macBytes)), nil
}
// WithMacaroonAuth modifies the passed context to include the macaroon KV
// metadata of the target macaroon. This method can be used to add the macaroon
// at call time, rather than when the connection to the gRPC server is created.
func (s serializedMacaroon) WithMacaroonAuth(ctx context.Context) context.Context {
return metadata.AppendToOutgoingContext(ctx, "macaroon", string(s))
}
// macaroonPouch holds the set of macaroons we need to interact with lnd for
// Loop. Each sub-server has its own macaroon, and for the remaining temporary
// calls that directly hit lnd, we'll use the admin macaroon.
type macaroonPouch struct {
// invoiceMac is the macaroon for the invoices sub-server.
invoiceMac serializedMacaroon
// chainMac is the macaroon for the ChainNotifier sub-server.
chainMac serializedMacaroon
// signerMac is the macaroon for the Signer sub-server.
signerMac serializedMacaroon
// walletKitMac is the macaroon for the WalletKit sub-server.
walletKitMac serializedMacaroon
// adminMac is the primary admin macaroon for lnd.
adminMac serializedMacaroon
}
// newMacaroonPouch returns a new instance of a fully populated macaroonPouch
// given the directory where all the macaroons are stored.
func newMacaroonPouch(macaroonDir string) (*macaroonPouch, error) {
m := &macaroonPouch{}
var err error
m.invoiceMac, err = newSerializedMacaroon(
filepath.Join(macaroonDir, defaultInvoiceMacaroonFilename),
)
if err != nil {
return nil, err
}
m.chainMac, err = newSerializedMacaroon(
filepath.Join(macaroonDir, defaultChainMacaroonFilename),
)
if err != nil {
return nil, err
}
m.signerMac, err = newSerializedMacaroon(
filepath.Join(macaroonDir, defaultSignerFilename),
)
if err != nil {
return nil, err
}
m.walletKitMac, err = newSerializedMacaroon(
filepath.Join(macaroonDir, defaultWalletKitMacaroonFilename),
)
if err != nil {
return nil, err
}
m.adminMac, err = newSerializedMacaroon(
filepath.Join(macaroonDir, defaultAdminMacaroonFilename),
)
if err != nil {
return nil, err
}
return m, nil
}
Loading…
Cancel
Save