Skip to content

Commit

Permalink
feat: LND setup form
Browse files Browse the repository at this point in the history
  • Loading branch information
rolznz committed Jan 16, 2024
1 parent f8442ba commit b4e4850
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 14 deletions.
4 changes: 4 additions & 0 deletions alby.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ func NewAlbyOauthService(svc *Service, e *echo.Echo) (result LNClient, err error
return albySvc, err
}

func (svc *AlbyOAuthService) Shutdown() error {
return nil
}

func (svc *AlbyOAuthService) FetchUserToken(ctx context.Context, app App) (token *oauth2.Token, err error) {
user := app.User
tok, err := svc.oauthConf.TokenSource(ctx, &oauth2.Token{
Expand Down
21 changes: 20 additions & 1 deletion api.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,33 @@ func (svc *Service) Setup(setupRequest *api.SetupRequest) error {
dbConfigEntries := []db.ConfigEntry{}

dbConfigEntries = append(dbConfigEntries, db.ConfigEntry{Key: "LN_BACKEND_TYPE", Value: setupRequest.LNBackendType})

// TODO: reduce duplication

if setupRequest.BreezMnemonic != "" {
dbConfigEntries = append(dbConfigEntries, db.ConfigEntry{Key: "BREEZ_MNEMONIC", Value: setupRequest.BreezMnemonic})
}
if setupRequest.GreenlightInviteCode != "" {
dbConfigEntries = append(dbConfigEntries, db.ConfigEntry{Key: "GREENLIGHT_INVITE_CODE", Value: setupRequest.GreenlightInviteCode})
}

// Update columns to default value on `id` conflict
if setupRequest.LNDAddress != "" {
dbConfigEntries = append(dbConfigEntries, db.ConfigEntry{Key: "LND_ADDRESS", Value: setupRequest.LNDAddress})
}
if setupRequest.LNDCertFile != "" {
dbConfigEntries = append(dbConfigEntries, db.ConfigEntry{Key: "LND_CERT_FILE", Value: setupRequest.LNDCertFile})
}
if setupRequest.LNDCertHex != "" {
dbConfigEntries = append(dbConfigEntries, db.ConfigEntry{Key: "LND_CERT_HEX", Value: setupRequest.LNDCertHex})
}
if setupRequest.LNDMacaroonFile != "" {
dbConfigEntries = append(dbConfigEntries, db.ConfigEntry{Key: "LND_MACAROON_FILE", Value: setupRequest.LNDMacaroonFile})
}
if setupRequest.LNDMacaroonHex != "" {
dbConfigEntries = append(dbConfigEntries, db.ConfigEntry{Key: "LND_MACAROON_HEX", Value: setupRequest.LNDMacaroonHex})
}

// replace existing keys with latest values
res := svc.db.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "key"}},
DoUpdates: clause.AssignmentColumns([]string{"value"}),
Expand Down
18 changes: 17 additions & 1 deletion breez.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,19 @@ func (BreezListener) OnEvent(e breez_sdk.BreezEvent) {
log.Printf("received event %#v", e)
}

func NewBreezService(mnemonic, apiKey, inviteCode, workDir string) (result LNClient, err error) {
func NewBreezService(nwcSvc *Service, mnemonic, apiKey, inviteCode, workDir string) (result LNClient, err error) {
// FIXME: split single and multi user app
//add default user to db
user := &User{}
err = nwcSvc.db.FirstOrInit(user, User{AlbyIdentifier: "breez"}).Error
if err != nil {
return nil, err
}
err = nwcSvc.db.Save(user).Error
if err != nil {
return nil, err
}

//create dir if not exists
newpath := filepath.Join(".", workDir)
err = os.MkdirAll(newpath, os.ModePerm)
Expand Down Expand Up @@ -75,6 +87,10 @@ func NewBreezService(mnemonic, apiKey, inviteCode, workDir string) (result LNCli
}, nil
}

func (bs *BreezService) Shutdown() error {
return bs.svc.Disconnect()
}

func (bs *BreezService) SendPaymentSync(ctx context.Context, senderPubkey string, payReq string) (preimage string, err error) {
sendPaymentRequest := breez_sdk.SendPaymentRequest{
Bolt11: payReq,
Expand Down
2 changes: 2 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ type Config struct {
AppType string `envconfig:"APP_TYPE" default:"HTTP"`
LNDAddress string `envconfig:"LND_ADDRESS"`
LNDCertFile string `envconfig:"LND_CERT_FILE"`
LNDCertHex string `envconfig:"LND_CERT_HEX"`
LNDMacaroonFile string `envconfig:"LND_MACAROON_FILE"`
LNDMacaroonHex string `envconfig:"LND_MACAROON_HEX"`
BreezMnemonic string `envconfig:"BREEZ_MNEMONIC"`
BreezAPIKey string `envconfig:"BREEZ_API_KEY"`
GreenlightInviteCode string `envconfig:"GREENLIGHT_INVITE_CODE"`
Expand Down
73 changes: 71 additions & 2 deletions frontend/src/screens/Setup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export function Setup() {
</select>

{backendType === "BREEZ" && <BreezForm handleSubmit={handleSubmit} />}
{backendType === "LND" && <p>Coming soon</p>}
{backendType === "LND" && <LNDForm handleSubmit={handleSubmit} />}
</>
);
}
Expand Down Expand Up @@ -111,7 +111,7 @@ function BreezForm({ handleSubmit }: SetupFormProps) {
className="bg-gray-50 border border-gray-300 text-gray-900 focus:ring-purple-700 dark:focus:ring-purple-600 dark:ring-offset-gray-800 focus:ring-2 text-sm rounded-lg block w-full p-2.5 dark:bg-surface-00dp dark:border-gray-700 dark:placeholder-gray-400 dark:text-white"
/>
<label
htmlFor="greenlight-invite-code"
htmlFor="mnemonic"
className="mt-4 block font-medium text-gray-900 dark:text-white"
>
BIP39 Mnemonic
Expand All @@ -129,3 +129,72 @@ function BreezForm({ handleSubmit }: SetupFormProps) {
</form>
);
}

function LNDForm({ handleSubmit }: SetupFormProps) {
const [lndAddress, setLndAddress] = React.useState<string>("");
const [lndCertHex, setLndCertHex] = React.useState<string>("");
const [lndMacaroonHex, setLndMacaroonHex] = React.useState<string>("");

function onSubmit(e: React.FormEvent) {
e.preventDefault();
if (!lndAddress || !lndCertHex || !lndMacaroonHex) {
alert("please fill out all fields");
return;
}
handleSubmit({
lndAddress,
lndCertHex,
lndMacaroonHex,
});
}

return (
<form onSubmit={onSubmit}>
<>
<label
htmlFor="lnd-address"
className="block font-medium text-gray-900 dark:text-white"
>
LND Address (GRPC)
</label>
<input
name="lnd-address"
onChange={(e) => setLndAddress(e.target.value)}
value={lndAddress}
id="lnd-address"
className="bg-gray-50 border border-gray-300 text-gray-900 focus:ring-purple-700 dark:focus:ring-purple-600 dark:ring-offset-gray-800 focus:ring-2 text-sm rounded-lg block w-full p-2.5 dark:bg-surface-00dp dark:border-gray-700 dark:placeholder-gray-400 dark:text-white"
/>

<label
htmlFor="lnd-cert-hex"
className="mt-4 block font-medium text-gray-900 dark:text-white"
>
TLS Certificate (Hex)
</label>
<input
name="lnd-cert-hex"
onChange={(e) => setLndCertHex(e.target.value)}
value={lndCertHex}
type="password"
id="lnd-cert-hex"
className="bg-gray-50 border border-gray-300 text-gray-900 focus:ring-purple-700 dark:focus:ring-purple-600 dark:ring-offset-gray-800 focus:ring-2 text-sm rounded-lg block w-full p-2.5 dark:bg-surface-00dp dark:border-gray-700 dark:placeholder-gray-400 dark:text-white"
/>
<label
htmlFor="lnd-macaroon-hex"
className="mt-4 block font-medium text-gray-900 dark:text-white"
>
Admin Macaroon (Hex)
</label>
<input
name="lnd-macaroon-hex"
onChange={(e) => setLndMacaroonHex(e.target.value)}
value={lndMacaroonHex}
type="password"
id="lnd-macaroon-hex"
className="bg-gray-50 border border-gray-300 text-gray-900 focus:ring-purple-700 dark:focus:ring-purple-600 dark:ring-offset-gray-800 focus:ring-2 text-sm rounded-lg block w-full p-2.5 dark:bg-surface-00dp dark:border-gray-700 dark:placeholder-gray-400 dark:text-white"
/>
</>
<ConnectButton />
</form>
);
}
16 changes: 12 additions & 4 deletions lnd.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type LNClient interface {
MakeInvoice(ctx context.Context, senderPubkey string, amount int64, description string, descriptionHash string, expiry int64) (transaction *Nip47Transaction, err error)
LookupInvoice(ctx context.Context, senderPubkey string, paymentHash string) (transaction *Nip47Transaction, err error)
ListTransactions(ctx context.Context, senderPubkey string, from, until, limit, offset uint64, unpaid bool, invoiceType string) (transactions []Nip47Transaction, err error)
Shutdown() error
}

// wrap it again :sweat_smile:
Expand Down Expand Up @@ -309,11 +310,13 @@ func makePreimageHex() ([]byte, error) {
return bytes, nil
}

func NewLNDService(svc *Service) (result LNClient, err error) {
func NewLNDService(svc *Service, lndAddress, lndCertFile, lndCertHex, lndMacaroonFile, lndMacaroonHex string) (result LNClient, err error) {
lndClient, err := lnd.NewLNDclient(lnd.LNDoptions{
Address: svc.cfg.LNDAddress,
CertFile: svc.cfg.LNDCertFile,
MacaroonFile: svc.cfg.LNDMacaroonFile,
Address: lndAddress,
CertFile: lndCertFile,
CertHex: lndCertHex,
MacaroonFile: lndMacaroonFile,
MacaroonHex: lndMacaroonHex,
}, svc.ctx)
if err != nil {
return nil, err
Expand All @@ -322,6 +325,7 @@ func NewLNDService(svc *Service) (result LNClient, err error) {
if err != nil {
return nil, err
}
// FIXME: split single and multi user app
//add default user to db
user := &User{}
err = svc.db.FirstOrInit(user, User{AlbyIdentifier: "lnd"}).Error
Expand All @@ -340,6 +344,10 @@ func NewLNDService(svc *Service) (result LNClient, err error) {
return lndService, nil
}

func (svc *LNDService) Shutdown() error {
return nil
}

func lndInvoiceToTransaction(invoice *lnrpc.Invoice) *Nip47Transaction {
var settledAt *int64
var preimage string
Expand Down
18 changes: 13 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,11 +240,13 @@ func main() {

func (svc *Service) launchLNBackend() error {
if svc.lnClient != nil {
// TODO: svc.lnClient.shutdown()
err := svc.lnClient.Shutdown()
if err != nil {
svc.Logger.Fatalf("Failed to disconnect from current node: %v", err)
}
svc.lnClient = nil
}

// TODO: merge with DB
dbCfgEntries := []db.ConfigEntry{}
svc.db.Find(&dbCfgEntries)

Expand All @@ -262,16 +264,22 @@ func (svc *Service) launchLNBackend() error {
breezMnemonic := mergeConfigEntry(svc.cfg.BreezMnemonic, "BREEZ_MNEMONIC")
greenlightInviteCode := mergeConfigEntry(svc.cfg.GreenlightInviteCode, "GREENLIGHT_INVITE_CODE")

lndAddress := mergeConfigEntry(svc.cfg.LNDAddress, "LND_ADDRESS")
lndCertFile := mergeConfigEntry(svc.cfg.LNDCertFile, "LND_CERT_FILE")
lndCertHex := mergeConfigEntry(svc.cfg.LNDCertHex, "LND_CERT_HEX")
lndMacaroonFile := mergeConfigEntry(svc.cfg.LNDMacaroonFile, "LND_MACAROON_FILE")
lndMacaroonHex := mergeConfigEntry(svc.cfg.LNDMacaroonHex, "LND_MACAROON_HEX")

svc.Logger.Infof("Launching new LN Backend: %s", lnBackendType)
switch lnBackendType {
case LNDBackendType:
// TODO: pass config to LND
lndClient, err := NewLNDService(svc)
lndClient, err := NewLNDService(svc, lndAddress, lndCertFile, lndCertHex, lndMacaroonFile, lndMacaroonHex)
if err != nil {
return err
}
svc.lnClient = lndClient
case BreezBackendType:
breezSvc, err := NewBreezService(breezMnemonic, svc.cfg.BreezAPIKey, greenlightInviteCode, svc.cfg.BreezWorkdir)
breezSvc, err := NewBreezService(svc, breezMnemonic, svc.cfg.BreezAPIKey, greenlightInviteCode, svc.cfg.BreezWorkdir)
if err != nil {
return err
}
Expand Down
6 changes: 5 additions & 1 deletion models/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ type SetupRequest struct {
BreezMnemonic string `json:"breezMnemonic"`
GreenlightInviteCode string `json:"greenlightInviteCode"`
// LND fields
// TODO: ....
LNDAddress string `json:"lndAddress"`
LNDCertFile string `json:"lndCertFile"`
LNDMacaroonFile string `json:"lndMacaroonFile"`
LNDCertHex string `json:"lndCertHex"`
LNDMacaroonHex string `json:"lndMacaroonHex"`
}

type CreateAppResponse struct {
Expand Down

0 comments on commit b4e4850

Please sign in to comment.