From ff017b45d20dfb48783c4942922e754ab3f8c3d7 Mon Sep 17 00:00:00 2001 From: mleku Date: Tue, 23 Sep 2025 15:08:30 +0100 Subject: [PATCH] Add relay identity pubkey and subscription-based profile updates; bump version to v0.8.4. - Included relay identity public key in `relayinfo` response. - Added `UpdateRelayProfile` function to dynamically create/update relay's subscription profile. - Incremented version from v0.8.3 to v0.8.4. --- app/handle-relayinfo.go | 15 +++++++++++- app/payment_processor.go | 52 ++++++++++++++++++++++++++++++++++++++++ pkg/version/version | 2 +- 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/app/handle-relayinfo.go b/app/handle-relayinfo.go index 1a0d577..e529f55 100644 --- a/app/handle-relayinfo.go +++ b/app/handle-relayinfo.go @@ -4,9 +4,12 @@ import ( "encoding/json" "net/http" "sort" + "strings" "lol.mleku.dev/chk" "lol.mleku.dev/log" + "next.orly.dev/pkg/crypto/p256k" + "next.orly.dev/pkg/encoders/hex" "next.orly.dev/pkg/protocol/relayinfo" "next.orly.dev/pkg/version" ) @@ -67,12 +70,22 @@ func (s *Server) HandleRelayInfo(w http.ResponseWriter, r *http.Request) { dashboardURL := s.DashboardURL(r) description := version.Description + " dashboard: " + dashboardURL + // Get relay identity pubkey as hex + var relayPubkey string + if skb, err := s.D.GetRelayIdentitySecret(); err == nil && len(skb) == 32 { + sign := new(p256k.Signer) + if err := sign.InitSec(skb); err == nil { + relayPubkey = hex.Enc(sign.Pub()) + } + } + info = &relayinfo.T{ Name: s.Config.AppName, Description: description, + PubKey: relayPubkey, Nips: supportedNIPs, Software: version.URL, - Version: version.V, + Version: strings.TrimPrefix(version.V, "v"), Limitation: relayinfo.Limits{ AuthRequired: s.Config.ACLMode != "none", RestrictedWrites: s.Config.ACLMode != "none", diff --git a/app/payment_processor.go b/app/payment_processor.go index cca0bac..c3a694a 100644 --- a/app/payment_processor.go +++ b/app/payment_processor.go @@ -820,6 +820,58 @@ func (pp *PaymentProcessor) npubToPubkey(npubStr string) ([]byte, error) { return pubkey, nil } +// UpdateRelayProfile creates or updates the relay's kind 0 profile with subscription information +func (pp *PaymentProcessor) UpdateRelayProfile() error { + // Get relay identity secret to sign the profile + skb, err := pp.db.GetRelayIdentitySecret() + if err != nil || len(skb) != 32 { + return fmt.Errorf("no relay identity configured") + } + + // Initialize signer + sign := new(p256k.Signer) + if err := sign.InitSec(skb); err != nil { + return fmt.Errorf("failed to initialize signer: %w", err) + } + + monthlyPrice := pp.config.MonthlyPriceSats + if monthlyPrice <= 0 { + monthlyPrice = 6000 + } + + // Calculate daily rate + dailyRate := monthlyPrice / 30 + + // Get relay wss:// URL - use dashboard URL but with wss:// scheme + relayURL := strings.Replace(pp.getDashboardURL(), "https://", "wss://", 1) + + // Create profile content as JSON + profileContent := fmt.Sprintf(`{ + "name": "Relay Bot", + "about": "This relay requires a subscription to access. Zap any of my notes to pay for access. Monthly price: %d sats (%d sats/day). Relay: %s", + "lud16": "", + "nip05": "", + "website": "%s" +}`, monthlyPrice, dailyRate, relayURL, pp.getDashboardURL()) + + // Build the profile event + ev := event.New() + ev.Kind = kind.ProfileMetadata.K // Kind 0 for profile metadata + ev.Pubkey = sign.Pub() + ev.CreatedAt = timestamp.Now().V + ev.Content = []byte(profileContent) + ev.Tags = tag.NewS() + + // Sign and save the event + ev.Sign(sign) + if _, _, err := pp.db.SaveEvent(pp.ctx, ev); err != nil { + return fmt.Errorf("failed to save relay profile: %w", err) + } + + log.I.F("updated relay profile with subscription information") + return nil +} + // decodeAnyPubkey decodes a public key from either hex string or npub format func decodeAnyPubkey(s string) ([]byte, error) { s = strings.TrimSpace(s) diff --git a/pkg/version/version b/pkg/version/version index dff41ab..c58a021 100644 --- a/pkg/version/version +++ b/pkg/version/version @@ -1 +1 @@ -v0.8.3 \ No newline at end of file +v0.8.4 \ No newline at end of file