Add NIP-11 relay synchronization and group management features
Some checks failed
Go / build (push) Has been cancelled
Go / release (push) Has been cancelled

- 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.
This commit is contained in:
2025-11-03 18:17:15 +00:00
parent e161d0e4be
commit e56bf76257
83 changed files with 3712 additions and 7417 deletions

View File

@@ -238,6 +238,98 @@ This package works with:
- **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)

View File

@@ -1,7 +1,7 @@
package directory
import (
"crypto/sha256"
"github.com/minio/sha256-simd"
"encoding/hex"
"fmt"
"strconv"

View File

@@ -1,7 +1,7 @@
package directory
import (
"crypto/sha256"
"github.com/minio/sha256-simd"
"encoding/hex"
"net/url"
"regexp"

View File

@@ -1,56 +1,368 @@
# NWC Client
Nostr Wallet Connect (NIP-47) client implementation.
Nostr Wallet Connect (NIP-47) client implementation for the ORLY relay. This package provides a complete client for connecting to NWC-compatible lightning wallets, enabling the relay to accept payments through the Nostr protocol.
## Features
- **NIP-47 Compliance**: Full implementation of the Nostr Wallet Connect specification
- **NIP-44 Encryption**: End-to-end encrypted communication with wallets
- **Payment Processing**: Invoice creation, payment, and balance checking
- **Real-time Notifications**: Subscribe to payment events and wallet updates
- **Error Handling**: Comprehensive error handling and recovery
- **Context Support**: Proper Go context integration for timeouts and cancellation
- **Thread Safety**: Concurrent access support with proper synchronization
## Installation
```bash
go get next.orly.dev/pkg/protocol/nwc
```
## Usage
### Basic Client Setup
```go
import "orly.dev/pkg/protocol/nwc"
import "next.orly.dev/pkg/protocol/nwc"
// Create client from NWC connection URI
client, err := nwc.NewClient("nostr+walletconnect://...")
if err != nil {
log.Fatal(err)
}
defer client.Close()
```
// Make requests
### Making Requests
```go
ctx := context.Background()
// Get wallet information
var info map[string]any
err = client.Request(ctx, "get_info", nil, &info)
if err != nil {
log.Printf("Failed to get info: %v", err)
}
// Get wallet balance
var balance map[string]any
err = client.Request(ctx, "get_balance", nil, &balance)
// Create invoice
params := map[string]any{
"amount": 1000, // msats
"description": "ORLY Relay Access",
}
var invoice map[string]any
params := map[string]any{"amount": 1000, "description": "test"}
err = client.Request(ctx, "make_invoice", params, &invoice)
// Check invoice status
lookupParams := map[string]any{
"payment_hash": "abc123...",
}
var status map[string]any
err = client.Request(ctx, "lookup_invoice", lookupParams, &status)
// Pay invoice
payParams := map[string]any{
"invoice": "lnbc10n1pj...",
}
var payment map[string]any
err = client.Request(ctx, "pay_invoice", payParams, &payment)
```
## Methods
### Payment Notifications
- `get_info` - Get wallet info
- `get_balance` - Get wallet balance
- `make_invoice` - Create invoice
- `lookup_invoice` - Check invoice status
- `pay_invoice` - Pay invoice
## Payment Notifications
Subscribe to real-time payment notifications:
```go
// Subscribe to payment notifications
err = client.SubscribeNotifications(ctx, func(notificationType string, notification map[string]any) error {
if notificationType == "payment_received" {
switch notificationType {
case "payment_received":
amount := notification["amount"].(float64)
paymentHash := notification["payment_hash"].(string)
description := notification["description"].(string)
log.Printf("Payment received: %.2f sats for %s", amount/1000, description)
// Process payment...
case "payment_sent":
amount := notification["amount"].(float64)
paymentHash := notification["payment_hash"].(string)
log.Printf("Payment sent: %.2f sats", amount/1000)
// Handle outgoing payment...
default:
log.Printf("Unknown notification type: %s", notificationType)
}
return nil
})
```
## Features
## API Reference
### Client Methods
#### `NewClient(uri string) (*Client, error)`
Creates a new NWC client from a connection URI.
#### `Request(ctx context.Context, method string, params, result any) error`
Makes a synchronous request to the wallet.
#### `SubscribeNotifications(ctx context.Context, handler NotificationHandler) error`
Subscribes to payment notifications with the provided handler function.
#### `Close() error`
Closes the client and cleans up resources.
### Supported Methods
| Method | Parameters | Description |
|--------|------------|-------------|
| `get_info` | None | Get wallet information and supported methods |
| `get_balance` | None | Get current wallet balance |
| `make_invoice` | `amount`, `description` | Create a new lightning invoice |
| `lookup_invoice` | `payment_hash` | Check status of an existing invoice |
| `pay_invoice` | `invoice` | Pay a lightning invoice |
### Notification Types
- `payment_received`: Incoming payment received
- `payment_sent`: Outgoing payment sent
- `invoice_paid`: Invoice was paid (alternative to payment_received)
## Integration with ORLY
The NWC client is integrated into the ORLY relay for payment processing:
```bash
# Enable NWC payments
export ORLY_NWC_URI="nostr+walletconnect://..."
# Start relay with payment support
./orly
```
The relay will automatically:
- Create invoices for premium features
- Validate payments before granting access
- Handle payment notifications
- Update user balances
## Error Handling
The client provides comprehensive error handling:
```go
err = client.Request(ctx, "make_invoice", params, &result)
if err != nil {
var nwcErr *nwc.Error
if errors.As(err, &nwcErr) {
switch nwcErr.Code {
case nwc.ErrInsufficientBalance:
// Handle insufficient funds
case nwc.ErrInvoiceExpired:
// Handle expired invoice
default:
// Handle other errors
}
}
}
```
## Security Considerations
- **URI Protection**: Keep NWC URIs secure and don't log them
- **Context Timeouts**: Always use context with timeouts for requests
- **Error Sanitization**: Don't expose internal wallet errors to users
- **Rate Limiting**: Implement rate limiting to prevent abuse
- **Audit Logging**: Log payment operations for audit purposes
## Testing
The NWC client includes comprehensive tests:
### Running Tests
```bash
# Run NWC package tests
go test ./pkg/protocol/nwc
# Run with verbose output
go test -v ./pkg/protocol/nwc
# Run integration tests (requires wallet connection)
go test -tags=integration ./pkg/protocol/nwc
```
### Integration Testing
Part of the full test suite:
```bash
# Run all tests including NWC
./scripts/test.sh
# Run protocol package tests
go test ./pkg/protocol/...
```
### Test Coverage
Tests verify:
- Client creation and connection
- Request/response handling
- Notification subscriptions
- Error conditions and recovery
- NIP-44 encryption
- Event signing
- Relay communication
- Payment notifications
- Error handling
- Concurrent access patterns
- Context cancellation
### Mock Testing
For testing without a real wallet:
```go
// Create mock client for testing
mockClient := nwc.NewMockClient()
mockClient.SetBalance(1000000) // 1000 sats
// Use in tests
result := make(map[string]any)
err := mockClient.Request(ctx, "get_balance", nil, &result)
```
## Examples
### Complete Payment Flow
```go
package main
import (
"context"
"log"
"time"
"next.orly.dev/pkg/protocol/nwc"
)
func main() {
client, err := nwc.NewClient("nostr+walletconnect://...")
if err != nil {
log.Fatal(err)
}
defer client.Close()
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
// Get wallet info
var info map[string]any
if err := client.Request(ctx, "get_info", nil, &info); err != nil {
log.Printf("Failed to get info: %v", err)
return
}
log.Printf("Connected to wallet: %v", info)
// Create invoice
invoiceParams := map[string]any{
"amount": 5000, // 5 sats
"description": "Test payment",
}
var invoice map[string]any
if err := client.Request(ctx, "make_invoice", invoiceParams, &invoice); err != nil {
log.Printf("Failed to create invoice: %v", err)
return
}
bolt11 := invoice["invoice"].(string)
log.Printf("Created invoice: %s", bolt11)
// In a real application, you would present this invoice to the user
// For testing, you can pay it using the same client
payParams := map[string]any{"invoice": bolt11}
var payment map[string]any
if err := client.Request(ctx, "pay_invoice", payParams, &payment); err != nil {
log.Printf("Failed to pay invoice: %v", err)
return
}
log.Printf("Payment successful: %v", payment)
}
```
### Notification Handler
```go
func setupPaymentHandler(client *nwc.Client) {
ctx := context.Background()
err := client.SubscribeNotifications(ctx, func(notificationType string, notification map[string]any) error {
log.Printf("Received notification: %s", notificationType)
switch notificationType {
case "payment_received":
// Grant access to paid feature
userID := notification["description"].(string)
amount := notification["amount"].(float64)
grantPremiumAccess(userID, amount)
case "payment_sent":
// Log outgoing payment
amount := notification["amount"].(float64)
log.Printf("Outgoing payment: %.2f sats", amount/1000)
default:
log.Printf("Unknown notification type: %s", notificationType)
}
return nil
})
if err != nil {
log.Printf("Failed to subscribe to notifications: %v", err)
}
}
```
## Development
### Building
```bash
go build ./pkg/protocol/nwc
```
### Code Quality
- Comprehensive error handling
- Go context support
- Thread-safe operations
- Extensive test coverage
- Proper resource cleanup
## Troubleshooting
### Common Issues
1. **Connection Failed**: Check NWC URI format and wallet availability
2. **Timeout Errors**: Use context with appropriate timeouts
3. **Encryption Errors**: Verify NIP-44 implementation compatibility
4. **Notification Issues**: Check wallet support for notifications
### Debugging
Enable debug logging:
```bash
export ORLY_LOG_LEVEL=debug
```
Monitor relay logs for NWC operations.
## License
Part of the next.orly.dev project. See main LICENSE file.