Created
November 2, 2020 20:27
-
-
Save bumi/e22b3e093c3d884cb6fe3d0c8f2fa668 to your computer and use it in GitHub Desktop.
This is an example on how to connect to the LND gRPC interface through tor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"crypto/x509" | |
"encoding/hex" | |
"fmt" | |
"log" | |
"net" | |
"time" | |
"github.com/lightningnetwork/lnd/lnrpc" | |
"github.com/lightningnetwork/lnd/macaroons" | |
"gopkg.in/macaroon.v2" | |
"google.golang.org/grpc" | |
"google.golang.org/grpc/credentials" | |
"github.com/cretz/bine/tor" | |
) | |
func main() { | |
log.Printf("Starting Tor") | |
// We'll give it 5 minutes to run the whole thing (way too much of course, usually about 20 seconds) | |
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) | |
defer cancel() | |
t, err := tor.Start(ctx, nil) | |
if err != nil { | |
log.Fatal(err) | |
} | |
defer t.Close() | |
conn, client, err := startClient(ctx, t) | |
if err != nil { | |
log.Fatal(err) | |
} | |
defer conn.Close() | |
resp, err := client.GetInfo(context.Background(), &lnrpc.GetInfoRequest{}) | |
fmt.Printf("%+v\n", resp) | |
resp, err = client.GetInfo(context.Background(), &lnrpc.GetInfoRequest{}) | |
fmt.Printf("%+v\n", resp) | |
} | |
func startClient(ctx context.Context, t *tor.Tor) (conn *grpc.ClientConn, client lnrpc.LightningClient, err error) { | |
address := "" | |
macaroonHex := "" | |
certHex := "" | |
// Wait at most a few minutes to connect to the service | |
connCtx, connCancel := context.WithTimeout(ctx, 3*time.Minute) | |
defer connCancel() | |
dialer, err := t.Dialer(connCtx, nil) | |
if err != nil { | |
return nil, nil, err | |
} | |
// Get credentials either from a hex string or a file | |
var creds credentials.TransportCredentials | |
// if a hex string is provided | |
cp := x509.NewCertPool() | |
cert, err := hex.DecodeString(certHex) | |
if err != nil { | |
return nil, nil, err | |
} | |
cp.AppendCertsFromPEM(cert) | |
creds = credentials.NewClientTLSFromCert(cp, "") | |
opts := []grpc.DialOption{ | |
grpc.WithTransportCredentials(creds), | |
} | |
macaroonData, err := hex.DecodeString(macaroonHex) | |
if err != nil { | |
return nil, nil, err | |
} | |
mac := &macaroon.Macaroon{} | |
if err := mac.UnmarshalBinary(macaroonData); err != nil { | |
return nil, nil, err | |
} | |
macCred := macaroons.NewMacaroonCredential(mac) | |
opts = append(opts, grpc.WithPerRPCCredentials(macCred)) | |
opts = append(opts, grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) { | |
dialCtx, dialCancel := context.WithTimeout(ctx, timeout) | |
defer dialCancel() | |
return dialer.DialContext(dialCtx, "tcp", addr) | |
})) | |
conn, err = grpc.DialContext(connCtx, address, opts...) | |
if err != nil { | |
return nil, nil, err | |
} | |
client = lnrpc.NewLightningClient(conn) | |
return | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment