- Introduced a TypeScript client library for the Distributed Directory Consensus Protocol (NIP-XX), providing a high-level API for managing directory events, identity resolution, and trust calculations. - Implemented core functionalities including event parsing, trust score aggregation, and replication filtering, mirroring the Go implementation. - Added comprehensive documentation and development guides for ease of use and integration. - Updated the `.gitignore` to include additional dependencies and build artifacts for the TypeScript client. - Enhanced validation mechanisms for group tag names and trust levels, ensuring robust input handling and security. - Created a new `bun.lock` file to manage package dependencies effectively.
121 lines
3.3 KiB
Go
121 lines
3.3 KiB
Go
// Package directory_client provides a client library for the Distributed
|
|
// Directory Consensus Protocol (NIP-XX).
|
|
//
|
|
// This package offers a high-level API for working with directory events,
|
|
// managing identity resolution, tracking key delegations, and computing
|
|
// trust scores. It builds on the lower-level directory protocol package.
|
|
//
|
|
// # Basic Usage
|
|
//
|
|
// // Create an identity resolver
|
|
// resolver := directory_client.NewIdentityResolver()
|
|
//
|
|
// // Parse and track events
|
|
// event := getDirectoryEvent()
|
|
// resolver.ProcessEvent(event)
|
|
//
|
|
// // Resolve identity behind a delegate key
|
|
// actualIdentity := resolver.ResolveIdentity(delegateKey)
|
|
//
|
|
// // Check if a key is a delegate
|
|
// isDelegate := resolver.IsDelegateKey(pubkey)
|
|
//
|
|
// # Trust Management
|
|
//
|
|
// // Create a trust calculator
|
|
// calculator := directory_client.NewTrustCalculator()
|
|
//
|
|
// // Add trust acts
|
|
// trustAct := directory.ParseTrustAct(event)
|
|
// calculator.AddAct(trustAct)
|
|
//
|
|
// // Calculate aggregate trust score
|
|
// score := calculator.CalculateTrust(targetPubkey)
|
|
//
|
|
// # Replication Filtering
|
|
//
|
|
// // Create a replication filter
|
|
// filter := directory_client.NewReplicationFilter(50) // min trust score of 50
|
|
//
|
|
// // Add trust acts to influence replication decisions
|
|
// filter.AddTrustAct(trustAct)
|
|
//
|
|
// // Check if should replicate from a relay
|
|
// if filter.ShouldReplicate(relayPubkey) {
|
|
// // Proceed with replication
|
|
// }
|
|
//
|
|
// # Event Filtering
|
|
//
|
|
// // Filter directory events from a stream
|
|
// events := getEvents()
|
|
// directoryEvents := directory_client.FilterDirectoryEvents(events)
|
|
//
|
|
// // Check if an event is a directory event
|
|
// if directory_client.IsDirectoryEvent(event) {
|
|
// // Handle directory event
|
|
// }
|
|
package directory_client
|
|
|
|
import (
|
|
"lol.mleku.dev/errorf"
|
|
"next.orly.dev/pkg/encoders/event"
|
|
"next.orly.dev/pkg/protocol/directory"
|
|
)
|
|
|
|
// IsDirectoryEvent checks if an event is a directory consensus event.
|
|
func IsDirectoryEvent(ev *event.E) bool {
|
|
if ev == nil {
|
|
return false
|
|
}
|
|
k := uint16(ev.Kind)
|
|
return k == 39100 || k == 39101 || k == 39102 ||
|
|
k == 39103 || k == 39104 || k == 39105
|
|
}
|
|
|
|
// FilterDirectoryEvents filters a slice of events to only directory events.
|
|
func FilterDirectoryEvents(events []*event.E) (filtered []*event.E) {
|
|
filtered = make([]*event.E, 0)
|
|
for _, ev := range events {
|
|
if IsDirectoryEvent(ev) {
|
|
filtered = append(filtered, ev)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// NormalizeRelayURL ensures a relay URL has the canonical format with trailing slash.
|
|
func NormalizeRelayURL(url string) string {
|
|
if url == "" {
|
|
return ""
|
|
}
|
|
if url[len(url)-1] != '/' {
|
|
return url + "/"
|
|
}
|
|
return url
|
|
}
|
|
|
|
// ParseDirectoryEvent parses any directory event based on its kind.
|
|
func ParseDirectoryEvent(ev *event.E) (parsed interface{}, err error) {
|
|
if !IsDirectoryEvent(ev) {
|
|
return nil, errorf.E("not a directory event: kind %d", uint16(ev.Kind))
|
|
}
|
|
|
|
switch uint16(ev.Kind) {
|
|
case 39100:
|
|
return directory.ParseRelayIdentityAnnouncement(ev)
|
|
case 39101:
|
|
return directory.ParseTrustAct(ev)
|
|
case 39102:
|
|
return directory.ParseGroupTagAct(ev)
|
|
case 39103:
|
|
return directory.ParsePublicKeyAdvertisement(ev)
|
|
case 39104:
|
|
return directory.ParseDirectoryEventReplicationRequest(ev)
|
|
case 39105:
|
|
return directory.ParseDirectoryEventReplicationResponse(ev)
|
|
default:
|
|
return nil, errorf.E("unknown directory event kind: %d", uint16(ev.Kind))
|
|
}
|
|
}
|