graph-mentions.go raw

   1  //go:build !(js && wasm)
   2  
   3  package database
   4  
   5  import (
   6  	"next.orly.dev/pkg/lol/log"
   7  	"next.orly.dev/pkg/database/indexes/types"
   8  	"next.orly.dev/pkg/nostr/encoders/hex"
   9  )
  10  
  11  // FindMentions finds events that mention a pubkey via p-tags.
  12  // This returns events grouped by depth, where depth represents how the events relate:
  13  // - Depth 1: Events that directly mention the seed pubkey
  14  // - Depth 2+: Not typically used for mentions (reserved for future expansion)
  15  //
  16  // The kinds parameter filters which event kinds to include (e.g., [1] for notes only,
  17  // [1,7] for notes and reactions, etc.)
  18  func (d *D) FindMentions(pubkey []byte, kinds []uint16) (*GraphResult, error) {
  19  	result := NewGraphResult()
  20  
  21  	if len(pubkey) != 32 {
  22  		return result, ErrPubkeyNotFound
  23  	}
  24  
  25  	// Get pubkey serial
  26  	pubkeySerial, err := d.GetPubkeySerial(pubkey)
  27  	if err != nil {
  28  		log.D.F("FindMentions: pubkey not in database: %s", hex.Enc(pubkey))
  29  		return result, nil
  30  	}
  31  
  32  	// Find all events that reference this pubkey
  33  	eventSerials, err := d.GetEventsReferencingPubkey(pubkeySerial, kinds)
  34  	if err != nil {
  35  		return nil, err
  36  	}
  37  
  38  	// Add each event at depth 1
  39  	for _, eventSerial := range eventSerials {
  40  		eventIDHex, err := d.GetEventIDFromSerial(eventSerial)
  41  		if err != nil {
  42  			log.D.F("FindMentions: error getting event ID for serial %d: %v", eventSerial.Get(), err)
  43  			continue
  44  		}
  45  		result.AddEventAtDepth(eventIDHex, 1)
  46  	}
  47  
  48  	log.D.F("FindMentions: found %d events mentioning pubkey %s", result.TotalEvents, hex.Enc(pubkey))
  49  
  50  	return result, nil
  51  }
  52  
  53  // FindMentionsFromHex is a convenience wrapper that accepts hex-encoded pubkey.
  54  func (d *D) FindMentionsFromHex(pubkeyHex string, kinds []uint16) (*GraphResult, error) {
  55  	pubkey, err := hex.Dec(pubkeyHex)
  56  	if err != nil {
  57  		return nil, err
  58  	}
  59  	return d.FindMentions(pubkey, kinds)
  60  }
  61  
  62  // FindMentionsByPubkeys returns events that mention any of the given pubkeys.
  63  // Useful for finding mentions across a set of followed accounts.
  64  func (d *D) FindMentionsByPubkeys(pubkeySerials []*types.Uint40, kinds []uint16) (*GraphResult, error) {
  65  	result := NewGraphResult()
  66  
  67  	seen := make(map[uint64]bool)
  68  
  69  	for _, pubkeySerial := range pubkeySerials {
  70  		eventSerials, err := d.GetEventsReferencingPubkey(pubkeySerial, kinds)
  71  		if err != nil {
  72  			log.D.F("FindMentionsByPubkeys: error for serial %d: %v", pubkeySerial.Get(), err)
  73  			continue
  74  		}
  75  
  76  		for _, eventSerial := range eventSerials {
  77  			if seen[eventSerial.Get()] {
  78  				continue
  79  			}
  80  			seen[eventSerial.Get()] = true
  81  
  82  			eventIDHex, err := d.GetEventIDFromSerial(eventSerial)
  83  			if err != nil {
  84  				continue
  85  			}
  86  			result.AddEventAtDepth(eventIDHex, 1)
  87  		}
  88  	}
  89  
  90  	return result, nil
  91  }
  92