2023-02-27 07:16:49 -08:00
|
|
|
package subservers
|
|
|
|
|
|
|
|
|
|
import (
|
2023-05-02 11:35:13 +02:00
|
|
|
"context"
|
|
|
|
|
|
|
|
|
|
restProxy "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
2023-02-27 07:16:49 -08:00
|
|
|
"github.com/lightninglabs/lndclient"
|
2023-05-02 11:43:52 +02:00
|
|
|
"github.com/lightninglabs/loop"
|
2023-02-27 07:16:49 -08:00
|
|
|
"github.com/lightninglabs/loop/loopd"
|
|
|
|
|
"github.com/lightninglabs/loop/looprpc"
|
2024-05-23 13:52:28 +02:00
|
|
|
"github.com/lightninglabs/taproot-assets/fn"
|
2023-02-27 07:16:49 -08:00
|
|
|
"github.com/lightningnetwork/lnd/lnrpc"
|
|
|
|
|
"google.golang.org/grpc"
|
2023-05-02 08:52:28 +02:00
|
|
|
"gopkg.in/macaroon-bakery.v2/bakery"
|
2023-02-27 07:16:49 -08:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// loopSubServer implements the SubServer interface.
|
|
|
|
|
type loopSubServer struct {
|
|
|
|
|
*loopd.Daemon
|
|
|
|
|
remote bool
|
|
|
|
|
cfg *loopd.Config
|
|
|
|
|
remoteCfg *RemoteDaemonConfig
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// A compile-time check to ensure that loopSubServer implements SubServer.
|
|
|
|
|
var _ SubServer = (*loopSubServer)(nil)
|
|
|
|
|
|
|
|
|
|
// NewLoopSubServer returns a new loop implementation of the SubServer
|
|
|
|
|
// interface.
|
|
|
|
|
func NewLoopSubServer(cfg *loopd.Config, remoteCfg *RemoteDaemonConfig,
|
|
|
|
|
remote bool) SubServer {
|
|
|
|
|
|
2023-05-02 11:43:52 +02:00
|
|
|
// Overwrite the loop daemon's user agent name, so it sends "litd"
|
|
|
|
|
// instead of "loopd".
|
|
|
|
|
loop.AgentName = "litd"
|
|
|
|
|
|
2023-02-27 07:16:49 -08:00
|
|
|
return &loopSubServer{
|
|
|
|
|
Daemon: loopd.New(cfg, nil),
|
|
|
|
|
cfg: cfg,
|
|
|
|
|
remoteCfg: remoteCfg,
|
|
|
|
|
remote: remote,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Name returns the name of the sub-server.
|
|
|
|
|
//
|
|
|
|
|
// NOTE: this is part of the SubServer interface.
|
|
|
|
|
func (l *loopSubServer) Name() string {
|
|
|
|
|
return LOOP
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Remote returns true if the sub-server is running remotely and so should be
|
|
|
|
|
// connected to instead of spinning up an integrated server.
|
|
|
|
|
//
|
|
|
|
|
// NOTE: this is part of the SubServer interface.
|
|
|
|
|
func (l *loopSubServer) Remote() bool {
|
|
|
|
|
return l.remote
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RemoteConfig returns the config required to connect to the sub-server if it
|
|
|
|
|
// is running in remote mode.
|
|
|
|
|
//
|
|
|
|
|
// NOTE: this is part of the SubServer interface.
|
|
|
|
|
func (l *loopSubServer) RemoteConfig() *RemoteDaemonConfig {
|
|
|
|
|
return l.remoteCfg
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Start starts the sub-server in integrated mode.
|
|
|
|
|
//
|
|
|
|
|
// NOTE: this is part of the SubServer interface.
|
|
|
|
|
func (l *loopSubServer) Start(_ lnrpc.LightningClient,
|
|
|
|
|
lndGrpc *lndclient.GrpcLndServices, withMacaroonService bool) error {
|
|
|
|
|
|
|
|
|
|
return l.StartAsSubserver(lndGrpc, withMacaroonService)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Stop stops the sub-server in integrated mode.
|
|
|
|
|
//
|
|
|
|
|
// NOTE: this is part of the SubServer interface.
|
|
|
|
|
func (l *loopSubServer) Stop() error {
|
|
|
|
|
l.Daemon.Stop()
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// RegisterGrpcService must register the sub-server's GRPC server with the given
|
|
|
|
|
// registrar.
|
|
|
|
|
//
|
|
|
|
|
// NOTE: this is part of the SubServer interface.
|
|
|
|
|
func (l *loopSubServer) RegisterGrpcService(registrar grpc.ServiceRegistrar) {
|
|
|
|
|
looprpc.RegisterSwapClientServer(registrar, l)
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-02 11:35:13 +02:00
|
|
|
// RegisterRestService registers the sub-server's REST handlers with the given
|
|
|
|
|
// endpoint.
|
|
|
|
|
//
|
|
|
|
|
// NOTE: this is part of the SubServer interface.
|
|
|
|
|
func (l *loopSubServer) RegisterRestService(ctx context.Context,
|
|
|
|
|
mux *restProxy.ServeMux, endpoint string,
|
|
|
|
|
dialOpts []grpc.DialOption) error {
|
|
|
|
|
|
|
|
|
|
return looprpc.RegisterSwapClientHandlerFromEndpoint(
|
|
|
|
|
ctx, mux, endpoint, dialOpts,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-27 07:16:49 -08:00
|
|
|
// ServerErrChan returns an error channel that should be listened on after
|
|
|
|
|
// starting the sub-server to listen for any runtime errors. It is optional and
|
|
|
|
|
// may be set to nil. This only applies in integrated mode.
|
|
|
|
|
//
|
|
|
|
|
// NOTE: this is part of the SubServer interface.
|
|
|
|
|
func (l *loopSubServer) ServerErrChan() chan error {
|
|
|
|
|
return l.ErrChan
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// MacPath returns the path to the sub-server's macaroon if it is not running in
|
|
|
|
|
// remote mode.
|
|
|
|
|
//
|
|
|
|
|
// NOTE: this is part of the SubServer interface.
|
|
|
|
|
func (l *loopSubServer) MacPath() string {
|
|
|
|
|
return l.cfg.MacaroonPath
|
|
|
|
|
}
|
2023-05-02 08:52:28 +02:00
|
|
|
|
|
|
|
|
// Permissions returns a map of all RPC methods and their required macaroon
|
|
|
|
|
// permissions to access the sub-server.
|
|
|
|
|
//
|
|
|
|
|
// NOTE: this is part of the SubServer interface.
|
|
|
|
|
func (l *loopSubServer) Permissions() map[string][]bakery.Op {
|
2025-05-02 09:36:25 +02:00
|
|
|
return looprpc.RequiredPermissions
|
2023-05-02 08:52:28 +02:00
|
|
|
}
|
2023-08-08 21:32:18 +02:00
|
|
|
|
|
|
|
|
// WhiteListedURLs returns a map of all the sub-server's URLs that can be
|
|
|
|
|
// accessed without a macaroon.
|
|
|
|
|
//
|
|
|
|
|
// NOTE: this is part of the SubServer interface.
|
|
|
|
|
func (l *loopSubServer) WhiteListedURLs() map[string]struct{} {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
2024-05-23 13:52:28 +02:00
|
|
|
|
|
|
|
|
// Impl returns the actual implementation of the sub-server. This might not be
|
|
|
|
|
// set if the sub-server is running in remote mode.
|
|
|
|
|
func (l *loopSubServer) Impl() fn.Option[any] {
|
|
|
|
|
if l.Daemon == nil {
|
|
|
|
|
return fn.None[any]()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return fn.Some[any](l.Daemon)
|
|
|
|
|
}
|