@voidly/agent-sdk 1.9.0 → 2.1.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 CHANGED
@@ -54,6 +54,16 @@ interface VoidlyAgentConfig {
54
54
  autoPin?: boolean;
55
55
  /** Default retry attempts for send() (default: 3) */
56
56
  retries?: number;
57
+ /** Fallback relays — if primary fails, try these in order */
58
+ fallbackRelays?: string[];
59
+ /** Enable message padding to resist traffic analysis (default: true) */
60
+ padding?: boolean;
61
+ /** Enable sealed sender — hide sender DID from relay metadata (default: false) */
62
+ sealedSender?: boolean;
63
+ /** Reject messages with invalid signatures (default: false — returns signatureValid: false) */
64
+ requireSignatures?: boolean;
65
+ /** Request timeout in milliseconds (default: 30000) */
66
+ timeout?: number;
57
67
  }
58
68
  interface ListenOptions {
59
69
  /** Milliseconds between polls (default: 2000, min: 500) */
@@ -128,9 +138,19 @@ declare class VoidlyAgent {
128
138
  private baseUrl;
129
139
  private autoPin;
130
140
  private defaultRetries;
141
+ private fallbackRelays;
142
+ private paddingEnabled;
143
+ private sealedSender;
144
+ private requireSignatures;
145
+ private timeout;
131
146
  private _pinnedDids;
132
147
  private _listeners;
133
148
  private _conversations;
149
+ private _offlineQueue;
150
+ private _ratchetStates;
151
+ private _identityCache;
152
+ private _seenMessageIds;
153
+ private _decryptFailCount;
134
154
  private constructor();
135
155
  /**
136
156
  * Register a new agent on the Voidly relay.
@@ -163,13 +183,28 @@ declare class VoidlyAgent {
163
183
  encryptionPublicKey: string;
164
184
  };
165
185
  /**
166
- * Send an E2E encrypted message with automatic retry and transparent TOFU.
186
+ * Get the number of messages that failed to decrypt.
187
+ * Useful for detecting key mismatches, attacks, or corruption.
188
+ */
189
+ get decryptFailCount(): number;
190
+ /**
191
+ * Generate a did:key identifier from this agent's Ed25519 signing key.
192
+ * did:key is a W3C standard — interoperable across systems.
193
+ * Format: did:key:z6Mk{base58-multicodec-ed25519-pubkey}
194
+ */
195
+ get didKey(): string;
196
+ /**
197
+ * Send an E2E encrypted message with hardened security.
167
198
  * Encryption happens locally — the relay NEVER sees plaintext or private keys.
168
199
  *
169
- * Features:
200
+ * Security features:
201
+ * - **Message padding** — ciphertext padded to power-of-2 boundary (traffic analysis resistance)
202
+ * - **Hash ratchet** — per-conversation forward secrecy (compromise key[n] can't derive key[n-1])
203
+ * - **Sealed sender** — optionally hide sender DID from relay metadata
170
204
  * - **Auto-retry** with exponential backoff on transient failures
171
- * - **Transparent TOFU** — automatically pins recipient keys on first contact
172
- * - **Key verification** — warns if pinned keys have changed (potential MitM)
205
+ * - **Multi-relay fallback** — try backup relays if primary is down
206
+ * - **Offline queue** — queue messages if all relays fail
207
+ * - **Transparent TOFU** — auto-pin recipient keys on first contact
173
208
  */
174
209
  send(recipientDid: string, message: string, options?: {
175
210
  contentType?: string;
@@ -181,6 +216,10 @@ declare class VoidlyAgent {
181
216
  retries?: number;
182
217
  /** Skip auto key pinning for this message */
183
218
  skipPin?: boolean;
219
+ /** Force sealed sender for this message */
220
+ sealedSender?: boolean;
221
+ /** Disable padding for this message */
222
+ noPadding?: boolean;
184
223
  }): Promise<SendResult>;
185
224
  /**
186
225
  * Receive and decrypt messages. Decryption happens locally.
@@ -625,7 +664,8 @@ declare class VoidlyAgent {
625
664
  }, signingPublicKey: string): boolean;
626
665
  /**
627
666
  * Store an encrypted key-value pair in persistent memory.
628
- * Values are encrypted with a key derived from your API key — only you can read them.
667
+ * Values are encrypted CLIENT-SIDE with nacl.secretbox before sending to relay.
668
+ * The relay never sees plaintext values — true E2E encrypted storage.
629
669
  */
630
670
  memorySet(namespace: string, key: string, value: unknown, options?: {
631
671
  valueType?: string;
@@ -638,7 +678,7 @@ declare class VoidlyAgent {
638
678
  }>;
639
679
  /**
640
680
  * Retrieve a value from persistent memory.
641
- * Decrypted server-side using your API key derivation.
681
+ * Decrypted CLIENT-SIDE relay never sees plaintext.
642
682
  */
643
683
  memoryGet(namespace: string, key: string): Promise<{
644
684
  namespace: string;
@@ -842,6 +882,28 @@ declare class VoidlyAgent {
842
882
  private _autoPinKeys;
843
883
  /** @internal Fetch with exponential backoff retry */
844
884
  private _fetchWithRetry;
885
+ /**
886
+ * Drain the offline message queue — retry sending queued messages.
887
+ * Call this when connectivity is restored.
888
+ * Returns: number of messages successfully sent.
889
+ */
890
+ drainQueue(): Promise<{
891
+ sent: number;
892
+ failed: number;
893
+ remaining: number;
894
+ }>;
895
+ /** Number of messages waiting in the offline queue */
896
+ get queueLength(): number;
897
+ /**
898
+ * Returns what the relay can and cannot see about this agent.
899
+ * Call this to understand your threat model. Total transparency.
900
+ */
901
+ threatModel(): {
902
+ relayCanSee: string[];
903
+ relayCannotSee: string[];
904
+ protections: string[];
905
+ gaps: string[];
906
+ };
845
907
  }
846
908
  /**
847
909
  * A conversation between two agents.
package/dist/index.d.ts CHANGED
@@ -54,6 +54,16 @@ interface VoidlyAgentConfig {
54
54
  autoPin?: boolean;
55
55
  /** Default retry attempts for send() (default: 3) */
56
56
  retries?: number;
57
+ /** Fallback relays — if primary fails, try these in order */
58
+ fallbackRelays?: string[];
59
+ /** Enable message padding to resist traffic analysis (default: true) */
60
+ padding?: boolean;
61
+ /** Enable sealed sender — hide sender DID from relay metadata (default: false) */
62
+ sealedSender?: boolean;
63
+ /** Reject messages with invalid signatures (default: false — returns signatureValid: false) */
64
+ requireSignatures?: boolean;
65
+ /** Request timeout in milliseconds (default: 30000) */
66
+ timeout?: number;
57
67
  }
58
68
  interface ListenOptions {
59
69
  /** Milliseconds between polls (default: 2000, min: 500) */
@@ -128,9 +138,19 @@ declare class VoidlyAgent {
128
138
  private baseUrl;
129
139
  private autoPin;
130
140
  private defaultRetries;
141
+ private fallbackRelays;
142
+ private paddingEnabled;
143
+ private sealedSender;
144
+ private requireSignatures;
145
+ private timeout;
131
146
  private _pinnedDids;
132
147
  private _listeners;
133
148
  private _conversations;
149
+ private _offlineQueue;
150
+ private _ratchetStates;
151
+ private _identityCache;
152
+ private _seenMessageIds;
153
+ private _decryptFailCount;
134
154
  private constructor();
135
155
  /**
136
156
  * Register a new agent on the Voidly relay.
@@ -163,13 +183,28 @@ declare class VoidlyAgent {
163
183
  encryptionPublicKey: string;
164
184
  };
165
185
  /**
166
- * Send an E2E encrypted message with automatic retry and transparent TOFU.
186
+ * Get the number of messages that failed to decrypt.
187
+ * Useful for detecting key mismatches, attacks, or corruption.
188
+ */
189
+ get decryptFailCount(): number;
190
+ /**
191
+ * Generate a did:key identifier from this agent's Ed25519 signing key.
192
+ * did:key is a W3C standard — interoperable across systems.
193
+ * Format: did:key:z6Mk{base58-multicodec-ed25519-pubkey}
194
+ */
195
+ get didKey(): string;
196
+ /**
197
+ * Send an E2E encrypted message with hardened security.
167
198
  * Encryption happens locally — the relay NEVER sees plaintext or private keys.
168
199
  *
169
- * Features:
200
+ * Security features:
201
+ * - **Message padding** — ciphertext padded to power-of-2 boundary (traffic analysis resistance)
202
+ * - **Hash ratchet** — per-conversation forward secrecy (compromise key[n] can't derive key[n-1])
203
+ * - **Sealed sender** — optionally hide sender DID from relay metadata
170
204
  * - **Auto-retry** with exponential backoff on transient failures
171
- * - **Transparent TOFU** — automatically pins recipient keys on first contact
172
- * - **Key verification** — warns if pinned keys have changed (potential MitM)
205
+ * - **Multi-relay fallback** — try backup relays if primary is down
206
+ * - **Offline queue** — queue messages if all relays fail
207
+ * - **Transparent TOFU** — auto-pin recipient keys on first contact
173
208
  */
174
209
  send(recipientDid: string, message: string, options?: {
175
210
  contentType?: string;
@@ -181,6 +216,10 @@ declare class VoidlyAgent {
181
216
  retries?: number;
182
217
  /** Skip auto key pinning for this message */
183
218
  skipPin?: boolean;
219
+ /** Force sealed sender for this message */
220
+ sealedSender?: boolean;
221
+ /** Disable padding for this message */
222
+ noPadding?: boolean;
184
223
  }): Promise<SendResult>;
185
224
  /**
186
225
  * Receive and decrypt messages. Decryption happens locally.
@@ -625,7 +664,8 @@ declare class VoidlyAgent {
625
664
  }, signingPublicKey: string): boolean;
626
665
  /**
627
666
  * Store an encrypted key-value pair in persistent memory.
628
- * Values are encrypted with a key derived from your API key — only you can read them.
667
+ * Values are encrypted CLIENT-SIDE with nacl.secretbox before sending to relay.
668
+ * The relay never sees plaintext values — true E2E encrypted storage.
629
669
  */
630
670
  memorySet(namespace: string, key: string, value: unknown, options?: {
631
671
  valueType?: string;
@@ -638,7 +678,7 @@ declare class VoidlyAgent {
638
678
  }>;
639
679
  /**
640
680
  * Retrieve a value from persistent memory.
641
- * Decrypted server-side using your API key derivation.
681
+ * Decrypted CLIENT-SIDE relay never sees plaintext.
642
682
  */
643
683
  memoryGet(namespace: string, key: string): Promise<{
644
684
  namespace: string;
@@ -842,6 +882,28 @@ declare class VoidlyAgent {
842
882
  private _autoPinKeys;
843
883
  /** @internal Fetch with exponential backoff retry */
844
884
  private _fetchWithRetry;
885
+ /**
886
+ * Drain the offline message queue — retry sending queued messages.
887
+ * Call this when connectivity is restored.
888
+ * Returns: number of messages successfully sent.
889
+ */
890
+ drainQueue(): Promise<{
891
+ sent: number;
892
+ failed: number;
893
+ remaining: number;
894
+ }>;
895
+ /** Number of messages waiting in the offline queue */
896
+ get queueLength(): number;
897
+ /**
898
+ * Returns what the relay can and cannot see about this agent.
899
+ * Call this to understand your threat model. Total transparency.
900
+ */
901
+ threatModel(): {
902
+ relayCanSee: string[];
903
+ relayCannotSee: string[];
904
+ protections: string[];
905
+ gaps: string[];
906
+ };
845
907
  }
846
908
  /**
847
909
  * A conversation between two agents.