-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
37a9195
commit ad943f2
Showing
17 changed files
with
877 additions
and
270 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,5 +6,7 @@ node_modules | |
nostr-wallet-connect | ||
nwc.db | ||
|
||
build | ||
|
||
frontend/dist | ||
frontend/node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,248 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"database/sql" | ||
"fmt" | ||
"os" | ||
"os/signal" | ||
"strings" | ||
"time" | ||
|
||
echologrus "github.com/davrux/echo-logrus/v4" | ||
"github.com/getAlby/nostr-wallet-connect/migrations" | ||
"github.com/glebarez/sqlite" | ||
"github.com/joho/godotenv" | ||
"github.com/kelseyhightower/envconfig" | ||
"github.com/labstack/echo/v4" | ||
"github.com/nbd-wtf/go-nostr" | ||
"github.com/nbd-wtf/go-nostr/nip19" | ||
log "github.com/sirupsen/logrus" | ||
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer" | ||
"gorm.io/driver/postgres" | ||
"gorm.io/gorm" | ||
|
||
"github.com/jackc/pgx/v5/stdlib" | ||
sqltrace "gopkg.in/DataDog/dd-trace-go.v1/contrib/database/sql" | ||
gormtrace "gopkg.in/DataDog/dd-trace-go.v1/contrib/gorm.io/gorm.v1" | ||
) | ||
|
||
// App struct | ||
type Wailsapp struct { | ||
ctx context.Context | ||
} | ||
|
||
// NewApp creates a new App application struct | ||
func NewApp() *Wailsapp { | ||
return &Wailsapp{} | ||
} | ||
|
||
// startup is called when the app starts. The context is saved | ||
// so we can call the runtime methods | ||
func (a *Wailsapp) startup(ctx context.Context) { | ||
a.ctx = ctx | ||
} | ||
|
||
// Greet returns a greeting for the given name | ||
func (a *Wailsapp) Greet(name string) string { | ||
return fmt.Sprintf("Hello %s, It's show time!", name) | ||
} | ||
|
||
func (a *Wailsapp) Start() { | ||
// Load config from environment variables / .env file | ||
godotenv.Load(".env") | ||
cfg := &Config{} | ||
err := envconfig.Process("", cfg) | ||
if err != nil { | ||
log.Fatalf("Error loading environment variables: %v", err) | ||
} | ||
|
||
var db *gorm.DB | ||
var sqlDb *sql.DB | ||
if strings.HasPrefix(cfg.DatabaseUri, "postgres://") || strings.HasPrefix(cfg.DatabaseUri, "postgresql://") || strings.HasPrefix(cfg.DatabaseUri, "unix://") { | ||
if os.Getenv("DATADOG_AGENT_URL") != "" { | ||
sqltrace.Register("pgx", &stdlib.Driver{}, sqltrace.WithServiceName("nostr-wallet-connect")) | ||
sqlDb, err = sqltrace.Open("pgx", cfg.DatabaseUri) | ||
if err != nil { | ||
log.Fatalf("Failed to open DB %v", err) | ||
} | ||
db, err = gormtrace.Open(postgres.New(postgres.Config{Conn: sqlDb}), &gorm.Config{}) | ||
if err != nil { | ||
log.Fatalf("Failed to open DB %v", err) | ||
} | ||
} else { | ||
db, err = gorm.Open(postgres.Open(cfg.DatabaseUri), &gorm.Config{}) | ||
if err != nil { | ||
log.Fatalf("Failed to open DB %v", err) | ||
} | ||
sqlDb, err = db.DB() | ||
if err != nil { | ||
log.Fatalf("Failed to set DB config: %v", err) | ||
} | ||
} | ||
} else { | ||
db, err = gorm.Open(sqlite.Open(cfg.DatabaseUri), &gorm.Config{}) | ||
if err != nil { | ||
log.Fatalf("Failed to open DB %v", err) | ||
} | ||
// Override SQLite config to max one connection | ||
cfg.DatabaseMaxConns = 1 | ||
// Enable foreign keys for sqlite | ||
db.Exec("PRAGMA foreign_keys=ON;") | ||
sqlDb, err = db.DB() | ||
if err != nil { | ||
log.Fatalf("Failed to set DB config: %v", err) | ||
} | ||
} | ||
sqlDb.SetMaxOpenConns(cfg.DatabaseMaxConns) | ||
sqlDb.SetMaxIdleConns(cfg.DatabaseMaxIdleConns) | ||
sqlDb.SetConnMaxLifetime(time.Duration(cfg.DatabaseConnMaxLifetime) * time.Second) | ||
|
||
err = migrations.Migrate(db) | ||
if err != nil { | ||
log.Fatalf("Migration failed: %v", err) | ||
} | ||
log.Println("Any pending migrations ran successfully") | ||
|
||
if cfg.NostrSecretKey == "" { | ||
if cfg.LNBackendType == AlbyBackendType { | ||
//not allowed | ||
log.Fatal("Nostr private key is required with this backend type.") | ||
} | ||
//first look up if we already have the private key in the database | ||
//else, generate and store private key | ||
identity := &Identity{} | ||
err = db.FirstOrInit(identity).Error | ||
if err != nil { | ||
log.WithError(err).Fatal("Error retrieving private key from database") | ||
} | ||
if identity.Privkey == "" { | ||
log.Info("No private key found in database, generating & saving.") | ||
identity.Privkey = nostr.GeneratePrivateKey() | ||
err = db.Save(identity).Error | ||
if err != nil { | ||
log.WithError(err).Fatal("Error saving private key to database") | ||
} | ||
} | ||
cfg.NostrSecretKey = identity.Privkey | ||
} | ||
|
||
identityPubkey, err := nostr.GetPublicKey(cfg.NostrSecretKey) | ||
if err != nil { | ||
log.Fatalf("Error converting nostr privkey to pubkey: %v", err) | ||
} | ||
cfg.IdentityPubkey = identityPubkey | ||
npub, err := nip19.EncodePublicKey(identityPubkey) | ||
if err != nil { | ||
log.Fatalf("Error converting nostr privkey to pubkey: %v", err) | ||
} | ||
|
||
log.Infof("Starting nostr-wallet-connect. npub: %s hex: %s", npub, identityPubkey) | ||
svc := &Service{ | ||
cfg: cfg, | ||
db: db, | ||
} | ||
|
||
if os.Getenv("DATADOG_AGENT_URL") != "" { | ||
tracer.Start(tracer.WithService("nostr-wallet-connect")) | ||
defer tracer.Stop() | ||
} | ||
|
||
echologrus.Logger = log.New() | ||
echologrus.Logger.SetFormatter(&log.JSONFormatter{}) | ||
echologrus.Logger.SetOutput(os.Stdout) | ||
echologrus.Logger.SetLevel(log.InfoLevel) | ||
svc.Logger = echologrus.Logger | ||
|
||
e := echo.New() | ||
ctx := context.Background() | ||
ctx, _ = signal.NotifyContext(ctx, os.Interrupt) | ||
// var wg sync.WaitGroup | ||
switch cfg.LNBackendType { | ||
case LNDBackendType: | ||
lndClient, err := NewLNDService(ctx, svc, e) | ||
if err != nil { | ||
svc.Logger.Fatal(err) | ||
} | ||
svc.lnClient = lndClient | ||
case AlbyBackendType: | ||
oauthService, err := NewAlbyOauthService(svc, e) | ||
if err != nil { | ||
svc.Logger.Fatal(err) | ||
} | ||
svc.lnClient = oauthService | ||
} | ||
|
||
//register shared routes | ||
svc.RegisterSharedRoutes(e) | ||
//start Echo server | ||
// wg.Add(1) | ||
// go func() { | ||
// if err := e.Start(fmt.Sprintf(":%v", svc.cfg.Port)); err != nil && err != http.ErrServerClosed { | ||
// e.Logger.Fatal("shutting down the server") | ||
// } | ||
// //handle graceful shutdown | ||
// <-ctx.Done() | ||
// ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) | ||
// defer cancel() | ||
// e.Shutdown(ctx) | ||
// svc.Logger.Info("Echo server exited") | ||
// wg.Done() | ||
// }() | ||
|
||
//connect to the relay | ||
svc.Logger.Infof("Connecting to the relay: %s", cfg.Relay) | ||
|
||
relay, err := nostr.RelayConnect(ctx, cfg.Relay, nostr.WithNoticeHandler(svc.noticeHandler)) | ||
if err != nil { | ||
svc.Logger.Fatal(err) | ||
} | ||
|
||
//publish event with NIP-47 info | ||
err = svc.PublishNip47Info(ctx, relay) | ||
if err != nil { | ||
svc.Logger.WithError(err).Error("Could not publish NIP47 info") | ||
} | ||
|
||
//Start infinite loop which will be only broken by canceling ctx (SIGINT) | ||
//TODO: we can start this loop for multiple relays | ||
for { | ||
svc.Logger.Info("Subscribing to events") | ||
sub, err := relay.Subscribe(ctx, svc.createFilters()) | ||
if err != nil { | ||
svc.Logger.Fatal(err) | ||
} | ||
err = svc.StartSubscription(ctx, sub) | ||
if err != nil { | ||
//err being non-nil means that we have an error on the websocket error channel. In this case we just try to reconnect. | ||
svc.Logger.WithError(err).Error("Got an error from the relay while listening to subscription. Reconnecting...") | ||
relay, err = nostr.RelayConnect(ctx, cfg.Relay) | ||
if err != nil { | ||
svc.Logger.Fatal(err) | ||
} | ||
continue | ||
} | ||
//err being nil means that the context was canceled and we should exit the program. | ||
break | ||
} | ||
err = relay.Close() | ||
if err != nil { | ||
svc.Logger.Error(err) | ||
} | ||
svc.Logger.Info("Graceful shutdown completed. Goodbye.") | ||
} | ||
|
||
func (svc *Service) createFilters() nostr.Filters { | ||
filter := nostr.Filter{ | ||
Tags: nostr.TagMap{"p": []string{svc.cfg.IdentityPubkey}}, | ||
Kinds: []int{NIP_47_REQUEST_KIND}, | ||
} | ||
if svc.cfg.ClientPubkey != "" { | ||
filter.Authors = []string{svc.cfg.ClientPubkey} | ||
} | ||
return []nostr.Filter{filter} | ||
} | ||
|
||
func (svc *Service) noticeHandler(notice string) { | ||
svc.Logger.Infof("Received a notice %s", notice) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
ceedfa9d05a93b4082a44060c09940f6 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL | ||
// This file is automatically generated. DO NOT EDIT | ||
|
||
export function Greet(arg1:string):Promise<string>; | ||
|
||
export function Start():Promise<void>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// @ts-check | ||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL | ||
// This file is automatically generated. DO NOT EDIT | ||
|
||
export function Greet(arg1) { | ||
return window['go']['main']['Wailsapp']['Greet'](arg1); | ||
} | ||
|
||
export function Start() { | ||
return window['go']['main']['Wailsapp']['Start'](); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"name": "@wailsapp/runtime", | ||
"version": "2.0.0", | ||
"description": "Wails Javascript runtime library", | ||
"main": "runtime.js", | ||
"types": "runtime.d.ts", | ||
"scripts": { | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/wailsapp/wails.git" | ||
}, | ||
"keywords": [ | ||
"Wails", | ||
"Javascript", | ||
"Go" | ||
], | ||
"author": "Lea Anthony <[email protected]>", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/wailsapp/wails/issues" | ||
}, | ||
"homepage": "https://github.com/wailsapp/wails#readme" | ||
} |
Oops, something went wrong.