// internal/nostr/nip65/outbox.go package nip65 import ( "github.com/nbd-wtf/go-nostr" "git.sovbit.dev/Enki/nostr-poster/internal/models" ) // GetOutboxRelaysForEvent determines the optimal set of relays for publishing an event // following the NIP-65 (Outbox Model) recommendations func GetOutboxRelaysForEvent(event *nostr.Event, authorRelays []*models.Relay, taggedPubkeys []string, taggedPubkeyRelays map[string][]*models.Relay) []*models.Relay { // Start with the author's WRITE relays var outboxRelays []*models.Relay var outboxRelayURLs = make(map[string]bool) // First, add all WRITE relays of the author for _, relay := range authorRelays { if relay.Write { outboxRelays = append(outboxRelays, relay) outboxRelayURLs[relay.URL] = true } } // Then add all READ relays of tagged users (if any) for _, pubkey := range taggedPubkeys { // Skip if we don't have relay info for this pubkey userRelays, ok := taggedPubkeyRelays[pubkey] if !ok { continue } // Add all READ relays that aren't already in our list for _, relay := range userRelays { if relay.Read && !outboxRelayURLs[relay.URL] { outboxRelays = append(outboxRelays, relay) outboxRelayURLs[relay.URL] = true } } } return outboxRelays } // ExtractTaggedPubkeys extracts all pubkeys tagged in an event func ExtractTaggedPubkeys(event *nostr.Event) []string { var pubkeys []string for _, tag := range event.Tags { if len(tag) >= 2 && tag[0] == "p" { pubkeys = append(pubkeys, tag[1]) } } return pubkeys } // PublishWithOutboxModel is a utility function to properly publish an event // following the NIP-65 Outbox Model func PublishWithOutboxModel(event *nostr.Event, relayManager interface{}, authorRelays []*models.Relay, taggedPubkeyRelaysFn func(pubkey string) ([]*models.Relay, error)) error { // Extract tagged pubkeys taggedPubkeys := ExtractTaggedPubkeys(event) // Get relays for tagged pubkeys taggedPubkeyRelays := make(map[string][]*models.Relay) for _, pubkey := range taggedPubkeys { relays, err := taggedPubkeyRelaysFn(pubkey) if err == nil { taggedPubkeyRelays[pubkey] = relays } } // Determine outbox relays outboxRelays := GetOutboxRelaysForEvent(event, authorRelays, taggedPubkeys, taggedPubkeyRelays) // Configure relay manager with these relays // This will be implementation-specific - this is just a skeleton return nil }