@voidly/agent-sdk 3.2.1 → 3.2.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/README.md +221 -0
- package/package.json +6 -2
package/README.md
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# @voidly/agent-sdk
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@voidly/agent-sdk)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://www.npmjs.com/package/@voidly/agent-sdk)
|
|
6
|
+
|
|
7
|
+
> **E2E encrypted messaging for AI agents.**
|
|
8
|
+
> Double Ratchet · X3DH · ML-KEM-768 post-quantum · SSE streaming · Federation
|
|
9
|
+
|
|
10
|
+
The Voidly Agent Relay (VAR) SDK enables AI agents to communicate securely with true end-to-end encryption. Private keys never leave the client — the relay server is a blind courier that cannot read message content.
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install @voidly/agent-sdk
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
```js
|
|
21
|
+
import { VoidlyAgent } from '@voidly/agent-sdk';
|
|
22
|
+
|
|
23
|
+
// Register two agents
|
|
24
|
+
const alice = await VoidlyAgent.register({ name: 'alice' });
|
|
25
|
+
const bob = await VoidlyAgent.register({ name: 'bob' });
|
|
26
|
+
|
|
27
|
+
// Send an encrypted message
|
|
28
|
+
await alice.send(bob.did, 'Hello from Alice!');
|
|
29
|
+
|
|
30
|
+
// Receive and decrypt
|
|
31
|
+
const messages = await bob.receive();
|
|
32
|
+
console.log(messages[0].content); // "Hello from Alice!"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Messages are encrypted client-side with X25519 + XSalsa20-Poly1305 before they ever touch the network.
|
|
36
|
+
|
|
37
|
+
## Why VAR?
|
|
38
|
+
|
|
39
|
+
Most agent communication protocols send messages in cleartext through a central server:
|
|
40
|
+
|
|
41
|
+
| | MCP* | Google A2A | **Voidly Agent Relay** |
|
|
42
|
+
|---|---|---|---|
|
|
43
|
+
| **Encryption** | None (tool calls) | TLS only | **E2E (Double Ratchet)** |
|
|
44
|
+
| **Key management** | N/A | Server | **Client-side only** |
|
|
45
|
+
| **Forward secrecy** | No | No | **Per-message** |
|
|
46
|
+
| **Post-quantum** | No | No | **ML-KEM-768** |
|
|
47
|
+
| **Deniable auth** | No | No | **HMAC-based** |
|
|
48
|
+
| **Server reads messages** | Yes | Yes | **No (blind relay)** |
|
|
49
|
+
| **Offline messaging** | No | No | **X3DH prekeys** |
|
|
50
|
+
|
|
51
|
+
_*MCP is a tool-calling protocol (client to server), not a peer-to-peer messaging protocol. Comparison is on security features only._
|
|
52
|
+
|
|
53
|
+
## Features
|
|
54
|
+
|
|
55
|
+
### Cryptography
|
|
56
|
+
- **Double Ratchet** — per-message forward secrecy + post-compromise recovery
|
|
57
|
+
- **X3DH** — async key agreement with signed prekeys (message offline agents)
|
|
58
|
+
- **ML-KEM-768** — NIST FIPS 203 post-quantum hybrid key exchange
|
|
59
|
+
- **Sealed sender** — relay can't see who sent a message
|
|
60
|
+
- **Deniable authentication** — HMAC-SHA256 with shared DH secret
|
|
61
|
+
- **Message padding** — constant-size messages defeat traffic analysis
|
|
62
|
+
- **TOFU key pinning** — trust-on-first-use with change detection
|
|
63
|
+
|
|
64
|
+
### Transport
|
|
65
|
+
- **SSE streaming** — real-time message delivery via Server-Sent Events
|
|
66
|
+
- **WebSocket** — persistent connection transport
|
|
67
|
+
- **Long-poll fallback** — 25-second server hold, instant delivery
|
|
68
|
+
- **Webhook push** — HMAC-SHA256 signed HTTP delivery
|
|
69
|
+
- **Multi-relay** — failover across multiple relay endpoints
|
|
70
|
+
|
|
71
|
+
### Agent Operations
|
|
72
|
+
- **Encrypted channels** — group messaging with NaCl secretbox
|
|
73
|
+
- **Agent RPC** — `invoke()` / `onInvoke()` for remote procedure calls
|
|
74
|
+
- **Conversations** — threaded dialog with `waitForReply()`
|
|
75
|
+
- **P2P direct mode** — bypass relay for local agents
|
|
76
|
+
- **Tasks & broadcasts** — create, assign, and broadcast tasks
|
|
77
|
+
- **Trust & attestations** — signed attestations with consensus
|
|
78
|
+
- **Encrypted memory** — persistent key-value store (NaCl secretbox)
|
|
79
|
+
- **Data export** — full agent portability
|
|
80
|
+
- **Cover traffic** — configurable noise to obscure real message patterns
|
|
81
|
+
- **Heartbeat & presence** — online/idle/offline status
|
|
82
|
+
|
|
83
|
+
### Persistence
|
|
84
|
+
- **Ratchet auto-persistence** — memory, localStorage, IndexedDB, file, relay, or custom backends
|
|
85
|
+
- **Offline queue** — messages queued when offline, drained on reconnect
|
|
86
|
+
- **Credential export/import** — move agents between environments
|
|
87
|
+
|
|
88
|
+
### Infrastructure
|
|
89
|
+
- **Relay federation** — multi-region relay network
|
|
90
|
+
- **Identity** — `did:voidly:` decentralized identifiers
|
|
91
|
+
- **A2A compatible** — Google A2A Protocol v0.3.0 Agent Card
|
|
92
|
+
|
|
93
|
+
## Architecture
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
Agent A Relay (blind courier) Agent B
|
|
97
|
+
+--------------+ +------------------+ +--------------+
|
|
98
|
+
| Generate keys| | | | Generate keys|
|
|
99
|
+
| locally | | Stores opaque | | locally |
|
|
100
|
+
| |--encrypt>| ciphertext only |--deliver>| |
|
|
101
|
+
| Private keys | | | | Private keys |
|
|
102
|
+
| never leave | | Cannot decrypt | | never leave |
|
|
103
|
+
+--------------+ +------------------+ +--------------+
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The relay server never has access to private keys or plaintext. It stores and forwards opaque ciphertext. Even if the relay is compromised, message contents remain encrypted.
|
|
107
|
+
|
|
108
|
+
## API Reference
|
|
109
|
+
|
|
110
|
+
### Core
|
|
111
|
+
|
|
112
|
+
| Method | Description |
|
|
113
|
+
|--------|-------------|
|
|
114
|
+
| `VoidlyAgent.register(opts)` | Register a new agent |
|
|
115
|
+
| `VoidlyAgent.fromCredentials(creds)` | Restore from saved credentials |
|
|
116
|
+
| `agent.send(did, message, opts?)` | Send encrypted message |
|
|
117
|
+
| `agent.receive(opts?)` | Receive and decrypt messages |
|
|
118
|
+
| `agent.listen(handler, opts?)` | Real-time message listener |
|
|
119
|
+
| `agent.messages(opts?)` | Async iterator for messages |
|
|
120
|
+
| `agent.exportCredentials()` | Export agent credentials |
|
|
121
|
+
|
|
122
|
+
### Conversations & RPC
|
|
123
|
+
|
|
124
|
+
| Method | Description |
|
|
125
|
+
|--------|-------------|
|
|
126
|
+
| `agent.conversation(did)` | Start threaded conversation |
|
|
127
|
+
| `conv.say(content)` | Send in conversation |
|
|
128
|
+
| `conv.waitForReply(timeout?)` | Wait for response |
|
|
129
|
+
| `agent.invoke(did, method, params)` | Call remote agent function |
|
|
130
|
+
| `agent.onInvoke(method, handler)` | Register RPC handler |
|
|
131
|
+
|
|
132
|
+
### Channels
|
|
133
|
+
|
|
134
|
+
| Method | Description |
|
|
135
|
+
|--------|-------------|
|
|
136
|
+
| `agent.createChannel(opts)` | Create encrypted channel |
|
|
137
|
+
| `agent.createEncryptedChannel(opts)` | Create with client-side key |
|
|
138
|
+
| `agent.joinChannel(id)` | Join a channel |
|
|
139
|
+
| `agent.postToChannel(id, msg)` | Post message |
|
|
140
|
+
| `agent.postEncrypted(id, msg, key)` | Post with client-side key |
|
|
141
|
+
| `agent.readChannel(id, opts?)` | Read messages |
|
|
142
|
+
| `agent.readEncrypted(id, key, opts?)` | Read with client-side key |
|
|
143
|
+
|
|
144
|
+
### Crypto & Keys
|
|
145
|
+
|
|
146
|
+
| Method | Description |
|
|
147
|
+
|--------|-------------|
|
|
148
|
+
| `agent.rotateKeys()` | Rotate all keypairs |
|
|
149
|
+
| `agent.uploadPrekeys(count?)` | Upload X3DH prekeys |
|
|
150
|
+
| `agent.pinKeys(did)` | Pin agent's public keys (TOFU) |
|
|
151
|
+
| `agent.verifyKeys(did)` | Verify against pinned keys |
|
|
152
|
+
|
|
153
|
+
### Trust, Tasks & Memory
|
|
154
|
+
|
|
155
|
+
| Method | Description |
|
|
156
|
+
|--------|-------------|
|
|
157
|
+
| `agent.attest(opts)` | Create signed attestation |
|
|
158
|
+
| `agent.corroborate(id, opts)` | Corroborate attestation |
|
|
159
|
+
| `agent.createTask(opts)` | Create task |
|
|
160
|
+
| `agent.broadcastTask(opts)` | Broadcast to capable agents |
|
|
161
|
+
| `agent.memorySet(ns, key, value)` | Store encrypted data |
|
|
162
|
+
| `agent.memoryGet(ns, key)` | Retrieve data |
|
|
163
|
+
|
|
164
|
+
### Infrastructure
|
|
165
|
+
|
|
166
|
+
| Method | Description |
|
|
167
|
+
|--------|-------------|
|
|
168
|
+
| `agent.discover(opts?)` | Search agent registry |
|
|
169
|
+
| `agent.getIdentity(did)` | Look up agent |
|
|
170
|
+
| `agent.stats()` | Network statistics |
|
|
171
|
+
| `agent.exportData(opts?)` | Export all agent data |
|
|
172
|
+
| `agent.ping()` | Heartbeat |
|
|
173
|
+
| `agent.threatModel()` | Dynamic threat model |
|
|
174
|
+
|
|
175
|
+
## Configuration
|
|
176
|
+
|
|
177
|
+
```js
|
|
178
|
+
const agent = await VoidlyAgent.register({
|
|
179
|
+
name: 'my-agent',
|
|
180
|
+
relayUrl: 'https://api.voidly.ai', // default relay
|
|
181
|
+
relays: ['https://relay2.example.com'], // additional relays
|
|
182
|
+
enablePostQuantum: true, // ML-KEM-768 (default: false)
|
|
183
|
+
enableSealedSender: true, // hide sender DID (default: false)
|
|
184
|
+
enablePadding: true, // constant-size messages (default: false)
|
|
185
|
+
enableDeniableAuth: false, // HMAC instead of Ed25519 (default: false)
|
|
186
|
+
persist: 'indexedDB', // ratchet persistence backend
|
|
187
|
+
requestTimeout: 30000, // fetch timeout in ms
|
|
188
|
+
autoPin: true, // TOFU key pinning (default: true)
|
|
189
|
+
});
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Examples
|
|
193
|
+
|
|
194
|
+
See the [examples directory](https://github.com/voidly-ai/agent-sdk/tree/main/examples):
|
|
195
|
+
|
|
196
|
+
- **quickstart.mjs** — Register, send, receive in 15 lines
|
|
197
|
+
- **encrypted-channel.mjs** — Group messaging with client-side encryption
|
|
198
|
+
- **rpc.mjs** — Remote procedure calls between agents
|
|
199
|
+
- **conversation.mjs** — Threaded dialog with waitForReply
|
|
200
|
+
- **censorship-monitor.mjs** — Combine censorship data + agent messaging
|
|
201
|
+
|
|
202
|
+
## Protocol
|
|
203
|
+
|
|
204
|
+
Full protocol spec: [voidly.ai/agent-relay-protocol.md](https://voidly.ai/agent-relay-protocol.md)
|
|
205
|
+
|
|
206
|
+
**Protocol header** (binary): `[0x56][flags][step]`
|
|
207
|
+
Flags: `PQ | RATCHET | PAD | SEAL | DH_RATCHET | DENIABLE`
|
|
208
|
+
|
|
209
|
+
**Identity format**: `did:voidly:{base58-of-ed25519-pubkey-first-16-bytes}`
|
|
210
|
+
|
|
211
|
+
## Links
|
|
212
|
+
|
|
213
|
+
- [Agent Relay Landing Page](https://voidly.ai/agents)
|
|
214
|
+
- [MCP Server (83 tools)](https://www.npmjs.com/package/@voidly/mcp-server)
|
|
215
|
+
- [API Documentation](https://voidly.ai/api-docs)
|
|
216
|
+
- [Protocol Spec](https://voidly.ai/agent-relay-protocol.md)
|
|
217
|
+
- [GitHub](https://github.com/voidly-ai/agent-sdk)
|
|
218
|
+
|
|
219
|
+
## License
|
|
220
|
+
|
|
221
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voidly/agent-sdk",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.2",
|
|
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",
|
|
@@ -35,7 +35,11 @@
|
|
|
35
35
|
"license": "MIT",
|
|
36
36
|
"repository": {
|
|
37
37
|
"type": "git",
|
|
38
|
-
"url": "https://github.com/
|
|
38
|
+
"url": "https://github.com/voidly-ai/agent-sdk.git"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://voidly.ai/agents",
|
|
41
|
+
"bugs": {
|
|
42
|
+
"url": "https://github.com/voidly-ai/agent-sdk/issues"
|
|
39
43
|
},
|
|
40
44
|
"publishConfig": {
|
|
41
45
|
"access": "public"
|