You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
109 lines
2.9 KiB
Go
109 lines
2.9 KiB
Go
// Grpc interface to lnd
|
|
package lndrpc
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"log"
|
|
|
|
"github.com/lightningnetwork/lnd/lncfg"
|
|
"github.com/lightningnetwork/lnd/macaroons"
|
|
macaroon "gopkg.in/macaroon.v2"
|
|
|
|
"git.sp4ke.com/sp4ke/bit4sat/config"
|
|
"github.com/lightningnetwork/lnd/lnrpc"
|
|
"google.golang.org/grpc"
|
|
"google.golang.org/grpc/credentials"
|
|
)
|
|
|
|
func fatal(err error) {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
func getClient() (lnrpc.LightningClient, func()) {
|
|
conn := getClientConn()
|
|
|
|
cleanUp := func() {
|
|
conn.Close()
|
|
}
|
|
|
|
return lnrpc.NewLightningClient(conn), cleanUp
|
|
}
|
|
|
|
func getClientConn() *grpc.ClientConn {
|
|
|
|
// Load the specified TLS certificate and build transport credentials
|
|
// with it.
|
|
creds, err := credentials.NewClientTLSFromFile(config.LndCertPath, "")
|
|
if err != nil {
|
|
fatal(err)
|
|
}
|
|
|
|
// Create a dial options array.
|
|
opts := []grpc.DialOption{
|
|
grpc.WithTransportCredentials(creds),
|
|
}
|
|
|
|
// Load the specified macaroon file.
|
|
macBytes, err := ioutil.ReadFile(config.LndAdminMacaroonPath)
|
|
if err != nil {
|
|
fatal(fmt.Errorf("unable to read macaroon path (check "+
|
|
"the network setting!): %v", err))
|
|
}
|
|
|
|
mac := &macaroon.Macaroon{}
|
|
if err = mac.UnmarshalBinary(macBytes); err != nil {
|
|
fatal(fmt.Errorf("unable to decode macaroon: %v", err))
|
|
}
|
|
|
|
macConstraints := []macaroons.Constraint{
|
|
// We add a time-based constraint to prevent replay of the
|
|
// macaroon. It's good for 60 seconds by default to make up for
|
|
// any discrepancy between client and server clocks, but leaking
|
|
// the macaroon before it becomes invalid makes it possible for
|
|
// an attacker to reuse the macaroon. In addition, the validity
|
|
// time of the macaroon is extended by the time the server clock
|
|
// is behind the client clock, or shortened by the time the
|
|
// server clock is ahead of the client clock (or invalid
|
|
// altogether if, in the latter case, this time is more than 60
|
|
// seconds).
|
|
// TODO(aakselrod): add better anti-replay protection.
|
|
macaroons.TimeoutConstraint(60),
|
|
|
|
// Lock macaroon down to a specific IP address.
|
|
//macaroons.IPLockConstraint(config.LockMacaroonIp),
|
|
macaroons.IPLockConstraint(""),
|
|
|
|
// ... Add more constraints if needed.
|
|
}
|
|
|
|
// Apply constraints to the macaroon.
|
|
constrainedMac, err := macaroons.AddConstraints(mac, macConstraints...)
|
|
if err != nil {
|
|
fatal(err)
|
|
}
|
|
|
|
// Now we append the macaroon credentials to the dial options.
|
|
cred := macaroons.NewMacaroonCredential(constrainedMac)
|
|
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(config.LndGrpcPort),
|
|
),
|
|
)
|
|
conn, err := grpc.Dial(fmt.Sprintf("%s:%s", config.LndGrpcHost, config.LndGrpcPort), opts...)
|
|
if err != nil {
|
|
fatal(fmt.Errorf("unable to connect to RPC server: %v", err))
|
|
}
|
|
|
|
return conn
|
|
}
|
|
|
|
func init() {
|
|
log.Println("init grpc")
|
|
}
|