Skip to content

Commit

Permalink
fix: nwc info event to only include capabilities based on the app per…
Browse files Browse the repository at this point in the history
…missions (#884)

fixes #766
  • Loading branch information
frnandu authored Dec 23, 2024
2 parents ea01b7d + 4865752 commit ad2d8dd
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 4 deletions.
1 change: 1 addition & 0 deletions alby/alby_oauth_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -1332,6 +1332,7 @@ func getEventWhitelist() []string {
"nwc_payment_sent",
"nwc_payment_failed",
"nwc_app_created",
"nwc_app_updated",
"nwc_app_deleted",
"nwc_unlocked",
"nwc_node_sync_failed",
Expand Down
7 changes: 7 additions & 0 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,13 @@ func (api *api) UpdateApp(userApp *db.App, updateAppRequest *UpdateAppRequest) e
return err
}
}
api.svc.GetEventPublisher().Publish(&events.Event{
Event: "nwc_app_updated",
Properties: map[string]interface{}{
"name": name,
"id": userApp.ID,
},
})

// commit transaction
return nil
Expand Down
31 changes: 27 additions & 4 deletions nip47/publish_nip47_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ import (
"strconv"
"strings"

"github.com/getAlby/hub/db"
"github.com/getAlby/hub/lnclient"
"github.com/getAlby/hub/logger"
"github.com/getAlby/hub/nip47/models"
nostrmodels "github.com/getAlby/hub/nostr/models"
"github.com/nbd-wtf/go-nostr"
"github.com/sirupsen/logrus"
)

func (svc *nip47Service) GetNip47Info(ctx context.Context, relay *nostr.Relay, appWalletPubKey string) (*nostr.Event, error) {
Expand All @@ -32,18 +35,38 @@ func (svc *nip47Service) GetNip47Info(ctx context.Context, relay *nostr.Relay, a
}

func (svc *nip47Service) PublishNip47Info(ctx context.Context, relay nostrmodels.Relay, appWalletPubKey string, appWalletPrivKey string, lnClient lnclient.LNClient) (*nostr.Event, error) {
// TODO: should the capabilities be based on the app permissions? (for non-legacy apps)
capabilities := lnClient.GetSupportedNIP47Methods()
if len(lnClient.GetSupportedNIP47NotificationTypes()) > 0 {
var capabilities []string
var permitsNotifications bool
tags := nostr.Tags{[]string{}}
if svc.keys.GetNostrPublicKey() == appWalletPubKey {
// legacy app, so return lnClient.GetSupportedNIP47Methods()
capabilities = lnClient.GetSupportedNIP47Methods()
permitsNotifications = true
} else {
app := db.App{}
err := svc.db.First(&app, &db.App{
WalletPubkey: &appWalletPubKey,
}).Error
if err != nil {
logger.Logger.WithFields(logrus.Fields{
"walletPubKey": appWalletPubKey,
}).WithError(err).Error("Failed to find app for wallet pubkey")
return nil, err
}
capabilities = svc.permissionsService.GetPermittedMethods(&app, lnClient)
permitsNotifications = svc.permissionsService.PermitsNotifications(&app)
}
if permitsNotifications && len(lnClient.GetSupportedNIP47NotificationTypes()) > 0 {
capabilities = append(capabilities, "notifications")
tags = append(tags, []string{"notifications", strings.Join(lnClient.GetSupportedNIP47NotificationTypes(), " ")})
}

ev := &nostr.Event{}
ev.Kind = models.INFO_EVENT_KIND
ev.Content = strings.Join(capabilities, " ")
ev.CreatedAt = nostr.Now()
ev.PubKey = appWalletPubKey
ev.Tags = nostr.Tags{[]string{"notifications", strings.Join(lnClient.GetSupportedNIP47NotificationTypes(), " ")}}
ev.Tags = tags
err := ev.Sign(appWalletPrivKey)
if err != nil {
return nil, err
Expand Down
8 changes: 8 additions & 0 deletions service/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ func (svc *service) startNostr(ctx context.Context) error {
var relay *nostr.Relay
waitToReconnectSeconds := 0
var createAppEventListener events.EventSubscriber
var updateAppEventListener events.EventSubscriber
for i := 0; ; i++ {
// wait for a delay if any before retrying
contextCancelled := false
Expand Down Expand Up @@ -94,6 +95,13 @@ func (svc *service) startNostr(ctx context.Context) error {
createAppEventListener = &createAppConsumer{svc: svc, relay: relay}
svc.eventPublisher.RegisterSubscriber(createAppEventListener)

// register a subscriber for events of "nwc_app_updated" which handles re-publishing of nip47 event info
if updateAppEventListener != nil {
svc.eventPublisher.RemoveSubscriber(updateAppEventListener)
}
updateAppEventListener = &updateAppConsumer{svc: svc, relay: relay}
svc.eventPublisher.RegisterSubscriber(updateAppEventListener)

// start each app wallet subscription which have a child derived wallet key
svc.startAllExistingAppsWalletSubscriptions(ctx, relay)

Expand Down
53 changes: 53 additions & 0 deletions service/update_app_consumer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package service

import (
"context"

"github.com/getAlby/hub/events"
"github.com/getAlby/hub/logger"
"github.com/nbd-wtf/go-nostr"
)

type updateAppConsumer struct {
events.EventSubscriber
svc *service
relay *nostr.Relay
}

// When a app is updated, re-publish the nip47 info event
func (s *updateAppConsumer) ConsumeEvent(ctx context.Context, event *events.Event, globalProperties map[string]interface{}) {
if event.Event != "nwc_app_updated" {
return
}

properties, ok := event.Properties.(map[string]interface{})
if !ok {
logger.Logger.WithField("event", event).Error("Failed to cast event.Properties to map")
return
}
id, ok := properties["id"].(uint)
if !ok {
logger.Logger.WithField("event", event).Error("Failed to get app id")
return
}
walletPrivKey, err := s.svc.keys.GetAppWalletKey(id)
if err != nil {
logger.Logger.WithError(err).Error("Failed to calculate app wallet priv key")
return
}
walletPubKey, err := nostr.GetPublicKey(walletPrivKey)
if err != nil {
logger.Logger.WithError(err).Error("Failed to calculate app wallet pub key")
return
}

if s.svc.keys.GetNostrPublicKey() != walletPubKey {
// only need to re-publish the nip47 event info if it is not a legacy wallet

_, err = s.svc.GetNip47Service().PublishNip47Info(ctx, s.relay, walletPubKey, walletPrivKey, s.svc.lnClient)
if err != nil {
logger.Logger.WithError(err).Error("Could not re-publish NIP47 info")
}

}
}

0 comments on commit ad2d8dd

Please sign in to comment.