@contextvm/sdk 0.1.10 → 0.1.12
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/README.md +19 -143
- package/dist/esm/core/constants.d.ts +4 -0
- package/dist/esm/core/constants.d.ts.map +1 -1
- package/dist/esm/core/constants.js +4 -0
- package/dist/esm/core/constants.js.map +1 -1
- package/dist/esm/core/encryption.d.ts +4 -3
- package/dist/esm/core/encryption.d.ts.map +1 -1
- package/dist/esm/core/encryption.js +10 -6
- package/dist/esm/core/encryption.js.map +1 -1
- package/dist/esm/core/interfaces.d.ts +10 -3
- package/dist/esm/core/interfaces.d.ts.map +1 -1
- package/dist/esm/core/utils/logger.d.ts +24 -0
- package/dist/esm/core/utils/logger.d.ts.map +1 -0
- package/dist/esm/core/utils/logger.js +46 -0
- package/dist/esm/core/utils/logger.js.map +1 -0
- package/dist/esm/core/utils/serializers.d.ts +2 -3
- package/dist/esm/core/utils/serializers.d.ts.map +1 -1
- package/dist/esm/core/utils/serializers.js +5 -3
- package/dist/esm/core/utils/serializers.js.map +1 -1
- package/dist/esm/core/utils/utils.d.ts +14 -0
- package/dist/esm/core/utils/utils.d.ts.map +1 -1
- package/dist/esm/core/utils/utils.js +25 -0
- package/dist/esm/core/utils/utils.js.map +1 -1
- package/dist/esm/gateway/index.d.ts.map +1 -1
- package/dist/esm/gateway/index.js +12 -8
- package/dist/esm/gateway/index.js.map +1 -1
- package/dist/esm/proxy/index.d.ts.map +1 -1
- package/dist/esm/proxy/index.js +10 -8
- package/dist/esm/proxy/index.js.map +1 -1
- package/dist/esm/relay/simple-relay-pool.d.ts +17 -0
- package/dist/esm/relay/simple-relay-pool.d.ts.map +1 -1
- package/dist/esm/relay/simple-relay-pool.js +81 -7
- package/dist/esm/relay/simple-relay-pool.js.map +1 -1
- package/dist/esm/signer/private-key-signer.d.ts +7 -1
- package/dist/esm/signer/private-key-signer.d.ts.map +1 -1
- package/dist/esm/signer/private-key-signer.js +14 -3
- package/dist/esm/signer/private-key-signer.js.map +1 -1
- package/dist/esm/transport/base-nostr-transport.d.ts +3 -3
- package/dist/esm/transport/base-nostr-transport.d.ts.map +1 -1
- package/dist/esm/transport/base-nostr-transport.js +37 -5
- package/dist/esm/transport/base-nostr-transport.js.map +1 -1
- package/dist/esm/transport/nostr-client-transport.d.ts +2 -6
- package/dist/esm/transport/nostr-client-transport.d.ts.map +1 -1
- package/dist/esm/transport/nostr-client-transport.js +10 -8
- package/dist/esm/transport/nostr-client-transport.js.map +1 -1
- package/dist/esm/transport/nostr-server-transport.d.ts.map +1 -1
- package/dist/esm/transport/nostr-server-transport.js +10 -8
- package/dist/esm/transport/nostr-server-transport.js.map +1 -1
- package/package.json +7 -7
package/dist/esm/proxy/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { NostrClientTransport, } from '../transport/nostr-client-transport.js';
|
|
2
|
+
import { createLogger } from '../core/utils/logger.js';
|
|
3
|
+
const logger = createLogger('proxy');
|
|
2
4
|
/**
|
|
3
5
|
* `NostrMCPProxy` acts as a bridge between a local MCP Host
|
|
4
6
|
* and a remote MCP Server accessible via the Nostr network.
|
|
@@ -25,7 +27,7 @@ export class NostrMCPProxy {
|
|
|
25
27
|
this.mcpHostTransport.start(),
|
|
26
28
|
this.nostrTransport.start(),
|
|
27
29
|
]);
|
|
28
|
-
|
|
30
|
+
logger.info('NostrMCPProxy started.');
|
|
29
31
|
}
|
|
30
32
|
/**
|
|
31
33
|
* Stops the proxy and closes all connections.
|
|
@@ -35,25 +37,25 @@ export class NostrMCPProxy {
|
|
|
35
37
|
async stop() {
|
|
36
38
|
await this.mcpHostTransport.close();
|
|
37
39
|
await this.nostrTransport.close();
|
|
38
|
-
|
|
40
|
+
logger.info('NostrMCPProxy stopped.');
|
|
39
41
|
}
|
|
40
42
|
setupEventHandlers() {
|
|
41
43
|
// Forward messages from the local host to Nostr.
|
|
42
44
|
this.mcpHostTransport.onmessage = (message) => {
|
|
43
45
|
this.nostrTransport
|
|
44
46
|
.send(message)
|
|
45
|
-
.catch((err) =>
|
|
47
|
+
.catch((err) => logger.error('Error sending message to Nostr:', err));
|
|
46
48
|
};
|
|
47
|
-
this.mcpHostTransport.onerror = (err) =>
|
|
48
|
-
this.mcpHostTransport.onclose = () =>
|
|
49
|
+
this.mcpHostTransport.onerror = (err) => logger.error('MCP Host Transport Error:', err);
|
|
50
|
+
this.mcpHostTransport.onclose = () => logger.info('MCP Host Transport closed');
|
|
49
51
|
// Forward messages from Nostr back to the local host.
|
|
50
52
|
this.nostrTransport.onmessage = (message) => {
|
|
51
53
|
this.mcpHostTransport
|
|
52
54
|
.send(message)
|
|
53
|
-
.catch((err) =>
|
|
55
|
+
.catch((err) => logger.error('Error sending message to local host:', err));
|
|
54
56
|
};
|
|
55
|
-
this.nostrTransport.onerror = (err) =>
|
|
56
|
-
this.nostrTransport.onclose = () =>
|
|
57
|
+
this.nostrTransport.onerror = (err) => logger.error('Nostr Transport Error:', err);
|
|
58
|
+
this.nostrTransport.onclose = () => logger.info('Nostr Transport closed');
|
|
57
59
|
}
|
|
58
60
|
}
|
|
59
61
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/proxy/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,oBAAoB,GAErB,MAAM,wCAAwC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/proxy/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,oBAAoB,GAErB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;AAgBrC;;;;;;GAMG;AACH,MAAM,OAAO,aAAa;IAIxB,YAAY,OAA6B;QACvC,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;QACjD,IAAI,CAAC,cAAc,GAAG,IAAI,oBAAoB,CAC5C,OAAO,CAAC,qBAAqB,CAC9B,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,KAAK;QAChB,0BAA0B;QAC1B,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,wBAAwB;QACxB,MAAM,OAAO,CAAC,GAAG,CAAC;YAChB,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE;YAC7B,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE;SAC5B,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IACxC,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,IAAI;QACf,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;QACpC,MAAM,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;QAClC,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IACxC,CAAC;IAEO,kBAAkB;QACxB,iDAAiD;QACjD,IAAI,CAAC,gBAAgB,CAAC,SAAS,GAAG,CAAC,OAAuB,EAAE,EAAE;YAC5D,IAAI,CAAC,cAAc;iBAChB,IAAI,CAAC,OAAO,CAAC;iBACb,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC1E,CAAC,CAAC;QACF,IAAI,CAAC,gBAAgB,CAAC,OAAO,GAAG,CAAC,GAAG,EAAE,EAAE,CACtC,MAAM,CAAC,KAAK,CAAC,2BAA2B,EAAE,GAAG,CAAC,CAAC;QACjD,IAAI,CAAC,gBAAgB,CAAC,OAAO,GAAG,GAAG,EAAE,CACnC,MAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;QAE3C,sDAAsD;QACtD,IAAI,CAAC,cAAc,CAAC,SAAS,GAAG,CAAC,OAAuB,EAAE,EAAE;YAC1D,IAAI,CAAC,gBAAgB;iBAClB,IAAI,CAAC,OAAO,CAAC;iBACb,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CACb,MAAM,CAAC,KAAK,CAAC,sCAAsC,EAAE,GAAG,CAAC,CAC1D,CAAC;QACN,CAAC,CAAC;QACF,IAAI,CAAC,cAAc,CAAC,OAAO,GAAG,CAAC,GAAG,EAAE,EAAE,CACpC,MAAM,CAAC,KAAK,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC;QAC9C,IAAI,CAAC,cAAc,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IAC5E,CAAC;CACF"}
|
|
@@ -2,15 +2,32 @@ import { type Filter, type NostrEvent } from 'nostr-tools';
|
|
|
2
2
|
import { RelayHandler } from '../core/interfaces.js';
|
|
3
3
|
/**
|
|
4
4
|
* A RelayHandler implementation that uses a SimplePool to manage connections and subscriptions.
|
|
5
|
+
* Implements exponential backoff for reconnection attempts when relays drop connections.
|
|
5
6
|
* @argument relayUrls - An array of relay URLs to connect to.
|
|
6
7
|
* @returns A RelayHandler implementation that uses a SimplePool to manage connections and subscriptions.
|
|
7
8
|
*/
|
|
8
9
|
export declare class SimpleRelayPool implements RelayHandler {
|
|
9
10
|
private readonly relayUrls;
|
|
10
11
|
private pool;
|
|
12
|
+
private reconnectIntervals;
|
|
13
|
+
private reconnectTimer?;
|
|
11
14
|
private subscriptions;
|
|
12
15
|
constructor(relayUrls: string[]);
|
|
16
|
+
/**
|
|
17
|
+
* Starts a loop that periodically checks connection status and reconnects if needed
|
|
18
|
+
* using exponential backoff strategy.
|
|
19
|
+
*/
|
|
20
|
+
private startReconnectLoop;
|
|
13
21
|
connect(): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Handles a disconnected relay with exponential backoff strategy.
|
|
24
|
+
* @param url - The relay URL to reconnect to
|
|
25
|
+
*/
|
|
26
|
+
private handleDisconnectedRelay;
|
|
27
|
+
/**
|
|
28
|
+
* Resubscribes to all active subscriptions after relay reconnection
|
|
29
|
+
*/
|
|
30
|
+
private resubscribeAll;
|
|
14
31
|
disconnect(relayUrls?: string[]): Promise<void>;
|
|
15
32
|
publish(event: NostrEvent): Promise<void>;
|
|
16
33
|
subscribe(filters: Filter[], onEvent: (event: NostrEvent) => void, onEose?: () => void): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simple-relay-pool.d.ts","sourceRoot":"","sources":["../../../src/relay/simple-relay-pool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,MAAM,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAEvE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"simple-relay-pool.d.ts","sourceRoot":"","sources":["../../../src/relay/simple-relay-pool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,MAAM,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAEvE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAMrD;;;;;GAKG;AACH,qBAAa,eAAgB,YAAW,YAAY;IAClD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IACrC,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,kBAAkB,CAAkC;IAC5D,OAAO,CAAC,cAAc,CAAC,CAAgC;IACvD,OAAO,CAAC,aAAa,CAKb;gBAEI,SAAS,EAAE,MAAM,EAAE;IAM/B;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAkBpB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAY9B;;;OAGG;YACW,uBAAuB;IAmBrC;;OAEG;IACH,OAAO,CAAC,cAAc;IAUhB,UAAU,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAwB/C,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,SAAS,CACb,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,EACpC,MAAM,CAAC,EAAE,MAAM,IAAI,GAClB,OAAO,CAAC,IAAI,CAAC;IAQhB,WAAW,IAAI,IAAI;CAIpB"}
|
|
@@ -1,27 +1,102 @@
|
|
|
1
1
|
import { SimplePool } from 'nostr-tools';
|
|
2
2
|
import { sleep } from '../core/utils/utils.js';
|
|
3
|
+
import { createLogger } from '../core/utils/logger.js';
|
|
4
|
+
const logger = createLogger('relay');
|
|
3
5
|
/**
|
|
4
6
|
* A RelayHandler implementation that uses a SimplePool to manage connections and subscriptions.
|
|
7
|
+
* Implements exponential backoff for reconnection attempts when relays drop connections.
|
|
5
8
|
* @argument relayUrls - An array of relay URLs to connect to.
|
|
6
9
|
* @returns A RelayHandler implementation that uses a SimplePool to manage connections and subscriptions.
|
|
7
10
|
*/
|
|
8
11
|
export class SimpleRelayPool {
|
|
9
12
|
constructor(relayUrls) {
|
|
13
|
+
this.reconnectIntervals = new Map();
|
|
10
14
|
this.subscriptions = [];
|
|
11
15
|
this.relayUrls = relayUrls;
|
|
12
16
|
this.pool = new SimplePool();
|
|
17
|
+
this.startReconnectLoop();
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Starts a loop that periodically checks connection status and reconnects if needed
|
|
21
|
+
* using exponential backoff strategy.
|
|
22
|
+
*/
|
|
23
|
+
startReconnectLoop() {
|
|
24
|
+
// Clear any existing timer
|
|
25
|
+
if (this.reconnectTimer) {
|
|
26
|
+
clearTimeout(this.reconnectTimer);
|
|
27
|
+
}
|
|
28
|
+
// Check all relays every 5 seconds
|
|
29
|
+
this.reconnectTimer = setTimeout(() => {
|
|
30
|
+
this.relayUrls.forEach((url) => {
|
|
31
|
+
const normalizedUrl = new URL(url).href;
|
|
32
|
+
if (!this.pool.listConnectionStatus().get(normalizedUrl)) {
|
|
33
|
+
this.handleDisconnectedRelay(url);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
this.startReconnectLoop(); // Schedule next check
|
|
37
|
+
}, 5000);
|
|
13
38
|
}
|
|
14
39
|
async connect() {
|
|
15
|
-
|
|
40
|
+
// Connect to all relays with exponential backoff tracking
|
|
41
|
+
await Promise.all(this.relayUrls.map(async (url) => {
|
|
16
42
|
const normalizedUrl = new URL(url).href;
|
|
17
43
|
if (!this.pool.listConnectionStatus().get(normalizedUrl)) {
|
|
18
|
-
this.
|
|
44
|
+
await this.handleDisconnectedRelay(url);
|
|
19
45
|
}
|
|
46
|
+
}));
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Handles a disconnected relay with exponential backoff strategy.
|
|
50
|
+
* @param url - The relay URL to reconnect to
|
|
51
|
+
*/
|
|
52
|
+
async handleDisconnectedRelay(url) {
|
|
53
|
+
const normalizedUrl = new URL(url).href;
|
|
54
|
+
const currentInterval = this.reconnectIntervals.get(normalizedUrl) || 1000;
|
|
55
|
+
this.pool['relays'].delete(normalizedUrl);
|
|
56
|
+
try {
|
|
57
|
+
await this.pool.ensureRelay(url, { connectionTimeout: 5000 });
|
|
58
|
+
// Reset backoff interval on successful connection
|
|
59
|
+
this.reconnectIntervals.delete(normalizedUrl);
|
|
60
|
+
// Resubscribe to all active subscriptions after successful reconnection
|
|
61
|
+
this.resubscribeAll();
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
logger.error("Can't connect to relay", error);
|
|
65
|
+
// Double the interval for next attempt (exponential backoff), capped at 30 seconds
|
|
66
|
+
const nextInterval = Math.min(currentInterval * 2, 30000);
|
|
67
|
+
this.reconnectIntervals.set(normalizedUrl, nextInterval);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Resubscribes to all active subscriptions after relay reconnection
|
|
72
|
+
*/
|
|
73
|
+
resubscribeAll() {
|
|
74
|
+
this.subscriptions.forEach((sub) => {
|
|
75
|
+
if (sub.closer)
|
|
76
|
+
sub.closer.close();
|
|
77
|
+
sub.closer = this.pool.subscribeMany(this.relayUrls, sub.filters, {
|
|
78
|
+
onevent: sub.onEvent,
|
|
79
|
+
oneose: sub.onEose,
|
|
80
|
+
});
|
|
20
81
|
});
|
|
21
82
|
}
|
|
22
83
|
async disconnect(relayUrls) {
|
|
23
84
|
if (!relayUrls) {
|
|
24
85
|
relayUrls = this.relayUrls;
|
|
86
|
+
// Clear all reconnect intervals when disconnecting all relays
|
|
87
|
+
this.reconnectIntervals.clear();
|
|
88
|
+
// Clear the reconnect loop timer
|
|
89
|
+
if (this.reconnectTimer) {
|
|
90
|
+
clearTimeout(this.reconnectTimer);
|
|
91
|
+
this.reconnectTimer = undefined;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
// Clear reconnect intervals for specific relays
|
|
96
|
+
relayUrls.forEach((url) => {
|
|
97
|
+
const normalizedUrl = new URL(url).href;
|
|
98
|
+
this.reconnectIntervals.delete(normalizedUrl);
|
|
99
|
+
});
|
|
25
100
|
}
|
|
26
101
|
this.pool.close(relayUrls);
|
|
27
102
|
await sleep(100);
|
|
@@ -30,16 +105,15 @@ export class SimpleRelayPool {
|
|
|
30
105
|
await Promise.all(this.pool.publish(this.relayUrls, event));
|
|
31
106
|
}
|
|
32
107
|
async subscribe(filters, onEvent, onEose) {
|
|
33
|
-
const
|
|
108
|
+
const closer = this.pool.subscribeMany(this.relayUrls, filters, {
|
|
34
109
|
onevent: onEvent,
|
|
35
110
|
oneose: onEose,
|
|
36
111
|
});
|
|
37
|
-
this.subscriptions.push(
|
|
112
|
+
this.subscriptions.push({ filters, onEvent, onEose, closer });
|
|
38
113
|
}
|
|
39
114
|
unsubscribe() {
|
|
40
|
-
this.subscriptions.forEach((sub) => {
|
|
41
|
-
|
|
42
|
-
});
|
|
115
|
+
this.subscriptions.forEach((sub) => { var _a; return (_a = sub.closer) === null || _a === void 0 ? void 0 : _a.close(); });
|
|
116
|
+
this.subscriptions = [];
|
|
43
117
|
}
|
|
44
118
|
}
|
|
45
119
|
//# sourceMappingURL=simple-relay-pool.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simple-relay-pool.js","sourceRoot":"","sources":["../../../src/relay/simple-relay-pool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAgC,MAAM,aAAa,CAAC;AAGvE,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"simple-relay-pool.js","sourceRoot":"","sources":["../../../src/relay/simple-relay-pool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAgC,MAAM,aAAa,CAAC;AAGvE,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;AAErC;;;;;GAKG;AACH,MAAM,OAAO,eAAe;IAY1B,YAAY,SAAmB;QATvB,uBAAkB,GAAwB,IAAI,GAAG,EAAE,CAAC;QAEpD,kBAAa,GAKhB,EAAE,CAAC;QAGN,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,IAAI,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC5B,CAAC;IAED;;;OAGG;IACK,kBAAkB;QACxB,2BAA2B;QAC3B,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACpC,CAAC;QAED,mCAAmC;QACnC,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC,GAAG,EAAE;YACpC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;gBAC7B,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACxC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;oBACzD,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC;gBACpC,CAAC;YACH,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC,sBAAsB;QACnD,CAAC,EAAE,IAAI,CAAC,CAAC;IACX,CAAC;IAED,KAAK,CAAC,OAAO;QACX,0DAA0D;QAC1D,MAAM,OAAO,CAAC,GAAG,CACf,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YAC/B,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACxC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;gBACzD,MAAM,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,uBAAuB,CAAC,GAAW;QAC/C,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;QACxC,MAAM,eAAe,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC;QAC3E,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QAC1C,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9D,kDAAkD;YAClD,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;YAE9C,wEAAwE;YACxE,IAAI,CAAC,cAAc,EAAE,CAAC;QACxB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;YAC9C,mFAAmF;YACnF,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,eAAe,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;YAC1D,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED;;OAEG;IACK,cAAc;QACpB,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YACjC,IAAI,GAAG,CAAC,MAAM;gBAAE,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YACnC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,OAAO,EAAE;gBAChE,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,MAAM,EAAE,GAAG,CAAC,MAAM;aACnB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,SAAoB;QACnC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;YAE3B,8DAA8D;YAC9D,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,CAAC;YAEhC,iCAAiC;YACjC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBACxB,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;gBAClC,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;YAClC,CAAC;QACH,CAAC;aAAM,CAAC;YACN,gDAAgD;YAChD,SAAS,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;gBACxB,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACxC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;YAChD,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC3B,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,KAAiB;QAC7B,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,SAAS,CACb,OAAiB,EACjB,OAAoC,EACpC,MAAmB;QAEnB,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE;YAC9D,OAAO,EAAE,OAAO;YAChB,MAAM,EAAE,MAAM;SACf,CAAC,CAAC;QACH,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,WAAW;QACT,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,WAAC,OAAA,MAAA,GAAG,CAAC,MAAM,0CAAE,KAAK,EAAE,CAAA,EAAA,CAAC,CAAC;QACzD,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;IAC1B,CAAC;CACF"}
|
|
@@ -9,8 +9,14 @@ export declare class PrivateKeySigner implements NostrSigner {
|
|
|
9
9
|
private readonly privateKey;
|
|
10
10
|
private readonly publicKey;
|
|
11
11
|
constructor(privateKey: string);
|
|
12
|
-
getSecretKey(): Promise<Uint8Array>;
|
|
13
12
|
getPublicKey(): Promise<string>;
|
|
14
13
|
signEvent(event: UnsignedEvent): Promise<NostrEvent>;
|
|
14
|
+
/**
|
|
15
|
+
* NIP-44 encryption and decryption implementation
|
|
16
|
+
*/
|
|
17
|
+
nip44: {
|
|
18
|
+
encrypt: (pubkey: string, plaintext: string) => Promise<string>;
|
|
19
|
+
decrypt: (pubkey: string, ciphertext: string) => Promise<string>;
|
|
20
|
+
};
|
|
15
21
|
}
|
|
16
22
|
//# sourceMappingURL=private-key-signer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"private-key-signer.d.ts","sourceRoot":"","sources":["../../../src/signer/private-key-signer.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,UAAU,EACf,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"private-key-signer.d.ts","sourceRoot":"","sources":["../../../src/signer/private-key-signer.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,UAAU,EACf,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGpD;;;;GAIG;AACH,qBAAa,gBAAiB,YAAW,WAAW;IAClD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,UAAU,EAAE,MAAM;IAKxB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAI/B,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC;IAI1D;;OAEG;IACH,KAAK;0BACqB,MAAM,aAAa,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC;0BAQ3C,MAAM,cAAc,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC;MAOpE;CACH"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { hexToBytes } from '@noble/hashes/utils';
|
|
2
2
|
import { finalizeEvent, getPublicKey, } from 'nostr-tools';
|
|
3
|
+
import { nip44 } from 'nostr-tools';
|
|
3
4
|
/**
|
|
4
5
|
* A signer that uses a private key to sign events.
|
|
5
6
|
* @argument privateKey - The private key in HEX to use for signing.
|
|
@@ -7,12 +8,22 @@ import { finalizeEvent, getPublicKey, } from 'nostr-tools';
|
|
|
7
8
|
*/
|
|
8
9
|
export class PrivateKeySigner {
|
|
9
10
|
constructor(privateKey) {
|
|
11
|
+
/**
|
|
12
|
+
* NIP-44 encryption and decryption implementation
|
|
13
|
+
*/
|
|
14
|
+
this.nip44 = {
|
|
15
|
+
encrypt: async (pubkey, plaintext) => {
|
|
16
|
+
const conversationKey = nip44.v2.utils.getConversationKey(this.privateKey, pubkey);
|
|
17
|
+
return nip44.v2.encrypt(plaintext, conversationKey);
|
|
18
|
+
},
|
|
19
|
+
decrypt: async (pubkey, ciphertext) => {
|
|
20
|
+
const conversationKey = nip44.v2.utils.getConversationKey(this.privateKey, pubkey);
|
|
21
|
+
return nip44.v2.decrypt(ciphertext, conversationKey);
|
|
22
|
+
},
|
|
23
|
+
};
|
|
10
24
|
this.privateKey = hexToBytes(privateKey);
|
|
11
25
|
this.publicKey = getPublicKey(this.privateKey);
|
|
12
26
|
}
|
|
13
|
-
async getSecretKey() {
|
|
14
|
-
return this.privateKey;
|
|
15
|
-
}
|
|
16
27
|
async getPublicKey() {
|
|
17
28
|
return this.publicKey;
|
|
18
29
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"private-key-signer.js","sourceRoot":"","sources":["../../../src/signer/private-key-signer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EACL,aAAa,EACb,YAAY,GAGb,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"private-key-signer.js","sourceRoot":"","sources":["../../../src/signer/private-key-signer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EACL,aAAa,EACb,YAAY,GAGb,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC;;;;GAIG;AACH,MAAM,OAAO,gBAAgB;IAI3B,YAAY,UAAkB;QAa9B;;WAEG;QACH,UAAK,GAAG;YACN,OAAO,EAAE,KAAK,EAAE,MAAc,EAAE,SAAiB,EAAmB,EAAE;gBACpE,MAAM,eAAe,GAAG,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB,CACvD,IAAI,CAAC,UAAU,EACf,MAAM,CACP,CAAC;gBACF,OAAO,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;YACtD,CAAC;YAED,OAAO,EAAE,KAAK,EAAE,MAAc,EAAE,UAAkB,EAAmB,EAAE;gBACrE,MAAM,eAAe,GAAG,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB,CACvD,IAAI,CAAC,UAAU,EACf,MAAM,CACP,CAAC;gBACF,OAAO,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;YACvD,CAAC;SACF,CAAC;QA/BA,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;QACzC,IAAI,CAAC,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,KAAoB;QAClC,OAAO,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAC/C,CAAC;CAsBF"}
|
|
@@ -36,9 +36,9 @@ export declare abstract class BaseNostrTransport {
|
|
|
36
36
|
*/
|
|
37
37
|
protected subscribe(filters: Filter[], onEvent: (event: NostrEvent) => void | Promise<void>): Promise<void>;
|
|
38
38
|
/**
|
|
39
|
-
*
|
|
39
|
+
* Validates and converts a Nostr event to an MCP message.
|
|
40
40
|
*/
|
|
41
|
-
protected convertNostrEventToMcpMessage(event: NostrEvent): JSONRPCMessage;
|
|
41
|
+
protected convertNostrEventToMcpMessage(event: NostrEvent): JSONRPCMessage | null;
|
|
42
42
|
/**
|
|
43
43
|
* Converts an MCP message to a Nostr event and signs it.
|
|
44
44
|
*/
|
|
@@ -50,7 +50,7 @@ export declare abstract class BaseNostrTransport {
|
|
|
50
50
|
/**
|
|
51
51
|
* Creates and publishes a Nostr event for an MCP message.
|
|
52
52
|
*/
|
|
53
|
-
protected sendMcpMessage(message: JSONRPCMessage, recipientPublicKey: string, kind: number, tags?: NostrEvent['tags'],
|
|
53
|
+
protected sendMcpMessage(message: JSONRPCMessage, recipientPublicKey: string, kind: number, tags?: NostrEvent['tags'], isEncrypted?: boolean): Promise<string>;
|
|
54
54
|
/**
|
|
55
55
|
* Creates subscription filters for listening to messages targeting a specific pubkey.
|
|
56
56
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-nostr-transport.d.ts","sourceRoot":"","sources":["../../../src/transport/base-nostr-transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EACL,cAAc,EACd,WAAW,EACX,YAAY,EACb,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"base-nostr-transport.d.ts","sourceRoot":"","sources":["../../../src/transport/base-nostr-transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EACL,cAAc,EACd,WAAW,EACX,YAAY,EACb,MAAM,uBAAuB,CAAC;AAgB/B;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,WAAW,CAAC;IACpB,YAAY,EAAE,YAAY,CAAC;IAC3B,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED;;;GAGG;AACH,8BAAsB,kBAAkB;IACtC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IACvC,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IAC9C,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IAClD,SAAS,CAAC,WAAW,UAAS;gBAElB,OAAO,EAAE,yBAAyB;IAM9C;;OAEG;cACa,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IASxC;;OAEG;cACa,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAU3C;;OAEG;cACa,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAI/C;;OAEG;cACa,SAAS,CACvB,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GACnD,OAAO,CAAC,IAAI,CAAC;IAIhB;;OAEG;IACH,SAAS,CAAC,6BAA6B,CACrC,KAAK,EAAE,UAAU,GAChB,cAAc,GAAG,IAAI;IAwBxB;;OAEG;cACa,sBAAsB,CACpC,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,GACxB,OAAO,CAAC,UAAU,CAAC;IAMtB;;OAEG;cACa,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9D;;OAEG;cACa,cAAc,CAC5B,OAAO,EAAE,cAAc,EACvB,kBAAkB,EAAE,MAAM,EAC1B,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,EACzB,WAAW,CAAC,EAAE,OAAO,GACpB,OAAO,CAAC,MAAM,CAAC;IAoClB;;OAEG;IACH,SAAS,CAAC,yBAAyB,CACjC,YAAY,EAAE,MAAM,EACpB,iBAAiB,GAAE,OAAO,CAAC,MAAM,CAAM,GACtC,MAAM,EAAE;IAWX;;OAEG;IACH,SAAS,CAAC,mBAAmB,CAAC,eAAe,EAAE,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;IAK1E;;OAEG;IACH,SAAS,CAAC,kBAAkB,CAC1B,eAAe,EAAE,MAAM,EACvB,eAAe,EAAE,MAAM,GACtB,UAAU,CAAC,MAAM,CAAC;CAOtB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { EncryptionMode, } from '../core/interfaces.js';
|
|
2
2
|
import { CTXVM_MESSAGES_KIND, GIFT_WRAP_KIND, mcpToNostrEvent, NOSTR_TAGS, nostrEventToMcpMessage, encryptMessage, SERVER_ANNOUNCEMENT_KIND, TOOLS_LIST_KIND, RESOURCES_LIST_KIND, RESOURCETEMPLATES_LIST_KIND, PROMPTS_LIST_KIND, } from '../core/index.js';
|
|
3
|
+
import { validateMessage, validateMessageSize } from '../core/utils/utils.js';
|
|
3
4
|
/**
|
|
4
5
|
* Base class for Nostr-based transports that provides common functionality
|
|
5
6
|
* for managing Nostr connections, event conversion, and message handling.
|
|
@@ -46,10 +47,28 @@ export class BaseNostrTransport {
|
|
|
46
47
|
await this.relayHandler.subscribe(filters, onEvent);
|
|
47
48
|
}
|
|
48
49
|
/**
|
|
49
|
-
*
|
|
50
|
+
* Validates and converts a Nostr event to an MCP message.
|
|
50
51
|
*/
|
|
51
52
|
convertNostrEventToMcpMessage(event) {
|
|
52
|
-
|
|
53
|
+
try {
|
|
54
|
+
const message = nostrEventToMcpMessage(event);
|
|
55
|
+
if (!message) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
// Validate message structure
|
|
59
|
+
const validatedMessage = validateMessage(message);
|
|
60
|
+
if (!validatedMessage) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
// Validate message size
|
|
64
|
+
if (!validateMessageSize(event.content)) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
return validatedMessage;
|
|
68
|
+
}
|
|
69
|
+
catch (_a) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
53
72
|
}
|
|
54
73
|
/**
|
|
55
74
|
* Converts an MCP message to a Nostr event and signs it.
|
|
@@ -68,7 +87,7 @@ export class BaseNostrTransport {
|
|
|
68
87
|
/**
|
|
69
88
|
* Creates and publishes a Nostr event for an MCP message.
|
|
70
89
|
*/
|
|
71
|
-
async sendMcpMessage(message, recipientPublicKey, kind, tags,
|
|
90
|
+
async sendMcpMessage(message, recipientPublicKey, kind, tags, isEncrypted) {
|
|
72
91
|
const unencryptedKinds = [
|
|
73
92
|
SERVER_ANNOUNCEMENT_KIND,
|
|
74
93
|
TOOLS_LIST_KIND,
|
|
@@ -76,8 +95,21 @@ export class BaseNostrTransport {
|
|
|
76
95
|
RESOURCETEMPLATES_LIST_KIND,
|
|
77
96
|
PROMPTS_LIST_KIND,
|
|
78
97
|
];
|
|
79
|
-
|
|
80
|
-
|
|
98
|
+
let shouldEncrypt = true;
|
|
99
|
+
if (unencryptedKinds.includes(kind)) {
|
|
100
|
+
shouldEncrypt = false;
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
if (this.encryptionMode === EncryptionMode.OPTIONAL) {
|
|
104
|
+
shouldEncrypt = isEncrypted !== null && isEncrypted !== void 0 ? isEncrypted : true;
|
|
105
|
+
}
|
|
106
|
+
else if (this.encryptionMode === EncryptionMode.DISABLED) {
|
|
107
|
+
shouldEncrypt = false;
|
|
108
|
+
}
|
|
109
|
+
else if (this.encryptionMode === EncryptionMode.REQUIRED) {
|
|
110
|
+
shouldEncrypt = true;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
81
113
|
const event = await this.createSignedNostrEvent(message, kind, tags);
|
|
82
114
|
if (shouldEncrypt) {
|
|
83
115
|
const encryptedEvent = encryptMessage(JSON.stringify(event), recipientPublicKey);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-nostr-transport.js","sourceRoot":"","sources":["../../../src/transport/base-nostr-transport.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,cAAc,GAGf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,UAAU,EACV,sBAAsB,EACtB,cAAc,EACd,wBAAwB,EACxB,eAAe,EACf,mBAAmB,EACnB,2BAA2B,EAC3B,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"base-nostr-transport.js","sourceRoot":"","sources":["../../../src/transport/base-nostr-transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
import { type JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';
|
|
2
2
|
import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
|
|
3
|
-
import {
|
|
4
|
-
import { BaseNostrTransport } from './base-nostr-transport.js';
|
|
3
|
+
import { BaseNostrTransport, BaseNostrTransportOptions } from './base-nostr-transport.js';
|
|
5
4
|
/**
|
|
6
5
|
* Options for configuring the NostrClientTransport.
|
|
7
6
|
*/
|
|
8
|
-
export interface NostrTransportOptions {
|
|
9
|
-
signer: NostrSigner;
|
|
10
|
-
relayHandler: RelayHandler;
|
|
7
|
+
export interface NostrTransportOptions extends BaseNostrTransportOptions {
|
|
11
8
|
serverPubkey: string;
|
|
12
|
-
encryptionMode?: EncryptionMode;
|
|
13
9
|
}
|
|
14
10
|
/**
|
|
15
11
|
* A transport layer for CTXVM that uses Nostr events for communication.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nostr-client-transport.d.ts","sourceRoot":"","sources":["../../../src/transport/nostr-client-transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EACpB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;
|
|
1
|
+
{"version":3,"file":"nostr-client-transport.d.ts","sourceRoot":"","sources":["../../../src/transport/nostr-client-transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EACpB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAM/E,OAAO,EACL,kBAAkB,EAClB,yBAAyB,EAC1B,MAAM,2BAA2B,CAAC;AAOnC;;GAEG;AACH,MAAM,WAAW,qBAAsB,SAAQ,yBAAyB;IACtE,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,qBAAa,oBACX,SAAQ,kBACR,YAAW,SAAS;IAGb,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;IAC9C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAGxC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAc;gBAEpC,OAAO,EAAE,qBAAqB;IAM1C;;OAEG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAQnC;;OAEG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKnC;;;OAGG;IACU,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAOzD;;;;OAIG;YACW,aAAa;IAW3B;;OAEG;YACW,oBAAoB;IAoClC;;;;OAIG;IACH,OAAO,CAAC,cAAc;IActB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;CAY3B"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { NotificationSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
2
2
|
import { CTXVM_MESSAGES_KIND, GIFT_WRAP_KIND, decryptMessage, } from '../core/index.js';
|
|
3
|
-
import { BaseNostrTransport } from './base-nostr-transport.js';
|
|
3
|
+
import { BaseNostrTransport, } from './base-nostr-transport.js';
|
|
4
4
|
import { getNostrEventTag } from '../core/utils/serializers.js';
|
|
5
|
+
import { createLogger } from '../core/utils/logger.js';
|
|
6
|
+
const logger = createLogger('nostr-client-transport');
|
|
5
7
|
/**
|
|
6
8
|
* A transport layer for CTXVM that uses Nostr events for communication.
|
|
7
9
|
* It implements the Transport interface from the @modelcontextprotocol/sdk.
|
|
@@ -57,15 +59,15 @@ export class NostrClientTransport extends BaseNostrTransport {
|
|
|
57
59
|
let nostrEvent = event;
|
|
58
60
|
// Handle encrypted messages
|
|
59
61
|
if (event.kind === GIFT_WRAP_KIND) {
|
|
60
|
-
const
|
|
61
|
-
if (!secretKey) {
|
|
62
|
-
throw new Error('Secret key is not available for decryption.');
|
|
63
|
-
}
|
|
64
|
-
const decryptedContent = decryptMessage(event, secretKey);
|
|
62
|
+
const decryptedContent = await decryptMessage(event, this.signer);
|
|
65
63
|
nostrEvent = JSON.parse(decryptedContent);
|
|
66
64
|
}
|
|
67
65
|
// Process the resulting event
|
|
68
66
|
const mcpMessage = this.convertNostrEventToMcpMessage(nostrEvent);
|
|
67
|
+
if (!mcpMessage) {
|
|
68
|
+
logger.error('Skipping invalid Nostr event with malformed JSON content');
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
69
71
|
const eTag = getNostrEventTag(nostrEvent.tags, 'e');
|
|
70
72
|
if (eTag) {
|
|
71
73
|
this.handleResponse(eTag, mcpMessage);
|
|
@@ -75,7 +77,7 @@ export class NostrClientTransport extends BaseNostrTransport {
|
|
|
75
77
|
}
|
|
76
78
|
}
|
|
77
79
|
catch (error) {
|
|
78
|
-
|
|
80
|
+
logger.error('Error handling incoming Nostr event:', error);
|
|
79
81
|
(_a = this.onerror) === null || _a === void 0 ? void 0 : _a.call(this, error instanceof Error
|
|
80
82
|
? error
|
|
81
83
|
: new Error('Failed to handle incoming Nostr event'));
|
|
@@ -93,7 +95,7 @@ export class NostrClientTransport extends BaseNostrTransport {
|
|
|
93
95
|
this.pendingRequestIds.delete(correlatedEventId);
|
|
94
96
|
}
|
|
95
97
|
else {
|
|
96
|
-
|
|
98
|
+
logger.error(`Received Nostr event with unexpected 'e' tag: ${correlatedEventId}.`);
|
|
97
99
|
}
|
|
98
100
|
}
|
|
99
101
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nostr-client-transport.js","sourceRoot":"","sources":["../../../src/transport/nostr-client-transport.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,GAEnB,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"nostr-client-transport.js","sourceRoot":"","sources":["../../../src/transport/nostr-client-transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nostr-server-transport.d.ts","sourceRoot":"","sources":["../../../src/transport/nostr-server-transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAYL,KAAK,cAAc,EAIpB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAC/E,OAAO,EACL,kBAAkB,EAClB,yBAAyB,EAC1B,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"nostr-server-transport.d.ts","sourceRoot":"","sources":["../../../src/transport/nostr-server-transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAYL,KAAK,cAAc,EAIpB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAC/E,OAAO,EACL,kBAAkB,EAClB,yBAAyB,EAC1B,MAAM,2BAA2B,CAAC;AAmBnC;;GAEG;AACH,MAAM,WAAW,2BAA4B,SAAQ,yBAAyB;IAC5E,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAYD;;;;;GAKG;AACH,qBAAa,oBACX,SAAQ,kBACR,YAAW,SAAS;IAEb,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;IAC9C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAExC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAoC;IACnE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAU;IAC1C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAW;IAC9C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAa;gBAE7B,OAAO,EAAE,2BAA2B;IAOhD;;;OAGG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAanC;;OAEG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAMnC;;;OAGG;IACU,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAYzD;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAsB3B;;;;OAIG;YACW,SAAS;IAkDvB;;;;;OAKG;IACH,OAAO,CAAC,wBAAwB;IAoBhC;;;;;OAKG;IACH,OAAO,CAAC,qBAAqB;IAmB7B;;;;OAIG;IACH,OAAO,CAAC,0BAA0B;IAYlC;;;OAGG;YACW,cAAc;IA8E5B;;;OAGG;YACW,kBAAkB;IAiChC;;;;;OAKG;IACU,gBAAgB,CAC3B,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,cAAc,EAC5B,iBAAiB,CAAC,EAAE,MAAM,GACzB,OAAO,CAAC,IAAI,CAAC;IAqBhB;;;;;OAKG;YACW,oBAAoB;IAQlC;;;OAGG;YACW,oBAAoB;IAoBlC;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAU9B;;;;OAIG;IACH,OAAO,CAAC,wBAAwB;IAoChC;;;;OAIG;IACI,uBAAuB,CAAC,SAAS,GAAE,MAAe,GAAG,MAAM;CAgBnE"}
|
|
@@ -2,6 +2,8 @@ import { InitializeResultSchema, isJSONRPCRequest, isJSONRPCResponse, isJSONRPCN
|
|
|
2
2
|
import { BaseNostrTransport, } from './base-nostr-transport.js';
|
|
3
3
|
import { announcementMethods, CTXVM_MESSAGES_KIND, GIFT_WRAP_KIND, NOSTR_TAGS, PROMPTS_LIST_KIND, RESOURCES_LIST_KIND, RESOURCETEMPLATES_LIST_KIND, SERVER_ANNOUNCEMENT_KIND, TOOLS_LIST_KIND, decryptMessage, } from '../core/index.js';
|
|
4
4
|
import { EncryptionMode } from '../core/interfaces.js';
|
|
5
|
+
import { createLogger } from '../core/utils/logger.js';
|
|
6
|
+
const logger = createLogger('nostr-server-transport');
|
|
5
7
|
/**
|
|
6
8
|
* A server-side transport layer for CTXVM that uses Nostr events for communication.
|
|
7
9
|
* This transport listens for incoming MCP requests via Nostr events and can send
|
|
@@ -308,15 +310,11 @@ export class NostrServerTransport extends BaseNostrTransport {
|
|
|
308
310
|
async handleEncryptedEvent(event) {
|
|
309
311
|
var _a;
|
|
310
312
|
if (this.encryptionMode === EncryptionMode.DISABLED) {
|
|
311
|
-
|
|
313
|
+
logger.error(`Received encrypted message from ${event.pubkey} but encryption is disabled. Ignoring.`);
|
|
312
314
|
return;
|
|
313
315
|
}
|
|
314
316
|
try {
|
|
315
|
-
const
|
|
316
|
-
if (!secretKey) {
|
|
317
|
-
throw new Error('Server secret key is unavailable for decryption.');
|
|
318
|
-
}
|
|
319
|
-
const decryptedJson = decryptMessage(event, secretKey);
|
|
317
|
+
const decryptedJson = await decryptMessage(event, this.signer);
|
|
320
318
|
const currentEvent = JSON.parse(decryptedJson);
|
|
321
319
|
this.authorizeAndProcessEvent(currentEvent, true);
|
|
322
320
|
}
|
|
@@ -332,7 +330,7 @@ export class NostrServerTransport extends BaseNostrTransport {
|
|
|
332
330
|
*/
|
|
333
331
|
handleUnencryptedEvent(event) {
|
|
334
332
|
if (this.encryptionMode === EncryptionMode.REQUIRED) {
|
|
335
|
-
|
|
333
|
+
logger.error(`Received unencrypted message from ${event.pubkey} but encryption is required. Ignoring.`);
|
|
336
334
|
return;
|
|
337
335
|
}
|
|
338
336
|
this.authorizeAndProcessEvent(event, false);
|
|
@@ -346,10 +344,14 @@ export class NostrServerTransport extends BaseNostrTransport {
|
|
|
346
344
|
var _a, _b;
|
|
347
345
|
if (((_a = this.allowedPublicKeys) === null || _a === void 0 ? void 0 : _a.length) &&
|
|
348
346
|
!this.allowedPublicKeys.includes(event.pubkey)) {
|
|
349
|
-
|
|
347
|
+
logger.error(`Unauthorized message from ${event.pubkey}. Ignoring.`);
|
|
350
348
|
return;
|
|
351
349
|
}
|
|
352
350
|
const mcpMessage = this.convertNostrEventToMcpMessage(event);
|
|
351
|
+
if (!mcpMessage) {
|
|
352
|
+
logger.error('Skipping invalid Nostr event with malformed JSON content');
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
353
355
|
const now = Date.now();
|
|
354
356
|
const session = this.getOrCreateClientSession(event.pubkey, now, isEncrypted);
|
|
355
357
|
session.lastActivity = now;
|