You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
227 lines
6.5 KiB
227 lines
6.5 KiB
package directory_client |
|
|
|
import ( |
|
"next.orly.dev/pkg/encoders/event" |
|
"next.orly.dev/pkg/protocol/directory" |
|
) |
|
|
|
// EventCollector provides utility methods for collecting specific types of |
|
// directory events from a slice. |
|
type EventCollector struct { |
|
events []*event.E |
|
} |
|
|
|
// NewEventCollector creates a new event collector for the given events. |
|
func NewEventCollector(events []*event.E) *EventCollector { |
|
return &EventCollector{events: events} |
|
} |
|
|
|
// RelayIdentities returns all relay identity declarations. |
|
func (ec *EventCollector) RelayIdentities() (identities []*directory.RelayIdentityAnnouncement) { |
|
identities = make([]*directory.RelayIdentityAnnouncement, 0) |
|
for _, ev := range ec.events { |
|
if uint16(ev.Kind) == 39100 { |
|
if identity, err := directory.ParseRelayIdentityAnnouncement(ev); err == nil { |
|
identities = append(identities, identity) |
|
} |
|
} |
|
} |
|
return |
|
} |
|
|
|
// TrustActs returns all trust acts. |
|
func (ec *EventCollector) TrustActs() (acts []*directory.TrustAct) { |
|
acts = make([]*directory.TrustAct, 0) |
|
for _, ev := range ec.events { |
|
if uint16(ev.Kind) == 39101 { |
|
if act, err := directory.ParseTrustAct(ev); err == nil { |
|
acts = append(acts, act) |
|
} |
|
} |
|
} |
|
return |
|
} |
|
|
|
// GroupTagActs returns all group tag acts. |
|
func (ec *EventCollector) GroupTagActs() (acts []*directory.GroupTagAct) { |
|
acts = make([]*directory.GroupTagAct, 0) |
|
for _, ev := range ec.events { |
|
if uint16(ev.Kind) == 39102 { |
|
if act, err := directory.ParseGroupTagAct(ev); err == nil { |
|
acts = append(acts, act) |
|
} |
|
} |
|
} |
|
return |
|
} |
|
|
|
// PublicKeyAdvertisements returns all public key advertisements. |
|
func (ec *EventCollector) PublicKeyAdvertisements() (ads []*directory.PublicKeyAdvertisement) { |
|
ads = make([]*directory.PublicKeyAdvertisement, 0) |
|
for _, ev := range ec.events { |
|
if uint16(ev.Kind) == 39103 { |
|
if ad, err := directory.ParsePublicKeyAdvertisement(ev); err == nil { |
|
ads = append(ads, ad) |
|
} |
|
} |
|
} |
|
return |
|
} |
|
|
|
// ReplicationRequests returns all replication requests. |
|
func (ec *EventCollector) ReplicationRequests() (requests []*directory.DirectoryEventReplicationRequest) { |
|
requests = make([]*directory.DirectoryEventReplicationRequest, 0) |
|
for _, ev := range ec.events { |
|
if uint16(ev.Kind) == 39104 { |
|
if req, err := directory.ParseDirectoryEventReplicationRequest(ev); err == nil { |
|
requests = append(requests, req) |
|
} |
|
} |
|
} |
|
return |
|
} |
|
|
|
// ReplicationResponses returns all replication responses. |
|
func (ec *EventCollector) ReplicationResponses() (responses []*directory.DirectoryEventReplicationResponse) { |
|
responses = make([]*directory.DirectoryEventReplicationResponse, 0) |
|
for _, ev := range ec.events { |
|
if uint16(ev.Kind) == 39105 { |
|
if resp, err := directory.ParseDirectoryEventReplicationResponse(ev); err == nil { |
|
responses = append(responses, resp) |
|
} |
|
} |
|
} |
|
return |
|
} |
|
|
|
// FindRelayIdentity finds a relay identity by relay URL. |
|
func FindRelayIdentity(events []*event.E, relayURL string) (*directory.RelayIdentityAnnouncement, bool) { |
|
normalizedURL := NormalizeRelayURL(relayURL) |
|
for _, ev := range events { |
|
if uint16(ev.Kind) == 39100 { |
|
if identity, err := directory.ParseRelayIdentityAnnouncement(ev); err == nil { |
|
if NormalizeRelayURL(identity.RelayURL) == normalizedURL { |
|
return identity, true |
|
} |
|
} |
|
} |
|
} |
|
return nil, false |
|
} |
|
|
|
// FindTrustActsForRelay finds all trust acts targeting a specific relay. |
|
func FindTrustActsForRelay(events []*event.E, targetPubkey string) (acts []*directory.TrustAct) { |
|
acts = make([]*directory.TrustAct, 0) |
|
for _, ev := range events { |
|
if uint16(ev.Kind) == 39101 { |
|
if act, err := directory.ParseTrustAct(ev); err == nil { |
|
if act.TargetPubkey == targetPubkey { |
|
acts = append(acts, act) |
|
} |
|
} |
|
} |
|
} |
|
return |
|
} |
|
|
|
// FindGroupTagActsForRelay finds all group tag acts targeting a specific relay. |
|
// Note: This function needs to be updated based on the actual GroupTagAct structure |
|
// which doesn't have a Target field. The filtering logic should be clarified. |
|
func FindGroupTagActsForRelay(events []*event.E, targetPubkey string) (acts []*directory.GroupTagAct) { |
|
acts = make([]*directory.GroupTagAct, 0) |
|
for _, ev := range events { |
|
if uint16(ev.Kind) == 39102 { |
|
if act, err := directory.ParseGroupTagAct(ev); err == nil { |
|
// Filter by actor since GroupTagAct doesn't have a Target field |
|
if act.Actor == targetPubkey { |
|
acts = append(acts, act) |
|
} |
|
} |
|
} |
|
} |
|
return |
|
} |
|
|
|
// FindGroupTagActsByGroup finds all group tag acts for a specific group. |
|
func FindGroupTagActsByGroup(events []*event.E, groupID string) (acts []*directory.GroupTagAct) { |
|
acts = make([]*directory.GroupTagAct, 0) |
|
for _, ev := range events { |
|
if uint16(ev.Kind) == 39102 { |
|
if act, err := directory.ParseGroupTagAct(ev); err == nil { |
|
if act.GroupID == groupID { |
|
acts = append(acts, act) |
|
} |
|
} |
|
} |
|
} |
|
return |
|
} |
|
|
|
// TrustGraph represents a directed graph of trust relationships. |
|
type TrustGraph struct { |
|
// edges maps source pubkey -> list of trust acts |
|
edges map[string][]*directory.TrustAct |
|
} |
|
|
|
// NewTrustGraph creates a new trust graph instance. |
|
func NewTrustGraph() *TrustGraph { |
|
return &TrustGraph{ |
|
edges: make(map[string][]*directory.TrustAct), |
|
} |
|
} |
|
|
|
// AddTrustAct adds a trust act to the graph. |
|
func (tg *TrustGraph) AddTrustAct(act *directory.TrustAct) { |
|
if act == nil { |
|
return |
|
} |
|
source := string(act.Event.Pubkey) |
|
tg.edges[source] = append(tg.edges[source], act) |
|
} |
|
|
|
// GetTrustActs returns all trust acts from a source pubkey. |
|
func (tg *TrustGraph) GetTrustActs(source string) []*directory.TrustAct { |
|
return tg.edges[source] |
|
} |
|
|
|
// GetTrustedBy returns all pubkeys that trust the given target. |
|
func (tg *TrustGraph) GetTrustedBy(target string) []string { |
|
trustedBy := make([]string, 0) |
|
for source, acts := range tg.edges { |
|
for _, act := range acts { |
|
if act.TargetPubkey == target { |
|
trustedBy = append(trustedBy, source) |
|
break |
|
} |
|
} |
|
} |
|
return trustedBy |
|
} |
|
|
|
// GetTrustTargets returns all pubkeys trusted by the given source. |
|
func (tg *TrustGraph) GetTrustTargets(source string) []string { |
|
acts := tg.edges[source] |
|
targets := make(map[string]bool) |
|
for _, act := range acts { |
|
targets[act.TargetPubkey] = true |
|
} |
|
|
|
result := make([]string, 0, len(targets)) |
|
for target := range targets { |
|
result = append(result, target) |
|
} |
|
return result |
|
} |
|
|
|
// BuildTrustGraph builds a trust graph from a collection of events. |
|
func BuildTrustGraph(events []*event.E) *TrustGraph { |
|
graph := NewTrustGraph() |
|
for _, ev := range events { |
|
if uint16(ev.Kind) == 39101 { |
|
if act, err := directory.ParseTrustAct(ev); err == nil { |
|
graph.AddTrustAct(act) |
|
} |
|
} |
|
} |
|
return graph |
|
}
|
|
|