mirror of
https://github.com/getAlby/hub.git
synced 2026-08-13 12:33:39 +02:00
feat: greenlight LNClient WIP
This commit is contained in:
parent
444953e89d
commit
096039cf4d
10 changed files with 361 additions and 28 deletions
17
README.md
17
README.md
|
|
@ -18,6 +18,7 @@ Ideally the app runs 24/7 (on a node, VPS or always-online desktop/laptop machin
|
|||
|
||||
- LND (see: lnd.go)
|
||||
- Breez (see: breez.go)
|
||||
- Greenlight (see: greenlight.go)
|
||||
- want more? please open an issue.
|
||||
|
||||
## Installation
|
||||
|
|
@ -32,10 +33,16 @@ As data storage SQLite is used.
|
|||
# edit the config for your needs
|
||||
vim .env
|
||||
|
||||
To get a new random Nostr key use `openssl rand -hex 32` or similar.
|
||||
#### Optional Requirements
|
||||
|
||||
See [Greenlight](./README_GREENLIGHT.md)
|
||||
|
||||
## Development
|
||||
|
||||
### Required Software
|
||||
|
||||
- Go
|
||||
|
||||
### Server (HTTP mode)
|
||||
|
||||
1. Create a Lightning Polar setup with two LND nodes and uncomment the Polar LND section in your `.env` file.
|
||||
|
|
@ -94,7 +101,7 @@ Breez SDK requires gcc to build the Breez bindings. Run `choco install mingw` an
|
|||
- `COOKIE_SECRET`: a randomly generated secret string. (only needed in http mode)
|
||||
- `DATABASE_URI`: a sqlite filename. Default: .data/nwc.db
|
||||
- `PORT`: the port on which the app should listen on (default: 8080)
|
||||
- `LN_BACKEND_TYPE`: LND or BREEZ
|
||||
- `LN_BACKEND_TYPE`: LND, BREEZ or GREENLIGHT
|
||||
- `WORK_DIR`: directory to store NWC data files. Default: .data
|
||||
-
|
||||
|
||||
|
|
@ -106,12 +113,6 @@ _For cert and macaroon, either hex or file options can be used._
|
|||
- `LND_CERT_FILE`: the location where LND's `tls.cert` file can be found (used with the LND backend)
|
||||
- `LND_MACAROON_FILE`: the location where LND's `admin.macaroon` file can be found (used with the LND backend)
|
||||
|
||||
### BREEZ Backend parameters
|
||||
|
||||
- `BREEZ_MNEMONIC`: your bip39 mnemonic key phrase e.g. "define limit soccer guilt trim mechanic beyond outside best give south shine"
|
||||
- `BREEZ_API_KEY`: contact breez for more info
|
||||
- `GREENLIGHT_INVITE_CODE`: contact blockstream for more info
|
||||
|
||||
## Application deeplink options
|
||||
|
||||
### `/apps/new` deeplink options
|
||||
|
|
|
|||
21
README_GREENLIGHT.md
Normal file
21
README_GREENLIGHT.md
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# Greenlight
|
||||
|
||||
To enable the GREENLIGHT LNClient some additional steps are required.
|
||||
|
||||
## Required Software
|
||||
|
||||
- Python 3 + pip
|
||||
- [Greenlight Client](https://github.com/Blockstream/greenlight/tree/main?tab=readme-ov-file#install-and-updating-glcli-and-python-api) with [fix commit](https://github.com/Blockstream/greenlight/commit/2dc5a94668d41baef7275dae860c09b4a5dba198)
|
||||
|
||||
## Setup
|
||||
|
||||
1. Wallet
|
||||
1. Existing mnemonic (possible through NWC UI)
|
||||
2. New mnemonic: (WIP)
|
||||
1. glcli scheduler register --network=bitcoin --invite=YOUR_INVITE_CODE
|
||||
2. glcli getinfo - "warning_lightningd_sync" should disappear after < 30 seconds
|
||||
2. Get Liquidity
|
||||
1. peer with blocktank (TBC): `glcli connect 0296b2db342fcf87ea94d981757fdf4d3e545bd5cef4919f58b5d38dfdd73bf5c9 130.211.95.29 9735`
|
||||
2. run `glcli scheduler schedule` to get your node ID and GRPC uri
|
||||
3. go to blocktank and pay for a channel. After paying invoice, claim manually. Format is without the https: `pubkey@domain_name:9735`
|
||||
4. Unless you paid for some outgoing liquidity, you'll need to deposit and reserve at least 1% of the channel balance to send outgoing payments.
|
||||
4
api.go
4
api.go
|
|
@ -231,8 +231,8 @@ func (api *API) Setup(setupRequest *models.SetupRequest) error {
|
|||
if setupRequest.BreezAPIKey != "" {
|
||||
api.svc.cfg.SetUpdate("BreezAPIKey", setupRequest.BreezAPIKey, setupRequest.UnlockPassword)
|
||||
}
|
||||
if setupRequest.BreezMnemonic != "" {
|
||||
api.svc.cfg.SetUpdate("BreezMnemonic", setupRequest.BreezMnemonic, setupRequest.UnlockPassword)
|
||||
if setupRequest.Mnemonic != "" {
|
||||
api.svc.cfg.SetUpdate("Mnemonic", setupRequest.Mnemonic, setupRequest.UnlockPassword)
|
||||
}
|
||||
if setupRequest.GreenlightInviteCode != "" {
|
||||
api.svc.cfg.SetUpdate("GreenlightInviteCode", setupRequest.GreenlightInviteCode, setupRequest.UnlockPassword)
|
||||
|
|
|
|||
11
config.go
11
config.go
|
|
@ -12,11 +12,12 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
LNDBackendType = "LND"
|
||||
BreezBackendType = "BREEZ"
|
||||
SessionCookieName = "session"
|
||||
SessionCookieAuthKey = "authenticated"
|
||||
UnlockPasswordCheck = "THIS STRING SHOULD MATCH IF PASSWORD IS CORRECT"
|
||||
LNDBackendType = "LND"
|
||||
GreenlightBackendType = "GREENLIGHT"
|
||||
BreezBackendType = "BREEZ"
|
||||
SessionCookieName = "session"
|
||||
SessionCookieAuthKey = "authenticated"
|
||||
UnlockPasswordCheck = "THIS STRING SHOULD MATCH IF PASSWORD IS CORRECT"
|
||||
)
|
||||
|
||||
type AppConfig struct {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ import { handleRequestError } from "src/utils/handleRequestError";
|
|||
import { request } from "src/utils/request"; // build the project for this to appear
|
||||
|
||||
export function SetupNode() {
|
||||
const [backendType, setBackendType] = React.useState<BackendType>("BREEZ");
|
||||
const [backendType, setBackendType] =
|
||||
React.useState<BackendType>("GREENLIGHT");
|
||||
const { unlockPassword } = useSetupStore();
|
||||
const [isConnecting, setConnecting] = React.useState(false);
|
||||
const navigate = useNavigate();
|
||||
|
|
@ -70,6 +71,7 @@ export function SetupNode() {
|
|||
id="backend-type"
|
||||
className="dark:bg-surface-00dp mb-4 block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:ring-2 focus:ring-purple-700 dark:border-gray-700 dark:text-white dark:placeholder-gray-400 dark:ring-offset-gray-800 dark:focus:ring-purple-600"
|
||||
>
|
||||
<option value={"GREENLIGHT"}>Greenlight</option>
|
||||
<option value={"BREEZ"}>Breez</option>
|
||||
<option value={"LND"}>LND</option>
|
||||
</select>
|
||||
|
|
@ -77,6 +79,12 @@ export function SetupNode() {
|
|||
{backendType === "BREEZ" && (
|
||||
<BreezForm handleSubmit={handleSubmit} isConnecting={isConnecting} />
|
||||
)}
|
||||
{backendType === "GREENLIGHT" && (
|
||||
<GreenlightForm
|
||||
handleSubmit={handleSubmit}
|
||||
isConnecting={isConnecting}
|
||||
/>
|
||||
)}
|
||||
{backendType === "LND" && (
|
||||
<LNDForm handleSubmit={handleSubmit} isConnecting={isConnecting} />
|
||||
)}
|
||||
|
|
@ -93,18 +101,18 @@ function BreezForm({ isConnecting, handleSubmit }: SetupFormProps) {
|
|||
const [greenlightInviteCode, setGreenlightInviteCode] =
|
||||
React.useState<string>("");
|
||||
const [breezApiKey, setBreezApiKey] = React.useState<string>("");
|
||||
const [breezMnemonic, setBreezMnemonic] = React.useState<string>("");
|
||||
const [mnemonic, setMnemonic] = React.useState<string>("");
|
||||
|
||||
function onSubmit(e: React.FormEvent) {
|
||||
e.preventDefault();
|
||||
if (!greenlightInviteCode || !breezMnemonic) {
|
||||
if (!greenlightInviteCode || !mnemonic) {
|
||||
alert("please fill out all fields");
|
||||
return;
|
||||
}
|
||||
handleSubmit({
|
||||
greenlightInviteCode,
|
||||
breezApiKey,
|
||||
breezMnemonic,
|
||||
mnemonic,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -147,8 +155,62 @@ function BreezForm({ isConnecting, handleSubmit }: SetupFormProps) {
|
|||
</label>
|
||||
<input
|
||||
name="mnemonic"
|
||||
onChange={(e) => setBreezMnemonic(e.target.value)}
|
||||
value={breezMnemonic}
|
||||
onChange={(e) => setMnemonic(e.target.value)}
|
||||
value={mnemonic}
|
||||
type="password"
|
||||
id="mnemonic"
|
||||
className="dark:bg-surface-00dp block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:ring-2 focus:ring-purple-700 dark:border-gray-700 dark:text-white dark:placeholder-gray-400 dark:ring-offset-gray-800 dark:focus:ring-purple-600"
|
||||
/>
|
||||
</>
|
||||
<ConnectButton isConnecting={isConnecting} />
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
function GreenlightForm({ isConnecting, handleSubmit }: SetupFormProps) {
|
||||
const [greenlightInviteCode, setGreenlightInviteCode] =
|
||||
React.useState<string>("");
|
||||
const [mnemonic, setMnemonic] = React.useState<string>("");
|
||||
|
||||
function onSubmit(e: React.FormEvent) {
|
||||
e.preventDefault();
|
||||
if (!greenlightInviteCode || !mnemonic) {
|
||||
alert("please fill out all fields");
|
||||
return;
|
||||
}
|
||||
handleSubmit({
|
||||
greenlightInviteCode,
|
||||
mnemonic,
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<form onSubmit={onSubmit}>
|
||||
<>
|
||||
<label
|
||||
htmlFor="greenlight-invite-code"
|
||||
className="block font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
Greenlight Invite Code
|
||||
</label>
|
||||
<input
|
||||
name="greenlight-invite-code"
|
||||
onChange={(e) => setGreenlightInviteCode(e.target.value)}
|
||||
value={greenlightInviteCode}
|
||||
type="password"
|
||||
id="greenlight-invite-code"
|
||||
className="dark:bg-surface-00dp block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:ring-2 focus:ring-purple-700 dark:border-gray-700 dark:text-white dark:placeholder-gray-400 dark:ring-offset-gray-800 dark:focus:ring-purple-600"
|
||||
/>
|
||||
<label
|
||||
htmlFor="mnemonic"
|
||||
className="mt-4 block font-medium text-gray-900 dark:text-white"
|
||||
>
|
||||
BIP39 Mnemonic
|
||||
</label>
|
||||
<input
|
||||
name="mnemonic"
|
||||
onChange={(e) => setMnemonic(e.target.value)}
|
||||
value={mnemonic}
|
||||
type="password"
|
||||
id="mnemonic"
|
||||
className="dark:bg-surface-00dp block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:ring-2 focus:ring-purple-700 dark:border-gray-700 dark:text-white dark:placeholder-gray-400 dark:ring-offset-gray-800 dark:focus:ring-purple-600"
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ export const NIP_47_MAKE_INVOICE_METHOD = "make_invoice";
|
|||
export const NIP_47_LOOKUP_INVOICE_METHOD = "lookup_invoice";
|
||||
export const NIP_47_LIST_TRANSACTIONS_METHOD = "list_transactions";
|
||||
|
||||
export type BackendType = "LND" | "BREEZ";
|
||||
export type BackendType = "LND" | "BREEZ" | "GREENLIGHT";
|
||||
|
||||
export type RequestMethodType =
|
||||
| "pay_invoice"
|
||||
|
|
|
|||
210
greenlight.go
Normal file
210
greenlight.go
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"log"
|
||||
"math/rand"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/breez/breez-sdk-go/breez_sdk"
|
||||
models "github.com/getAlby/nostr-wallet-connect/models/greenlight"
|
||||
)
|
||||
|
||||
type GreenlightService struct {
|
||||
workdir string
|
||||
hsmdCmd *exec.Cmd
|
||||
//svc *breez_sdk.BlockingGreenlightServices
|
||||
}
|
||||
|
||||
func NewGreenlightService(mnemonic, inviteCode, workDir string) (result LNClient, err error) {
|
||||
if mnemonic == "" || inviteCode == "" || workDir == "" {
|
||||
return nil, errors.New("One or more required greenlight configuration are missing")
|
||||
}
|
||||
|
||||
//create dir if not exists
|
||||
newpath := filepath.Join(".", workDir)
|
||||
err = os.MkdirAll(newpath, os.ModePerm)
|
||||
if err != nil {
|
||||
log.Printf("Failed to create greenlight working dir: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
seed, err := breez_sdk.MnemonicToSeed(mnemonic)
|
||||
if err != nil {
|
||||
log.Printf("Failed to convert mnemonic to seed: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hsmSecretPath := filepath.Join(newpath, "hsm_secret")
|
||||
err = os.WriteFile(hsmSecretPath, seed[0:32], 0644)
|
||||
if err != nil {
|
||||
log.Printf("Failed to write hsm secret: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
gs := GreenlightService{
|
||||
workdir: newpath,
|
||||
//listener: &listener,
|
||||
//svc: svc,
|
||||
}
|
||||
|
||||
err = gs.recover()
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("failed to recover: %v", err)
|
||||
}
|
||||
|
||||
nodeInfo := models.NodeInfo{}
|
||||
err = gs.execJSONCommand(&nodeInfo, "getinfo")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err == nil {
|
||||
log.Printf("Node info: %v", nodeInfo)
|
||||
}
|
||||
|
||||
// TODO: schedule
|
||||
|
||||
gs.hsmdCmd = gs.createCommand("hsmd")
|
||||
|
||||
if err := gs.hsmdCmd.Start(); err != nil {
|
||||
log.Fatalf("Failed to start hsmd: %v", err)
|
||||
}
|
||||
|
||||
return &gs, nil
|
||||
}
|
||||
|
||||
func (gs *GreenlightService) recover() error {
|
||||
output, err := gs.execCommand("scheduler", "recover")
|
||||
log.Printf("scheduler recover: %v", string(output))
|
||||
return err
|
||||
}
|
||||
|
||||
func (gs *GreenlightService) createCommand(args ...string) *exec.Cmd {
|
||||
cmd := exec.Command("glcli", args...)
|
||||
cmd.Dir = gs.workdir
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (gs *GreenlightService) execCommand(args ...string) ([]byte, error) {
|
||||
cmd := gs.createCommand(args...)
|
||||
|
||||
var outputBuffer bytes.Buffer
|
||||
var errorBuffer bytes.Buffer
|
||||
|
||||
cmd.Stdout = &outputBuffer
|
||||
cmd.Stderr = &errorBuffer
|
||||
err := cmd.Run()
|
||||
|
||||
if err != nil {
|
||||
errorOutput := errorBuffer.String()
|
||||
log.Printf("Failed to exec command %v: %v %v", args, err, errorOutput)
|
||||
return nil, err
|
||||
}
|
||||
output := outputBuffer.Bytes()
|
||||
return output, err
|
||||
}
|
||||
|
||||
func (gs *GreenlightService) execJSONCommand(dest any, args ...string) error {
|
||||
output, err := gs.execCommand(args...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(output, dest)
|
||||
if err != nil {
|
||||
log.Printf("Failed to unmarshal command output %v: %v", string(output), err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (gs *GreenlightService) Shutdown() error {
|
||||
if gs.hsmdCmd != nil {
|
||||
if err := gs.hsmdCmd.Process.Kill(); err != nil {
|
||||
log.Printf("Failed to kill hsmd process: %v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
//return bs.svc.Disconnect()
|
||||
}
|
||||
|
||||
func (gs *GreenlightService) SendPaymentSync(ctx context.Context, payReq string) (preimage string, err error) {
|
||||
//glcli pay BOLT11_INVOICE_HERE
|
||||
|
||||
payResponse := models.PayResponse{}
|
||||
err = gs.execJSONCommand(&payResponse, "pay", payReq)
|
||||
if err != nil {
|
||||
log.Printf("SendPaymentSync failed: %v", err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
return payResponse.Preimage, nil
|
||||
}
|
||||
|
||||
func (gs *GreenlightService) SendKeysend(ctx context.Context, amount int64, destination, preimage string, custom_records []TLVRecord) (preImage string, err error) {
|
||||
log.Println("TODO: SendKeysend")
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (gs *GreenlightService) GetBalance(ctx context.Context) (balance int64, err error) {
|
||||
/*info, err := bs.svc.NodeInfo()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int64(info.ChannelsBalanceMsat) / 1000, nil*/
|
||||
log.Println("TODO: GetBalance")
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (gs *GreenlightService) MakeInvoice(ctx context.Context, amount int64, description string, descriptionHash string, expiry int64) (transaction *Nip47Transaction, err error) {
|
||||
//glcli invoice example_label3 21000msat
|
||||
|
||||
invoice := models.Invoice{}
|
||||
err = gs.execJSONCommand(&invoice, "invoice", "label_"+strconv.Itoa(rand.Int()), strconv.FormatInt(amount, 10)+"msat")
|
||||
if err != nil {
|
||||
log.Println("MakeInvoice failed: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
transaction = &Nip47Transaction{
|
||||
Type: "incoming",
|
||||
Invoice: invoice.Bolt11,
|
||||
PaymentHash: invoice.PaymentHash,
|
||||
Amount: amount,
|
||||
CreatedAt: time.Now().Unix(),
|
||||
ExpiresAt: &invoice.ExpiresAt,
|
||||
}
|
||||
|
||||
return transaction, nil
|
||||
}
|
||||
|
||||
func (gs *GreenlightService) LookupInvoice(ctx context.Context, paymentHash string) (transaction *Nip47Transaction, err error) {
|
||||
log.Println("TODO: LookupInvoice")
|
||||
return nil, errors.New("TODO: LookupInvoice")
|
||||
}
|
||||
|
||||
func (gs *GreenlightService) ListTransactions(ctx context.Context, from, until, limit, offset uint64, unpaid bool, invoiceType string) (transactions []Nip47Transaction, err error) {
|
||||
log.Println("TODO: ListTransactions")
|
||||
transactions = []Nip47Transaction{}
|
||||
return transactions, nil
|
||||
}
|
||||
|
||||
func (gs *GreenlightService) GetInfo(ctx context.Context) (info *NodeInfo, err error) {
|
||||
log.Println("TODO: GetInfo")
|
||||
return &NodeInfo{
|
||||
Alias: "greenlight",
|
||||
Color: "",
|
||||
Pubkey: "",
|
||||
Network: "mainnet",
|
||||
BlockHeight: 0,
|
||||
BlockHash: "",
|
||||
}, nil
|
||||
}
|
||||
|
|
@ -42,10 +42,14 @@ type UnlockRequest struct {
|
|||
|
||||
type SetupRequest struct {
|
||||
LNBackendType string `json:"backendType"`
|
||||
// Breez fields
|
||||
BreezMnemonic string `json:"breezMnemonic"`
|
||||
BreezAPIKey string `json:"breezApiKey"`
|
||||
|
||||
// Breez / Greenlight
|
||||
Mnemonic string `json:"mnemonic"`
|
||||
GreenlightInviteCode string `json:"greenlightInviteCode"`
|
||||
|
||||
// Breez fields
|
||||
BreezAPIKey string `json:"breezApiKey"`
|
||||
|
||||
// LND fields
|
||||
LNDAddress string `json:"lndAddress"`
|
||||
LNDCertFile string `json:"lndCertFile"`
|
||||
|
|
|
|||
28
models/greenlight/greenlight.go
Normal file
28
models/greenlight/greenlight.go
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
package greenlight
|
||||
|
||||
type NodeInfo struct {
|
||||
ID string `json:"id"`
|
||||
Alias string `json:"alias"`
|
||||
// ...other fields
|
||||
}
|
||||
|
||||
type Invoice struct {
|
||||
Bolt11 string `json:"bolt11"`
|
||||
PaymentHash string `json:"payment_hash"`
|
||||
Preimage string `json:"payment_secret"`
|
||||
ExpiresAt int64 `json:"expires_at"`
|
||||
// ...other fields
|
||||
}
|
||||
|
||||
type MsatValue struct {
|
||||
Msat uint `json:"msat"`
|
||||
}
|
||||
|
||||
type PayResponse struct {
|
||||
PaymentHash string `json:"payment_hash"`
|
||||
Preimage string `json:"payment_preimage"`
|
||||
CreatedAt float64 `json:"created_at"`
|
||||
AmountMsat MsatValue `json:"amount_msat"`
|
||||
AmountSentMsat MsatValue `json:"amount_sent_msat"`
|
||||
// ...other fields
|
||||
}
|
||||
12
service.go
12
service.go
|
|
@ -134,13 +134,19 @@ func (svc *Service) launchLNBackend(encryptionKey string) error {
|
|||
LNDCertHex, _ := svc.cfg.Get("LNDCertHex", encryptionKey)
|
||||
LNDMacaroonHex, _ := svc.cfg.Get("LNDMacaroonHex", encryptionKey)
|
||||
lnClient, err = NewLNDService(svc, LNDAddress, LNDCertHex, LNDMacaroonHex)
|
||||
case lndBackend:
|
||||
BreezMnemonic, _ := svc.cfg.Get("BreezMnemonic", encryptionKey)
|
||||
case GreenlightBackendType:
|
||||
Mnemonic, _ := svc.cfg.Get("Mnemonic", encryptionKey)
|
||||
GreenlightInviteCode, _ := svc.cfg.Get("GreenlightInviteCode", encryptionKey)
|
||||
GreenlightWorkdir := path.Join(svc.cfg.Env.Workdir, "greenlightcli")
|
||||
|
||||
lnClient, err = NewGreenlightService(Mnemonic, GreenlightInviteCode, GreenlightWorkdir)
|
||||
case BreezBackendType:
|
||||
Mnemonic, _ := svc.cfg.Get("Mnemonic", encryptionKey)
|
||||
BreezAPIKey, _ := svc.cfg.Get("BreezAPIKey", encryptionKey)
|
||||
GreenlightInviteCode, _ := svc.cfg.Get("GreenlightInviteCode", encryptionKey)
|
||||
BreezWorkdir := path.Join(svc.cfg.Env.Workdir, "breez")
|
||||
|
||||
lnClient, err = NewBreezService(BreezMnemonic, BreezAPIKey, GreenlightInviteCode, BreezWorkdir)
|
||||
lnClient, err = NewBreezService(Mnemonic, BreezAPIKey, GreenlightInviteCode, BreezWorkdir)
|
||||
default:
|
||||
svc.Logger.Fatalf("Unsupported LNBackendType: %v", lndBackend)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue