- Introduced a new `sync` package for managing NIP-11 relay information and relay group configurations. - Implemented a cache for NIP-11 documents, allowing retrieval of relay public keys and authoritative configurations. - Enhanced the sync manager to update peer lists based on authoritative configurations from relay group events. - Updated event handling to incorporate policy checks during event imports, ensuring compliance with relay rules. - Refactored various components to utilize the new `sha256-simd` package for improved performance. - Added comprehensive tests to validate the new synchronization and group management functionalities. - Bumped version to v0.24.1 to reflect these changes.
341 lines
10 KiB
Markdown
341 lines
10 KiB
Markdown
# Directory Client Library
|
|
|
|
High-level Go client library for the Distributed Directory Consensus Protocol (NIP-XX).
|
|
|
|
## Overview
|
|
|
|
This package provides a convenient 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.
|
|
|
|
## Features
|
|
|
|
- **Identity Resolution**: Track and resolve delegate keys to their primary identities
|
|
- **Trust Management**: Calculate aggregate trust scores from multiple trust acts
|
|
- **Replication Filtering**: Determine which relays to trust for event replication
|
|
- **Event Collection**: Convenient utilities for extracting specific event types
|
|
- **Trust Graph**: Build and analyze trust relationship networks
|
|
- **Thread-Safe**: All components support concurrent access
|
|
|
|
## Installation
|
|
|
|
```go
|
|
import "next.orly.dev/pkg/protocol/directory-client"
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
### Identity Resolution
|
|
|
|
```go
|
|
// Create an identity resolver
|
|
resolver := directory_client.NewIdentityResolver()
|
|
|
|
// Process events to build identity mappings
|
|
for _, event := range events {
|
|
resolver.ProcessEvent(event)
|
|
}
|
|
|
|
// Resolve identity behind a delegate key
|
|
actualIdentity := resolver.ResolveIdentity(delegateKey)
|
|
|
|
// Check if a key is a delegate
|
|
if resolver.IsDelegateKey(pubkey) {
|
|
tag, _ := resolver.GetIdentityTag(pubkey)
|
|
fmt.Printf("Delegate belongs to: %s\n", tag.Identity)
|
|
}
|
|
|
|
// Get all delegates for an identity
|
|
delegates := resolver.GetDelegatesForIdentity(identityPubkey)
|
|
|
|
// Filter events by identity (including delegates)
|
|
filteredEvents := resolver.FilterEventsByIdentity(events, identityPubkey)
|
|
```
|
|
|
|
### Trust Management
|
|
|
|
```go
|
|
// Create a trust calculator
|
|
calculator := directory_client.NewTrustCalculator()
|
|
|
|
// Add trust acts
|
|
for _, event := range trustEvents {
|
|
if act, err := directory.ParseTrustAct(event); err == nil {
|
|
calculator.AddAct(act)
|
|
}
|
|
}
|
|
|
|
// Calculate aggregate trust score (0-100)
|
|
score := calculator.CalculateTrust(targetPubkey)
|
|
|
|
// Get active (non-expired) trust acts
|
|
activeActs := calculator.GetActiveTrustActs(targetPubkey)
|
|
```
|
|
|
|
### Replication Filtering
|
|
|
|
```go
|
|
// Create filter with minimum trust score threshold
|
|
filter := directory_client.NewReplicationFilter(50)
|
|
|
|
// Add trust acts
|
|
for _, act := range trustActs {
|
|
filter.AddTrustAct(act)
|
|
}
|
|
|
|
// Check if should replicate from a relay
|
|
if filter.ShouldReplicate(relayPubkey) {
|
|
// Proceed with replication
|
|
}
|
|
|
|
// Get all trusted relays
|
|
trustedRelays := filter.GetTrustedRelays()
|
|
|
|
// Filter events to only trusted sources
|
|
trustedEvents := filter.FilterEvents(events)
|
|
```
|
|
|
|
### Event Collection
|
|
|
|
```go
|
|
// Create event collector
|
|
collector := directory_client.NewEventCollector(events)
|
|
|
|
// Extract specific event types
|
|
identities := collector.RelayIdentities()
|
|
trustActs := collector.TrustActs()
|
|
groupTagActs := collector.GroupTagActs()
|
|
keyAds := collector.PublicKeyAdvertisements()
|
|
requests := collector.ReplicationRequests()
|
|
responses := collector.ReplicationResponses()
|
|
|
|
// Find specific events
|
|
identity, found := directory_client.FindRelayIdentity(events, "wss://relay.example.com/")
|
|
trustActs := directory_client.FindTrustActsForRelay(events, targetPubkey)
|
|
groupActs := directory_client.FindGroupTagActsByGroup(events, "premium")
|
|
```
|
|
|
|
### Trust Graph Analysis
|
|
|
|
```go
|
|
// Build trust graph from events
|
|
graph := directory_client.BuildTrustGraph(events)
|
|
|
|
// Find who trusts a relay
|
|
trustedBy := graph.GetTrustedBy(targetPubkey)
|
|
fmt.Printf("Trusted by %d relays\n", len(trustedBy))
|
|
|
|
// Find who a relay trusts
|
|
targets := graph.GetTrustTargets(sourcePubkey)
|
|
fmt.Printf("Trusts %d relays\n", len(targets))
|
|
|
|
// Get all trust acts from a source
|
|
acts := graph.GetTrustActs(sourcePubkey)
|
|
```
|
|
|
|
## API Reference
|
|
|
|
### IdentityResolver
|
|
|
|
Manages identity resolution and key delegation tracking.
|
|
|
|
**Methods:**
|
|
- `NewIdentityResolver() *IdentityResolver` - Create new instance
|
|
- `ProcessEvent(ev *event.E)` - Process event to extract identity info
|
|
- `ResolveIdentity(pubkey string) string` - Resolve delegate to identity
|
|
- `ResolveEventIdentity(ev *event.E) string` - Resolve event's identity
|
|
- `IsDelegateKey(pubkey string) bool` - Check if key is a delegate
|
|
- `IsIdentityKey(pubkey string) bool` - Check if key has delegates
|
|
- `GetDelegatesForIdentity(identity string) []string` - Get all delegates
|
|
- `GetIdentityTag(delegate string) (*IdentityTag, error)` - Get identity tag
|
|
- `GetPublicKeyAdvertisements(identity string) []*PublicKeyAdvertisement` - Get key ads
|
|
- `FilterEventsByIdentity(events []*event.E, identity string) []*event.E` - Filter events
|
|
- `ClearCache()` - Clear all cached mappings
|
|
- `GetStats() Stats` - Get statistics
|
|
|
|
### TrustCalculator
|
|
|
|
Computes aggregate trust scores from multiple trust acts.
|
|
|
|
**Methods:**
|
|
- `NewTrustCalculator() *TrustCalculator` - Create new instance
|
|
- `AddAct(act *TrustAct)` - Add a trust act
|
|
- `CalculateTrust(pubkey string) float64` - Calculate trust score (0-100)
|
|
- `GetActs(pubkey string) []*TrustAct` - Get all acts for pubkey
|
|
- `GetActiveTrustActs(pubkey string) []*TrustAct` - Get non-expired acts
|
|
- `Clear()` - Remove all acts
|
|
- `GetAllPubkeys() []string` - Get all tracked pubkeys
|
|
|
|
**Trust Score Weights:**
|
|
- High: 100
|
|
- Medium: 50
|
|
- Low: 25
|
|
|
|
### ReplicationFilter
|
|
|
|
Manages replication decisions based on trust scores.
|
|
|
|
**Methods:**
|
|
- `NewReplicationFilter(minTrustScore float64) *ReplicationFilter` - Create new instance
|
|
- `AddTrustAct(act *TrustAct)` - Add trust act and update trusted relays
|
|
- `ShouldReplicate(pubkey string) bool` - Check if relay is trusted
|
|
- `GetTrustedRelays() []string` - Get all trusted relay pubkeys
|
|
- `GetTrustScore(pubkey string) float64` - Get trust score for relay
|
|
- `SetMinTrustScore(minScore float64)` - Update threshold
|
|
- `GetMinTrustScore() float64` - Get current threshold
|
|
- `FilterEvents(events []*event.E) []*event.E` - Filter to trusted events
|
|
|
|
### EventCollector
|
|
|
|
Utility for collecting specific types of directory events.
|
|
|
|
**Methods:**
|
|
- `NewEventCollector(events []*event.E) *EventCollector` - Create new instance
|
|
- `RelayIdentities() []*RelayIdentity` - Get all relay identities
|
|
- `TrustActs() []*TrustAct` - Get all trust acts
|
|
- `GroupTagActs() []*GroupTagAct` - Get all group tag acts
|
|
- `PublicKeyAdvertisements() []*PublicKeyAdvertisement` - Get all key ads
|
|
- `ReplicationRequests() []*ReplicationRequest` - Get all requests
|
|
- `ReplicationResponses() []*ReplicationResponse` - Get all responses
|
|
|
|
### Helper Functions
|
|
|
|
**Event Filtering:**
|
|
- `IsDirectoryEvent(ev *event.E) bool` - Check if event is directory event
|
|
- `FilterDirectoryEvents(events []*event.E) []*event.E` - Filter to directory events
|
|
- `ParseDirectoryEvent(ev *event.E) (interface{}, error)` - Parse any directory event
|
|
|
|
**Event Finding:**
|
|
- `FindRelayIdentity(events, relayURL) (*RelayIdentity, bool)` - Find identity by URL
|
|
- `FindTrustActsForRelay(events, targetPubkey) []*TrustAct` - Find trust acts
|
|
- `FindGroupTagActsForRelay(events, targetPubkey) []*GroupTagAct` - Find group acts
|
|
- `FindGroupTagActsByGroup(events, groupTag) []*GroupTagAct` - Find by group
|
|
|
|
**URL Utilities:**
|
|
- `NormalizeRelayURL(url string) string` - Ensure trailing slash
|
|
|
|
**Trust Graph:**
|
|
- `NewTrustGraph() *TrustGraph` - Create new graph
|
|
- `BuildTrustGraph(events []*event.E) *TrustGraph` - Build from events
|
|
- `AddTrustAct(act *TrustAct)` - Add trust act to graph
|
|
- `GetTrustActs(source string) []*TrustAct` - Get acts from source
|
|
- `GetTrustedBy(target string) []string` - Get who trusts target
|
|
- `GetTrustTargets(source string) []string` - Get who source trusts
|
|
|
|
## Thread Safety
|
|
|
|
All components are thread-safe and can be used concurrently from multiple goroutines. Internal state is protected by read-write mutexes (`sync.RWMutex`).
|
|
|
|
## Performance Considerations
|
|
|
|
- **IdentityResolver**: Maintains in-memory caches. Use `ClearCache()` if needed
|
|
- **TrustCalculator**: Stores all trust acts in memory. Consider periodic cleanup of expired acts
|
|
- **ReplicationFilter**: Minimal memory overhead, recalculates trust on each act addition
|
|
|
|
## Integration
|
|
|
|
This package works with:
|
|
|
|
- **directory protocol package**: For parsing and creating events
|
|
- **event package**: For event structures
|
|
- **EventStore**: Can be integrated with any event storage system
|
|
|
|
## Testing
|
|
|
|
The directory-client package includes comprehensive tests to ensure reliability and correctness:
|
|
|
|
### Running Tests
|
|
|
|
```bash
|
|
# Run directory-client tests
|
|
go test ./pkg/protocol/directory-client
|
|
|
|
# Run all tests including directory-client
|
|
go test ./...
|
|
|
|
# Run with verbose output
|
|
go test -v ./pkg/protocol/directory-client
|
|
|
|
# Run with race detection
|
|
go test -race ./pkg/protocol/directory-client
|
|
|
|
# Run with coverage
|
|
go test -cover ./pkg/protocol/directory-client
|
|
```
|
|
|
|
### Integration Testing
|
|
|
|
The directory-client is tested as part of the project's integration test suite:
|
|
|
|
```bash
|
|
# Run the full test suite
|
|
./scripts/test.sh
|
|
|
|
# Run specific package tests
|
|
go test ./pkg/protocol/...
|
|
```
|
|
|
|
### Test Coverage
|
|
|
|
The test suite covers:
|
|
|
|
- **Identity Resolution**: Delegate key mapping, identity resolution, caching
|
|
- **Trust Calculation**: Trust score computation, act aggregation, expiration handling
|
|
- **Replication Filtering**: Trust threshold filtering, relay selection
|
|
- **Event Collection**: Event parsing, filtering by type, collection utilities
|
|
- **Trust Graph**: Graph construction, relationship analysis
|
|
- **Thread Safety**: Concurrent access patterns, race condition prevention
|
|
- **Error Handling**: Invalid events, malformed data, edge cases
|
|
|
|
### Example Test Usage
|
|
|
|
```bash
|
|
# Test identity resolution functionality
|
|
go test -v ./pkg/protocol/directory-client -run TestIdentityResolver
|
|
|
|
# Test trust calculation
|
|
go test -v ./pkg/protocol/directory-client -run TestTrustCalculator
|
|
|
|
# Test thread safety
|
|
go test -race -v ./pkg/protocol/directory-client
|
|
```
|
|
|
|
## Development
|
|
|
|
### Building and Usage
|
|
|
|
```bash
|
|
# Build the directory-client package
|
|
go build ./pkg/protocol/directory-client
|
|
|
|
# Run example usage
|
|
go run -tags=example ./pkg/protocol/directory-client
|
|
```
|
|
|
|
### Code Quality
|
|
|
|
The directory-client follows Go best practices:
|
|
|
|
- Comprehensive error handling with custom error types
|
|
- Thread-safe concurrent access
|
|
- Memory-efficient data structures
|
|
- Extensive documentation and examples
|
|
- Full test coverage with race detection
|
|
|
|
### Adding New Features
|
|
|
|
When adding new functionality:
|
|
|
|
1. Add unit tests for new components
|
|
2. Update existing tests if behavior changes
|
|
3. Ensure thread safety for concurrent access
|
|
4. Add documentation and examples
|
|
5. Update the API reference section
|
|
|
|
## Related Documentation
|
|
|
|
- [NIP-XX Specification](../../docs/NIP-XX-distributed-directory-consensus.md)
|
|
- [Directory Protocol Package](../directory/)
|
|
|
|
## License
|
|
|
|
See [LICENSE](../../LICENSE) file.
|