2024-09-10 22:37:48 -03:00
package sdk
import (
"net/url"
"github.com/nbd-wtf/go-nostr"
"github.com/nbd-wtf/go-nostr/sdk/hints"
)
2024-12-24 00:15:10 -03:00
func ( sys * System ) TrackQueryAttempts ( relay string , author string , kind int ) {
if IsVirtualRelay ( relay ) {
return
}
if kind < 30000 && kind >= 20000 {
return
}
if kind == 0 || kind == 10002 || kind == 3 {
return
}
sys . Hints . Save ( author , relay , hints . LastFetchAttempt , nostr . Now ( ) )
}
2025-01-16 17:47:31 -03:00
// TrackEventHintsAndRelays is meant to be as an argument to WithEventMiddleware() when you're interested
// in tracking relays associated to event ids as well as feeding hints to the HintsDB.
2025-01-16 17:38:03 -03:00
func ( sys * System ) TrackEventHintsAndRelays ( ie nostr . RelayEvent ) {
2024-09-10 22:37:48 -03:00
if IsVirtualRelay ( ie . Relay . URL ) {
return
}
2024-09-17 08:06:04 -03:00
if ie . Kind < 30000 && ie . Kind >= 20000 {
return
}
2024-09-10 22:37:48 -03:00
2025-01-16 17:38:03 -03:00
if ie . Kind != 0 && ie . Kind != 10002 {
2025-01-16 17:47:31 -03:00
sys . trackEventRelay ( ie . ID , ie . Relay . URL , false )
2025-01-16 17:38:03 -03:00
}
2025-01-16 17:47:31 -03:00
sys . trackEventHints ( ie )
}
// TrackEventHints is meant to be used standalone as an argument to WithEventMiddleware() when you're not interested
// in tracking relays associated to event ids.
func ( sys * System ) TrackEventHints ( ie nostr . RelayEvent ) {
if IsVirtualRelay ( ie . Relay . URL ) {
return
}
if ie . Kind < 30000 && ie . Kind >= 20000 {
return
}
sys . trackEventHints ( ie )
}
func ( sys * System ) trackEventHints ( ie nostr . RelayEvent ) {
2024-09-10 22:37:48 -03:00
switch ie . Kind {
2024-12-24 00:15:10 -03:00
case nostr . KindProfileMetadata :
// this could be anywhere so it doesn't count
return
2024-09-10 22:37:48 -03:00
case nostr . KindRelayListMetadata :
2024-12-24 00:15:10 -03:00
// this is special, we only use it to track relay-list hints
if len ( ie . Tags ) > 12 {
// too many relays in the list means this person is not using this correctly so we better ignore them
return
}
2024-09-10 22:37:48 -03:00
for _ , tag := range ie . Tags {
if len ( tag ) < 2 || tag [ 0 ] != "r" {
continue
}
if len ( tag ) == 2 || ( tag [ 2 ] == "" || tag [ 2 ] == "write" ) {
2025-01-16 17:38:03 -03:00
sys . Hints . Save ( ie . PubKey , nostr . NormalizeURL ( tag [ 1 ] ) , hints . LastInRelayList , ie . CreatedAt )
2024-09-10 22:37:48 -03:00
}
}
2024-09-19 14:12:41 +03:30
case nostr . KindFollowList :
2024-12-24 00:15:10 -03:00
// this is special, we only use it to check if there are hints for the contacts
2024-09-10 22:37:48 -03:00
for _ , tag := range ie . Tags {
if len ( tag ) < 3 {
continue
}
if IsVirtualRelay ( tag [ 2 ] ) {
continue
}
if p , err := url . Parse ( tag [ 2 ] ) ; err != nil || ( p . Scheme != "wss" && p . Scheme != "ws" ) {
continue
}
if tag [ 0 ] == "p" && nostr . IsValidPublicKey ( tag [ 1 ] ) {
2025-01-16 17:38:03 -03:00
sys . Hints . Save ( tag [ 1 ] , nostr . NormalizeURL ( tag [ 2 ] ) , hints . LastInTag , ie . CreatedAt )
2024-09-10 22:37:48 -03:00
}
}
2024-12-24 00:15:10 -03:00
default :
2025-01-16 17:38:03 -03:00
// everything else we track by relays and also check for hints
2024-09-10 22:37:48 -03:00
sys . Hints . Save ( ie . PubKey , ie . Relay . URL , hints . MostRecentEventFetched , ie . CreatedAt )
for _ , tag := range ie . Tags {
if len ( tag ) < 3 {
continue
}
if IsVirtualRelay ( tag [ 2 ] ) {
continue
}
if p , err := url . Parse ( tag [ 2 ] ) ; err != nil || ( p . Scheme != "wss" && p . Scheme != "ws" ) {
continue
}
if tag [ 0 ] == "p" && nostr . IsValidPublicKey ( tag [ 1 ] ) {
2025-01-16 17:38:03 -03:00
sys . Hints . Save ( tag [ 1 ] , nostr . NormalizeURL ( tag [ 2 ] ) , hints . LastInTag , ie . CreatedAt )
2024-09-10 22:37:48 -03:00
}
}
2025-01-01 18:16:36 -03:00
for ref := range ParseReferences ( * ie . Event ) {
2024-09-10 22:37:48 -03:00
if ref . Profile != nil {
for _ , relay := range ref . Profile . Relays {
if IsVirtualRelay ( relay ) {
continue
}
if p , err := url . Parse ( relay ) ; err != nil || ( p . Scheme != "wss" && p . Scheme != "ws" ) {
continue
}
if nostr . IsValidPublicKey ( ref . Profile . PublicKey ) {
2025-01-16 17:38:03 -03:00
sys . Hints . Save ( ref . Profile . PublicKey , nostr . NormalizeURL ( relay ) , hints . LastInNprofile , ie . CreatedAt )
2024-09-10 22:37:48 -03:00
}
}
} else if ref . Event != nil && nostr . IsValidPublicKey ( ref . Event . Author ) {
for _ , relay := range ref . Event . Relays {
if IsVirtualRelay ( relay ) {
continue
}
if p , err := url . Parse ( relay ) ; err != nil || ( p . Scheme != "wss" && p . Scheme != "ws" ) {
continue
}
2025-01-16 17:38:03 -03:00
sys . Hints . Save ( ref . Event . Author , nostr . NormalizeURL ( relay ) , hints . LastInNevent , ie . CreatedAt )
2024-09-10 22:37:48 -03:00
}
}
}
}
}
2025-01-15 00:30:24 -03:00
2025-01-16 17:47:31 -03:00
// TrackEventRelaysD is a companion to TrackEventRelays meant to be used with WithDuplicateMiddleware()
2025-01-15 00:30:24 -03:00
func ( sys * System ) TrackEventRelaysD ( relay , id string ) {
2025-01-16 17:38:03 -03:00
if IsVirtualRelay ( relay ) {
return
}
2025-01-16 17:47:31 -03:00
sys . trackEventRelay ( id , relay , true /* we pass this flag so we'll skip creating entries for events that didn't pass the checks on the function above -- i.e. ephemeral events */ )
2025-01-15 00:30:24 -03:00
}