@voidly/agent-sdk 3.3.0 → 3.3.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/index.d.ts +5 -1
- package/dist/index.js +87 -6
- package/dist/index.mjs +87 -6
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -364,7 +364,11 @@ declare class VoidlyAgent {
|
|
|
364
364
|
messageType?: string;
|
|
365
365
|
unreadOnly?: boolean;
|
|
366
366
|
}): Promise<DecryptedMessage[]>;
|
|
367
|
-
/** Decrypt raw message objects (shared by receive(), SSE, WebSocket transports)
|
|
367
|
+
/** Decrypt raw message objects (shared by receive(), SSE, WebSocket transports)
|
|
368
|
+
* Returns decrypted messages AND IDs of messages that failed to decrypt.
|
|
369
|
+
* Failed messages should be marked as read on the relay — they are permanently
|
|
370
|
+
* undecryptable and will poison the queue if left unread (Signal-style handling).
|
|
371
|
+
*/
|
|
368
372
|
private _decryptMessages;
|
|
369
373
|
/**
|
|
370
374
|
* Delete a message by ID (must be sender or recipient).
|
package/dist/index.js
CHANGED
|
@@ -4220,6 +4220,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
4220
4220
|
} catch {
|
|
4221
4221
|
}
|
|
4222
4222
|
}
|
|
4223
|
+
const effectiveConfig = !mlkemSk && config?.postQuantum !== false ? { ...config, postQuantum: false } : config;
|
|
4223
4224
|
const agent = new _VoidlyAgent({
|
|
4224
4225
|
did: creds.did,
|
|
4225
4226
|
apiKey: creds.apiKey,
|
|
@@ -4230,7 +4231,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
4230
4231
|
},
|
|
4231
4232
|
mlkemPublicKey: mlkemPk,
|
|
4232
4233
|
mlkemSecretKey: mlkemSk
|
|
4233
|
-
},
|
|
4234
|
+
}, effectiveConfig);
|
|
4234
4235
|
if (creds.ratchetStates) {
|
|
4235
4236
|
for (const [pairId, rs] of Object.entries(creds.ratchetStates)) {
|
|
4236
4237
|
try {
|
|
@@ -4784,16 +4785,37 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
4784
4785
|
throw new Error(`Receive failed: ${err.error?.message || err.error || res.statusText}`);
|
|
4785
4786
|
}
|
|
4786
4787
|
const data = await res.json();
|
|
4787
|
-
|
|
4788
|
+
const { decrypted, failedIds } = await this._decryptMessages(data.messages);
|
|
4789
|
+
if (failedIds.length > 0) {
|
|
4790
|
+
try {
|
|
4791
|
+
await this.markReadBatch(failedIds);
|
|
4792
|
+
} catch {
|
|
4793
|
+
for (const id of failedIds) {
|
|
4794
|
+
try {
|
|
4795
|
+
await this.markRead(id);
|
|
4796
|
+
} catch {
|
|
4797
|
+
}
|
|
4798
|
+
}
|
|
4799
|
+
}
|
|
4800
|
+
}
|
|
4801
|
+
return decrypted;
|
|
4788
4802
|
}
|
|
4789
|
-
/** Decrypt raw message objects (shared by receive(), SSE, WebSocket transports)
|
|
4803
|
+
/** Decrypt raw message objects (shared by receive(), SSE, WebSocket transports)
|
|
4804
|
+
* Returns decrypted messages AND IDs of messages that failed to decrypt.
|
|
4805
|
+
* Failed messages should be marked as read on the relay — they are permanently
|
|
4806
|
+
* undecryptable and will poison the queue if left unread (Signal-style handling).
|
|
4807
|
+
*/
|
|
4790
4808
|
async _decryptMessages(rawMessages) {
|
|
4791
4809
|
const decrypted = [];
|
|
4810
|
+
const failedIds = [];
|
|
4792
4811
|
const resetPeers = /* @__PURE__ */ new Set();
|
|
4793
4812
|
for (const msg of rawMessages) {
|
|
4794
4813
|
try {
|
|
4795
4814
|
if (this._seenMessageIds.has(msg.id)) continue;
|
|
4796
|
-
if (resetPeers.has(msg.from))
|
|
4815
|
+
if (resetPeers.has(msg.from)) {
|
|
4816
|
+
failedIds.push(msg.id);
|
|
4817
|
+
continue;
|
|
4818
|
+
}
|
|
4797
4819
|
let senderEncPub;
|
|
4798
4820
|
let senderSignPubBytes = null;
|
|
4799
4821
|
if (msg.sender_encryption_key) {
|
|
@@ -4929,6 +4951,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
4929
4951
|
const skip = targetStep - state.recvStep;
|
|
4930
4952
|
if (skip > MAX_SKIP) {
|
|
4931
4953
|
this._decryptFailCount++;
|
|
4954
|
+
failedIds.push(msg.id);
|
|
4932
4955
|
const peerForSkip = msg.from || "unknown";
|
|
4933
4956
|
const prevSkipFails = this._peerDecryptFails.get(peerForSkip) || 0;
|
|
4934
4957
|
this._peerDecryptFails.set(peerForSkip, prevSkipFails + 1);
|
|
@@ -4956,6 +4979,55 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
4956
4979
|
rawPlaintext = import_tweetnacl.default.secretbox.open(ciphertext, nonce, messageKey);
|
|
4957
4980
|
}
|
|
4958
4981
|
}
|
|
4982
|
+
if (!rawPlaintext && envelopeDhRatchetKey && this.doubleRatchet && state) {
|
|
4983
|
+
try {
|
|
4984
|
+
const x25519Shared2 = import_tweetnacl.default.box.before(senderEncPub, this.encryptionKeyPair.secretKey);
|
|
4985
|
+
let initialKey2;
|
|
4986
|
+
if (envelopePqCiphertext && this.mlkemSecretKey) {
|
|
4987
|
+
try {
|
|
4988
|
+
const pqCt2 = (0, import_tweetnacl_util.decodeBase64)(envelopePqCiphertext);
|
|
4989
|
+
const kem2 = new MlKem768();
|
|
4990
|
+
const pqShared2 = await kem2.decap(pqCt2, this.mlkemSecretKey);
|
|
4991
|
+
const combined2 = new Uint8Array(x25519Shared2.length + pqShared2.length);
|
|
4992
|
+
combined2.set(x25519Shared2, 0);
|
|
4993
|
+
combined2.set(pqShared2, x25519Shared2.length);
|
|
4994
|
+
initialKey2 = new Uint8Array(await globalThis.crypto.subtle.digest("SHA-256", combined2));
|
|
4995
|
+
} catch {
|
|
4996
|
+
initialKey2 = x25519Shared2;
|
|
4997
|
+
}
|
|
4998
|
+
} else {
|
|
4999
|
+
initialKey2 = x25519Shared2;
|
|
5000
|
+
}
|
|
5001
|
+
const senderDhPub2 = (0, import_tweetnacl_util.decodeBase64)(envelopeDhRatchetKey);
|
|
5002
|
+
const dhOutput2 = import_tweetnacl.default.box.before(senderDhPub2, this.encryptionKeyPair.secretKey);
|
|
5003
|
+
const { newRootKey: rk2, newChainKey: ck2 } = await kdfRK(initialKey2, dhOutput2);
|
|
5004
|
+
let freshCk = ck2;
|
|
5005
|
+
for (let fi = 1; fi < envelopeRatchetStep; fi++) {
|
|
5006
|
+
const { nextChainKey: nck } = await ratchetStep(freshCk);
|
|
5007
|
+
freshCk = nck;
|
|
5008
|
+
}
|
|
5009
|
+
const { nextChainKey: finalCk, messageKey: freshMk } = await ratchetStep(freshCk);
|
|
5010
|
+
const freshPlain = import_tweetnacl.default.secretbox.open(ciphertext, nonce, freshMk);
|
|
5011
|
+
if (freshPlain) {
|
|
5012
|
+
rawPlaintext = freshPlain;
|
|
5013
|
+
state.recvChainKey = finalCk;
|
|
5014
|
+
state.recvStep = envelopeRatchetStep;
|
|
5015
|
+
state.rootKey = rk2;
|
|
5016
|
+
state.dhRecvPubKey = senderDhPub2;
|
|
5017
|
+
state.prevSendStep = state.sendStep;
|
|
5018
|
+
state.dhSendKeyPair = import_tweetnacl.default.box.keyPair();
|
|
5019
|
+
state.sendStep = 0;
|
|
5020
|
+
state.sendChainKey = initialKey2;
|
|
5021
|
+
const dhOut3 = import_tweetnacl.default.box.before(senderDhPub2, state.dhSendKeyPair.secretKey);
|
|
5022
|
+
const kdf3 = await kdfRK(state.rootKey, dhOut3);
|
|
5023
|
+
state.rootKey = kdf3.newRootKey;
|
|
5024
|
+
state.sendChainKey = kdf3.newChainKey;
|
|
5025
|
+
if (state.dhSkippedKeys) state.dhSkippedKeys.clear();
|
|
5026
|
+
if (state.skippedKeys) state.skippedKeys.clear();
|
|
5027
|
+
}
|
|
5028
|
+
} catch {
|
|
5029
|
+
}
|
|
5030
|
+
}
|
|
4959
5031
|
if (!rawPlaintext) {
|
|
4960
5032
|
rawPlaintext = import_tweetnacl.default.box.open(ciphertext, nonce, senderEncPub, this.encryptionKeyPair.secretKey);
|
|
4961
5033
|
}
|
|
@@ -4964,6 +5036,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
4964
5036
|
}
|
|
4965
5037
|
if (!rawPlaintext) {
|
|
4966
5038
|
this._decryptFailCount++;
|
|
5039
|
+
failedIds.push(msg.id);
|
|
4967
5040
|
const senderForFail = msg.from || "unknown";
|
|
4968
5041
|
const prevFails = this._peerDecryptFails.get(senderForFail) || 0;
|
|
4969
5042
|
this._peerDecryptFails.set(senderForFail, prevFails + 1);
|
|
@@ -5044,6 +5117,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
5044
5117
|
}
|
|
5045
5118
|
if (this.requireSignatures && !signatureValid) {
|
|
5046
5119
|
this._decryptFailCount++;
|
|
5120
|
+
failedIds.push(msg.id);
|
|
5047
5121
|
const peerForSig = msg.from || "unknown";
|
|
5048
5122
|
const prevSigFails = this._peerDecryptFails.get(peerForSig) || 0;
|
|
5049
5123
|
this._peerDecryptFails.set(peerForSig, prevSigFails + 1);
|
|
@@ -5073,6 +5147,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
5073
5147
|
});
|
|
5074
5148
|
} catch {
|
|
5075
5149
|
this._decryptFailCount++;
|
|
5150
|
+
failedIds.push(msg.id);
|
|
5076
5151
|
const peerForCatch = msg.from || "unknown";
|
|
5077
5152
|
const prevCatchFails = this._peerDecryptFails.get(peerForCatch) || 0;
|
|
5078
5153
|
this._peerDecryptFails.set(peerForCatch, prevCatchFails + 1);
|
|
@@ -5087,7 +5162,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
5087
5162
|
this._persistRatchetState().catch(() => {
|
|
5088
5163
|
});
|
|
5089
5164
|
}
|
|
5090
|
-
return decrypted;
|
|
5165
|
+
return { decrypted, failedIds };
|
|
5091
5166
|
}
|
|
5092
5167
|
// ─── Message Management ─────────────────────────────────────────────────────
|
|
5093
5168
|
/**
|
|
@@ -6443,7 +6518,13 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
6443
6518
|
if (eventType === "message" && dataStr) {
|
|
6444
6519
|
try {
|
|
6445
6520
|
const rawMsg = JSON.parse(dataStr);
|
|
6446
|
-
const decrypted = await this._decryptMessages([rawMsg]);
|
|
6521
|
+
const { decrypted, failedIds } = await this._decryptMessages([rawMsg]);
|
|
6522
|
+
for (const id of failedIds) {
|
|
6523
|
+
try {
|
|
6524
|
+
await this.markRead(id);
|
|
6525
|
+
} catch {
|
|
6526
|
+
}
|
|
6527
|
+
}
|
|
6447
6528
|
if (decrypted.length > 0) {
|
|
6448
6529
|
consecutiveEmpty = 0;
|
|
6449
6530
|
sseFailures = 0;
|
package/dist/index.mjs
CHANGED
|
@@ -4210,6 +4210,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
4210
4210
|
} catch {
|
|
4211
4211
|
}
|
|
4212
4212
|
}
|
|
4213
|
+
const effectiveConfig = !mlkemSk && config?.postQuantum !== false ? { ...config, postQuantum: false } : config;
|
|
4213
4214
|
const agent = new _VoidlyAgent({
|
|
4214
4215
|
did: creds.did,
|
|
4215
4216
|
apiKey: creds.apiKey,
|
|
@@ -4220,7 +4221,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
4220
4221
|
},
|
|
4221
4222
|
mlkemPublicKey: mlkemPk,
|
|
4222
4223
|
mlkemSecretKey: mlkemSk
|
|
4223
|
-
},
|
|
4224
|
+
}, effectiveConfig);
|
|
4224
4225
|
if (creds.ratchetStates) {
|
|
4225
4226
|
for (const [pairId, rs] of Object.entries(creds.ratchetStates)) {
|
|
4226
4227
|
try {
|
|
@@ -4774,16 +4775,37 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
4774
4775
|
throw new Error(`Receive failed: ${err.error?.message || err.error || res.statusText}`);
|
|
4775
4776
|
}
|
|
4776
4777
|
const data = await res.json();
|
|
4777
|
-
|
|
4778
|
+
const { decrypted, failedIds } = await this._decryptMessages(data.messages);
|
|
4779
|
+
if (failedIds.length > 0) {
|
|
4780
|
+
try {
|
|
4781
|
+
await this.markReadBatch(failedIds);
|
|
4782
|
+
} catch {
|
|
4783
|
+
for (const id of failedIds) {
|
|
4784
|
+
try {
|
|
4785
|
+
await this.markRead(id);
|
|
4786
|
+
} catch {
|
|
4787
|
+
}
|
|
4788
|
+
}
|
|
4789
|
+
}
|
|
4790
|
+
}
|
|
4791
|
+
return decrypted;
|
|
4778
4792
|
}
|
|
4779
|
-
/** Decrypt raw message objects (shared by receive(), SSE, WebSocket transports)
|
|
4793
|
+
/** Decrypt raw message objects (shared by receive(), SSE, WebSocket transports)
|
|
4794
|
+
* Returns decrypted messages AND IDs of messages that failed to decrypt.
|
|
4795
|
+
* Failed messages should be marked as read on the relay — they are permanently
|
|
4796
|
+
* undecryptable and will poison the queue if left unread (Signal-style handling).
|
|
4797
|
+
*/
|
|
4780
4798
|
async _decryptMessages(rawMessages) {
|
|
4781
4799
|
const decrypted = [];
|
|
4800
|
+
const failedIds = [];
|
|
4782
4801
|
const resetPeers = /* @__PURE__ */ new Set();
|
|
4783
4802
|
for (const msg of rawMessages) {
|
|
4784
4803
|
try {
|
|
4785
4804
|
if (this._seenMessageIds.has(msg.id)) continue;
|
|
4786
|
-
if (resetPeers.has(msg.from))
|
|
4805
|
+
if (resetPeers.has(msg.from)) {
|
|
4806
|
+
failedIds.push(msg.id);
|
|
4807
|
+
continue;
|
|
4808
|
+
}
|
|
4787
4809
|
let senderEncPub;
|
|
4788
4810
|
let senderSignPubBytes = null;
|
|
4789
4811
|
if (msg.sender_encryption_key) {
|
|
@@ -4919,6 +4941,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
4919
4941
|
const skip = targetStep - state.recvStep;
|
|
4920
4942
|
if (skip > MAX_SKIP) {
|
|
4921
4943
|
this._decryptFailCount++;
|
|
4944
|
+
failedIds.push(msg.id);
|
|
4922
4945
|
const peerForSkip = msg.from || "unknown";
|
|
4923
4946
|
const prevSkipFails = this._peerDecryptFails.get(peerForSkip) || 0;
|
|
4924
4947
|
this._peerDecryptFails.set(peerForSkip, prevSkipFails + 1);
|
|
@@ -4946,6 +4969,55 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
4946
4969
|
rawPlaintext = import_tweetnacl.default.secretbox.open(ciphertext, nonce, messageKey);
|
|
4947
4970
|
}
|
|
4948
4971
|
}
|
|
4972
|
+
if (!rawPlaintext && envelopeDhRatchetKey && this.doubleRatchet && state) {
|
|
4973
|
+
try {
|
|
4974
|
+
const x25519Shared2 = import_tweetnacl.default.box.before(senderEncPub, this.encryptionKeyPair.secretKey);
|
|
4975
|
+
let initialKey2;
|
|
4976
|
+
if (envelopePqCiphertext && this.mlkemSecretKey) {
|
|
4977
|
+
try {
|
|
4978
|
+
const pqCt2 = (0, import_tweetnacl_util.decodeBase64)(envelopePqCiphertext);
|
|
4979
|
+
const kem2 = new MlKem768();
|
|
4980
|
+
const pqShared2 = await kem2.decap(pqCt2, this.mlkemSecretKey);
|
|
4981
|
+
const combined2 = new Uint8Array(x25519Shared2.length + pqShared2.length);
|
|
4982
|
+
combined2.set(x25519Shared2, 0);
|
|
4983
|
+
combined2.set(pqShared2, x25519Shared2.length);
|
|
4984
|
+
initialKey2 = new Uint8Array(await globalThis.crypto.subtle.digest("SHA-256", combined2));
|
|
4985
|
+
} catch {
|
|
4986
|
+
initialKey2 = x25519Shared2;
|
|
4987
|
+
}
|
|
4988
|
+
} else {
|
|
4989
|
+
initialKey2 = x25519Shared2;
|
|
4990
|
+
}
|
|
4991
|
+
const senderDhPub2 = (0, import_tweetnacl_util.decodeBase64)(envelopeDhRatchetKey);
|
|
4992
|
+
const dhOutput2 = import_tweetnacl.default.box.before(senderDhPub2, this.encryptionKeyPair.secretKey);
|
|
4993
|
+
const { newRootKey: rk2, newChainKey: ck2 } = await kdfRK(initialKey2, dhOutput2);
|
|
4994
|
+
let freshCk = ck2;
|
|
4995
|
+
for (let fi = 1; fi < envelopeRatchetStep; fi++) {
|
|
4996
|
+
const { nextChainKey: nck } = await ratchetStep(freshCk);
|
|
4997
|
+
freshCk = nck;
|
|
4998
|
+
}
|
|
4999
|
+
const { nextChainKey: finalCk, messageKey: freshMk } = await ratchetStep(freshCk);
|
|
5000
|
+
const freshPlain = import_tweetnacl.default.secretbox.open(ciphertext, nonce, freshMk);
|
|
5001
|
+
if (freshPlain) {
|
|
5002
|
+
rawPlaintext = freshPlain;
|
|
5003
|
+
state.recvChainKey = finalCk;
|
|
5004
|
+
state.recvStep = envelopeRatchetStep;
|
|
5005
|
+
state.rootKey = rk2;
|
|
5006
|
+
state.dhRecvPubKey = senderDhPub2;
|
|
5007
|
+
state.prevSendStep = state.sendStep;
|
|
5008
|
+
state.dhSendKeyPair = import_tweetnacl.default.box.keyPair();
|
|
5009
|
+
state.sendStep = 0;
|
|
5010
|
+
state.sendChainKey = initialKey2;
|
|
5011
|
+
const dhOut3 = import_tweetnacl.default.box.before(senderDhPub2, state.dhSendKeyPair.secretKey);
|
|
5012
|
+
const kdf3 = await kdfRK(state.rootKey, dhOut3);
|
|
5013
|
+
state.rootKey = kdf3.newRootKey;
|
|
5014
|
+
state.sendChainKey = kdf3.newChainKey;
|
|
5015
|
+
if (state.dhSkippedKeys) state.dhSkippedKeys.clear();
|
|
5016
|
+
if (state.skippedKeys) state.skippedKeys.clear();
|
|
5017
|
+
}
|
|
5018
|
+
} catch {
|
|
5019
|
+
}
|
|
5020
|
+
}
|
|
4949
5021
|
if (!rawPlaintext) {
|
|
4950
5022
|
rawPlaintext = import_tweetnacl.default.box.open(ciphertext, nonce, senderEncPub, this.encryptionKeyPair.secretKey);
|
|
4951
5023
|
}
|
|
@@ -4954,6 +5026,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
4954
5026
|
}
|
|
4955
5027
|
if (!rawPlaintext) {
|
|
4956
5028
|
this._decryptFailCount++;
|
|
5029
|
+
failedIds.push(msg.id);
|
|
4957
5030
|
const senderForFail = msg.from || "unknown";
|
|
4958
5031
|
const prevFails = this._peerDecryptFails.get(senderForFail) || 0;
|
|
4959
5032
|
this._peerDecryptFails.set(senderForFail, prevFails + 1);
|
|
@@ -5034,6 +5107,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
5034
5107
|
}
|
|
5035
5108
|
if (this.requireSignatures && !signatureValid) {
|
|
5036
5109
|
this._decryptFailCount++;
|
|
5110
|
+
failedIds.push(msg.id);
|
|
5037
5111
|
const peerForSig = msg.from || "unknown";
|
|
5038
5112
|
const prevSigFails = this._peerDecryptFails.get(peerForSig) || 0;
|
|
5039
5113
|
this._peerDecryptFails.set(peerForSig, prevSigFails + 1);
|
|
@@ -5063,6 +5137,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
5063
5137
|
});
|
|
5064
5138
|
} catch {
|
|
5065
5139
|
this._decryptFailCount++;
|
|
5140
|
+
failedIds.push(msg.id);
|
|
5066
5141
|
const peerForCatch = msg.from || "unknown";
|
|
5067
5142
|
const prevCatchFails = this._peerDecryptFails.get(peerForCatch) || 0;
|
|
5068
5143
|
this._peerDecryptFails.set(peerForCatch, prevCatchFails + 1);
|
|
@@ -5077,7 +5152,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
5077
5152
|
this._persistRatchetState().catch(() => {
|
|
5078
5153
|
});
|
|
5079
5154
|
}
|
|
5080
|
-
return decrypted;
|
|
5155
|
+
return { decrypted, failedIds };
|
|
5081
5156
|
}
|
|
5082
5157
|
// ─── Message Management ─────────────────────────────────────────────────────
|
|
5083
5158
|
/**
|
|
@@ -6433,7 +6508,13 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
6433
6508
|
if (eventType === "message" && dataStr) {
|
|
6434
6509
|
try {
|
|
6435
6510
|
const rawMsg = JSON.parse(dataStr);
|
|
6436
|
-
const decrypted = await this._decryptMessages([rawMsg]);
|
|
6511
|
+
const { decrypted, failedIds } = await this._decryptMessages([rawMsg]);
|
|
6512
|
+
for (const id of failedIds) {
|
|
6513
|
+
try {
|
|
6514
|
+
await this.markRead(id);
|
|
6515
|
+
} catch {
|
|
6516
|
+
}
|
|
6517
|
+
}
|
|
6437
6518
|
if (decrypted.length > 0) {
|
|
6438
6519
|
consecutiveEmpty = 0;
|
|
6439
6520
|
sseFailures = 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voidly/agent-sdk",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.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",
|