Add wrap manager for tracking gift wraps
This commit is contained in:
@@ -1,70 +0,0 @@
|
||||
# Tracker
|
||||
|
||||
Event tracker for managing which events have been seen from which relays, used for deduplication across multiple relay connections.
|
||||
|
||||
## Classes
|
||||
|
||||
### Tracker
|
||||
|
||||
Tracks the relationship between event IDs and relay URLs to prevent duplicate processing.
|
||||
|
||||
**Properties:**
|
||||
- `relaysById` - Map of event IDs to sets of relay URLs
|
||||
- `idsByRelay` - Map of relay URLs to sets of event IDs
|
||||
|
||||
**Methods:**
|
||||
- `getIds(relay)` - Gets all event IDs seen from a relay
|
||||
- `getRelays(eventId)` - Gets all relays that have sent an event
|
||||
- `hasRelay(eventId, relay)` - Checks if an event was seen from a relay
|
||||
- `addRelay(eventId, relay)` - Records that an event was seen from a relay
|
||||
- `removeRelay(eventId, relay)` - Removes the event-relay association
|
||||
- `track(eventId, relay)` - Tracks an event and returns true if already seen
|
||||
- `copy(eventId1, eventId2)` - Copies relay associations from one event to another
|
||||
- `load(relaysById)` - Loads tracker state from a map
|
||||
- `clear()` - Clears all tracked data
|
||||
|
||||
**Events:**
|
||||
- `add` - Emitted when event-relay association is added
|
||||
- `remove` - Emitted when event-relay association is removed
|
||||
- `load` - Emitted when tracker state is loaded
|
||||
- `clear` - Emitted when tracker is cleared
|
||||
|
||||
## Example
|
||||
|
||||
```typescript
|
||||
import {Tracker} from "@welshman/net"
|
||||
|
||||
const tracker = new Tracker()
|
||||
|
||||
// Track events from different relays
|
||||
const isDuplicate1 = tracker.track("event123", "wss://relay1.com") // false
|
||||
const isDuplicate2 = tracker.track("event123", "wss://relay2.com") // false
|
||||
const isDuplicate3 = tracker.track("event123", "wss://relay1.com") // true (duplicate)
|
||||
|
||||
// Check which relays have sent an event
|
||||
const relays = tracker.getRelays("event123") // Set(["wss://relay1.com", "wss://relay2.com"])
|
||||
```
|
||||
|
||||
If you're not using `@welshman/app`, you might want to track relays for all events that come through:
|
||||
|
||||
```typescript
|
||||
import {Pool, Tracker, SocketEvent, isRelayEvent} from "@welshman/net"
|
||||
import {isEphemeralKind, isDVMKind, verifyEvent} from "@welshman/util"
|
||||
import {Repository} from "@welshman/relay"
|
||||
|
||||
const tracker = new Tracker()
|
||||
const repository = new Repository()
|
||||
|
||||
Pool.get().subscribe(socket => {
|
||||
socket.on(SocketEvent.Receive, message => {
|
||||
if (isRelayEvent(message)) {
|
||||
const event = message[2]
|
||||
|
||||
if (!isEphemeralKind(event.kind) && !isDVMKind(event.kind) && verifyEvent(event)) {
|
||||
tracker.track(event.id, socket.url)
|
||||
repository.publish(event)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
```
|
||||
@@ -8,6 +8,8 @@ A few utilites for storing nostr events in memory.
|
||||
|
||||
- **Event Store** - A Repository class which stores events in memory
|
||||
- **Relay Adapter** - A LocalRelay class which adapts nostr messages to the repository
|
||||
- **Event Tracker** - A Tracker class for managing which events have been seen from which relays
|
||||
- **Gift Wrap Manager** - A WrapManager class for tracking and unwrapping NIP-59 gift wrapped events
|
||||
|
||||
## Quick Example
|
||||
|
||||
@@ -66,6 +68,74 @@ relay.send("EVENT", {
|
||||
relay.send("REQ", "tagged", {kinds: [1], "#t": ["welshman"]})
|
||||
```
|
||||
|
||||
### Tracking Events Across Relays
|
||||
|
||||
```typescript
|
||||
import {Tracker} from "@welshman/relay"
|
||||
|
||||
const tracker = new Tracker()
|
||||
|
||||
// Track events from different relays
|
||||
const isDuplicate1 = tracker.track("event123", "wss://relay1.com") // false
|
||||
const isDuplicate2 = tracker.track("event123", "wss://relay2.com") // false
|
||||
const isDuplicate3 = tracker.track("event123", "wss://relay1.com") // true (duplicate)
|
||||
|
||||
// Check which relays have sent an event
|
||||
const relays = tracker.getRelays("event123") // Set(["wss://relay1.com", "wss://relay2.com"])
|
||||
|
||||
// Copy relay tracking from one event to another (useful for wrapped events)
|
||||
tracker.copy("wrap-event-id", "rumor-event-id")
|
||||
```
|
||||
|
||||
### Managing Gift Wrapped Events
|
||||
|
||||
The WrapManager handles NIP-59 gift wrapped events, automatically unwrapping incoming wrapped events and tracking the relationship between wraps and their inner rumors.
|
||||
|
||||
```typescript
|
||||
import {Repository, LocalRelay, Tracker, WrapManager} from "@welshman/relay"
|
||||
import {ISigner} from "@welshman/signer"
|
||||
|
||||
const repository = Repository.get()
|
||||
const relay = new LocalRelay(repository)
|
||||
const tracker = new Tracker()
|
||||
|
||||
// Create a wrap manager with a function to get signers for different pubkeys
|
||||
const wrapManager = new WrapManager({
|
||||
relay,
|
||||
tracker,
|
||||
getSigner: (pubkey: string) => {
|
||||
// Return the appropriate signer for this pubkey
|
||||
return mySignerMap.get(pubkey)
|
||||
}
|
||||
})
|
||||
|
||||
// When you publish a wrapped event, track it
|
||||
wrapManager.add({
|
||||
recipient: recipientPubkey,
|
||||
wrap: wrappedEvent,
|
||||
rumor: innerEvent
|
||||
})
|
||||
|
||||
// When you receive a wrapped event, unwrap it
|
||||
await wrapManager.unwrap(receivedWrapEvent)
|
||||
|
||||
// The rumor will be automatically published to the repository
|
||||
// and relay tracking will be copied from the wrap to the rumor
|
||||
|
||||
// Remove wraps by various criteria
|
||||
wrapManager.remove(wrapId)
|
||||
wrapManager.removeByRumorId(rumorId)
|
||||
|
||||
// Listen for wrap manager events
|
||||
wrapManager.on("add", (wrapItem) => {
|
||||
console.log("Wrap added:", wrapItem)
|
||||
})
|
||||
|
||||
wrapManager.on("remove", (wrapItem) => {
|
||||
console.log("Wrap removed:", wrapItem)
|
||||
})
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
|
||||
Reference in New Issue
Block a user