@contextvm/sdk 0.1.0 → 0.1.2
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 +65 -0
- package/dist/esm/core/constants.d.ts.map +1 -0
- package/dist/esm/core/constants.js +70 -0
- package/dist/esm/core/constants.js.map +1 -0
- package/dist/esm/core/encryption.d.ts +18 -0
- package/dist/esm/core/encryption.d.ts.map +1 -0
- package/dist/esm/core/encryption.js +40 -0
- package/dist/esm/core/encryption.js.map +1 -0
- package/dist/esm/core/index.d.ts +5 -0
- package/dist/esm/core/index.d.ts.map +1 -0
- package/dist/esm/core/index.js +5 -0
- package/dist/esm/core/index.js.map +1 -0
- package/dist/esm/core/interfaces.d.ts +39 -0
- package/dist/esm/core/interfaces.d.ts.map +1 -0
- package/dist/esm/core/interfaces.js +13 -0
- package/dist/esm/core/interfaces.js.map +1 -0
- package/dist/esm/core/utils/serializers.d.ts +29 -0
- package/dist/esm/core/utils/serializers.d.ts.map +1 -0
- package/dist/esm/core/utils/serializers.js +46 -0
- package/dist/esm/core/utils/serializers.js.map +1 -0
- package/dist/esm/gateway/index.d.ts +60 -0
- package/dist/esm/gateway/index.d.ts.map +1 -0
- package/dist/esm/gateway/index.js +110 -0
- package/dist/esm/gateway/index.js.map +1 -0
- package/dist/esm/index.d.ts +7 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/proxy/index.d.ts +42 -0
- package/dist/esm/proxy/index.d.ts.map +1 -0
- package/dist/esm/proxy/index.js +59 -0
- package/dist/esm/proxy/index.js.map +1 -0
- package/dist/esm/proxy/proxy-server.d.ts +3 -0
- package/dist/esm/proxy/proxy-server.d.ts.map +1 -0
- package/dist/esm/proxy/proxy-server.js +55 -0
- package/dist/esm/proxy/proxy-server.js.map +1 -0
- package/dist/esm/relay/index.d.ts +2 -0
- package/dist/esm/relay/index.d.ts.map +1 -0
- package/dist/esm/relay/index.js +2 -0
- package/dist/esm/relay/index.js.map +1 -0
- package/dist/esm/relay/simple-relay-pool.d.ts +19 -0
- package/dist/esm/relay/simple-relay-pool.d.ts.map +1 -0
- package/dist/esm/relay/simple-relay-pool.js +44 -0
- package/dist/esm/relay/simple-relay-pool.js.map +1 -0
- package/dist/esm/signer/index.d.ts +2 -0
- package/dist/esm/signer/index.d.ts.map +1 -0
- package/dist/esm/signer/index.js +2 -0
- package/dist/esm/signer/index.js.map +1 -0
- package/dist/esm/signer/private-key-signer.d.ts +16 -0
- package/dist/esm/signer/private-key-signer.d.ts.map +1 -0
- package/dist/esm/signer/private-key-signer.js +23 -0
- package/dist/esm/signer/private-key-signer.js.map +1 -0
- package/dist/esm/transport/base-nostr-transport.d.ts +67 -0
- package/dist/esm/transport/base-nostr-transport.d.ts.map +1 -0
- package/dist/esm/transport/base-nostr-transport.js +122 -0
- package/dist/esm/transport/base-nostr-transport.js.map +1 -0
- package/dist/esm/transport/index.d.ts +4 -0
- package/dist/esm/transport/index.d.ts.map +1 -0
- package/dist/esm/transport/index.js +4 -0
- package/dist/esm/transport/index.js.map +1 -0
- package/dist/esm/transport/nostr-client-transport.d.ts +60 -0
- package/dist/esm/transport/nostr-client-transport.d.ts.map +1 -0
- package/dist/esm/transport/nostr-client-transport.js +116 -0
- package/dist/esm/transport/nostr-client-transport.js.map +1 -0
- package/dist/esm/transport/nostr-server-transport.d.ts +128 -0
- package/dist/esm/transport/nostr-server-transport.d.ts.map +1 -0
- package/dist/esm/transport/nostr-server-transport.js +383 -0
- package/dist/esm/transport/nostr-server-transport.js.map +1 -0
- package/package.json +4 -3
- package/COPYING.LESSER +0 -165
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { NostrClientTransport, } from '../transport/nostr-client-transport.js';
|
|
2
|
+
/**
|
|
3
|
+
* `NostrMCPProxy` acts as a bridge between a local MCP Host
|
|
4
|
+
* and a remote MCP Server accessible via the Nostr network.
|
|
5
|
+
*
|
|
6
|
+
* It listens for MCP messages from the local host, forwards them over Nostr,
|
|
7
|
+
* and relays the responses back.
|
|
8
|
+
*/
|
|
9
|
+
export class NostrMCPProxy {
|
|
10
|
+
constructor(options) {
|
|
11
|
+
this.mcpHostTransport = options.mcpHostTransport;
|
|
12
|
+
this.nostrTransport = new NostrClientTransport(options.nostrTransportOptions);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Starts the proxy, establishing connections to both the local MCP host
|
|
16
|
+
* and the remote Nostr transport.
|
|
17
|
+
*
|
|
18
|
+
* @returns Promise that resolves when both transports are started
|
|
19
|
+
*/
|
|
20
|
+
async start() {
|
|
21
|
+
// Set up message handlers
|
|
22
|
+
this.setupEventHandlers();
|
|
23
|
+
// Start both transports
|
|
24
|
+
await Promise.all([
|
|
25
|
+
this.mcpHostTransport.start(),
|
|
26
|
+
this.nostrTransport.start(),
|
|
27
|
+
]);
|
|
28
|
+
console.log('NostrMCPProxy started.');
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Stops the proxy and closes all connections.
|
|
32
|
+
*
|
|
33
|
+
* @returns Promise that resolves when both transports are closed
|
|
34
|
+
*/
|
|
35
|
+
async stop() {
|
|
36
|
+
await this.mcpHostTransport.close();
|
|
37
|
+
await this.nostrTransport.close();
|
|
38
|
+
console.log('NostrMCPProxy stopped.');
|
|
39
|
+
}
|
|
40
|
+
setupEventHandlers() {
|
|
41
|
+
// Forward messages from the local host to Nostr.
|
|
42
|
+
this.mcpHostTransport.onmessage = (message) => {
|
|
43
|
+
this.nostrTransport
|
|
44
|
+
.send(message)
|
|
45
|
+
.catch((err) => console.error('Error sending message to Nostr:', err));
|
|
46
|
+
};
|
|
47
|
+
this.mcpHostTransport.onerror = (err) => console.error('MCP Host Transport Error:', err);
|
|
48
|
+
this.mcpHostTransport.onclose = () => console.log('MCP Host Transport closed');
|
|
49
|
+
// Forward messages from Nostr back to the local host.
|
|
50
|
+
this.nostrTransport.onmessage = (message) => {
|
|
51
|
+
this.mcpHostTransport
|
|
52
|
+
.send(message)
|
|
53
|
+
.catch((err) => console.error('Error sending message to local host:', err));
|
|
54
|
+
};
|
|
55
|
+
this.nostrTransport.onerror = (err) => console.error('Nostr Transport Error:', err);
|
|
56
|
+
this.nostrTransport.onclose = () => console.log('Nostr Transport closed');
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/proxy/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,oBAAoB,GAErB,MAAM,wCAAwC,CAAC;AAgBhD;;;;;;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,OAAO,CAAC,GAAG,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,OAAO,CAAC,GAAG,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,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC3E,CAAC,CAAC;QACF,IAAI,CAAC,gBAAgB,CAAC,OAAO,GAAG,CAAC,GAAG,EAAE,EAAE,CACtC,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,GAAG,CAAC,CAAC;QAClD,IAAI,CAAC,gBAAgB,CAAC,OAAO,GAAG,GAAG,EAAE,CACnC,OAAO,CAAC,GAAG,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,OAAO,CAAC,KAAK,CAAC,sCAAsC,EAAE,GAAG,CAAC,CAC3D,CAAC;QACN,CAAC,CAAC;QACF,IAAI,CAAC,cAAc,CAAC,OAAO,GAAG,CAAC,GAAG,EAAE,EAAE,CACpC,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC;QAC/C,IAAI,CAAC,cAAc,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IAC5E,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-server.d.ts","sourceRoot":"","sources":["../../../src/proxy/proxy-server.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
|
+
import { NostrMCPProxy } from './index.js';
|
|
4
|
+
import { PrivateKeySigner } from '../signer/private-key-signer.js';
|
|
5
|
+
import { SimpleRelayPool } from '../relay/simple-relay-pool.js';
|
|
6
|
+
/**
|
|
7
|
+
* Proxy server that exposes a remote Nostr MCP server via stdio.
|
|
8
|
+
* This allows MCP clients to connect to remote servers through the Nostr network.
|
|
9
|
+
*/
|
|
10
|
+
async function main() {
|
|
11
|
+
// Get configuration from environment variables
|
|
12
|
+
const relayUrl = process.env.RELAY_URL || 'ws://localhost:7777';
|
|
13
|
+
const clientPrivateKey = process.env.CLIENT_PRIVATE_KEY;
|
|
14
|
+
const serverPubkey = process.env.SERVER_PUBKEY;
|
|
15
|
+
if (!clientPrivateKey) {
|
|
16
|
+
console.error('CLIENT_PRIVATE_KEY environment variable is required');
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
if (!serverPubkey) {
|
|
20
|
+
console.error('SERVER_PUBKEY environment variable is required');
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
// Set up stdio transport for the server
|
|
24
|
+
const transport = new StdioServerTransport();
|
|
25
|
+
// Create Nostr components
|
|
26
|
+
const signer = new PrivateKeySigner(clientPrivateKey);
|
|
27
|
+
const relayPool = new SimpleRelayPool([relayUrl]);
|
|
28
|
+
// Create and start the proxy
|
|
29
|
+
const proxy = new NostrMCPProxy({
|
|
30
|
+
mcpHostTransport: transport,
|
|
31
|
+
nostrTransportOptions: {
|
|
32
|
+
signer,
|
|
33
|
+
relayHandler: relayPool,
|
|
34
|
+
serverPubkey,
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
// Handle cleanup on process termination
|
|
38
|
+
process.on('SIGINT', async () => {
|
|
39
|
+
await proxy.stop();
|
|
40
|
+
process.exit(0);
|
|
41
|
+
});
|
|
42
|
+
process.on('SIGTERM', async () => {
|
|
43
|
+
await proxy.stop();
|
|
44
|
+
process.exit(0);
|
|
45
|
+
});
|
|
46
|
+
// Start the proxy
|
|
47
|
+
await proxy.start();
|
|
48
|
+
console.error('Proxy server started and connected to stdio');
|
|
49
|
+
}
|
|
50
|
+
// Run the server
|
|
51
|
+
main().catch((error) => {
|
|
52
|
+
console.error('Proxy server error:', error);
|
|
53
|
+
process.exit(1);
|
|
54
|
+
});
|
|
55
|
+
//# sourceMappingURL=proxy-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-server.js","sourceRoot":"","sources":["../../../src/proxy/proxy-server.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAEhE;;;GAGG;AACH,KAAK,UAAU,IAAI;IACjB,+CAA+C;IAC/C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,qBAAqB,CAAC;IAChE,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;IACxD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IAE/C,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,OAAO,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,wCAAwC;IACxC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAE7C,0BAA0B;IAC1B,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;IACtD,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IAElD,6BAA6B;IAC7B,MAAM,KAAK,GAAG,IAAI,aAAa,CAAC;QAC9B,gBAAgB,EAAE,SAAS;QAC3B,qBAAqB,EAAE;YACrB,MAAM;YACN,YAAY,EAAE,SAAS;YACvB,YAAY;SACb;KACF,CAAC,CAAC;IAEH,wCAAwC;IACxC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;QAC9B,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;QAC/B,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,kBAAkB;IAClB,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;IACpB,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;AAC/D,CAAC;AAED,iBAAiB;AACjB,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;IAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/relay/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/relay/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type Filter, type NostrEvent } from 'nostr-tools';
|
|
2
|
+
import { RelayHandler } from '../core/interfaces.js';
|
|
3
|
+
/**
|
|
4
|
+
* A RelayHandler implementation that uses a SimplePool to manage connections and subscriptions.
|
|
5
|
+
* @argument relayUrls - An array of relay URLs to connect to.
|
|
6
|
+
* @returns A RelayHandler implementation that uses a SimplePool to manage connections and subscriptions.
|
|
7
|
+
*/
|
|
8
|
+
export declare class SimpleRelayPool implements RelayHandler {
|
|
9
|
+
private readonly relayUrls;
|
|
10
|
+
private pool;
|
|
11
|
+
private subscriptions;
|
|
12
|
+
constructor(relayUrls: string[]);
|
|
13
|
+
connect(): Promise<void>;
|
|
14
|
+
disconnect(relayUrls?: string[]): Promise<void>;
|
|
15
|
+
publish(event: NostrEvent): Promise<void>;
|
|
16
|
+
subscribe(filters: Filter[], onEvent: (event: NostrEvent) => void, onEose?: () => void): Promise<void>;
|
|
17
|
+
unsubscribe(): void;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=simple-relay-pool.d.ts.map
|
|
@@ -0,0 +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;AAErD;;;;GAIG;AACH,qBAAa,eAAgB,YAAW,YAAY;IAClD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IACrC,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,aAAa,CAAmB;gBAE5B,SAAS,EAAE,MAAM,EAAE;IAKzB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IASxB,UAAU,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ/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;CAKpB"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { SimplePool } from 'nostr-tools';
|
|
2
|
+
/**
|
|
3
|
+
* A RelayHandler implementation that uses a SimplePool to manage connections and subscriptions.
|
|
4
|
+
* @argument relayUrls - An array of relay URLs to connect to.
|
|
5
|
+
* @returns A RelayHandler implementation that uses a SimplePool to manage connections and subscriptions.
|
|
6
|
+
*/
|
|
7
|
+
export class SimpleRelayPool {
|
|
8
|
+
constructor(relayUrls) {
|
|
9
|
+
this.subscriptions = [];
|
|
10
|
+
this.relayUrls = relayUrls;
|
|
11
|
+
this.pool = new SimplePool();
|
|
12
|
+
}
|
|
13
|
+
async connect() {
|
|
14
|
+
this.relayUrls.forEach((url) => {
|
|
15
|
+
const normalizedUrl = new URL(url).href;
|
|
16
|
+
if (!this.pool.listConnectionStatus().get(normalizedUrl)) {
|
|
17
|
+
this.pool.ensureRelay(url, { connectionTimeout: 5000 });
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
async disconnect(relayUrls) {
|
|
22
|
+
if (!relayUrls) {
|
|
23
|
+
relayUrls = this.relayUrls;
|
|
24
|
+
}
|
|
25
|
+
this.pool.close(relayUrls);
|
|
26
|
+
await Bun.sleep(100);
|
|
27
|
+
}
|
|
28
|
+
async publish(event) {
|
|
29
|
+
await Promise.all(this.pool.publish(this.relayUrls, event));
|
|
30
|
+
}
|
|
31
|
+
async subscribe(filters, onEvent, onEose) {
|
|
32
|
+
const sub = this.pool.subscribeMany(this.relayUrls, filters, {
|
|
33
|
+
onevent: onEvent,
|
|
34
|
+
oneose: onEose,
|
|
35
|
+
});
|
|
36
|
+
this.subscriptions.push(sub);
|
|
37
|
+
}
|
|
38
|
+
unsubscribe() {
|
|
39
|
+
this.subscriptions.forEach((sub) => {
|
|
40
|
+
sub.close();
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=simple-relay-pool.js.map
|
|
@@ -0,0 +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;AAIvE;;;;GAIG;AACH,MAAM,OAAO,eAAe;IAK1B,YAAY,SAAmB;QAFvB,kBAAa,GAAgB,EAAE,CAAC;QAGtC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,IAAI,GAAG,IAAI,UAAU,EAAE,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YAC7B,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,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,SAAoB;QACnC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAC7B,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC3B,MAAM,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACvB,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,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE;YAC3D,OAAO,EAAE,OAAO;YAChB,MAAM,EAAE,MAAM;SACf,CAAC,CAAC;QACH,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAED,WAAW;QACT,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YACjC,GAAG,CAAC,KAAK,EAAE,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/signer/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/signer/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type NostrEvent, type UnsignedEvent } from 'nostr-tools';
|
|
2
|
+
import { NostrSigner } from '../core/interfaces.js';
|
|
3
|
+
/**
|
|
4
|
+
* A signer that uses a private key to sign events.
|
|
5
|
+
* @argument privateKey - The private key to use for signing.
|
|
6
|
+
* @returns A signer that uses the provided private key to sign events.
|
|
7
|
+
*/
|
|
8
|
+
export declare class PrivateKeySigner implements NostrSigner {
|
|
9
|
+
private readonly privateKey;
|
|
10
|
+
private readonly publicKey;
|
|
11
|
+
constructor(privateKey: string);
|
|
12
|
+
getSecretKey(): Promise<Uint8Array>;
|
|
13
|
+
getPublicKey(): Promise<string>;
|
|
14
|
+
signEvent(event: UnsignedEvent): Promise<NostrEvent>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=private-key-signer.d.ts.map
|
|
@@ -0,0 +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;AAEpD;;;;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,UAAU,CAAC;IAInC,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAI/B,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC;CAG3D"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { hexToBytes } from '@noble/hashes/utils';
|
|
2
|
+
import { finalizeEvent, getPublicKey, } from 'nostr-tools';
|
|
3
|
+
/**
|
|
4
|
+
* A signer that uses a private key to sign events.
|
|
5
|
+
* @argument privateKey - The private key to use for signing.
|
|
6
|
+
* @returns A signer that uses the provided private key to sign events.
|
|
7
|
+
*/
|
|
8
|
+
export class PrivateKeySigner {
|
|
9
|
+
constructor(privateKey) {
|
|
10
|
+
this.privateKey = hexToBytes(privateKey);
|
|
11
|
+
this.publicKey = getPublicKey(this.privateKey);
|
|
12
|
+
}
|
|
13
|
+
async getSecretKey() {
|
|
14
|
+
return this.privateKey;
|
|
15
|
+
}
|
|
16
|
+
async getPublicKey() {
|
|
17
|
+
return this.publicKey;
|
|
18
|
+
}
|
|
19
|
+
async signEvent(event) {
|
|
20
|
+
return finalizeEvent(event, this.privateKey);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=private-key-signer.js.map
|
|
@@ -0,0 +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;AAGrB;;;;GAIG;AACH,MAAM,OAAO,gBAAgB;IAI3B,YAAY,UAAkB;QAC5B,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,UAAU,CAAC;IACzB,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;CACF"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
import type { Event as NostrEvent, Filter } from 'nostr-tools';
|
|
3
|
+
import { EncryptionMode, NostrSigner, RelayHandler } from '../core/interfaces.js';
|
|
4
|
+
/**
|
|
5
|
+
* Base options for configuring Nostr-based transports.
|
|
6
|
+
*/
|
|
7
|
+
export interface BaseNostrTransportOptions {
|
|
8
|
+
signer: NostrSigner;
|
|
9
|
+
relayHandler: RelayHandler;
|
|
10
|
+
encryptionMode?: EncryptionMode;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Base class for Nostr-based transports that provides common functionality
|
|
14
|
+
* for managing Nostr connections, event conversion, and message handling.
|
|
15
|
+
*/
|
|
16
|
+
export declare abstract class BaseNostrTransport {
|
|
17
|
+
protected readonly signer: NostrSigner;
|
|
18
|
+
protected readonly relayHandler: RelayHandler;
|
|
19
|
+
protected readonly encryptionMode: EncryptionMode;
|
|
20
|
+
protected isConnected: boolean;
|
|
21
|
+
constructor(options: BaseNostrTransportOptions);
|
|
22
|
+
/**
|
|
23
|
+
* Connects to the Nostr relay network.
|
|
24
|
+
*/
|
|
25
|
+
protected connect(): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Disconnects from the Nostr relay network.
|
|
28
|
+
*/
|
|
29
|
+
protected disconnect(): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Gets the public key from the signer.
|
|
32
|
+
*/
|
|
33
|
+
protected getPublicKey(): Promise<string>;
|
|
34
|
+
/**
|
|
35
|
+
* Sets up a subscription to listen for Nostr events.
|
|
36
|
+
*/
|
|
37
|
+
protected subscribe(filters: Filter[], onEvent: (event: NostrEvent) => void | Promise<void>): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Converts a Nostr event to an MCP message.
|
|
40
|
+
*/
|
|
41
|
+
protected convertNostrEventToMcpMessage(event: NostrEvent): JSONRPCMessage;
|
|
42
|
+
/**
|
|
43
|
+
* Converts an MCP message to a Nostr event and signs it.
|
|
44
|
+
*/
|
|
45
|
+
protected createSignedNostrEvent(message: JSONRPCMessage, kind: number, tags?: NostrEvent['tags']): Promise<NostrEvent>;
|
|
46
|
+
/**
|
|
47
|
+
* Publishes a signed Nostr event to the relay network.
|
|
48
|
+
*/
|
|
49
|
+
protected publishEvent(event: NostrEvent): Promise<void>;
|
|
50
|
+
/**
|
|
51
|
+
* Creates and publishes a Nostr event for an MCP message.
|
|
52
|
+
*/
|
|
53
|
+
protected sendMcpMessage(message: JSONRPCMessage, recipientPublicKey: string, kind: number, tags?: NostrEvent['tags'], forceEncryption?: boolean): Promise<string>;
|
|
54
|
+
/**
|
|
55
|
+
* Creates subscription filters for listening to messages targeting a specific pubkey.
|
|
56
|
+
*/
|
|
57
|
+
protected createSubscriptionFilters(targetPubkey: string, additionalFilters?: Partial<Filter>): Filter[];
|
|
58
|
+
/**
|
|
59
|
+
* Creates tags for targeting a specific recipient.
|
|
60
|
+
*/
|
|
61
|
+
protected createRecipientTags(recipientPubkey: string): NostrEvent['tags'];
|
|
62
|
+
/**
|
|
63
|
+
* Creates tags for responding to a specific event.
|
|
64
|
+
*/
|
|
65
|
+
protected createResponseTags(recipientPubkey: string, originalEventId: string): NostrEvent['tags'];
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=base-nostr-transport.d.ts.map
|
|
@@ -0,0 +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,KAAK,IAAI,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EACL,cAAc,EACd,WAAW,EACX,YAAY,EACb,MAAM,uBAAuB,CAAC;AAe/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,CAAC,KAAK,EAAE,UAAU,GAAG,cAAc;IAI1E;;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,eAAe,CAAC,EAAE,OAAO,GACxB,OAAO,CAAC,MAAM,CAAC;IA0BlB;;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"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { EncryptionMode, } from '../core/interfaces.js';
|
|
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
|
+
/**
|
|
4
|
+
* Base class for Nostr-based transports that provides common functionality
|
|
5
|
+
* for managing Nostr connections, event conversion, and message handling.
|
|
6
|
+
*/
|
|
7
|
+
export class BaseNostrTransport {
|
|
8
|
+
constructor(options) {
|
|
9
|
+
var _a;
|
|
10
|
+
this.isConnected = false;
|
|
11
|
+
this.signer = options.signer;
|
|
12
|
+
this.relayHandler = options.relayHandler;
|
|
13
|
+
this.encryptionMode = (_a = options.encryptionMode) !== null && _a !== void 0 ? _a : EncryptionMode.OPTIONAL;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Connects to the Nostr relay network.
|
|
17
|
+
*/
|
|
18
|
+
async connect() {
|
|
19
|
+
if (this.isConnected) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
await this.relayHandler.connect();
|
|
23
|
+
this.isConnected = true;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Disconnects from the Nostr relay network.
|
|
27
|
+
*/
|
|
28
|
+
async disconnect() {
|
|
29
|
+
if (!this.isConnected) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
this.relayHandler.unsubscribe();
|
|
33
|
+
await this.relayHandler.disconnect();
|
|
34
|
+
this.isConnected = false;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Gets the public key from the signer.
|
|
38
|
+
*/
|
|
39
|
+
async getPublicKey() {
|
|
40
|
+
return await this.signer.getPublicKey();
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Sets up a subscription to listen for Nostr events.
|
|
44
|
+
*/
|
|
45
|
+
async subscribe(filters, onEvent) {
|
|
46
|
+
await this.relayHandler.subscribe(filters, onEvent);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Converts a Nostr event to an MCP message.
|
|
50
|
+
*/
|
|
51
|
+
convertNostrEventToMcpMessage(event) {
|
|
52
|
+
return nostrEventToMcpMessage(event);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Converts an MCP message to a Nostr event and signs it.
|
|
56
|
+
*/
|
|
57
|
+
async createSignedNostrEvent(message, kind, tags) {
|
|
58
|
+
const pubkey = await this.getPublicKey();
|
|
59
|
+
const unsignedEvent = mcpToNostrEvent(message, pubkey, kind, tags);
|
|
60
|
+
return await this.signer.signEvent(unsignedEvent);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Publishes a signed Nostr event to the relay network.
|
|
64
|
+
*/
|
|
65
|
+
async publishEvent(event) {
|
|
66
|
+
await this.relayHandler.publish(event);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Creates and publishes a Nostr event for an MCP message.
|
|
70
|
+
*/
|
|
71
|
+
async sendMcpMessage(message, recipientPublicKey, kind, tags, forceEncryption) {
|
|
72
|
+
const unencryptedKinds = [
|
|
73
|
+
SERVER_ANNOUNCEMENT_KIND,
|
|
74
|
+
TOOLS_LIST_KIND,
|
|
75
|
+
RESOURCES_LIST_KIND,
|
|
76
|
+
RESOURCETEMPLATES_LIST_KIND,
|
|
77
|
+
PROMPTS_LIST_KIND,
|
|
78
|
+
];
|
|
79
|
+
const shouldEncrypt = (!unencryptedKinds.includes(kind) || forceEncryption) &&
|
|
80
|
+
this.encryptionMode !== EncryptionMode.DISABLED;
|
|
81
|
+
const event = await this.createSignedNostrEvent(message, kind, tags);
|
|
82
|
+
if (shouldEncrypt) {
|
|
83
|
+
const encryptedEvent = encryptMessage(JSON.stringify(event), recipientPublicKey);
|
|
84
|
+
await this.publishEvent(encryptedEvent);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
await this.publishEvent(event);
|
|
88
|
+
}
|
|
89
|
+
return event.id;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Creates subscription filters for listening to messages targeting a specific pubkey.
|
|
93
|
+
*/
|
|
94
|
+
createSubscriptionFilters(targetPubkey, additionalFilters = {}) {
|
|
95
|
+
return [
|
|
96
|
+
{
|
|
97
|
+
'#p': [targetPubkey],
|
|
98
|
+
kinds: [CTXVM_MESSAGES_KIND, GIFT_WRAP_KIND],
|
|
99
|
+
since: Math.floor(Date.now() / 1000),
|
|
100
|
+
...additionalFilters,
|
|
101
|
+
},
|
|
102
|
+
];
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Creates tags for targeting a specific recipient.
|
|
106
|
+
*/
|
|
107
|
+
createRecipientTags(recipientPubkey) {
|
|
108
|
+
const tags = [[NOSTR_TAGS.PUBKEY, recipientPubkey]];
|
|
109
|
+
return tags;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Creates tags for responding to a specific event.
|
|
113
|
+
*/
|
|
114
|
+
createResponseTags(recipientPubkey, originalEventId) {
|
|
115
|
+
const tags = [
|
|
116
|
+
[NOSTR_TAGS.PUBKEY, recipientPubkey],
|
|
117
|
+
[NOSTR_TAGS.EVENT_ID, originalEventId],
|
|
118
|
+
];
|
|
119
|
+
return tags;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=base-nostr-transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-nostr-transport.js","sourceRoot":"","sources":["../../../src/transport/base-nostr-transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/transport/index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2BAA2B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/transport/index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { type JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
|
|
3
|
+
import { EncryptionMode, NostrSigner, RelayHandler } from '../core/interfaces.js';
|
|
4
|
+
import { BaseNostrTransport } from './base-nostr-transport.js';
|
|
5
|
+
/**
|
|
6
|
+
* Options for configuring the NostrClientTransport.
|
|
7
|
+
*/
|
|
8
|
+
export interface NostrTransportOptions {
|
|
9
|
+
signer: NostrSigner;
|
|
10
|
+
relayHandler: RelayHandler;
|
|
11
|
+
serverPubkey: string;
|
|
12
|
+
encryptionMode?: EncryptionMode;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A transport layer for CTXVM that uses Nostr events for communication.
|
|
16
|
+
* It implements the Transport interface from the @modelcontextprotocol/sdk.
|
|
17
|
+
*/
|
|
18
|
+
export declare class NostrClientTransport extends BaseNostrTransport implements Transport {
|
|
19
|
+
onmessage?: (message: JSONRPCMessage) => void;
|
|
20
|
+
onclose?: () => void;
|
|
21
|
+
onerror?: (error: Error) => void;
|
|
22
|
+
private readonly serverPubkey;
|
|
23
|
+
private readonly pendingRequestIds;
|
|
24
|
+
constructor(options: NostrTransportOptions);
|
|
25
|
+
/**
|
|
26
|
+
* Starts the transport, connecting to the relay and setting up event listeners.
|
|
27
|
+
*/
|
|
28
|
+
start(): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Closes the transport, disconnecting from the relay.
|
|
31
|
+
*/
|
|
32
|
+
close(): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Sends a JSON-RPC message over the Nostr transport.
|
|
35
|
+
* @param message The JSON-RPC request or response to send.
|
|
36
|
+
*/
|
|
37
|
+
send(message: JSONRPCMessage): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Internal method to send a JSON-RPC message and get the resulting event ID.
|
|
40
|
+
* @param message The JSON-RPC message to send.
|
|
41
|
+
* @returns The ID of the published Nostr event.
|
|
42
|
+
*/
|
|
43
|
+
private _sendInternal;
|
|
44
|
+
/**
|
|
45
|
+
* Processes incoming Nostr events, routing them to the correct handler.
|
|
46
|
+
*/
|
|
47
|
+
private processIncomingEvent;
|
|
48
|
+
/**
|
|
49
|
+
* Handles response messages by correlating them with pending requests.
|
|
50
|
+
* @param correlatedEventId The event ID from the 'e' tag.
|
|
51
|
+
* @param mcpMessage The incoming MCP message.
|
|
52
|
+
*/
|
|
53
|
+
private handleResponse;
|
|
54
|
+
/**
|
|
55
|
+
* Handles notification messages.
|
|
56
|
+
* @param mcpMessage The incoming MCP message.
|
|
57
|
+
*/
|
|
58
|
+
private handleNotification;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=nostr-client-transport.d.ts.map
|
|
@@ -0,0 +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;AAE/E,OAAO,EACL,cAAc,EACd,WAAW,EACX,YAAY,EACb,MAAM,uBAAuB,CAAC;AAM/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAG/D;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,WAAW,CAAC;IACpB,YAAY,EAAE,YAAY,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;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;IAgClC;;;;OAIG;IACH,OAAO,CAAC,cAAc;IActB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;CAY3B"}
|