1
1
package lndclient
2
2
3
3
import (
4
+ "encoding/hex"
4
5
"fmt"
5
6
"io/ioutil"
6
7
"path/filepath"
@@ -52,13 +53,14 @@ func (bc *basicClientOptions) applyBasicClientOptions(options ...BasicClientOpti
52
53
// NewBasicClient creates a new basic gRPC client to lnd. We call this client
53
54
// "basic" as it falls back to expected defaults if the arguments aren't
54
55
// provided.
55
- func NewBasicClient (lndHost , tlsPath , macDir , network string ,
56
- basicOptions ... BasicClientOption ) (
56
+ func NewBasicClient (lndHost , tlsPath , macDir , tlsData , macData ,
57
+ network string , basicOptions ... BasicClientOption ) (
57
58
58
59
lnrpc.LightningClient , error ) {
59
60
60
61
conn , err := NewBasicConn (
61
- lndHost , tlsPath , macDir , network , basicOptions ... ,
62
+ lndHost , tlsPath , macDir , tlsData , macData , network ,
63
+ basicOptions ... ,
62
64
)
63
65
if err != nil {
64
66
return nil , err
@@ -70,54 +72,26 @@ func NewBasicClient(lndHost, tlsPath, macDir, network string,
70
72
// NewBasicConn creates a new basic gRPC connection to lnd. We call this
71
73
// connection "basic" as it falls back to expected defaults if the arguments
72
74
// aren't provided.
73
- func NewBasicConn (lndHost , tlsPath , macDir , network string ,
74
- basicOptions ... BasicClientOption ) (
75
+ func NewBasicConn (lndHost string , tlsPath , macDir , tlsData , macData ,
76
+ network string , basicOptions ... BasicClientOption ) (
75
77
76
78
* grpc.ClientConn , error ) {
77
79
78
- if tlsPath == "" {
79
- tlsPath = defaultTLSCertPath
80
- }
81
-
82
- // Load the specified TLS certificate and build transport credentials
83
- creds , err := credentials .NewClientTLSFromFile (tlsPath , "" )
80
+ creds , mac , err := parseTLSAndMacaroon (
81
+ tlsPath , macDir , tlsData , macData , network , basicOptions ... ,
82
+ )
84
83
if err != nil {
85
84
return nil , err
86
85
}
87
86
87
+ // Now we append the macaroon credentials to the dial options.
88
+ cred := macaroons .NewMacaroonCredential (mac )
89
+
88
90
// Create a dial options array.
89
91
opts := []grpc.DialOption {
90
92
grpc .WithTransportCredentials (creds ),
91
- }
92
-
93
- if macDir == "" {
94
- macDir = filepath .Join (
95
- defaultLndDir , defaultDataDir , defaultChainSubDir ,
96
- "bitcoin" , network ,
97
- )
98
- }
99
-
100
- // Starting with the set of default options, we'll apply any specified
101
- // functional options to the basic client.
102
- bco := defaultBasicClientOptions ()
103
- bco .applyBasicClientOptions (basicOptions ... )
104
-
105
- macPath := filepath .Join (macDir , bco .macFilename )
106
-
107
- // Load the specified macaroon file.
108
- macBytes , err := ioutil .ReadFile (macPath )
109
- if err == nil {
110
- // Only if file is found
111
- mac := & macaroon.Macaroon {}
112
- if err = mac .UnmarshalBinary (macBytes ); err != nil {
113
- return nil , fmt .Errorf ("unable to decode macaroon: %v" ,
114
- err )
115
- }
116
-
117
- // Now we append the macaroon credentials to the dial options.
118
- cred := macaroons .NewMacaroonCredential (mac )
119
- opts = append (opts , grpc .WithPerRPCCredentials (cred ))
120
- opts = append (opts , grpc .WithDefaultCallOptions (maxMsgRecvSize ))
93
+ grpc .WithPerRPCCredentials (cred ),
94
+ grpc .WithDefaultCallOptions (maxMsgRecvSize ),
121
95
}
122
96
123
97
// We need to use a custom dialer so we can also connect to unix sockets
@@ -134,3 +108,45 @@ func NewBasicConn(lndHost, tlsPath, macDir, network string,
134
108
135
109
return conn , nil
136
110
}
111
+
112
+ // parseTLSAndMacaroon looks to see if the TLS certificate and macaroon were
113
+ // passed in as a path or as straight-up data, and processes it accordingly so
114
+ // it can be passed into grpc to establish a connection with LND.
115
+ func parseTLSAndMacaroon (tlsPath , macDir , tlsData , macData , network string ,
116
+ basicOptions ... BasicClientOption ) (credentials.TransportCredentials ,
117
+ * macaroon.Macaroon , error ) {
118
+
119
+ creds , err := GetTLSCredentials (tlsData , tlsPath )
120
+ if err != nil {
121
+ return nil , nil , err
122
+ }
123
+
124
+ // Starting with the set of default options, we'll apply any specified
125
+ // functional options to the basic client.
126
+ bco := defaultBasicClientOptions ()
127
+ bco .applyBasicClientOptions (basicOptions ... )
128
+
129
+ var macBytes []byte
130
+ mac := & macaroon.Macaroon {}
131
+ if macData != "" {
132
+ macBytes , err = hex .DecodeString (macData )
133
+ if err != nil {
134
+ return nil , nil , err
135
+ }
136
+ } else {
137
+ macPath := filepath .Join (macDir , bco .macFilename )
138
+
139
+ // Load the specified macaroon file.
140
+ macBytes , err = ioutil .ReadFile (macPath )
141
+ if err != nil {
142
+ return nil , nil , err
143
+ }
144
+ }
145
+
146
+ if err = mac .UnmarshalBinary (macBytes ); err != nil {
147
+ return nil , nil , fmt .Errorf ("unable to decode macaroon: %v" ,
148
+ err )
149
+ }
150
+
151
+ return creds , mac , nil
152
+ }
0 commit comments