@contextvm/sdk 0.9.1 → 0.11.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.
- package/dist/esm/core/constants.d.ts +8 -0
- package/dist/esm/core/constants.d.ts.map +1 -1
- package/dist/esm/core/constants.js +8 -0
- package/dist/esm/core/constants.js.map +1 -1
- package/dist/esm/core/index.d.ts +1 -0
- package/dist/esm/core/index.d.ts.map +1 -1
- package/dist/esm/core/index.js +1 -0
- package/dist/esm/core/index.js.map +1 -1
- package/dist/esm/core/utils/common-schema.d.ts +25 -0
- package/dist/esm/core/utils/common-schema.d.ts.map +1 -0
- package/dist/esm/core/utils/common-schema.js +66 -0
- package/dist/esm/core/utils/common-schema.js.map +1 -0
- package/dist/esm/relay/applesauce-relay-pool.d.ts.map +1 -1
- package/dist/esm/relay/applesauce-relay-pool.js +14 -14
- package/dist/esm/relay/applesauce-relay-pool.js.map +1 -1
- package/dist/esm/transport/call-tool-stream.d.ts +22 -0
- package/dist/esm/transport/call-tool-stream.d.ts.map +1 -0
- package/dist/esm/transport/call-tool-stream.js +26 -0
- package/dist/esm/transport/call-tool-stream.js.map +1 -0
- package/dist/esm/transport/discovery-tags.d.ts +2 -0
- package/dist/esm/transport/discovery-tags.d.ts.map +1 -1
- package/dist/esm/transport/discovery-tags.js +1 -0
- package/dist/esm/transport/discovery-tags.js.map +1 -1
- package/dist/esm/transport/index.d.ts +4 -0
- package/dist/esm/transport/index.d.ts.map +1 -1
- package/dist/esm/transport/index.js +4 -0
- package/dist/esm/transport/index.js.map +1 -1
- package/dist/esm/transport/nostr-client-transport.d.ts +31 -1
- package/dist/esm/transport/nostr-client-transport.d.ts.map +1 -1
- package/dist/esm/transport/nostr-client-transport.js +168 -1
- package/dist/esm/transport/nostr-client-transport.js.map +1 -1
- package/dist/esm/transport/nostr-server/announcement-manager.d.ts +7 -1
- package/dist/esm/transport/nostr-server/announcement-manager.d.ts.map +1 -1
- package/dist/esm/transport/nostr-server/announcement-manager.js +18 -3
- package/dist/esm/transport/nostr-server/announcement-manager.js.map +1 -1
- package/dist/esm/transport/nostr-server/session-store.d.ts +2 -0
- package/dist/esm/transport/nostr-server/session-store.d.ts.map +1 -1
- package/dist/esm/transport/nostr-server/session-store.js +1 -0
- package/dist/esm/transport/nostr-server/session-store.js.map +1 -1
- package/dist/esm/transport/nostr-server-transport.d.ts +37 -2
- package/dist/esm/transport/nostr-server-transport.d.ts.map +1 -1
- package/dist/esm/transport/nostr-server-transport.js +254 -24
- package/dist/esm/transport/nostr-server-transport.js.map +1 -1
- package/dist/esm/transport/open-stream/constants.d.ts +8 -0
- package/dist/esm/transport/open-stream/constants.d.ts.map +1 -0
- package/dist/esm/transport/open-stream/constants.js +8 -0
- package/dist/esm/transport/open-stream/constants.js.map +1 -0
- package/dist/esm/transport/open-stream/errors.d.ts +19 -0
- package/dist/esm/transport/open-stream/errors.d.ts.map +1 -0
- package/dist/esm/transport/open-stream/errors.js +31 -0
- package/dist/esm/transport/open-stream/errors.js.map +1 -0
- package/dist/esm/transport/open-stream/frames.d.ts +37 -0
- package/dist/esm/transport/open-stream/frames.d.ts.map +1 -0
- package/dist/esm/transport/open-stream/frames.js +91 -0
- package/dist/esm/transport/open-stream/frames.js.map +1 -0
- package/dist/esm/transport/open-stream/index.d.ts +9 -0
- package/dist/esm/transport/open-stream/index.d.ts.map +1 -0
- package/dist/esm/transport/open-stream/index.js +9 -0
- package/dist/esm/transport/open-stream/index.js.map +1 -0
- package/dist/esm/transport/open-stream/receiver.d.ts +18 -0
- package/dist/esm/transport/open-stream/receiver.d.ts.map +1 -0
- package/dist/esm/transport/open-stream/receiver.js +31 -0
- package/dist/esm/transport/open-stream/receiver.js.map +1 -0
- package/dist/esm/transport/open-stream/registry.d.ts +37 -0
- package/dist/esm/transport/open-stream/registry.d.ts.map +1 -0
- package/dist/esm/transport/open-stream/registry.js +115 -0
- package/dist/esm/transport/open-stream/registry.js.map +1 -0
- package/dist/esm/transport/open-stream/session.d.ts +80 -0
- package/dist/esm/transport/open-stream/session.d.ts.map +1 -0
- package/dist/esm/transport/open-stream/session.js +343 -0
- package/dist/esm/transport/open-stream/session.js.map +1 -0
- package/dist/esm/transport/open-stream/types.d.ts +52 -0
- package/dist/esm/transport/open-stream/types.d.ts.map +1 -0
- package/dist/esm/transport/open-stream/types.js +2 -0
- package/dist/esm/transport/open-stream/types.js.map +1 -0
- package/dist/esm/transport/open-stream/writer.d.ts +38 -0
- package/dist/esm/transport/open-stream/writer.d.ts.map +1 -0
- package/dist/esm/transport/open-stream/writer.js +123 -0
- package/dist/esm/transport/open-stream/writer.js.map +1 -0
- package/dist/esm/transport/open-stream-policy.d.ts +12 -0
- package/dist/esm/transport/open-stream-policy.d.ts.map +1 -0
- package/dist/esm/transport/open-stream-policy.js +2 -0
- package/dist/esm/transport/open-stream-policy.js.map +1 -0
- package/dist/esm/transport/server-transport-common-schemas.d.ts +23 -0
- package/dist/esm/transport/server-transport-common-schemas.d.ts.map +1 -0
- package/dist/esm/transport/server-transport-common-schemas.js +119 -0
- package/dist/esm/transport/server-transport-common-schemas.js.map +1 -0
- package/package.json +2 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';
|
|
1
|
+
import { type ListToolsResult, type JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';
|
|
2
2
|
import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
|
|
3
3
|
import { BaseNostrTransport, BaseNostrTransportOptions } from './base-nostr-transport.js';
|
|
4
4
|
import { NostrEvent } from 'nostr-tools';
|
|
@@ -7,7 +7,9 @@ import { CorrelationStore } from './nostr-server/correlation-store.js';
|
|
|
7
7
|
import { ClientSession, SessionStore } from './nostr-server/session-store.js';
|
|
8
8
|
import { CapabilityExclusion } from './nostr-server/authorization-policy.js';
|
|
9
9
|
import { type ProfileMetadata, type ServerInfo } from './nostr-server/announcement-manager.js';
|
|
10
|
-
import { type TransferPolicy } from './oversized-transfer/index.js';
|
|
10
|
+
import { OversizedTransferReceiver, type TransferPolicy } from './oversized-transfer/index.js';
|
|
11
|
+
import { OpenStreamReceiver } from './open-stream/index.js';
|
|
12
|
+
import type { OpenStreamTransportPolicy } from './open-stream-policy.js';
|
|
11
13
|
/**
|
|
12
14
|
* Options for configuring the NostrServerTransport.
|
|
13
15
|
*/
|
|
@@ -83,7 +85,16 @@ export interface NostrServerTransportOptions extends BaseNostrTransportOptions {
|
|
|
83
85
|
/** Receiver-side admission policy. */
|
|
84
86
|
policy?: TransferPolicy;
|
|
85
87
|
};
|
|
88
|
+
/** Options controlling CEP-41 open-ended stream transfer. */
|
|
89
|
+
openStream?: {
|
|
90
|
+
/** Whether open stream transfer is enabled. @default false */
|
|
91
|
+
enabled?: boolean;
|
|
92
|
+
/** Receiver/session policy reserved for CEP-41 stream lifecycle limits. */
|
|
93
|
+
policy?: OpenStreamTransportPolicy;
|
|
94
|
+
};
|
|
86
95
|
}
|
|
96
|
+
export type ListToolsResultTransformer = (result: ListToolsResult) => ListToolsResult;
|
|
97
|
+
export type ListToolsAnnouncementTagsProducer = (result: ListToolsResult) => string[][];
|
|
87
98
|
export type InboundMiddlewareFn = (message: JSONRPCMessage, ctx: {
|
|
88
99
|
clientPubkey: string;
|
|
89
100
|
clientPmis?: readonly string[];
|
|
@@ -109,6 +120,8 @@ export declare class NostrServerTransport extends BaseNostrTransport implements
|
|
|
109
120
|
private readonly shouldInjectRequestEventId;
|
|
110
121
|
private readonly onClientSessionEvicted;
|
|
111
122
|
private readonly inboundMiddlewares;
|
|
123
|
+
private readonly listToolsResultTransformers;
|
|
124
|
+
private readonly listToolsAnnouncementTagsProducers;
|
|
112
125
|
/**
|
|
113
126
|
* Deduplicate inbound events to avoid redundant work.
|
|
114
127
|
*
|
|
@@ -117,9 +130,16 @@ export declare class NostrServerTransport extends BaseNostrTransport implements
|
|
|
117
130
|
private readonly seenEventIds;
|
|
118
131
|
/** Receives inbound oversized-transfer frames from clients (client→server requests). */
|
|
119
132
|
private readonly oversizedReceiver;
|
|
133
|
+
/** Receives inbound open-stream frames from clients (client→server notifications). */
|
|
134
|
+
private readonly openStreamReceiver;
|
|
135
|
+
/** Pending final responses held until their CEP-41 stream terminates. */
|
|
136
|
+
private readonly pendingOpenStreamResponses;
|
|
137
|
+
/** Active server-side CEP-41 writers keyed by inbound request event id. */
|
|
138
|
+
private readonly openStreamWriters;
|
|
120
139
|
private readonly oversizedEnabled;
|
|
121
140
|
private readonly oversizedThreshold;
|
|
122
141
|
private readonly oversizedChunkSize;
|
|
142
|
+
private readonly openStreamEnabled;
|
|
123
143
|
constructor(options: NostrServerTransportOptions);
|
|
124
144
|
/**
|
|
125
145
|
* Sets extra tags to include in server announcement + initialize response events.
|
|
@@ -139,6 +159,16 @@ export declare class NostrServerTransport extends BaseNostrTransport implements
|
|
|
139
159
|
* Middleware runs in the order it is added.
|
|
140
160
|
*/
|
|
141
161
|
addInboundMiddleware(middleware: InboundMiddlewareFn): void;
|
|
162
|
+
/**
|
|
163
|
+
* Adds a transformer for `tools/list` results emitted by the server.
|
|
164
|
+
*
|
|
165
|
+
* Transformers are applied to direct responses and public announcement payloads.
|
|
166
|
+
*/
|
|
167
|
+
addListToolsResultTransformer(transformer: ListToolsResultTransformer): void;
|
|
168
|
+
/**
|
|
169
|
+
* Adds a provider for extra tags on public tools/list announcement events.
|
|
170
|
+
*/
|
|
171
|
+
addListToolsAnnouncementTagsProducer(producer: ListToolsAnnouncementTagsProducer): void;
|
|
142
172
|
/**
|
|
143
173
|
* Starts the transport, connecting to the relay and setting up event listeners
|
|
144
174
|
* to receive incoming MCP requests.
|
|
@@ -187,6 +217,7 @@ export declare class NostrServerTransport extends BaseNostrTransport implements
|
|
|
187
217
|
* @param clientPubkey The client's public key.
|
|
188
218
|
*/
|
|
189
219
|
private handleIncomingRequest;
|
|
220
|
+
private flushPendingOpenStreamResponse;
|
|
190
221
|
/**
|
|
191
222
|
* Cleans up request correlation for a request that was dropped by middleware.
|
|
192
223
|
*/
|
|
@@ -201,6 +232,8 @@ export declare class NostrServerTransport extends BaseNostrTransport implements
|
|
|
201
232
|
* Handles response messages by finding the original request and routing back to client.
|
|
202
233
|
* @param response The JSON-RPC response or error to send.
|
|
203
234
|
*/
|
|
235
|
+
private applyListToolsResultTransformers;
|
|
236
|
+
private buildListToolsAnnouncementTags;
|
|
204
237
|
private handleResponse;
|
|
205
238
|
/**
|
|
206
239
|
* Handles notification messages with routing.
|
|
@@ -245,6 +278,8 @@ export declare class NostrServerTransport extends BaseNostrTransport implements
|
|
|
245
278
|
getInternalStateForTesting(): {
|
|
246
279
|
sessionStore: SessionStore;
|
|
247
280
|
correlationStore: CorrelationStore;
|
|
281
|
+
oversizedReceiver: OversizedTransferReceiver;
|
|
282
|
+
openStreamReceiver: OpenStreamReceiver;
|
|
248
283
|
};
|
|
249
284
|
}
|
|
250
285
|
//# sourceMappingURL=nostr-server-transport.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nostr-server-transport.d.ts","sourceRoot":"","sources":["../../../src/transport/nostr-server-transport.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"nostr-server-transport.d.ts","sourceRoot":"","sources":["../../../src/transport/nostr-server-transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,eAAe,EAGpB,KAAK,cAAc,EAMpB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAC/E,OAAO,EACL,kBAAkB,EAClB,yBAAyB,EAC1B,MAAM,2BAA2B,CAAC;AAYnC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAMnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAG9E,OAAO,EAEL,mBAAmB,EACpB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,UAAU,EAChB,MAAM,wCAAwC,CAAC;AAEhD,OAAO,EACL,yBAAyB,EACzB,KAAK,cAAc,EACpB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,kBAAkB,EAMnB,MAAM,wBAAwB,CAAC;AAUhC,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAEzE;;GAEG;AACH,MAAM,WAAW,2BAA4B,SAAQ,yBAAyB;IAC5E,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,oFAAoF;IACpF,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC;;OAEG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,uEAAuE;IACvE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,8GAA8G;IAC9G,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,0EAA0E;IAC1E,kBAAkB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,gGAAgG;IAChG,eAAe,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvE,uFAAuF;IACvF,oBAAoB,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAC7C,wGAAwG;IACxG,oBAAoB,CAAC,EAAE,CACrB,SAAS,EAAE,mBAAmB,KAC3B,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAChC,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,yEAAyE;IACzE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B;;;OAGG;IACH,sBAAsB,CAAC,EAAE,CAAC,GAAG,EAAE;QAC7B,YAAY,EAAE,MAAM,CAAC;QACrB,OAAO,EAAE,aAAa,CAAC;KACxB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,CAClB,OAAO,EAAE,cAAc,EACvB,GAAG,EAAE;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,EAC7B,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,KAChD,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,6DAA6D;IAC7D,iBAAiB,CAAC,EAAE;QAClB,2DAA2D;QAC3D,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB;;;WAGG;QACH,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,yEAAyE;QACzE,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,sCAAsC;QACtC,MAAM,CAAC,EAAE,cAAc,CAAC;KACzB,CAAC;IACF,6DAA6D;IAC7D,UAAU,CAAC,EAAE;QACX,8DAA8D;QAC9D,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,2EAA2E;QAC3E,MAAM,CAAC,EAAE,yBAAyB,CAAC;KACpC,CAAC;CACH;AAED,MAAM,MAAM,0BAA0B,GAAG,CACvC,MAAM,EAAE,eAAe,KACpB,eAAe,CAAC;AAErB,MAAM,MAAM,iCAAiC,GAAG,CAC9C,MAAM,EAAE,eAAe,KACpB,MAAM,EAAE,EAAE,CAAC;AAEhB,MAAM,MAAM,mBAAmB,GAAG,CAChC,OAAO,EAAE,cAAc,EACvB,GAAG,EAAE;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,EAC7D,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,KAChD,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB;;;;;GAKG;AACH,qBAAa,oBACX,SAAQ,kBACR,YAAW,SAAS;IAEb,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;IAC9C,oBAAoB,CAAC,EAAE,CAC5B,OAAO,EAAE,cAAc,EACvB,GAAG,EAAE;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,KAC1B,IAAI,CAAC;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAExC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;IACpD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAsB;IAC1D,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAsB;IAC1D,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAU;IAC7C,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAAU;IACrD,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAKzB;IACd,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA6B;IAChE,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CACvC;IACL,OAAO,CAAC,QAAQ,CAAC,kCAAkC,CAC9C;IAEL;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAwC;IAErE,wFAAwF;IACxF,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA4B;IAE9D,sFAAsF;IACtF,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAqB;IAExD,yEAAyE;IACzE,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAGvC;IAEJ,2EAA2E;IAC3E,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAuC;IAGzE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAU;IAC3C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAC5C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAC5C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAU;gBAEhC,OAAO,EAAE,2BAA2B;IA4KhD;;;;OAIG;IACI,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI;IAIvD;;;;OAIG;IACI,0BAA0B,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI;IAIzD;;;;OAIG;IACI,oBAAoB,CAAC,UAAU,EAAE,mBAAmB,GAAG,IAAI;IAIlE;;;;OAIG;IACI,6BAA6B,CAClC,WAAW,EAAE,0BAA0B,GACtC,IAAI;IAIP;;OAEG;IACI,oCAAoC,CACzC,QAAQ,EAAE,iCAAiC,GAC1C,IAAI;IAIP;;;OAGG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAuCnC;;OAEG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAsBnC;;;OAGG;IACU,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAazD;;;;;;OAMG;IACU,kBAAkB,CAC7B,MAAM,GAAE,MAA0B,GACjC,OAAO,CAAC,UAAU,EAAE,CAAC;IAIxB;;;;;OAKG;IACI,oBAAoB,CAAC,cAAc,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAI3E;;;;;OAKG;IACH,OAAO,CAAC,wBAAwB;IAchC,OAAO,CAAC,8BAA8B;IAStC,OAAO,CAAC,uBAAuB;IAsB/B,OAAO,CAAC,gCAAgC;IAyBxC,OAAO,CAAC,YAAY;YAIN,uBAAuB;IAkCrC;;;;;OAKG;IACH,OAAO,CAAC,qBAAqB;YA8Cf,8BAA8B;IAY5C;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAQ7B;;;;OAIG;IACH,OAAO,CAAC,0BAA0B;IAYlC;;;OAGG;IACH,OAAO,CAAC,gCAAgC;IASxC,OAAO,CAAC,8BAA8B;YAMxB,cAAc;IAmJ5B;;;OAGG;YACW,kBAAkB;IAiEhC;;;;;OAKG;IACU,gBAAgB,CAC3B,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,cAAc,EAC5B,iBAAiB,CAAC,EAAE,MAAM,GACzB,OAAO,CAAC,IAAI,CAAC;IA+BhB;;;;;OAKG;YACW,oBAAoB;IAsClC;;;OAGG;YACW,oBAAoB;IAwDlC;;;OAGG;YACW,sBAAsB;IAiBpC;;;;;OAKG;YACW,wBAAwB;IA0WtC;;;OAGG;IACH,0BAA0B;;;;;;CAQ3B"}
|
|
@@ -2,6 +2,7 @@ import { InitializeResultSchema, ListPromptsResultSchema, ListResourcesResultSch
|
|
|
2
2
|
import { BaseNostrTransport, } from './base-nostr-transport.js';
|
|
3
3
|
import { CTXVM_MESSAGES_KIND, DEFAULT_TIMEOUT_MS, EPHEMERAL_GIFT_WRAP_KIND, GIFT_WRAP_KIND, NOSTR_TAGS, NOTIFICATIONS_INITIALIZED_METHOD, decryptMessage, DEFAULT_LRU_SIZE, } from '../core/index.js';
|
|
4
4
|
import { EncryptionMode, GiftWrapMode } from '../core/interfaces.js';
|
|
5
|
+
import { verifyEvent } from 'nostr-tools/pure';
|
|
5
6
|
import { injectClientPubkey, injectRequestEventId, withTimeout, } from '../core/utils/utils.js';
|
|
6
7
|
import { CorrelationStore } from './nostr-server/correlation-store.js';
|
|
7
8
|
import { SessionStore } from './nostr-server/session-store.js';
|
|
@@ -10,6 +11,7 @@ import { ApplesauceRelayPool } from '../relay/applesauce-relay-pool.js';
|
|
|
10
11
|
import { AuthorizationPolicy, } from './nostr-server/authorization-policy.js';
|
|
11
12
|
import { AnnouncementManager, } from './nostr-server/announcement-manager.js';
|
|
12
13
|
import { OversizedTransferReceiver, } from './oversized-transfer/index.js';
|
|
14
|
+
import { OpenStreamReceiver, OpenStreamWriter, buildOpenStreamAcceptFrame, buildOpenStreamAbortFrame, buildOpenStreamPingFrame, buildOpenStreamPongFrame, } from './open-stream/index.js';
|
|
13
15
|
import { DEFAULT_CHUNK_SIZE, DEFAULT_OVERSIZED_THRESHOLD, } from './oversized-transfer/constants.js';
|
|
14
16
|
import { learnPeerCapabilities } from './discovery-tags.js';
|
|
15
17
|
import { sendAcceptFrame, sendOversizedServerResponse, } from './nostr-server/oversized-server-handler.js';
|
|
@@ -21,15 +23,21 @@ import { sendAcceptFrame, sendOversizedServerResponse, } from './nostr-server/ov
|
|
|
21
23
|
*/
|
|
22
24
|
export class NostrServerTransport extends BaseNostrTransport {
|
|
23
25
|
constructor(options) {
|
|
24
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
26
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
|
|
25
27
|
super('nostr-server-transport', options);
|
|
26
28
|
this.inboundMiddlewares = [];
|
|
29
|
+
this.listToolsResultTransformers = [];
|
|
30
|
+
this.listToolsAnnouncementTagsProducers = [];
|
|
27
31
|
/**
|
|
28
32
|
* Deduplicate inbound events to avoid redundant work.
|
|
29
33
|
*
|
|
30
34
|
* Used for gift-wrap envelopes (outer event ids) and decrypted inner events.
|
|
31
35
|
*/
|
|
32
36
|
this.seenEventIds = new LruCache(DEFAULT_LRU_SIZE);
|
|
37
|
+
/** Pending final responses held until their CEP-41 stream terminates. */
|
|
38
|
+
this.pendingOpenStreamResponses = new Map();
|
|
39
|
+
/** Active server-side CEP-41 writers keyed by inbound request event id. */
|
|
40
|
+
this.openStreamWriters = new Map();
|
|
33
41
|
this.injectClientPubkey = (_a = options.injectClientPubkey) !== null && _a !== void 0 ? _a : false;
|
|
34
42
|
this.shouldInjectRequestEventId = (_b = options.injectRequestEventId) !== null && _b !== void 0 ? _b : false;
|
|
35
43
|
this.onClientSessionEvicted = options.onClientSessionEvicted;
|
|
@@ -91,6 +99,8 @@ export class NostrServerTransport extends BaseNostrTransport {
|
|
|
91
99
|
publishRelayList: options.publishRelayList,
|
|
92
100
|
relayListUrls: options.relayListUrls,
|
|
93
101
|
bootstrapRelayUrls: options.bootstrapRelayUrls,
|
|
102
|
+
transformListToolsResult: (result) => this.applyListToolsResultTransformers(result),
|
|
103
|
+
getListToolsAnnouncementTags: (result) => this.buildListToolsAnnouncementTags(result),
|
|
94
104
|
onDispatchMessage: (message) => { var _a; return (_a = this.onmessage) === null || _a === void 0 ? void 0 : _a.call(this, message); },
|
|
95
105
|
onPublishEvent: (event) => this.publishEvent(event),
|
|
96
106
|
onPublishEventToRelays: (event, relayUrls) => this.publishEventToRelayUrls(event, relayUrls),
|
|
@@ -105,12 +115,66 @@ export class NostrServerTransport extends BaseNostrTransport {
|
|
|
105
115
|
this.oversizedThreshold = (_f = ot === null || ot === void 0 ? void 0 : ot.thresholdBytes) !== null && _f !== void 0 ? _f : DEFAULT_OVERSIZED_THRESHOLD;
|
|
106
116
|
this.oversizedChunkSize = (_g = ot === null || ot === void 0 ? void 0 : ot.chunkSizeBytes) !== null && _g !== void 0 ? _g : DEFAULT_CHUNK_SIZE;
|
|
107
117
|
this.oversizedReceiver = new OversizedTransferReceiver((_h = ot === null || ot === void 0 ? void 0 : ot.policy) !== null && _h !== void 0 ? _h : {}, this.logger);
|
|
118
|
+
this.openStreamEnabled = (_k = (_j = options.openStream) === null || _j === void 0 ? void 0 : _j.enabled) !== null && _k !== void 0 ? _k : false;
|
|
119
|
+
this.openStreamReceiver = new OpenStreamReceiver({
|
|
120
|
+
maxConcurrentStreams: (_m = (_l = options.openStream) === null || _l === void 0 ? void 0 : _l.policy) === null || _m === void 0 ? void 0 : _m.maxConcurrentStreams,
|
|
121
|
+
maxBufferedChunksPerStream: (_p = (_o = options.openStream) === null || _o === void 0 ? void 0 : _o.policy) === null || _p === void 0 ? void 0 : _p.maxBufferedChunksPerStream,
|
|
122
|
+
maxBufferedBytesPerStream: (_r = (_q = options.openStream) === null || _q === void 0 ? void 0 : _q.policy) === null || _r === void 0 ? void 0 : _r.maxBufferedBytesPerStream,
|
|
123
|
+
idleTimeoutMs: (_t = (_s = options.openStream) === null || _s === void 0 ? void 0 : _s.policy) === null || _t === void 0 ? void 0 : _t.idleTimeoutMs,
|
|
124
|
+
probeTimeoutMs: (_v = (_u = options.openStream) === null || _u === void 0 ? void 0 : _u.policy) === null || _v === void 0 ? void 0 : _v.probeTimeoutMs,
|
|
125
|
+
closeGracePeriodMs: (_x = (_w = options.openStream) === null || _w === void 0 ? void 0 : _w.policy) === null || _x === void 0 ? void 0 : _x.closeGracePeriodMs,
|
|
126
|
+
getSessionOptions: (progressToken) => {
|
|
127
|
+
let progress = 0;
|
|
128
|
+
return {
|
|
129
|
+
sendPing: async (nonce) => {
|
|
130
|
+
progress += 1;
|
|
131
|
+
await this.sendNotification(progressToken, {
|
|
132
|
+
jsonrpc: '2.0',
|
|
133
|
+
method: 'notifications/progress',
|
|
134
|
+
params: buildOpenStreamPingFrame({
|
|
135
|
+
progressToken,
|
|
136
|
+
progress,
|
|
137
|
+
nonce,
|
|
138
|
+
}),
|
|
139
|
+
});
|
|
140
|
+
},
|
|
141
|
+
sendPong: async (nonce) => {
|
|
142
|
+
progress += 1;
|
|
143
|
+
await this.sendNotification(progressToken, {
|
|
144
|
+
jsonrpc: '2.0',
|
|
145
|
+
method: 'notifications/progress',
|
|
146
|
+
params: buildOpenStreamPongFrame({
|
|
147
|
+
progressToken,
|
|
148
|
+
progress,
|
|
149
|
+
nonce,
|
|
150
|
+
}),
|
|
151
|
+
});
|
|
152
|
+
},
|
|
153
|
+
sendAbort: async (reason) => {
|
|
154
|
+
progress += 1;
|
|
155
|
+
await this.sendNotification(progressToken, {
|
|
156
|
+
jsonrpc: '2.0',
|
|
157
|
+
method: 'notifications/progress',
|
|
158
|
+
params: buildOpenStreamAbortFrame({
|
|
159
|
+
progressToken,
|
|
160
|
+
progress,
|
|
161
|
+
reason,
|
|
162
|
+
}),
|
|
163
|
+
});
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
},
|
|
167
|
+
logger: this.logger,
|
|
168
|
+
});
|
|
108
169
|
// Advertise CEP-22 support so clients can skip the accept handshake.
|
|
170
|
+
const internalCommonTags = [];
|
|
109
171
|
if (this.oversizedEnabled) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
172
|
+
internalCommonTags.push([NOSTR_TAGS.SUPPORT_OVERSIZED_TRANSFER]);
|
|
173
|
+
}
|
|
174
|
+
if (this.openStreamEnabled) {
|
|
175
|
+
internalCommonTags.push([NOSTR_TAGS.SUPPORT_OPEN_STREAM]);
|
|
113
176
|
}
|
|
177
|
+
this.announcementManager.setInternalCommonTags(internalCommonTags);
|
|
114
178
|
}
|
|
115
179
|
/**
|
|
116
180
|
* Sets extra tags to include in server announcement + initialize response events.
|
|
@@ -136,6 +200,20 @@ export class NostrServerTransport extends BaseNostrTransport {
|
|
|
136
200
|
addInboundMiddleware(middleware) {
|
|
137
201
|
this.inboundMiddlewares.push(middleware);
|
|
138
202
|
}
|
|
203
|
+
/**
|
|
204
|
+
* Adds a transformer for `tools/list` results emitted by the server.
|
|
205
|
+
*
|
|
206
|
+
* Transformers are applied to direct responses and public announcement payloads.
|
|
207
|
+
*/
|
|
208
|
+
addListToolsResultTransformer(transformer) {
|
|
209
|
+
this.listToolsResultTransformers.push(transformer);
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Adds a provider for extra tags on public tools/list announcement events.
|
|
213
|
+
*/
|
|
214
|
+
addListToolsAnnouncementTagsProducer(producer) {
|
|
215
|
+
this.listToolsAnnouncementTagsProducers.push(producer);
|
|
216
|
+
}
|
|
139
217
|
/**
|
|
140
218
|
* Starts the transport, connecting to the relay and setting up event listeners
|
|
141
219
|
* to receive incoming MCP requests.
|
|
@@ -191,6 +269,9 @@ export class NostrServerTransport extends BaseNostrTransport {
|
|
|
191
269
|
this.correlationStore.clear();
|
|
192
270
|
this.seenEventIds.clear();
|
|
193
271
|
this.oversizedReceiver.clear();
|
|
272
|
+
this.openStreamReceiver.clear();
|
|
273
|
+
this.pendingOpenStreamResponses.clear();
|
|
274
|
+
this.openStreamWriters.clear();
|
|
194
275
|
(_a = this.onclose) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
195
276
|
}
|
|
196
277
|
catch (error) {
|
|
@@ -321,6 +402,35 @@ export class NostrServerTransport extends BaseNostrTransport {
|
|
|
321
402
|
// Register the event route in the correlation store
|
|
322
403
|
const progressToken = (_b = (_a = request.params) === null || _a === void 0 ? void 0 : _a._meta) === null || _b === void 0 ? void 0 : _b.progressToken;
|
|
323
404
|
this.correlationStore.registerEventRoute(eventId, clientPubkey, originalRequestId, progressToken ? String(progressToken) : undefined, wrapKind, this.shouldInjectRequestEventId ? event : undefined);
|
|
405
|
+
if (this.openStreamEnabled && progressToken) {
|
|
406
|
+
const writer = new OpenStreamWriter({
|
|
407
|
+
progressToken: String(progressToken),
|
|
408
|
+
publishFrame: async (frame) => {
|
|
409
|
+
await this.sendNotification(clientPubkey, {
|
|
410
|
+
jsonrpc: '2.0',
|
|
411
|
+
method: 'notifications/progress',
|
|
412
|
+
params: frame,
|
|
413
|
+
});
|
|
414
|
+
return undefined;
|
|
415
|
+
},
|
|
416
|
+
onClose: async () => {
|
|
417
|
+
await this.flushPendingOpenStreamResponse(eventId);
|
|
418
|
+
},
|
|
419
|
+
onAbort: async () => {
|
|
420
|
+
await this.flushPendingOpenStreamResponse(eventId);
|
|
421
|
+
},
|
|
422
|
+
});
|
|
423
|
+
this.openStreamWriters.set(eventId, writer);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
async flushPendingOpenStreamResponse(eventId) {
|
|
427
|
+
const pendingResponse = this.pendingOpenStreamResponses.get(eventId);
|
|
428
|
+
this.pendingOpenStreamResponses.delete(eventId);
|
|
429
|
+
this.openStreamWriters.delete(eventId);
|
|
430
|
+
if (!pendingResponse) {
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
await this.handleResponse(pendingResponse);
|
|
324
434
|
}
|
|
325
435
|
/**
|
|
326
436
|
* Cleans up request correlation for a request that was dropped by middleware.
|
|
@@ -346,6 +456,12 @@ export class NostrServerTransport extends BaseNostrTransport {
|
|
|
346
456
|
* Handles response messages by finding the original request and routing back to client.
|
|
347
457
|
* @param response The JSON-RPC response or error to send.
|
|
348
458
|
*/
|
|
459
|
+
applyListToolsResultTransformers(result) {
|
|
460
|
+
return this.listToolsResultTransformers.reduce((currentResult, transformer) => transformer(currentResult), result);
|
|
461
|
+
}
|
|
462
|
+
buildListToolsAnnouncementTags(result) {
|
|
463
|
+
return this.listToolsAnnouncementTagsProducers.flatMap((producer) => producer(result));
|
|
464
|
+
}
|
|
349
465
|
async handleResponse(response) {
|
|
350
466
|
var _a, _b;
|
|
351
467
|
// Handle special announcement responses
|
|
@@ -360,6 +476,11 @@ export class NostrServerTransport extends BaseNostrTransport {
|
|
|
360
476
|
}
|
|
361
477
|
// Find the event route using O(1) lookup
|
|
362
478
|
const nostrEventId = response.id;
|
|
479
|
+
const existingOpenStreamWriter = this.openStreamWriters.get(nostrEventId);
|
|
480
|
+
if (existingOpenStreamWriter && existingOpenStreamWriter.isActive) {
|
|
481
|
+
this.pendingOpenStreamResponses.set(nostrEventId, response);
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
363
484
|
const route = this.correlationStore.popEventRoute(nostrEventId);
|
|
364
485
|
if (!route) {
|
|
365
486
|
(_a = this.onerror) === null || _a === void 0 ? void 0 : _a.call(this, new Error(`No pending request found for response ID: ${response.id}`));
|
|
@@ -370,14 +491,23 @@ export class NostrServerTransport extends BaseNostrTransport {
|
|
|
370
491
|
(_b = this.onerror) === null || _b === void 0 ? void 0 : _b.call(this, new Error(`No session found for client: ${route.clientPubkey}`));
|
|
371
492
|
return;
|
|
372
493
|
}
|
|
494
|
+
const parsedListToolsResult = isJSONRPCResultResponse(response)
|
|
495
|
+
? ListToolsResultSchema.safeParse(response.result)
|
|
496
|
+
: null;
|
|
497
|
+
const responseToSend = (parsedListToolsResult === null || parsedListToolsResult === void 0 ? void 0 : parsedListToolsResult.success)
|
|
498
|
+
? {
|
|
499
|
+
...response,
|
|
500
|
+
result: this.applyListToolsResultTransformers(parsedListToolsResult.data),
|
|
501
|
+
}
|
|
502
|
+
: response;
|
|
373
503
|
// Restore the original request ID in the response
|
|
374
|
-
|
|
504
|
+
responseToSend.id = route.originalRequestId;
|
|
375
505
|
// CEP-22 Oversized Transfer (proactive path for server responses)
|
|
376
506
|
if (this.oversizedEnabled &&
|
|
377
507
|
route.progressToken &&
|
|
378
508
|
session.supportsOversizedTransfer) {
|
|
379
509
|
// Serialize before restoring id so the client receives the correct id.
|
|
380
|
-
const serialized = JSON.stringify(
|
|
510
|
+
const serialized = JSON.stringify(responseToSend);
|
|
381
511
|
const byteLength = new TextEncoder().encode(serialized).byteLength;
|
|
382
512
|
if (byteLength > this.oversizedThreshold) {
|
|
383
513
|
const continuationFrameTags = this.createResponseTags(route.clientPubkey, nostrEventId);
|
|
@@ -416,8 +546,8 @@ export class NostrServerTransport extends BaseNostrTransport {
|
|
|
416
546
|
fallbackWrapKind: route.wrapKind,
|
|
417
547
|
});
|
|
418
548
|
// Attach pricing tags to capability list responses so clients can access CEP-8 pricing
|
|
419
|
-
if (isJSONRPCResultResponse(
|
|
420
|
-
const result =
|
|
549
|
+
if (isJSONRPCResultResponse(responseToSend)) {
|
|
550
|
+
const result = responseToSend.result;
|
|
421
551
|
if (ListToolsResultSchema.safeParse(result).success ||
|
|
422
552
|
ListResourcesResultSchema.safeParse(result).success ||
|
|
423
553
|
ListResourceTemplatesResultSchema.safeParse(result).success ||
|
|
@@ -426,7 +556,7 @@ export class NostrServerTransport extends BaseNostrTransport {
|
|
|
426
556
|
}
|
|
427
557
|
}
|
|
428
558
|
try {
|
|
429
|
-
await this.sendMcpMessage(
|
|
559
|
+
await this.sendMcpMessage(responseToSend, route.clientPubkey, CTXVM_MESSAGES_KIND, tags, session.isEncrypted, undefined, giftWrapKind);
|
|
430
560
|
}
|
|
431
561
|
catch (error) {
|
|
432
562
|
this.correlationStore.registerEventRoute(nostrEventId, route.clientPubkey, route.originalRequestId, route.progressToken, route.wrapKind);
|
|
@@ -567,6 +697,17 @@ export class NostrServerTransport extends BaseNostrTransport {
|
|
|
567
697
|
try {
|
|
568
698
|
const decryptedJson = await withTimeout(decryptMessage(event, this.signer), DEFAULT_TIMEOUT_MS, 'Decrypt message timed out');
|
|
569
699
|
const currentEvent = JSON.parse(decryptedJson);
|
|
700
|
+
// Verify the inner event's cryptographic signature to prevent identity
|
|
701
|
+
// forgery. Without this check an attacker can place any pubkey inside
|
|
702
|
+
// the plaintext and bypass allowlists. (Fixes #64)
|
|
703
|
+
if (!verifyEvent(currentEvent)) {
|
|
704
|
+
this.logger.error('Rejecting decrypted inner event with invalid signature', {
|
|
705
|
+
innerEventId: currentEvent.id,
|
|
706
|
+
innerPubkey: currentEvent.pubkey,
|
|
707
|
+
outerEventId: event.id,
|
|
708
|
+
});
|
|
709
|
+
return;
|
|
710
|
+
}
|
|
570
711
|
// Deduplicate decrypted inner events before authorization and dispatch.
|
|
571
712
|
if (this.seenEventIds.has(currentEvent.id)) {
|
|
572
713
|
this.logger.debug('Skipping duplicate decrypted inner event', {
|
|
@@ -599,6 +740,13 @@ export class NostrServerTransport extends BaseNostrTransport {
|
|
|
599
740
|
this.logger.error(`Received unencrypted message from ${event.pubkey} but encryption is required. Ignoring.`);
|
|
600
741
|
return;
|
|
601
742
|
}
|
|
743
|
+
if (!verifyEvent(event)) {
|
|
744
|
+
this.logger.error('Rejecting unencrypted event with invalid signature', {
|
|
745
|
+
eventId: event.id,
|
|
746
|
+
pubkey: event.pubkey,
|
|
747
|
+
});
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
602
750
|
await this.authorizeAndProcessEvent(event, false);
|
|
603
751
|
}
|
|
604
752
|
/**
|
|
@@ -608,7 +756,7 @@ export class NostrServerTransport extends BaseNostrTransport {
|
|
|
608
756
|
* @param isEncrypted Whether the original event was encrypted.
|
|
609
757
|
*/
|
|
610
758
|
async authorizeAndProcessEvent(event, isEncrypted, wrapKind) {
|
|
611
|
-
var _a;
|
|
759
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
612
760
|
try {
|
|
613
761
|
const mcpMessage = this.convertNostrEventToMcpMessage(event);
|
|
614
762
|
if (!mcpMessage) {
|
|
@@ -619,6 +767,7 @@ export class NostrServerTransport extends BaseNostrTransport {
|
|
|
619
767
|
});
|
|
620
768
|
return;
|
|
621
769
|
}
|
|
770
|
+
const inboundMessage = mcpMessage;
|
|
622
771
|
// Check authorization using the authorization policy
|
|
623
772
|
const authDecision = await this.authorizationPolicy.authorize(event.pubkey, mcpMessage);
|
|
624
773
|
if (!authDecision.allowed) {
|
|
@@ -660,6 +809,7 @@ export class NostrServerTransport extends BaseNostrTransport {
|
|
|
660
809
|
session.supportsEphemeralEncryption || (session.supportsEphemeralEncryption = discoveredCapabilities.supportsEphemeralEncryption);
|
|
661
810
|
session.supportsOversizedTransfer || (session.supportsOversizedTransfer = this.oversizedEnabled &&
|
|
662
811
|
discoveredCapabilities.supportsOversizedTransfer);
|
|
812
|
+
session.supportsOpenStream || (session.supportsOpenStream = this.openStreamEnabled && discoveredCapabilities.supportsOpenStream);
|
|
663
813
|
const shouldSendAccept = !hadLearnedOversizedSupport;
|
|
664
814
|
const forward = async (msg) => {
|
|
665
815
|
var _a, _b;
|
|
@@ -688,29 +838,107 @@ export class NostrServerTransport extends BaseNostrTransport {
|
|
|
688
838
|
});
|
|
689
839
|
return forwarded;
|
|
690
840
|
};
|
|
691
|
-
if (isJSONRPCRequest(
|
|
692
|
-
this.handleIncomingRequest(event, event.id,
|
|
841
|
+
if (isJSONRPCRequest(inboundMessage)) {
|
|
842
|
+
this.handleIncomingRequest(event, event.id, inboundMessage, event.pubkey, wrapKind);
|
|
693
843
|
if (this.shouldInjectRequestEventId) {
|
|
694
|
-
injectRequestEventId(
|
|
844
|
+
injectRequestEventId(inboundMessage, event.id);
|
|
695
845
|
}
|
|
696
846
|
if (this.injectClientPubkey) {
|
|
697
|
-
injectClientPubkey(
|
|
847
|
+
injectClientPubkey(inboundMessage, event.pubkey);
|
|
848
|
+
}
|
|
849
|
+
const openStreamWriter = this.openStreamWriters.get(event.id);
|
|
850
|
+
if (openStreamWriter) {
|
|
851
|
+
const params = (_a = inboundMessage.params) !== null && _a !== void 0 ? _a : {};
|
|
852
|
+
inboundMessage.params = params;
|
|
853
|
+
const meta = (_b = params._meta) !== null && _b !== void 0 ? _b : {};
|
|
854
|
+
params._meta = meta;
|
|
855
|
+
meta.stream = openStreamWriter;
|
|
698
856
|
}
|
|
699
857
|
}
|
|
700
|
-
else if (isJSONRPCNotification(
|
|
701
|
-
this.handleIncomingNotification(event.pubkey,
|
|
702
|
-
if (
|
|
703
|
-
|
|
858
|
+
else if (isJSONRPCNotification(inboundMessage)) {
|
|
859
|
+
this.handleIncomingNotification(event.pubkey, inboundMessage);
|
|
860
|
+
if (inboundMessage.method === 'notifications/progress' &&
|
|
861
|
+
OpenStreamReceiver.isOpenStreamFrame(inboundMessage)) {
|
|
862
|
+
const frame = (_c = inboundMessage.params) === null || _c === void 0 ? void 0 : _c.cvm;
|
|
863
|
+
if ((frame === null || frame === void 0 ? void 0 : frame.frameType) === 'abort') {
|
|
864
|
+
const progressToken = String((_e = (_d = inboundMessage.params) === null || _d === void 0 ? void 0 : _d.progressToken) !== null && _e !== void 0 ? _e : '');
|
|
865
|
+
const eventId = this.correlationStore.getEventIdByProgressToken(progressToken);
|
|
866
|
+
const writer = eventId
|
|
867
|
+
? this.openStreamWriters.get(eventId)
|
|
868
|
+
: undefined;
|
|
869
|
+
if (writer) {
|
|
870
|
+
void writer.abort(frame.reason).catch((err) => {
|
|
871
|
+
var _a;
|
|
872
|
+
this.logger.error('Open stream abort propagation failed (server)', {
|
|
873
|
+
error: err instanceof Error ? err.message : String(err),
|
|
874
|
+
pubkey: event.pubkey,
|
|
875
|
+
progressToken,
|
|
876
|
+
});
|
|
877
|
+
(_a = this.onerror) === null || _a === void 0 ? void 0 : _a.call(this, err instanceof Error ? err : new Error(String(err)));
|
|
878
|
+
});
|
|
879
|
+
}
|
|
880
|
+
return;
|
|
881
|
+
}
|
|
882
|
+
if ((frame === null || frame === void 0 ? void 0 : frame.frameType) === 'ping') {
|
|
883
|
+
const progressToken = String((_g = (_f = inboundMessage.params) === null || _f === void 0 ? void 0 : _f.progressToken) !== null && _g !== void 0 ? _g : '');
|
|
884
|
+
const nonce = 'nonce' in frame && typeof frame.nonce === 'string'
|
|
885
|
+
? frame.nonce
|
|
886
|
+
: '';
|
|
887
|
+
const eventId = this.correlationStore.getEventIdByProgressToken(progressToken);
|
|
888
|
+
const writer = eventId
|
|
889
|
+
? this.openStreamWriters.get(eventId)
|
|
890
|
+
: undefined;
|
|
891
|
+
if (writer) {
|
|
892
|
+
void writer.pong(nonce).catch((err) => {
|
|
893
|
+
var _a;
|
|
894
|
+
this.logger.error('Open stream ping handling failed (server)', {
|
|
895
|
+
error: err instanceof Error ? err.message : String(err),
|
|
896
|
+
pubkey: event.pubkey,
|
|
897
|
+
progressToken,
|
|
898
|
+
});
|
|
899
|
+
(_a = this.onerror) === null || _a === void 0 ? void 0 : _a.call(this, err instanceof Error ? err : new Error(String(err)));
|
|
900
|
+
});
|
|
901
|
+
return;
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
this.openStreamReceiver
|
|
905
|
+
.processFrame(inboundMessage)
|
|
906
|
+
.then(async () => {
|
|
907
|
+
var _a, _b, _c, _d;
|
|
908
|
+
const frameType = frame === null || frame === void 0 ? void 0 : frame.frameType;
|
|
909
|
+
if (frameType === 'start' && session.supportsOpenStream) {
|
|
910
|
+
await this.sendNotification(event.pubkey, {
|
|
911
|
+
jsonrpc: '2.0',
|
|
912
|
+
method: 'notifications/progress',
|
|
913
|
+
params: buildOpenStreamAcceptFrame({
|
|
914
|
+
progressToken: String((_b = (_a = inboundMessage.params) === null || _a === void 0 ? void 0 : _a.progressToken) !== null && _b !== void 0 ? _b : ''),
|
|
915
|
+
progress: Number((_d = (_c = inboundMessage.params) === null || _c === void 0 ? void 0 : _c.progress) !== null && _d !== void 0 ? _d : 0) + 1,
|
|
916
|
+
}),
|
|
917
|
+
});
|
|
918
|
+
}
|
|
919
|
+
})
|
|
920
|
+
.catch((err) => {
|
|
921
|
+
var _a;
|
|
922
|
+
this.logger.error('Open stream error (server)', {
|
|
923
|
+
error: err instanceof Error ? err.message : String(err),
|
|
924
|
+
pubkey: event.pubkey,
|
|
925
|
+
});
|
|
926
|
+
(_a = this.onerror) === null || _a === void 0 ? void 0 : _a.call(this, err instanceof Error ? err : new Error(String(err)));
|
|
927
|
+
});
|
|
928
|
+
return;
|
|
929
|
+
}
|
|
930
|
+
if (inboundMessage.method === 'notifications/progress' &&
|
|
931
|
+
OversizedTransferReceiver.isOversizedFrame(inboundMessage)) {
|
|
704
932
|
this.oversizedReceiver
|
|
705
|
-
.processFrame(
|
|
933
|
+
.processFrame(inboundMessage)
|
|
706
934
|
.then(async (synthetic) => {
|
|
707
935
|
var _a, _b, _c, _d;
|
|
708
936
|
if (synthetic === null) {
|
|
709
|
-
if (((_b = (_a =
|
|
937
|
+
if (((_b = (_a = inboundMessage.params) === null || _a === void 0 ? void 0 : _a.cvm) === null || _b === void 0 ? void 0 : _b.frameType) === 'start' &&
|
|
710
938
|
shouldSendAccept) {
|
|
711
939
|
await sendAcceptFrame({
|
|
712
940
|
clientPubkey: event.pubkey,
|
|
713
|
-
progressToken: String((_d = (_c =
|
|
941
|
+
progressToken: String((_d = (_c = inboundMessage.params) === null || _c === void 0 ? void 0 : _c.progressToken) !== null && _d !== void 0 ? _d : ''),
|
|
714
942
|
}, {
|
|
715
943
|
sendNotification: this.sendNotification.bind(this),
|
|
716
944
|
}).catch((err) => {
|
|
@@ -760,10 +988,10 @@ export class NostrServerTransport extends BaseNostrTransport {
|
|
|
760
988
|
return;
|
|
761
989
|
}
|
|
762
990
|
}
|
|
763
|
-
void dispatch(0,
|
|
991
|
+
void dispatch(0, inboundMessage)
|
|
764
992
|
.then((forwarded) => {
|
|
765
993
|
if (!forwarded) {
|
|
766
|
-
this.cleanupDroppedRequest(
|
|
994
|
+
this.cleanupDroppedRequest(inboundMessage);
|
|
767
995
|
}
|
|
768
996
|
})
|
|
769
997
|
.catch((err) => {
|
|
@@ -783,7 +1011,7 @@ export class NostrServerTransport extends BaseNostrTransport {
|
|
|
783
1011
|
eventId: event.id,
|
|
784
1012
|
pubkey: event.pubkey,
|
|
785
1013
|
});
|
|
786
|
-
(
|
|
1014
|
+
(_h = this.onerror) === null || _h === void 0 ? void 0 : _h.call(this, error instanceof Error ? error : new Error(String(error)));
|
|
787
1015
|
}
|
|
788
1016
|
}
|
|
789
1017
|
/**
|
|
@@ -794,6 +1022,8 @@ export class NostrServerTransport extends BaseNostrTransport {
|
|
|
794
1022
|
return {
|
|
795
1023
|
sessionStore: this.sessionStore,
|
|
796
1024
|
correlationStore: this.correlationStore,
|
|
1025
|
+
oversizedReceiver: this.oversizedReceiver,
|
|
1026
|
+
openStreamReceiver: this.openStreamReceiver,
|
|
797
1027
|
};
|
|
798
1028
|
}
|
|
799
1029
|
}
|