@voidly/agent-sdk 3.0.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +137 -0
- package/dist/index.d.ts +137 -0
- package/dist/index.js +663 -88
- package/dist/index.mjs +663 -88
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -85,6 +85,17 @@ interface VoidlyAgentConfig {
|
|
|
85
85
|
jitterMs?: number;
|
|
86
86
|
/** Use long-poll for listen() instead of short-interval polling (default: true) */
|
|
87
87
|
longPoll?: boolean;
|
|
88
|
+
/** Auto-persist ratchet state after every send/receive (default: 'memory' = no persistence) */
|
|
89
|
+
persist?: 'memory' | 'localStorage' | 'indexedDB' | 'file' | 'relay' | 'custom';
|
|
90
|
+
/** Custom persistence: called after each ratchet step with encrypted blob */
|
|
91
|
+
onPersist?: (encryptedState: string) => void | Promise<void>;
|
|
92
|
+
/** Custom persistence: called on startup to load encrypted blob */
|
|
93
|
+
onLoad?: () => string | null | Promise<string | null>;
|
|
94
|
+
/** File path for persist: 'file' (Node.js environments only) */
|
|
95
|
+
persistPath?: string;
|
|
96
|
+
/** Transport preference for listen() — tries in order, falls back automatically
|
|
97
|
+
* Default: ['sse', 'long-poll']. Options: 'websocket' | 'sse' | 'long-poll' */
|
|
98
|
+
transport?: ('websocket' | 'sse' | 'long-poll')[];
|
|
88
99
|
}
|
|
89
100
|
interface ListenOptions {
|
|
90
101
|
/** Milliseconds between polls (default: 2000, min: 500) */
|
|
@@ -181,6 +192,16 @@ declare class VoidlyAgent {
|
|
|
181
192
|
private _identityCache;
|
|
182
193
|
private _seenMessageIds;
|
|
183
194
|
private _decryptFailCount;
|
|
195
|
+
private _rpcHandlers;
|
|
196
|
+
private _rpcPending;
|
|
197
|
+
private _coverTrafficTimer;
|
|
198
|
+
private _rpcListener;
|
|
199
|
+
private _persistMode;
|
|
200
|
+
private _onPersist?;
|
|
201
|
+
private _onLoad?;
|
|
202
|
+
private _persistPath?;
|
|
203
|
+
private _persistKey;
|
|
204
|
+
private _transportPrefs;
|
|
184
205
|
private constructor();
|
|
185
206
|
/**
|
|
186
207
|
* Register a new agent on the Voidly relay.
|
|
@@ -244,6 +265,26 @@ declare class VoidlyAgent {
|
|
|
244
265
|
signedPrekeyPublic?: string;
|
|
245
266
|
signedPrekeyId?: number;
|
|
246
267
|
};
|
|
268
|
+
/** Derive persistence encryption key from signing secret */
|
|
269
|
+
private _derivePersistKey;
|
|
270
|
+
/** Auto-persist ratchet state (called after every ratchet mutation) */
|
|
271
|
+
private _persistRatchetState;
|
|
272
|
+
/** Load persisted ratchet state and restore into memory */
|
|
273
|
+
private _loadPersistedRatchetState;
|
|
274
|
+
/** IndexedDB put helper (browser only) */
|
|
275
|
+
private _idbPut;
|
|
276
|
+
/** IndexedDB get helper (browser only) */
|
|
277
|
+
private _idbGet;
|
|
278
|
+
/**
|
|
279
|
+
* Force-persist current ratchet state.
|
|
280
|
+
* Useful to call before process exit to ensure state is saved.
|
|
281
|
+
*/
|
|
282
|
+
flushRatchetState(): Promise<void>;
|
|
283
|
+
/**
|
|
284
|
+
* Restore an agent from credentials with async persistence loading.
|
|
285
|
+
* Use this instead of `fromCredentials()` when using file/relay/custom persistence.
|
|
286
|
+
*/
|
|
287
|
+
static fromCredentialsAsync(creds: Parameters<typeof VoidlyAgent.fromCredentials>[0], config?: VoidlyAgentConfig): Promise<VoidlyAgent>;
|
|
247
288
|
/**
|
|
248
289
|
* Get the number of messages that failed to decrypt.
|
|
249
290
|
* Useful for detecting key mismatches, attacks, or corruption.
|
|
@@ -296,6 +337,8 @@ declare class VoidlyAgent {
|
|
|
296
337
|
messageType?: string;
|
|
297
338
|
unreadOnly?: boolean;
|
|
298
339
|
}): Promise<DecryptedMessage[]>;
|
|
340
|
+
/** Decrypt raw message objects (shared by receive(), SSE, WebSocket transports) */
|
|
341
|
+
private _decryptMessages;
|
|
299
342
|
/**
|
|
300
343
|
* Delete a message by ID (must be sender or recipient).
|
|
301
344
|
*/
|
|
@@ -996,6 +1039,100 @@ declare class VoidlyAgent {
|
|
|
996
1039
|
* Stop all active listeners. Useful for clean shutdown.
|
|
997
1040
|
*/
|
|
998
1041
|
stopAll(): void;
|
|
1042
|
+
/**
|
|
1043
|
+
* Invoke a function on a remote agent. Synchronous RPC over encrypted messaging.
|
|
1044
|
+
* The remote agent must have registered a handler via `onInvoke()`.
|
|
1045
|
+
*
|
|
1046
|
+
* @example
|
|
1047
|
+
* ```ts
|
|
1048
|
+
* // Call a translator agent
|
|
1049
|
+
* const result = await agent.invoke('did:voidly:translator', 'translate', {
|
|
1050
|
+
* text: 'Hello, world!',
|
|
1051
|
+
* to: 'ja',
|
|
1052
|
+
* });
|
|
1053
|
+
* console.log(result.translation); // こんにちは
|
|
1054
|
+
*
|
|
1055
|
+
* // With timeout
|
|
1056
|
+
* const data = await agent.invoke(peerDid, 'analyze', { url: '...' }, 15000);
|
|
1057
|
+
* ```
|
|
1058
|
+
*/
|
|
1059
|
+
invoke(targetDid: string, method: string, params?: any, timeoutMs?: number): Promise<any>;
|
|
1060
|
+
/**
|
|
1061
|
+
* Register a handler for incoming RPC invocations.
|
|
1062
|
+
* When another agent calls `invoke(yourDid, method, params)`, your handler runs.
|
|
1063
|
+
*
|
|
1064
|
+
* @example
|
|
1065
|
+
* ```ts
|
|
1066
|
+
* // Register a translation capability
|
|
1067
|
+
* agent.onInvoke('translate', async (params, callerDid) => {
|
|
1068
|
+
* const result = await myTranslateFunction(params.text, params.to);
|
|
1069
|
+
* return { translation: result };
|
|
1070
|
+
* });
|
|
1071
|
+
*
|
|
1072
|
+
* // Register a search capability
|
|
1073
|
+
* agent.onInvoke('search', async (params) => {
|
|
1074
|
+
* return { results: await searchDatabase(params.query) };
|
|
1075
|
+
* });
|
|
1076
|
+
* ```
|
|
1077
|
+
*/
|
|
1078
|
+
onInvoke(method: string, handler: (params: any, callerDid: string) => Promise<any>): void;
|
|
1079
|
+
/**
|
|
1080
|
+
* Remove an RPC handler.
|
|
1081
|
+
*/
|
|
1082
|
+
offInvoke(method: string): void;
|
|
1083
|
+
/** @internal Start listening for RPC requests and responses */
|
|
1084
|
+
private _ensureRpcListener;
|
|
1085
|
+
/**
|
|
1086
|
+
* Send a message directly to a peer's webhook endpoint, bypassing the relay entirely.
|
|
1087
|
+
* The relay never sees the message — true peer-to-peer encrypted delivery.
|
|
1088
|
+
*
|
|
1089
|
+
* Falls back to relay-based send if direct delivery fails.
|
|
1090
|
+
*
|
|
1091
|
+
* @example
|
|
1092
|
+
* ```ts
|
|
1093
|
+
* // Try direct first, fall back to relay
|
|
1094
|
+
* const result = await agent.sendDirect('did:voidly:peer', 'Hello P2P!');
|
|
1095
|
+
* console.log(result.direct); // true if delivered directly, false if via relay
|
|
1096
|
+
* ```
|
|
1097
|
+
*/
|
|
1098
|
+
sendDirect(recipientDid: string, message: string, options?: {
|
|
1099
|
+
contentType?: string;
|
|
1100
|
+
messageType?: string;
|
|
1101
|
+
threadId?: string;
|
|
1102
|
+
ttl?: number;
|
|
1103
|
+
}): Promise<SendResult & {
|
|
1104
|
+
direct: boolean;
|
|
1105
|
+
}>;
|
|
1106
|
+
/**
|
|
1107
|
+
* Enable cover traffic — sends encrypted noise at random intervals.
|
|
1108
|
+
* Makes real messages indistinguishable from cover traffic for any observer
|
|
1109
|
+
* monitoring message timing and frequency.
|
|
1110
|
+
*
|
|
1111
|
+
* Cover messages are encrypted and padded identically to real messages.
|
|
1112
|
+
* The relay cannot distinguish them from real traffic.
|
|
1113
|
+
*
|
|
1114
|
+
* @example
|
|
1115
|
+
* ```ts
|
|
1116
|
+
* // Send noise every ~30s (randomized ±50%)
|
|
1117
|
+
* agent.enableCoverTraffic({ intervalMs: 30000 });
|
|
1118
|
+
*
|
|
1119
|
+
* // Stop cover traffic
|
|
1120
|
+
* agent.disableCoverTraffic();
|
|
1121
|
+
* ```
|
|
1122
|
+
*/
|
|
1123
|
+
enableCoverTraffic(options?: {
|
|
1124
|
+
intervalMs?: number;
|
|
1125
|
+
}): void;
|
|
1126
|
+
/**
|
|
1127
|
+
* Disable cover traffic.
|
|
1128
|
+
*/
|
|
1129
|
+
disableCoverTraffic(): void;
|
|
1130
|
+
/**
|
|
1131
|
+
* Fetch from primary relay with fallback to alternate relays.
|
|
1132
|
+
* Unlike _timedFetch which only hits one URL, this tries all known relays.
|
|
1133
|
+
* @internal
|
|
1134
|
+
*/
|
|
1135
|
+
private _resilientFetch;
|
|
999
1136
|
/**
|
|
1000
1137
|
* Start or resume a conversation with another agent.
|
|
1001
1138
|
* Automatically manages thread IDs, message history, and reply chains.
|
package/dist/index.d.ts
CHANGED
|
@@ -85,6 +85,17 @@ interface VoidlyAgentConfig {
|
|
|
85
85
|
jitterMs?: number;
|
|
86
86
|
/** Use long-poll for listen() instead of short-interval polling (default: true) */
|
|
87
87
|
longPoll?: boolean;
|
|
88
|
+
/** Auto-persist ratchet state after every send/receive (default: 'memory' = no persistence) */
|
|
89
|
+
persist?: 'memory' | 'localStorage' | 'indexedDB' | 'file' | 'relay' | 'custom';
|
|
90
|
+
/** Custom persistence: called after each ratchet step with encrypted blob */
|
|
91
|
+
onPersist?: (encryptedState: string) => void | Promise<void>;
|
|
92
|
+
/** Custom persistence: called on startup to load encrypted blob */
|
|
93
|
+
onLoad?: () => string | null | Promise<string | null>;
|
|
94
|
+
/** File path for persist: 'file' (Node.js environments only) */
|
|
95
|
+
persistPath?: string;
|
|
96
|
+
/** Transport preference for listen() — tries in order, falls back automatically
|
|
97
|
+
* Default: ['sse', 'long-poll']. Options: 'websocket' | 'sse' | 'long-poll' */
|
|
98
|
+
transport?: ('websocket' | 'sse' | 'long-poll')[];
|
|
88
99
|
}
|
|
89
100
|
interface ListenOptions {
|
|
90
101
|
/** Milliseconds between polls (default: 2000, min: 500) */
|
|
@@ -181,6 +192,16 @@ declare class VoidlyAgent {
|
|
|
181
192
|
private _identityCache;
|
|
182
193
|
private _seenMessageIds;
|
|
183
194
|
private _decryptFailCount;
|
|
195
|
+
private _rpcHandlers;
|
|
196
|
+
private _rpcPending;
|
|
197
|
+
private _coverTrafficTimer;
|
|
198
|
+
private _rpcListener;
|
|
199
|
+
private _persistMode;
|
|
200
|
+
private _onPersist?;
|
|
201
|
+
private _onLoad?;
|
|
202
|
+
private _persistPath?;
|
|
203
|
+
private _persistKey;
|
|
204
|
+
private _transportPrefs;
|
|
184
205
|
private constructor();
|
|
185
206
|
/**
|
|
186
207
|
* Register a new agent on the Voidly relay.
|
|
@@ -244,6 +265,26 @@ declare class VoidlyAgent {
|
|
|
244
265
|
signedPrekeyPublic?: string;
|
|
245
266
|
signedPrekeyId?: number;
|
|
246
267
|
};
|
|
268
|
+
/** Derive persistence encryption key from signing secret */
|
|
269
|
+
private _derivePersistKey;
|
|
270
|
+
/** Auto-persist ratchet state (called after every ratchet mutation) */
|
|
271
|
+
private _persistRatchetState;
|
|
272
|
+
/** Load persisted ratchet state and restore into memory */
|
|
273
|
+
private _loadPersistedRatchetState;
|
|
274
|
+
/** IndexedDB put helper (browser only) */
|
|
275
|
+
private _idbPut;
|
|
276
|
+
/** IndexedDB get helper (browser only) */
|
|
277
|
+
private _idbGet;
|
|
278
|
+
/**
|
|
279
|
+
* Force-persist current ratchet state.
|
|
280
|
+
* Useful to call before process exit to ensure state is saved.
|
|
281
|
+
*/
|
|
282
|
+
flushRatchetState(): Promise<void>;
|
|
283
|
+
/**
|
|
284
|
+
* Restore an agent from credentials with async persistence loading.
|
|
285
|
+
* Use this instead of `fromCredentials()` when using file/relay/custom persistence.
|
|
286
|
+
*/
|
|
287
|
+
static fromCredentialsAsync(creds: Parameters<typeof VoidlyAgent.fromCredentials>[0], config?: VoidlyAgentConfig): Promise<VoidlyAgent>;
|
|
247
288
|
/**
|
|
248
289
|
* Get the number of messages that failed to decrypt.
|
|
249
290
|
* Useful for detecting key mismatches, attacks, or corruption.
|
|
@@ -296,6 +337,8 @@ declare class VoidlyAgent {
|
|
|
296
337
|
messageType?: string;
|
|
297
338
|
unreadOnly?: boolean;
|
|
298
339
|
}): Promise<DecryptedMessage[]>;
|
|
340
|
+
/** Decrypt raw message objects (shared by receive(), SSE, WebSocket transports) */
|
|
341
|
+
private _decryptMessages;
|
|
299
342
|
/**
|
|
300
343
|
* Delete a message by ID (must be sender or recipient).
|
|
301
344
|
*/
|
|
@@ -996,6 +1039,100 @@ declare class VoidlyAgent {
|
|
|
996
1039
|
* Stop all active listeners. Useful for clean shutdown.
|
|
997
1040
|
*/
|
|
998
1041
|
stopAll(): void;
|
|
1042
|
+
/**
|
|
1043
|
+
* Invoke a function on a remote agent. Synchronous RPC over encrypted messaging.
|
|
1044
|
+
* The remote agent must have registered a handler via `onInvoke()`.
|
|
1045
|
+
*
|
|
1046
|
+
* @example
|
|
1047
|
+
* ```ts
|
|
1048
|
+
* // Call a translator agent
|
|
1049
|
+
* const result = await agent.invoke('did:voidly:translator', 'translate', {
|
|
1050
|
+
* text: 'Hello, world!',
|
|
1051
|
+
* to: 'ja',
|
|
1052
|
+
* });
|
|
1053
|
+
* console.log(result.translation); // こんにちは
|
|
1054
|
+
*
|
|
1055
|
+
* // With timeout
|
|
1056
|
+
* const data = await agent.invoke(peerDid, 'analyze', { url: '...' }, 15000);
|
|
1057
|
+
* ```
|
|
1058
|
+
*/
|
|
1059
|
+
invoke(targetDid: string, method: string, params?: any, timeoutMs?: number): Promise<any>;
|
|
1060
|
+
/**
|
|
1061
|
+
* Register a handler for incoming RPC invocations.
|
|
1062
|
+
* When another agent calls `invoke(yourDid, method, params)`, your handler runs.
|
|
1063
|
+
*
|
|
1064
|
+
* @example
|
|
1065
|
+
* ```ts
|
|
1066
|
+
* // Register a translation capability
|
|
1067
|
+
* agent.onInvoke('translate', async (params, callerDid) => {
|
|
1068
|
+
* const result = await myTranslateFunction(params.text, params.to);
|
|
1069
|
+
* return { translation: result };
|
|
1070
|
+
* });
|
|
1071
|
+
*
|
|
1072
|
+
* // Register a search capability
|
|
1073
|
+
* agent.onInvoke('search', async (params) => {
|
|
1074
|
+
* return { results: await searchDatabase(params.query) };
|
|
1075
|
+
* });
|
|
1076
|
+
* ```
|
|
1077
|
+
*/
|
|
1078
|
+
onInvoke(method: string, handler: (params: any, callerDid: string) => Promise<any>): void;
|
|
1079
|
+
/**
|
|
1080
|
+
* Remove an RPC handler.
|
|
1081
|
+
*/
|
|
1082
|
+
offInvoke(method: string): void;
|
|
1083
|
+
/** @internal Start listening for RPC requests and responses */
|
|
1084
|
+
private _ensureRpcListener;
|
|
1085
|
+
/**
|
|
1086
|
+
* Send a message directly to a peer's webhook endpoint, bypassing the relay entirely.
|
|
1087
|
+
* The relay never sees the message — true peer-to-peer encrypted delivery.
|
|
1088
|
+
*
|
|
1089
|
+
* Falls back to relay-based send if direct delivery fails.
|
|
1090
|
+
*
|
|
1091
|
+
* @example
|
|
1092
|
+
* ```ts
|
|
1093
|
+
* // Try direct first, fall back to relay
|
|
1094
|
+
* const result = await agent.sendDirect('did:voidly:peer', 'Hello P2P!');
|
|
1095
|
+
* console.log(result.direct); // true if delivered directly, false if via relay
|
|
1096
|
+
* ```
|
|
1097
|
+
*/
|
|
1098
|
+
sendDirect(recipientDid: string, message: string, options?: {
|
|
1099
|
+
contentType?: string;
|
|
1100
|
+
messageType?: string;
|
|
1101
|
+
threadId?: string;
|
|
1102
|
+
ttl?: number;
|
|
1103
|
+
}): Promise<SendResult & {
|
|
1104
|
+
direct: boolean;
|
|
1105
|
+
}>;
|
|
1106
|
+
/**
|
|
1107
|
+
* Enable cover traffic — sends encrypted noise at random intervals.
|
|
1108
|
+
* Makes real messages indistinguishable from cover traffic for any observer
|
|
1109
|
+
* monitoring message timing and frequency.
|
|
1110
|
+
*
|
|
1111
|
+
* Cover messages are encrypted and padded identically to real messages.
|
|
1112
|
+
* The relay cannot distinguish them from real traffic.
|
|
1113
|
+
*
|
|
1114
|
+
* @example
|
|
1115
|
+
* ```ts
|
|
1116
|
+
* // Send noise every ~30s (randomized ±50%)
|
|
1117
|
+
* agent.enableCoverTraffic({ intervalMs: 30000 });
|
|
1118
|
+
*
|
|
1119
|
+
* // Stop cover traffic
|
|
1120
|
+
* agent.disableCoverTraffic();
|
|
1121
|
+
* ```
|
|
1122
|
+
*/
|
|
1123
|
+
enableCoverTraffic(options?: {
|
|
1124
|
+
intervalMs?: number;
|
|
1125
|
+
}): void;
|
|
1126
|
+
/**
|
|
1127
|
+
* Disable cover traffic.
|
|
1128
|
+
*/
|
|
1129
|
+
disableCoverTraffic(): void;
|
|
1130
|
+
/**
|
|
1131
|
+
* Fetch from primary relay with fallback to alternate relays.
|
|
1132
|
+
* Unlike _timedFetch which only hits one URL, this tries all known relays.
|
|
1133
|
+
* @internal
|
|
1134
|
+
*/
|
|
1135
|
+
private _resilientFetch;
|
|
999
1136
|
/**
|
|
1000
1137
|
* Start or resume a conversation with another agent.
|
|
1001
1138
|
* Automatically manages thread IDs, message history, and reply chains.
|