Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 24 additions & 5 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ const (

uiPasswordMinLength = 8

ModeIntegrated = "integrated"
ModeRemote = "remote"
ModeIntegrated = "integrated"
ModeRemote = "remote"
ModeStatelessRemote = "stateless-remote"

defaultLndMode = ModeRemote
defaultFaradayMode = ModeIntegrated
Expand Down Expand Up @@ -149,7 +150,7 @@ type Config struct {
// friendly. Because then we can reference the explicit modes in the
// help descriptions of the section headers. We'll parse the mode into
// a bool for internal use for better code readability.
LndMode string `long:"lnd-mode" description:"The mode to run lnd in, either 'remote' (default) or 'integrated'. 'integrated' means lnd is started alongside the UI and everything is stored in lnd's main data directory, configure everything by using the --lnd.* flags. 'remote' means the UI connects to an existing lnd node and acts as a proxy for gRPC calls to it. In the remote node LiT creates its own directory for log and configuration files, configure everything using the --remote.* flags." choice:"integrated" choice:"remote"`
LndMode string `long:"lnd-mode" description:"The mode to run lnd in, either 'remote' (default) or 'integrated'. 'integrated' means lnd is started alongside the UI and everything is stored in lnd's main data directory, configure everything by using the --lnd.* flags. 'remote' means the UI connects to an existing lnd node and acts as a proxy for gRPC calls to it. In the remote node LiT creates its own directory for log and configuration files, configure everything using the --remote.* flags. 'stateless-remote' means that sensitive information related to LND and the lightning daemons is passed by the user via the UI before connecting to them." choice:"integrated" choice:"remote" choice:"stateless-remote"`
Lnd *lnd.Config `group:"Integrated lnd (use when lnd-mode=integrated)" namespace:"lnd"`

FaradayMode string `long:"faraday-mode" description:"The mode to run faraday in, either 'integrated' (default) or 'remote'. 'integrated' means faraday is started alongside the UI and everything is stored in faraday's main data directory, configure everything by using the --faraday.* flags. 'remote' means the UI connects to an existing faraday node and acts as a proxy for gRPC calls to it." choice:"integrated" choice:"remote"`
Expand Down Expand Up @@ -208,15 +209,28 @@ type RemoteDaemonConfig struct {
// TLSCertPath is the path to the tls cert of the remote daemon that
// should be used to verify the TLS identity of the remote RPC server.
TLSCertPath string `long:"tlscertpath" description:"The full path to the remote daemon's TLS cert to use for RPC connection verification."`

// In stateless-remote mode, we grab the macaroon directly instead of getting it from a path.
Macaroon string `long:"macaroon" description:"In stateless-remote mode, we grab the macaroon directly instead of getting it from a path."`

// In stateless-remote mode, we grab the tls certificate directly instead of getting it from a path.
TLSCert string `long:"tlscert" description:"In stateless-remote mode, we grab the tls certificate directly instead of getting it from a path."`
}

// lndConnectParams returns the connection parameters to connect to the local
// lnd instance.
func (c *Config) lndConnectParams() (string, lndclient.Network, string,
string) {

// In remote lnd mode, we just pass along what was configured in the
// In either remote mode, we just pass along what was configured in the
// remote section of the lnd config.
if c.LndMode == ModeStatelessRemote {
return c.Remote.Lnd.RPCServer,
lndclient.Network(c.Network),
c.Remote.Lnd.TLSCert,
c.Remote.Lnd.Macaroon
}

if c.LndMode == ModeRemote {
return c.Remote.Lnd.RPCServer,
lndclient.Network(c.Network),
Expand Down Expand Up @@ -533,6 +547,11 @@ func loadConfigFile(preCfg *Config, usageMessage string,
return nil, err
}

case ModeStatelessRemote:
if err := validateRemoteModeConfig(cfg); err != nil {
return nil, err
}

default:
return nil, fmt.Errorf("invalid lnd mode %v", cfg.LndMode)
}
Expand Down Expand Up @@ -720,7 +739,7 @@ func buildTLSConfigForHttp2(config *Config) (*tls.Config, error) {
GetCertificate: manager.GetCertificate,
}

case config.LndMode == ModeRemote:
case config.LndMode == ModeRemote || config.LndMode == ModeStatelessRemote:
tlsCertPath := config.Remote.LitTLSCertPath
tlsKeyPath := config.Remote.LitTLSKeyPath

Expand Down
44 changes: 44 additions & 0 deletions doc/config-lnd-stateless-remote.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Configuring LiT in stateless-remote mode

Stateless remote is a mode where LiT can be run without any sensitive data
stored on disk. Instead, the macaroon and TLS certificate data are passed in.

## Configuring stateless-remote mode

The lit.conf (which is by default located in the .lit folder) config should
look like this:

```
httpslisten=[::]:8443
uipassword=<insert password>
lnd-mode=stateless-remote
```

## Generating a "super" macaroon

In order to use this new stateless-remote mode. We'll need to bake a new
"super" macaroon that is able to access LND, Pool, Loop, and Faraday. Using
LND BakeMacaroon to create a macaroon via the command line like:

`lncli bakemacaroon --allow_external_permissions onchain:read offchain:read address:read message:read peers:read info:read invoices:read signer:read macaroon:read onchain:write offchain:write address:write message:write peers:write info:write invoices:write signer:generate macaroon:generate macaroon:write recommendation:read report:read audit:read insights:read rates:read loop:out loop:in swap:execute swap:read terms:read auth:read suggestions:read suggestions:write account:read account:write order:read order:write auction:read auth:read`

## Pass in an lndconnect string

Now, create a lndconnect string containing the host info, macaroon, and tls
certificate, like so: https://github.com/LN-Zap/lndconnect/blob/master/lnd_connect_uri.md

In full, an example lndconnect string might look like:


`lndconnect://localhost:10009?cert=MIICbzCCAhWgAwIBAgIRAL3ybHGc4hSVHoSO49QTHzIwCgYIKoZIzj0EAwIwMzEfMB0GA1UEChMWbG5kIGF1dG9nZW5lcmF0ZWQgY2VydDEQMA4GA1UEAxMHb3JiaXRhbDAeFw0yMTA3MTEwNTM5MjVaFw0yMjA5MDUwNTM5MjVaMDMxHzAdBgNVBAoTFmxuZCBhdXRvZ2VuZXJhdGVkIGNlcnQxEDAOBgNVBAMTB29yYml0YWwwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARy136neRMl40N2KRC%2BQXZUCbpFvYgwe1vEDmksNHBDggqY4zDDMg8OorWeUCCb%2BGaAi0z0M1sirB%2FNKu9xm4Yco4IBCDCCAQQwDgYDVR0PAQH%2FBAQDAgKkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1UdEwEB%2FwQFMAMBAf8wHQYDVR0OBBYEFESdIcJVWCF4aUqHVlqv%2BmtMORO%2FMIGsBgNVHREEgaQwgaGCB29yYml0YWyCCWxvY2FsaG9zdIIEdW5peIIKdW5peHBhY2tldIIHYnVmY29ubocEfwAAAYcQAAAAAAAAAAAAAAAAAAAAAYcEwKgABIcErBEAAYcErBIAAYcQJgEEQU0Ao5A2CXYVJBFsb4cQJgEEQU0Ao5AwGun%2F3cB0g4cQ%2FoAAAAAAAADv29UMGwZVEYcQ%2FoAAAAAAAAAAQtT%2F%2Foii0DAKBggqhkjOPQQDAgNIADBFAiEAt3%2FeNBX09qjejnZykwSls95ppasWjGHmkpqaM7T6%2BQgCIGyjfzJHx8RRy2uSbCfHctaR5%2F5v4sNUSelJIpT0o4c1&macaroon=0201047465737402067788991234560000062052d26ed139ea5af83e675500c4ccb2471f62191b745bab820f129e5588a255d2`

When making the lndconnect string, make sure to do the following:

* Remove linebreaks (\n) from the certificate, as grpc will reject a metadata
string value with linebreaks.
* Make sure the query string is valid, by encoding the url. `+` is not a valid
character to be passed in by way of a query string, for instance.

Once litd is running, open localhost:8443 and enter the lndconnect string.


Loading