@voidly/agent-sdk 3.2.6 → 3.2.7

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.
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Post-Quantum + Ratchet Persistence — Future-proof encrypted messaging.
4
+ *
5
+ * Run: node examples/post-quantum.mjs
6
+ *
7
+ * Features demonstrated:
8
+ * 1. ML-KEM-768 hybrid key exchange (NIST FIPS 203) — quantum-resistant
9
+ * 2. Double Ratchet forward secrecy — compromise now can't decrypt past messages
10
+ * 3. Ratchet persistence — session survives agent restarts
11
+ * 4. Sealed sender — relay can't see who sent the message
12
+ * 5. Deniable auth — both parties can produce the signature (plausible deniability)
13
+ */
14
+ import { VoidlyAgent } from '@voidly/agent-sdk';
15
+
16
+ // ─── Register with full security config ─────────────────────────────────────
17
+ const alice = await VoidlyAgent.register(
18
+ { name: 'pq-alice', capabilities: ['chat', 'intel'] },
19
+ {
20
+ pq: true, // Enable ML-KEM-768 post-quantum hybrid
21
+ padding: true, // Pad all messages to power-of-2 (traffic analysis resistance)
22
+ sealedSender: true, // Hide sender DID from relay metadata
23
+ deniable: true, // HMAC signatures (both parties can produce — deniable)
24
+ persist: 'memory', // Ratchet state persists in memory (use 'file' or 'relay' for disk)
25
+ autoPin: true, // TOFU: pin first-seen keys, warn on change
26
+ }
27
+ );
28
+
29
+ const bob = await VoidlyAgent.register(
30
+ { name: 'pq-bob', capabilities: ['chat', 'analysis'] },
31
+ {
32
+ pq: true,
33
+ padding: true,
34
+ sealedSender: true,
35
+ deniable: true,
36
+ persist: 'memory',
37
+ autoPin: true,
38
+ }
39
+ );
40
+
41
+ console.log(`Alice: ${alice.did} (PQ + sealed + deniable)`);
42
+ console.log(`Bob: ${bob.did} (PQ + sealed + deniable)\n`);
43
+
44
+ // ─── Verify post-quantum is active ──────────────────────────────────────────
45
+ const threat = alice.threatModel();
46
+ console.log('Active protections:');
47
+ threat.protections.forEach(p => console.log(` ✓ ${p}`));
48
+ console.log('Known gaps:');
49
+ threat.gaps.forEach(g => console.log(` ⚠ ${g}`));
50
+
51
+ // ─── Send messages with full protection stack ───────────────────────────────
52
+ console.log('\nSending with PQ hybrid + Double Ratchet + sealed sender + padding...');
53
+ await alice.send(bob.did, 'Quantum-resistant hello from Alice', { threadId: 'pq-demo' });
54
+ await alice.send(bob.did, 'Even a quantum computer cannot decrypt this retroactively');
55
+
56
+ // Bob receives and decrypts
57
+ const messages = await bob.receive({ limit: 10 });
58
+ for (const msg of messages) {
59
+ console.log(`\n Bob received: "${msg.content}"`);
60
+ console.log(` From: ${msg.from.slice(0, 30)}...`);
61
+ console.log(` Signature valid: ${msg.signatureValid}`);
62
+ }
63
+
64
+ // ─── Demonstrate forward secrecy ────────────────────────────────────────────
65
+ console.log('\n─── Forward Secrecy Demo ───');
66
+ console.log('Ratchet advances with each message — past keys are deleted.');
67
+ console.log('Even if an attacker compromises the agent NOW, they cannot');
68
+ console.log('decrypt messages that were already received and processed.\n');
69
+
70
+ // Bob replies — DH ratchet advances
71
+ await bob.send(alice.did, 'Reply from Bob — ratchet advanced');
72
+ const replies = await alice.receive({ limit: 5 });
73
+ for (const r of replies) {
74
+ console.log(` Alice received: "${r.content}"`);
75
+ }
76
+
77
+ // ─── Credential export (includes ratchet state) ─────────────────────────────
78
+ console.log('\n─── Credential Export ───');
79
+ const creds = alice.exportCredentials();
80
+ console.log(` DID: ${creds.did}`);
81
+ console.log(` Signing key: ${creds.signingSecretKey.slice(0, 16)}...`);
82
+ console.log(` PQ enabled: ${!!creds.mlkemSecretKey}`);
83
+
84
+ // Restore agent from credentials (e.g., after restart)
85
+ const restored = VoidlyAgent.fromCredentials(creds, {
86
+ pq: true, padding: true, sealedSender: true, deniable: true, persist: 'memory',
87
+ });
88
+ console.log(` Restored DID: ${restored.did} (matches: ${restored.did === alice.did})`);
89
+
90
+ // ─── Flush ratchet state ────────────────────────────────────────────────────
91
+ await alice.flushRatchetState();
92
+ console.log('\n Ratchet state flushed to persistence backend.');
93
+
94
+ // Clean shutdown
95
+ alice.stopAll();
96
+ bob.stopAll();
97
+ restored.stopAll();
98
+
99
+ console.log('\n✓ Done — post-quantum hybrid encryption with forward secrecy.');
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * SSE Streaming — Real-time message delivery via Server-Sent Events.
4
+ *
5
+ * Run: node examples/sse-streaming.mjs
6
+ *
7
+ * Instead of polling, Bob opens an SSE connection to the relay.
8
+ * Messages arrive in near-real-time (~1s latency) with automatic reconnection.
9
+ * All decryption still happens client-side.
10
+ */
11
+ import { VoidlyAgent } from '@voidly/agent-sdk';
12
+
13
+ const alice = await VoidlyAgent.register({ name: 'sse-alice' });
14
+ const bob = await VoidlyAgent.register(
15
+ { name: 'sse-bob' },
16
+ { transport: ['sse', 'long-poll'] } // Prefer SSE, fall back to long-poll
17
+ );
18
+
19
+ console.log(`Alice: ${alice.did}`);
20
+ console.log(`Bob: ${bob.did} (SSE transport)\n`);
21
+
22
+ // Bob listens via SSE — messages arrive in near-real-time
23
+ const handle = bob.listen(
24
+ (msg) => {
25
+ console.log(` ← Bob received: "${msg.content}" from ${msg.from.slice(0, 24)}...`);
26
+ console.log(` Signature valid: ${msg.signatureValid}`);
27
+ },
28
+ {
29
+ interval: 2000, // Reconnect interval if SSE drops
30
+ adaptive: true, // Back off when idle
31
+ heartbeat: false, // Don't send pings
32
+ }
33
+ );
34
+
35
+ // Wait for SSE connection to establish
36
+ await new Promise(r => setTimeout(r, 1500));
37
+
38
+ // Alice sends a burst of messages
39
+ console.log('Alice sending 3 messages...');
40
+ await alice.send(bob.did, 'Message 1 — SSE delivery');
41
+ await alice.send(bob.did, 'Message 2 — near-real-time');
42
+ await alice.send(bob.did, 'Message 3 — all encrypted');
43
+
44
+ // Wait for delivery
45
+ await new Promise(r => setTimeout(r, 5000));
46
+
47
+ // Clean shutdown
48
+ handle.stop();
49
+ alice.stopAll();
50
+ bob.stopAll();
51
+
52
+ console.log('\n✓ Done — SSE streaming with E2E encryption.');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voidly/agent-sdk",
3
- "version": "3.2.6",
3
+ "version": "3.2.7",
4
4
  "description": "E2E encrypted agent-to-agent communication SDK — Double Ratchet, X3DH, deniable auth, ML-KEM-768 post-quantum, SSE streaming, ratchet persistence, multi-relay federation",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",