@contextvm/sdk 0.1.47 → 0.2.0

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.
Files changed (61) hide show
  1. package/dist/esm/core/constants.d.ts +3 -0
  2. package/dist/esm/core/constants.d.ts.map +1 -1
  3. package/dist/esm/core/constants.js +3 -0
  4. package/dist/esm/core/constants.js.map +1 -1
  5. package/dist/esm/core/utils/logger.d.ts +1 -1
  6. package/dist/esm/core/utils/logger.d.ts.map +1 -1
  7. package/dist/esm/core/utils/lru-cache.d.ts.map +1 -1
  8. package/dist/esm/core/utils/lru-cache.js +9 -1
  9. package/dist/esm/core/utils/lru-cache.js.map +1 -1
  10. package/dist/esm/core/utils/task-queue.d.ts +5 -0
  11. package/dist/esm/core/utils/task-queue.d.ts.map +1 -1
  12. package/dist/esm/core/utils/task-queue.js +11 -0
  13. package/dist/esm/core/utils/task-queue.js.map +1 -1
  14. package/dist/esm/core/utils/utils.d.ts +8 -0
  15. package/dist/esm/core/utils/utils.d.ts.map +1 -1
  16. package/dist/esm/core/utils/utils.js +23 -0
  17. package/dist/esm/core/utils/utils.js.map +1 -1
  18. package/dist/esm/relay/applesauce-relay-pool.d.ts +37 -4
  19. package/dist/esm/relay/applesauce-relay-pool.d.ts.map +1 -1
  20. package/dist/esm/relay/applesauce-relay-pool.js +165 -11
  21. package/dist/esm/relay/applesauce-relay-pool.js.map +1 -1
  22. package/dist/esm/signer/private-key-signer.d.ts.map +1 -1
  23. package/dist/esm/signer/private-key-signer.js +1 -1
  24. package/dist/esm/signer/private-key-signer.js.map +1 -1
  25. package/dist/esm/transport/base-nostr-transport.d.ts +1 -1
  26. package/dist/esm/transport/base-nostr-transport.d.ts.map +1 -1
  27. package/dist/esm/transport/base-nostr-transport.js +8 -6
  28. package/dist/esm/transport/base-nostr-transport.js.map +1 -1
  29. package/dist/esm/transport/nostr-client/correlation-store.d.ts +60 -0
  30. package/dist/esm/transport/nostr-client/correlation-store.d.ts.map +1 -0
  31. package/dist/esm/transport/nostr-client/correlation-store.js +61 -0
  32. package/dist/esm/transport/nostr-client/correlation-store.js.map +1 -0
  33. package/dist/esm/transport/nostr-client/stateless-mode-handler.d.ts +24 -0
  34. package/dist/esm/transport/nostr-client/stateless-mode-handler.d.ts.map +1 -0
  35. package/dist/esm/transport/nostr-client/stateless-mode-handler.js +61 -0
  36. package/dist/esm/transport/nostr-client/stateless-mode-handler.js.map +1 -0
  37. package/dist/esm/transport/nostr-client-transport.d.ts +48 -24
  38. package/dist/esm/transport/nostr-client-transport.d.ts.map +1 -1
  39. package/dist/esm/transport/nostr-client-transport.js +92 -131
  40. package/dist/esm/transport/nostr-client-transport.js.map +1 -1
  41. package/dist/esm/transport/nostr-server/announcement-manager.d.ts +116 -0
  42. package/dist/esm/transport/nostr-server/announcement-manager.d.ts.map +1 -0
  43. package/dist/esm/transport/nostr-server/announcement-manager.js +288 -0
  44. package/dist/esm/transport/nostr-server/announcement-manager.js.map +1 -0
  45. package/dist/esm/transport/nostr-server/authorization-policy.d.ts +74 -0
  46. package/dist/esm/transport/nostr-server/authorization-policy.d.ts.map +1 -0
  47. package/dist/esm/transport/nostr-server/authorization-policy.js +91 -0
  48. package/dist/esm/transport/nostr-server/authorization-policy.js.map +1 -0
  49. package/dist/esm/transport/nostr-server/correlation-store.d.ts +102 -0
  50. package/dist/esm/transport/nostr-server/correlation-store.d.ts.map +1 -0
  51. package/dist/esm/transport/nostr-server/correlation-store.js +167 -0
  52. package/dist/esm/transport/nostr-server/correlation-store.js.map +1 -0
  53. package/dist/esm/transport/nostr-server/session-store.d.ts +99 -0
  54. package/dist/esm/transport/nostr-server/session-store.d.ts.map +1 -0
  55. package/dist/esm/transport/nostr-server/session-store.js +123 -0
  56. package/dist/esm/transport/nostr-server/session-store.js.map +1 -0
  57. package/dist/esm/transport/nostr-server-transport.d.ts +18 -63
  58. package/dist/esm/transport/nostr-server-transport.d.ts.map +1 -1
  59. package/dist/esm/transport/nostr-server-transport.js +135 -378
  60. package/dist/esm/transport/nostr-server-transport.js.map +1 -1
  61. package/package.json +15 -12
@@ -0,0 +1,288 @@
1
+ /**
2
+ * Internal announcement manager for NostrServerTransport.
3
+ * Handles public server announcements including initialization handshake,
4
+ * schema mapping, and deletion events.
5
+ *
6
+ */
7
+ import { InitializeResultSchema, ListPromptsResultSchema, ListResourcesResultSchema, ListResourceTemplatesResultSchema, ListToolsResultSchema, isJSONRPCResultResponse, } from '@modelcontextprotocol/sdk/types.js';
8
+ import { EventDeletion } from 'nostr-tools/kinds';
9
+ import { LATEST_PROTOCOL_VERSION } from '@modelcontextprotocol/sdk/types.js';
10
+ import { announcementMethods, SERVER_ANNOUNCEMENT_KIND, TOOLS_LIST_KIND, RESOURCES_LIST_KIND, RESOURCETEMPLATES_LIST_KIND, PROMPTS_LIST_KIND, NOSTR_TAGS, INITIALIZE_METHOD, NOTIFICATIONS_INITIALIZED_METHOD, } from '../../core/index.js';
11
+ import { EncryptionMode } from '../../core/interfaces.js';
12
+ /**
13
+ * Internal manager for public server announcements.
14
+ *
15
+ * This class encapsulates the announcement flow:
16
+ * - Initialize handshake with timeout
17
+ * - Schema-to-kind mapping for different announcement types
18
+ * - Publishing announcements as Nostr events
19
+ * - Deleting announcements via deletion events
20
+ */
21
+ export class AnnouncementManager {
22
+ constructor(options) {
23
+ this.isInitialized = false;
24
+ this.serverInfo = options.serverInfo;
25
+ this.encryptionMode = options.encryptionMode;
26
+ this.onSendMessage = options.onSendMessage;
27
+ this.onPublishEvent = options.onPublishEvent;
28
+ this.onSignEvent = options.onSignEvent;
29
+ this.onGetPublicKey = options.onGetPublicKey;
30
+ this.onSubscribe = options.onSubscribe;
31
+ this.logger = options.logger;
32
+ }
33
+ /**
34
+ * Generates common tags from server information for use in Nostr events.
35
+ * @returns Array of tag arrays for Nostr events.
36
+ */
37
+ getCommonTags() {
38
+ var _a, _b, _c, _d;
39
+ if (this.cachedCommonTags) {
40
+ return this.cachedCommonTags;
41
+ }
42
+ const commonTags = [];
43
+ if ((_a = this.serverInfo) === null || _a === void 0 ? void 0 : _a.name) {
44
+ commonTags.push([NOSTR_TAGS.NAME, this.serverInfo.name]);
45
+ }
46
+ if ((_b = this.serverInfo) === null || _b === void 0 ? void 0 : _b.about) {
47
+ commonTags.push([NOSTR_TAGS.ABOUT, this.serverInfo.about]);
48
+ }
49
+ if ((_c = this.serverInfo) === null || _c === void 0 ? void 0 : _c.website) {
50
+ commonTags.push([NOSTR_TAGS.WEBSITE, this.serverInfo.website]);
51
+ }
52
+ if ((_d = this.serverInfo) === null || _d === void 0 ? void 0 : _d.picture) {
53
+ commonTags.push([NOSTR_TAGS.PICTURE, this.serverInfo.picture]);
54
+ }
55
+ if (this.encryptionMode !== EncryptionMode.DISABLED) {
56
+ commonTags.push([NOSTR_TAGS.SUPPORT_ENCRYPTION]);
57
+ }
58
+ this.cachedCommonTags = commonTags;
59
+ return commonTags;
60
+ }
61
+ /**
62
+ * Gets the announcement mapping for schema-to-kind conversion.
63
+ * @returns Array of announcement mappings.
64
+ */
65
+ getAnnouncementMapping() {
66
+ const commonTags = this.getCommonTags();
67
+ return [
68
+ {
69
+ schema: InitializeResultSchema,
70
+ kind: SERVER_ANNOUNCEMENT_KIND,
71
+ tags: commonTags,
72
+ },
73
+ { schema: ListToolsResultSchema, kind: TOOLS_LIST_KIND, tags: [] },
74
+ {
75
+ schema: ListResourcesResultSchema,
76
+ kind: RESOURCES_LIST_KIND,
77
+ tags: [],
78
+ },
79
+ {
80
+ schema: ListResourceTemplatesResultSchema,
81
+ kind: RESOURCETEMPLATES_LIST_KIND,
82
+ tags: [],
83
+ },
84
+ { schema: ListPromptsResultSchema, kind: PROMPTS_LIST_KIND, tags: [] },
85
+ ];
86
+ }
87
+ /**
88
+ * Initiates the process of fetching announcement data from the server's internal logic.
89
+ * This method properly handles the initialization handshake by first sending
90
+ * the initialize request, waiting for the response, and then proceeding with other announcements.
91
+ */
92
+ async getAnnouncementData() {
93
+ try {
94
+ const initializeParams = {
95
+ protocolVersion: LATEST_PROTOCOL_VERSION,
96
+ capabilities: {},
97
+ clientInfo: {
98
+ name: 'DummyClient',
99
+ version: '1.0.0',
100
+ },
101
+ };
102
+ // Send the initialize request if not already initialized
103
+ if (!this.isInitialized) {
104
+ const initializeMessage = {
105
+ jsonrpc: '2.0',
106
+ id: 'announcement',
107
+ method: INITIALIZE_METHOD,
108
+ params: initializeParams,
109
+ };
110
+ this.logger.info('Sending initialize request for announcement');
111
+ this.onSendMessage(initializeMessage);
112
+ }
113
+ try {
114
+ // Wait for initialization to complete
115
+ await this.waitForInitialization();
116
+ // Send all announcements now that we're initialized
117
+ for (const [key, methodValue] of Object.entries(announcementMethods)) {
118
+ this.logger.info('Sending announcement', { key, methodValue });
119
+ const message = {
120
+ jsonrpc: '2.0',
121
+ id: 'announcement',
122
+ method: methodValue,
123
+ params: key === 'server' ? initializeParams : {},
124
+ };
125
+ this.onSendMessage(message);
126
+ }
127
+ }
128
+ catch (error) {
129
+ this.logger.warn('Server not initialized after waiting, skipping announcements', { error: error instanceof Error ? error.message : error });
130
+ }
131
+ }
132
+ catch (error) {
133
+ this.logger.error('Error in getAnnouncementData', {
134
+ error: error instanceof Error ? error.message : String(error),
135
+ stack: error instanceof Error ? error.stack : undefined,
136
+ });
137
+ }
138
+ }
139
+ /**
140
+ * Waits for the server to be initialized with a timeout.
141
+ * @returns Promise that resolves when initialized or after 10-second timeout.
142
+ * The method will always resolve, allowing announcements to proceed.
143
+ */
144
+ async waitForInitialization() {
145
+ if (this.isInitialized)
146
+ return;
147
+ if (!this.initializationPromise) {
148
+ this.initializationPromise = new Promise((resolve) => {
149
+ this.initializationResolver = resolve;
150
+ });
151
+ }
152
+ const timeout = new Promise((_, reject) => setTimeout(() => reject(new Error('Initialization timeout')), 10000));
153
+ try {
154
+ await Promise.race([this.initializationPromise, timeout]);
155
+ }
156
+ catch (_a) {
157
+ this.logger.warn('Server initialization not completed within timeout, proceeding with announcements');
158
+ }
159
+ }
160
+ /**
161
+ * Handles the JSON-RPC responses for public server announcements and publishes
162
+ * them as Nostr events to the configured relays.
163
+ * @param message The JSON-RPC response containing the announcement data.
164
+ * @returns true if the message was an announcement response and was handled, false otherwise.
165
+ */
166
+ async handleAnnouncementResponse(message) {
167
+ var _a;
168
+ // Only process announcement responses
169
+ if (message.id !== 'announcement') {
170
+ return false;
171
+ }
172
+ if (!isJSONRPCResultResponse(message) || !message.result) {
173
+ return true; // Was an announcement response, but no result
174
+ }
175
+ // Handle initialize response
176
+ if (InitializeResultSchema.safeParse(message.result).success) {
177
+ this.isInitialized = true;
178
+ (_a = this.initializationResolver) === null || _a === void 0 ? void 0 : _a.call(this); // Resolve waiting promise
179
+ // Clean up promise references to prevent memory leaks
180
+ this.initializationPromise = undefined;
181
+ this.initializationResolver = undefined;
182
+ // Send the initialized notification
183
+ const initializedNotification = {
184
+ jsonrpc: '2.0',
185
+ method: NOTIFICATIONS_INITIALIZED_METHOD,
186
+ };
187
+ this.onSendMessage(initializedNotification);
188
+ this.logger.info('Initialized');
189
+ }
190
+ // Publish the announcement as a Nostr event
191
+ await this.publishAnnouncement(message.result);
192
+ return true;
193
+ }
194
+ /**
195
+ * Publishes an announcement as a Nostr event.
196
+ * @param result The announcement result to publish.
197
+ */
198
+ async publishAnnouncement(result) {
199
+ try {
200
+ const recipientPubkey = await this.onGetPublicKey();
201
+ const announcementMapping = this.getAnnouncementMapping();
202
+ for (const mapping of announcementMapping) {
203
+ if (mapping.schema.safeParse(result).success) {
204
+ const eventTemplate = {
205
+ kind: mapping.kind,
206
+ content: JSON.stringify(result),
207
+ tags: mapping.tags,
208
+ created_at: Math.floor(Date.now() / 1000),
209
+ pubkey: recipientPubkey,
210
+ };
211
+ const signedEvent = await this.onSignEvent(eventTemplate);
212
+ await this.onPublishEvent(signedEvent);
213
+ this.logger.debug('Published announcement event', {
214
+ kind: mapping.kind,
215
+ eventId: signedEvent.id,
216
+ });
217
+ break;
218
+ }
219
+ }
220
+ }
221
+ catch (error) {
222
+ this.logger.error('Error publishing announcement', {
223
+ error: error instanceof Error ? error.message : String(error),
224
+ stack: error instanceof Error ? error.stack : undefined,
225
+ });
226
+ }
227
+ }
228
+ /**
229
+ * Deletes server announcements and capability listings by publishing deletion events.
230
+ * This method queries for existing announcement events and publishes deletion events (kind 5)
231
+ * to remove them from the relay network.
232
+ * @param reason Optional reason for deletion (default: 'Service offline').
233
+ * @returns Promise that resolves to an array of deletion events that were published.
234
+ */
235
+ async deleteAnnouncement(reason = 'Service offline') {
236
+ const publicKey = await this.onGetPublicKey();
237
+ const allDeletedEvents = [];
238
+ const kinds = [
239
+ SERVER_ANNOUNCEMENT_KIND,
240
+ TOOLS_LIST_KIND,
241
+ RESOURCES_LIST_KIND,
242
+ RESOURCETEMPLATES_LIST_KIND,
243
+ PROMPTS_LIST_KIND,
244
+ ];
245
+ for (const kind of kinds) {
246
+ const eventsForKind = [];
247
+ const filter = {
248
+ kinds: [kind],
249
+ authors: [publicKey],
250
+ };
251
+ // Collect events for this specific kind
252
+ await this.onSubscribe([filter], (event) => {
253
+ try {
254
+ eventsForKind.push(event);
255
+ }
256
+ catch (error) {
257
+ this.logger.error('Error in relay subscription event collection', {
258
+ error: error instanceof Error ? error.message : String(error),
259
+ eventId: event.id,
260
+ });
261
+ }
262
+ });
263
+ if (!eventsForKind.length) {
264
+ this.logger.info(`No events found for kind ${kind} to delete`);
265
+ continue;
266
+ }
267
+ const deletionEventTemplate = {
268
+ kind: EventDeletion,
269
+ pubkey: publicKey,
270
+ content: reason,
271
+ tags: eventsForKind.map((ev) => ['e', ev.id]),
272
+ created_at: Math.floor(Date.now() / 1000),
273
+ };
274
+ const deletionEvent = await this.onSignEvent(deletionEventTemplate);
275
+ await this.onPublishEvent(deletionEvent);
276
+ this.logger.info(`Published deletion event for kind ${kind} (${eventsForKind.length} events)`);
277
+ allDeletedEvents.push(...eventsForKind);
278
+ }
279
+ return allDeletedEvents;
280
+ }
281
+ /**
282
+ * Checks if the manager is initialized.
283
+ */
284
+ get initialized() {
285
+ return this.isInitialized;
286
+ }
287
+ }
288
+ //# sourceMappingURL=announcement-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"announcement-manager.js","sourceRoot":"","sources":["../../../../src/transport/nostr-server/announcement-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Internal authorization policy for NostrServerTransport.
3
+ * Handles whitelist and excluded-capability checks.
4
+ *
5
+ * This module is not exported from the public API.
6
+ */
7
+ import type { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';
8
+ /**
9
+ * Represents a capability exclusion pattern that can bypass whitelisting.
10
+ * Can be either a method-only pattern (e.g., 'tools/list') or a method + name pattern (e.g., 'tools/call, get_weather').
11
+ */
12
+ export interface CapabilityExclusion {
13
+ /** The JSON-RPC method to exclude from whitelisting (e.g., 'tools/call', 'tools/list') */
14
+ method: string;
15
+ /** Optional capability name to specifically exclude (e.g., 'get_weather') */
16
+ name?: string;
17
+ }
18
+ /**
19
+ * Authorization decision result.
20
+ */
21
+ export type AuthorizationDecision = {
22
+ allowed: true;
23
+ } | {
24
+ allowed: false;
25
+ shouldReplyUnauthorized: boolean;
26
+ };
27
+ /**
28
+ * Options for configuring the AuthorizationPolicy.
29
+ */
30
+ export interface AuthorizationPolicyOptions {
31
+ /** Set of allowed public keys (whitelist). If undefined, all clients are allowed. */
32
+ allowedPublicKeys?: Set<string>;
33
+ /** List of capabilities that are excluded from public key whitelisting requirements */
34
+ excludedCapabilities?: CapabilityExclusion[];
35
+ /** Whether this is a public server (affects unauthorized response behavior) */
36
+ isPublicServer?: boolean;
37
+ }
38
+ /**
39
+ * Internal policy for authorizing incoming messages.
40
+ *
41
+ * This class encapsulates the authorization logic, making it easier to test
42
+ * and maintain. It handles:
43
+ * - Whitelist checking
44
+ * - Excluded capability checking
45
+ * - Determining whether to send an unauthorized response
46
+ */
47
+ export declare class AuthorizationPolicy {
48
+ private readonly allowedPublicKeys?;
49
+ private readonly excludedCapabilities?;
50
+ readonly isPublicServer?: boolean;
51
+ constructor(options?: AuthorizationPolicyOptions);
52
+ /**
53
+ * Checks if a capability is excluded from whitelisting requirements.
54
+ * @param method The JSON-RPC method (e.g., 'tools/call', 'tools/list')
55
+ * @param name Optional capability name for method-specific exclusions (e.g., 'get_weather')
56
+ * @returns true if the capability should bypass whitelisting, false otherwise
57
+ */
58
+ private isCapabilityExcluded;
59
+ /**
60
+ * Determines whether a message should be allowed based on authorization policy.
61
+ *
62
+ * @param clientPubkey The client's public key
63
+ * @param message The incoming JSON-RPC message
64
+ * @returns Authorization decision indicating whether the message is allowed
65
+ */
66
+ authorize(clientPubkey: string, message: JSONRPCMessage): AuthorizationDecision;
67
+ /**
68
+ * Checks if a client public key is in the allowed whitelist.
69
+ * @param clientPubkey The client's public key
70
+ * @returns true if the client is whitelisted, false otherwise
71
+ */
72
+ isClientWhitelisted(clientPubkey: string): boolean;
73
+ }
74
+ //# sourceMappingURL=authorization-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authorization-policy.d.ts","sourceRoot":"","sources":["../../../../src/transport/nostr-server/authorization-policy.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAMzE;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,0FAA0F;IAC1F,MAAM,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAC7B;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GACjB;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,uBAAuB,EAAE,OAAO,CAAA;CAAE,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,qFAAqF;IACrF,iBAAiB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAChC,uFAAuF;IACvF,oBAAoB,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAC7C,+EAA+E;IAC/E,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;;GAQG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAc;IACjD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAwB;IAC9D,SAAgB,cAAc,CAAC,EAAE,OAAO,CAAC;gBAE7B,OAAO,GAAE,0BAA+B;IAMpD;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IA6B5B;;;;;;OAMG;IACH,SAAS,CACP,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,cAAc,GACtB,qBAAqB;IA2BxB;;;;OAIG;IACH,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO;CAMnD"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Internal authorization policy for NostrServerTransport.
3
+ * Handles whitelist and excluded-capability checks.
4
+ *
5
+ * This module is not exported from the public API.
6
+ */
7
+ import { INITIALIZE_METHOD, NOTIFICATIONS_INITIALIZED_METHOD, } from '@contextvm/sdk/core/constants.js';
8
+ import { isJSONRPCRequest, isJSONRPCNotification, } from '@modelcontextprotocol/sdk/types.js';
9
+ /**
10
+ * Internal policy for authorizing incoming messages.
11
+ *
12
+ * This class encapsulates the authorization logic, making it easier to test
13
+ * and maintain. It handles:
14
+ * - Whitelist checking
15
+ * - Excluded capability checking
16
+ * - Determining whether to send an unauthorized response
17
+ */
18
+ export class AuthorizationPolicy {
19
+ constructor(options = {}) {
20
+ this.allowedPublicKeys = options.allowedPublicKeys;
21
+ this.excludedCapabilities = options.excludedCapabilities;
22
+ this.isPublicServer = options.isPublicServer;
23
+ }
24
+ /**
25
+ * Checks if a capability is excluded from whitelisting requirements.
26
+ * @param method The JSON-RPC method (e.g., 'tools/call', 'tools/list')
27
+ * @param name Optional capability name for method-specific exclusions (e.g., 'get_weather')
28
+ * @returns true if the capability should bypass whitelisting, false otherwise
29
+ */
30
+ isCapabilityExcluded(method, name) {
31
+ var _a;
32
+ // Always allow fundamental MCP methods for connection establishment
33
+ if (method === INITIALIZE_METHOD ||
34
+ method === NOTIFICATIONS_INITIALIZED_METHOD) {
35
+ return true;
36
+ }
37
+ if (!((_a = this.excludedCapabilities) === null || _a === void 0 ? void 0 : _a.length)) {
38
+ return false;
39
+ }
40
+ return this.excludedCapabilities.some((exclusion) => {
41
+ // Check if method matches
42
+ if (exclusion.method !== method) {
43
+ return false;
44
+ }
45
+ // If exclusion has no name requirement, method match is sufficient
46
+ if (!exclusion.name) {
47
+ return true;
48
+ }
49
+ // If exclusion has a name requirement, check if it matches the provided name
50
+ return exclusion.name === name;
51
+ });
52
+ }
53
+ /**
54
+ * Determines whether a message should be allowed based on authorization policy.
55
+ *
56
+ * @param clientPubkey The client's public key
57
+ * @param message The incoming JSON-RPC message
58
+ * @returns Authorization decision indicating whether the message is allowed
59
+ */
60
+ authorize(clientPubkey, message) {
61
+ var _a, _b, _c, _d;
62
+ // If no whitelist is configured, allow all messages
63
+ if (!((_a = this.allowedPublicKeys) === null || _a === void 0 ? void 0 : _a.size)) {
64
+ return { allowed: true };
65
+ }
66
+ // Check if the message should bypass whitelisting due to excluded capabilities
67
+ const shouldBypassWhitelisting = ((_b = this.excludedCapabilities) === null || _b === void 0 ? void 0 : _b.length) &&
68
+ (isJSONRPCRequest(message) || isJSONRPCNotification(message)) &&
69
+ this.isCapabilityExcluded(message.method, (_c = message.params) === null || _c === void 0 ? void 0 : _c.name);
70
+ if (this.allowedPublicKeys.has(clientPubkey) || shouldBypassWhitelisting) {
71
+ return { allowed: true };
72
+ }
73
+ // Message is not authorized
74
+ // Only send unauthorized response for requests on public servers
75
+ const shouldReplyUnauthorized = ((_d = this.isPublicServer) !== null && _d !== void 0 ? _d : false) && isJSONRPCRequest(message);
76
+ return { allowed: false, shouldReplyUnauthorized };
77
+ }
78
+ /**
79
+ * Checks if a client public key is in the allowed whitelist.
80
+ * @param clientPubkey The client's public key
81
+ * @returns true if the client is whitelisted, false otherwise
82
+ */
83
+ isClientWhitelisted(clientPubkey) {
84
+ var _a;
85
+ if (!((_a = this.allowedPublicKeys) === null || _a === void 0 ? void 0 : _a.size)) {
86
+ return true; // No whitelist means all clients are allowed
87
+ }
88
+ return this.allowedPublicKeys.has(clientPubkey);
89
+ }
90
+ }
91
+ //# sourceMappingURL=authorization-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authorization-policy.js","sourceRoot":"","sources":["../../../../src/transport/nostr-server/authorization-policy.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,iBAAiB,EACjB,gCAAgC,GACjC,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EACL,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,oCAAoC,CAAC;AAgC5C;;;;;;;;GAQG;AACH,MAAM,OAAO,mBAAmB;IAK9B,YAAY,UAAsC,EAAE;QAClD,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;QACnD,IAAI,CAAC,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC;QACzD,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;IAC/C,CAAC;IAED;;;;;OAKG;IACK,oBAAoB,CAAC,MAAc,EAAE,IAAa;;QACxD,oEAAoE;QACpE,IACE,MAAM,KAAK,iBAAiB;YAC5B,MAAM,KAAK,gCAAgC,EAC3C,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,CAAC,CAAA,MAAA,IAAI,CAAC,oBAAoB,0CAAE,MAAM,CAAA,EAAE,CAAC;YACvC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE;YAClD,0BAA0B;YAC1B,IAAI,SAAS,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;gBAChC,OAAO,KAAK,CAAC;YACf,CAAC;YAED,mEAAmE;YACnE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;gBACpB,OAAO,IAAI,CAAC;YACd,CAAC;YAED,6EAA6E;YAC7E,OAAO,SAAS,CAAC,IAAI,KAAK,IAAI,CAAC;QACjC,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACH,SAAS,CACP,YAAoB,EACpB,OAAuB;;QAEvB,oDAAoD;QACpD,IAAI,CAAC,CAAA,MAAA,IAAI,CAAC,iBAAiB,0CAAE,IAAI,CAAA,EAAE,CAAC;YAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QAED,+EAA+E;QAC/E,MAAM,wBAAwB,GAC5B,CAAA,MAAA,IAAI,CAAC,oBAAoB,0CAAE,MAAM;YACjC,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,qBAAqB,CAAC,OAAO,CAAC,CAAC;YAC7D,IAAI,CAAC,oBAAoB,CACvB,OAAO,CAAC,MAAM,EACd,MAAA,OAAO,CAAC,MAAM,0CAAE,IAA0B,CAC3C,CAAC;QAEJ,IAAI,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,wBAAwB,EAAE,CAAC;YACzE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QAED,4BAA4B;QAC5B,iEAAiE;QACjE,MAAM,uBAAuB,GAC3B,CAAC,MAAA,IAAI,CAAC,cAAc,mCAAI,KAAK,CAAC,IAAI,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAE9D,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC;IACrD,CAAC;IAED;;;;OAIG;IACH,mBAAmB,CAAC,YAAoB;;QACtC,IAAI,CAAC,CAAA,MAAA,IAAI,CAAC,iBAAiB,0CAAE,IAAI,CAAA,EAAE,CAAC;YAClC,OAAO,IAAI,CAAC,CAAC,6CAA6C;QAC5D,CAAC;QACD,OAAO,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAClD,CAAC;CACF"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Internal correlation store for NostrServerTransport.
3
+ * Provides O(1) routing for responses and progress notifications.
4
+ *
5
+ * This module is not exported from the public API.
6
+ */
7
+ /**
8
+ * Represents a route for an in-flight request.
9
+ */
10
+ export interface EventRoute {
11
+ /** The client's public key that originated this request */
12
+ clientPubkey: string;
13
+ /** The original JSON-RPC request ID (before it was replaced with eventId) */
14
+ originalRequestId: string | number;
15
+ /** Optional progress token for this request */
16
+ progressToken?: string;
17
+ }
18
+ /**
19
+ * Options for configuring the CorrelationStore.
20
+ */
21
+ export interface CorrelationStoreOptions {
22
+ /** Maximum number of event routes to keep in memory */
23
+ maxEventRoutes?: number;
24
+ /** Maximum number of progress token mappings to keep in memory */
25
+ maxProgressTokens?: number;
26
+ /** Callback invoked when an event route is evicted */
27
+ onEventRouteEvicted?: (eventId: string, route: EventRoute) => void;
28
+ }
29
+ /**
30
+ * Internal store for managing request/response correlation and progress routing.
31
+ */
32
+ export declare class CorrelationStore {
33
+ private readonly eventRoutes;
34
+ private readonly progressTokenToEventId;
35
+ private readonly clientEventIds;
36
+ constructor(options?: CorrelationStoreOptions);
37
+ /**
38
+ * Registers a new event route for an incoming request.
39
+ *
40
+ * @param eventId The Nostr event ID (used as the request ID)
41
+ * @param clientPubkey The client's public key
42
+ * @param originalRequestId The original JSON-RPC request ID
43
+ * @param progressToken Optional progress token for this request
44
+ */
45
+ registerEventRoute(eventId: string, clientPubkey: string, originalRequestId: string | number, progressToken?: string): void;
46
+ /**
47
+ * Gets the route for a given event ID.
48
+ *
49
+ * @param eventId The Nostr event ID
50
+ * @returns The event route, or undefined if not found
51
+ */
52
+ getEventRoute(eventId: string): EventRoute | undefined;
53
+ /**
54
+ * Gets the event ID for a given progress token.
55
+ *
56
+ * @param progressToken The progress token
57
+ * @returns The event ID, or undefined if not found
58
+ */
59
+ getEventIdByProgressToken(progressToken: string): string | undefined;
60
+ /**
61
+ * Removes an event route and its associated progress token mapping.
62
+ *
63
+ * @param eventId The Nostr event ID
64
+ * @returns true if the route was found and removed, false otherwise
65
+ */
66
+ removeEventRoute(eventId: string): boolean;
67
+ /**
68
+ * Removes all event routes for a specific client.
69
+ * This is called when a session is evicted or closed.
70
+ *
71
+ * @param clientPubkey The client's public key
72
+ * @returns The number of routes removed
73
+ */
74
+ removeRoutesForClient(clientPubkey: string): number;
75
+ /**
76
+ * Checks if an event route exists.
77
+ *
78
+ * @param eventId The Nostr event ID
79
+ * @returns true if the route exists, false otherwise
80
+ */
81
+ hasEventRoute(eventId: string): boolean;
82
+ /**
83
+ * Checks if a progress token mapping exists.
84
+ *
85
+ * @param progressToken The progress token
86
+ * @returns true if the mapping exists, false otherwise
87
+ */
88
+ hasProgressToken(progressToken: string): boolean;
89
+ /**
90
+ * Gets the current number of event routes.
91
+ */
92
+ get eventRouteCount(): number;
93
+ /**
94
+ * Gets the current number of progress token mappings.
95
+ */
96
+ get progressTokenCount(): number;
97
+ /**
98
+ * Clears all event routes and progress token mappings.
99
+ */
100
+ clear(): void;
101
+ }
102
+ //# sourceMappingURL=correlation-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"correlation-store.d.ts","sourceRoot":"","sources":["../../../../src/transport/nostr-server/correlation-store.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,2DAA2D;IAC3D,YAAY,EAAE,MAAM,CAAC;IACrB,6EAA6E;IAC7E,iBAAiB,EAAE,MAAM,GAAG,MAAM,CAAC;IACnC,+CAA+C;IAC/C,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,uDAAuD;IACvD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kEAAkE;IAClE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,sDAAsD;IACtD,mBAAmB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;CACpE;AAED;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuB;IACnD,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAmB;IAC1D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA2B;gBAE9C,OAAO,GAAE,uBAA4B;IA8BjD;;;;;;;OAOG;IACH,kBAAkB,CAChB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,iBAAiB,EAAE,MAAM,GAAG,MAAM,EAClC,aAAa,CAAC,EAAE,MAAM,GACrB,IAAI;IAsBP;;;;;OAKG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAItD;;;;;OAKG;IACH,yBAAyB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIpE;;;;;OAKG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAyB1C;;;;;;OAMG;IACH,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IAuBnD;;;;;OAKG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAIvC;;;;;OAKG;IACH,gBAAgB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO;IAIhD;;OAEG;IACH,IAAI,eAAe,IAAI,MAAM,CAE5B;IAED;;OAEG;IACH,IAAI,kBAAkB,IAAI,MAAM,CAE/B;IAED;;OAEG;IACH,KAAK,IAAI,IAAI;CAId"}