nostr-inbox 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "nostr-inbox",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Unified Nostr notification stream for AI agents — mentions, DMs, DVM requests, zaps, WoT attestations in one event loop",
5
5
  "main": "src/index.cjs",
6
+ "types": "src/index.d.cts",
6
7
  "bin": {
7
8
  "nostr-inbox": "src/cli.cjs"
8
9
  },
package/src/filters.cjs CHANGED
@@ -85,25 +85,61 @@ function buildFilters(pubkey, channels = {}, since = null) {
85
85
  }
86
86
 
87
87
  // DVM requests: kind 5xxx tagged to us (we're a DVM provider)
88
+ // Split into small batches to avoid overwhelming relays
88
89
  if (dvmRequests) {
89
- const dvmRequestKinds = [];
90
- for (let k = 5000; k < 5100; k++) dvmRequestKinds.push(k);
91
- filters.push({
92
- kinds: dvmRequestKinds,
93
- '#p': [pubkey],
94
- ...sinceObj
95
- });
90
+ const dvmKinds = channels.dvmKinds; // optional: specific DVM kinds to watch
91
+ if (dvmKinds && Array.isArray(dvmKinds)) {
92
+ // User specified exact kinds — use them directly
93
+ filters.push({
94
+ kinds: dvmKinds,
95
+ '#p': [pubkey],
96
+ ...sinceObj
97
+ });
98
+ } else {
99
+ // Common DVM kinds in small batches (max 20 per filter)
100
+ const commonDvmKinds = [
101
+ 5000, 5001, 5002, 5003, 5004, 5005, // generic
102
+ 5050, // text generation
103
+ 5100, // image generation
104
+ 5200, // text-to-speech
105
+ 5250, // speech-to-text
106
+ 5300, // content discovery
107
+ 5301, 5302, // search, recommendations
108
+ 5400, 5401, // data processing
109
+ 5500, 5501, // translation
110
+ 5900, 5901, 5902, 5903, 5904, 5905 // custom range
111
+ ];
112
+ filters.push({
113
+ kinds: commonDvmKinds,
114
+ '#p': [pubkey],
115
+ ...sinceObj
116
+ });
117
+ }
96
118
  }
97
119
 
98
120
  // DVM results: kind 6xxx tagged to us (we requested something)
99
121
  if (dvmResults) {
100
- const dvmResultKinds = [];
101
- for (let k = 6000; k < 6100; k++) dvmResultKinds.push(k);
102
- filters.push({
103
- kinds: dvmResultKinds,
104
- '#p': [pubkey],
105
- ...sinceObj
106
- });
122
+ const dvmKinds = channels.dvmKinds;
123
+ if (dvmKinds && Array.isArray(dvmKinds)) {
124
+ // Map request kinds to result kinds
125
+ filters.push({
126
+ kinds: dvmKinds.map(k => k + 1000),
127
+ '#p': [pubkey],
128
+ ...sinceObj
129
+ });
130
+ } else {
131
+ const commonResultKinds = [
132
+ 6000, 6001, 6002, 6003, 6004, 6005,
133
+ 6050, 6100, 6200, 6250, 6300, 6301, 6302,
134
+ 6400, 6401, 6500, 6501,
135
+ 6900, 6901, 6902, 6903, 6904, 6905
136
+ ];
137
+ filters.push({
138
+ kinds: commonResultKinds,
139
+ '#p': [pubkey],
140
+ ...sinceObj
141
+ });
142
+ }
107
143
  }
108
144
 
109
145
  // Zaps: receipts tagged to our pubkey
@@ -0,0 +1,137 @@
1
+ // Type definitions for nostr-inbox
2
+
3
+ import { EventEmitter } from 'events';
4
+
5
+ export interface NostrEvent {
6
+ id: string;
7
+ pubkey: string;
8
+ kind: number;
9
+ created_at: number;
10
+ tags: string[][];
11
+ content: string;
12
+ sig: string;
13
+ }
14
+
15
+ export type NotificationType =
16
+ | 'mention' | 'dm' | 'dvm_request' | 'dvm_result' | 'dvm_feedback'
17
+ | 'zap' | 'reaction' | 'trust' | 'trust_network'
18
+ | 'marketplace_bid' | 'marketplace_delivery' | 'marketplace_resolution'
19
+ | 'unknown';
20
+
21
+ export type Priority = 'high' | 'medium' | 'low';
22
+
23
+ export interface Notification {
24
+ id: string;
25
+ type: NotificationType;
26
+ priority: Priority;
27
+ from: string;
28
+ content: string;
29
+ kind: number;
30
+ tags: string[][];
31
+ createdAt: number;
32
+ raw: NostrEvent;
33
+ dvmKind?: number;
34
+ }
35
+
36
+ export interface Channels {
37
+ mentions?: boolean;
38
+ dms?: boolean;
39
+ dvmRequests?: boolean;
40
+ dvmResults?: boolean;
41
+ zaps?: boolean;
42
+ reactions?: boolean;
43
+ trust?: boolean;
44
+ marketplace?: boolean;
45
+ dvmKinds?: number[];
46
+ }
47
+
48
+ export interface InboxOptions {
49
+ pubkey: string;
50
+ relays?: string[];
51
+ channels?: Channels;
52
+ since?: number;
53
+ dedup?: boolean;
54
+ onEvent?: (notification: Notification) => void;
55
+ onError?: (error: { relay: string; error: string }) => void;
56
+ reconnectMs?: number;
57
+ connectTimeoutMs?: number;
58
+ }
59
+
60
+ export interface InboxStatus {
61
+ running: boolean;
62
+ relays: {
63
+ connected: number;
64
+ total: number;
65
+ urls: string[];
66
+ };
67
+ seen: number;
68
+ latestTimestamp: number;
69
+ channels: Channels;
70
+ }
71
+
72
+ export interface Inbox {
73
+ start(): Promise<EventEmitter>;
74
+ stop(): void;
75
+ status(): InboxStatus;
76
+ on(event: 'notification', handler: (n: Notification) => void): void;
77
+ on(event: 'urgent', handler: (n: Notification) => void): void;
78
+ on(event: NotificationType, handler: (n: Notification) => void): void;
79
+ on(event: 'connected', handler: (info: { relay: string }) => void): void;
80
+ on(event: 'started', handler: (info: { connected: number; total: number }) => void): void;
81
+ on(event: 'stopped', handler: () => void): void;
82
+ on(event: 'synced', handler: (info: { relay: string }) => void): void;
83
+ on(event: 'error', handler: (error: { relay: string; error: string }) => void): void;
84
+ off(event: string, handler: Function): void;
85
+ once(event: string, handler: Function): void;
86
+ waitFor(type: NotificationType, timeoutMs?: number): Promise<Notification>;
87
+ collect(durationMs?: number, filter?: (n: Notification) => boolean): Promise<Notification[]>;
88
+ emitter: EventEmitter;
89
+ }
90
+
91
+ export interface PollOptions {
92
+ pubkey: string;
93
+ relays?: string[];
94
+ channels?: Channels;
95
+ since?: number;
96
+ timeoutMs?: number;
97
+ }
98
+
99
+ export interface PollResult {
100
+ total: number;
101
+ urgent: number;
102
+ notifications: Notification[];
103
+ byType: Record<NotificationType, Notification[]>;
104
+ since: number;
105
+ queriedAt: number;
106
+ }
107
+
108
+ export interface Classification {
109
+ type: NotificationType;
110
+ priority: Priority;
111
+ dvmKind?: number;
112
+ }
113
+
114
+ export function createInbox(opts: InboxOptions): Inbox;
115
+ export function poll(opts: PollOptions): Promise<PollResult>;
116
+ export function buildFilters(pubkey: string, channels?: Channels, since?: number): object[];
117
+ export function classifyEvent(event: NostrEvent, myPubkey: string): Classification;
118
+
119
+ export const KINDS: {
120
+ TEXT_NOTE: 1;
121
+ DM_ENCRYPTED: 4;
122
+ REACTION: 7;
123
+ DVM_REQUEST_BASE: 5000;
124
+ DVM_RESULT_BASE: 6000;
125
+ DVM_FEEDBACK: 7000;
126
+ ZAP_RECEIPT: 9735;
127
+ ZAP_REQUEST: 9734;
128
+ LABEL: 1985;
129
+ GIFT_WRAP: 1059;
130
+ SEAL: 13;
131
+ AGENT_SERVICE: 38990;
132
+ TASK: 30950;
133
+ BID: 950;
134
+ DELIVERY: 951;
135
+ RESOLUTION: 952;
136
+ COMMENT: 1111;
137
+ };