Skip to content

Commit

Permalink
feat: adding subscription WiP
Browse files Browse the repository at this point in the history
  • Loading branch information
frnandu committed Oct 15, 2024
1 parent 546322c commit 8cbe566
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 4 deletions.
8 changes: 8 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions .idea/hub.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 9 additions & 1 deletion api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func NewAPI(svc service.Service, gormDB *gorm.DB, config config.Config, keys key
}
}

func (api *api) CreateApp(createAppRequest *CreateAppRequest) (*CreateAppResponse, error) {
func (api *api) CreateApp(ctx context.Context, createAppRequest *CreateAppRequest) (*CreateAppResponse, error) {
expiresAt, err := api.parseExpiresAt(createAppRequest.ExpiresAt)
if err != nil {
return nil, fmt.Errorf("invalid expiresAt: %v", err)
Expand Down Expand Up @@ -128,6 +128,14 @@ func (api *api) CreateApp(createAppRequest *CreateAppRequest) (*CreateAppRespons
lud16 = fmt.Sprintf("&lud16=%s", lightningAddress)
}
responseBody.PairingUri = fmt.Sprintf("nostr+walletconnect://%s?relay=%s&secret=%s%s", appWalletPubKey, relayUrl, pairingSecretKey, lud16)

fmt.Println("~+~+~+~+~+~+~+~+~+ GOING TO SUBSCRIBE TO NEW APP WALLET!!!!!!!!!!!!!! ")
err = api.svc.SubscribeToAppRequests(ctx, appWalletPubKey)
if err != nil {
fmt.Println("error subscribing to new app wallet key: ", err)
return nil, err
}

return responseBody, nil
}

Expand Down
2 changes: 1 addition & 1 deletion api/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

type API interface {
CreateApp(createAppRequest *CreateAppRequest) (*CreateAppResponse, error)
CreateApp(ctx context.Context, createAppRequest *CreateAppRequest) (*CreateAppResponse, error)
UpdateApp(userApp *db.App, updateAppRequest *UpdateAppRequest) error
DeleteApp(userApp *db.App) error
GetApp(userApp *db.App) *App
Expand Down
2 changes: 1 addition & 1 deletion http/http_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -837,7 +837,7 @@ func (httpSvc *HttpService) appsCreateHandler(c echo.Context) error {
})
}

responseBody, err := httpSvc.api.CreateApp(&requestData)
responseBody, err := httpSvc.api.CreateApp(c.Request().Context(), &requestData)

if err != nil {
logger.Logger.WithField("requestData", requestData).WithError(err).Error("Failed to save app")
Expand Down
3 changes: 3 additions & 0 deletions service/models.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package service

import (
"context"

"github.com/getAlby/hub/alby"
"github.com/getAlby/hub/config"
"github.com/getAlby/hub/events"
Expand All @@ -14,6 +16,7 @@ type Service interface {
StartApp(encryptionKey string) error
StopApp()
Shutdown()
SubscribeToAppRequests(ctx context.Context, appWalletPubKey string) error

// TODO: remove getters (currently used by http / wails services)
GetAlbyOAuthSvc() alby.AlbyOAuthService
Expand Down
2 changes: 1 addition & 1 deletion service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ func NewService(ctx context.Context) (*service, error) {

func (svc *service) createFilters(identityPubkey string) nostr.Filters {
filter := nostr.Filter{
// Tags: nostr.TagMap{"p": []string{identityPubkey}},
Tags: nostr.TagMap{"p": []string{identityPubkey}},
Kinds: []int{models.REQUEST_KIND},
}
return []nostr.Filter{filter}
Expand Down
76 changes: 76 additions & 0 deletions service/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,82 @@ func (svc *service) startNostr(ctx context.Context, encryptionKey string) error
return nil
}

func (svc *service) SubscribeToAppRequests(ctx context.Context, appWalletPubKey string) error {
relayUrl := svc.cfg.GetRelayUrl()
go func() {
// ensure the relay is properly disconnected before exiting
defer svc.wg.Done()
//Start infinite loop which will be only broken by canceling ctx (SIGINT)
var relay *nostr.Relay
waitToReconnectSeconds := 0

for i := 0; ; i++ {

// wait for a delay if any before retrying
if waitToReconnectSeconds > 0 {
contextCancelled := false

select {
case <-ctx.Done(): //context cancelled
logger.Logger.Info("service context cancelled while waiting for retry")
contextCancelled = true
case <-time.After(time.Duration(waitToReconnectSeconds) * time.Second): //timeout
}
if contextCancelled {
break
}
}

closeRelay(relay)

//connect to the relay
logger.Logger.WithFields(logrus.Fields{
"relay_url": relayUrl,
"iteration": i,
}).Info("Connecting to the relay")

relay, err := nostr.RelayConnect(ctx, relayUrl, nostr.WithNoticeHandler(svc.noticeHandler))
if err != nil {
// exponential backoff from 2 - 60 seconds
waitToReconnectSeconds = max(waitToReconnectSeconds, 1)
waitToReconnectSeconds *= 2
waitToReconnectSeconds = min(waitToReconnectSeconds, 60)
logger.Logger.WithFields(logrus.Fields{
"iteration": i,
"retry_seconds": waitToReconnectSeconds,
}).WithError(err).Error("Failed to connect to relay")
continue
}

waitToReconnectSeconds = 0

//publish event with NIP-47 info
err = svc.nip47Service.PublishNip47Info(ctx, relay, svc.lnClient)
if err != nil {
logger.Logger.WithError(err).Error("Could not publish NIP47 info")
}

logger.Logger.Info("Subscribing to events")
sub, err := relay.Subscribe(ctx, svc.createFilters(appWalletPubKey))
if err != nil {
logger.Logger.WithError(err).Error("Failed to subscribe to events")
continue
}
err = svc.StartSubscription(sub.Context, 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.
logger.Logger.WithError(err).Error("Got an error from the relay while listening to subscription.")
continue
}
//err being nil means that the context was canceled and we should exit the program.
break
}
closeRelay(relay)
logger.Logger.Info("Relay subroutine ended")
}()
return nil
}

func (svc *service) StartApp(encryptionKey string) error {
if svc.lnClient != nil {
return errors.New("app already started")
Expand Down

0 comments on commit 8cbe566

Please sign in to comment.