@voidly/agent-sdk 3.3.0 → 3.3.1
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 +38 -6
- package/dist/index.mjs +38 -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);
|
|
@@ -4964,6 +4987,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
4964
4987
|
}
|
|
4965
4988
|
if (!rawPlaintext) {
|
|
4966
4989
|
this._decryptFailCount++;
|
|
4990
|
+
failedIds.push(msg.id);
|
|
4967
4991
|
const senderForFail = msg.from || "unknown";
|
|
4968
4992
|
const prevFails = this._peerDecryptFails.get(senderForFail) || 0;
|
|
4969
4993
|
this._peerDecryptFails.set(senderForFail, prevFails + 1);
|
|
@@ -5044,6 +5068,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
5044
5068
|
}
|
|
5045
5069
|
if (this.requireSignatures && !signatureValid) {
|
|
5046
5070
|
this._decryptFailCount++;
|
|
5071
|
+
failedIds.push(msg.id);
|
|
5047
5072
|
const peerForSig = msg.from || "unknown";
|
|
5048
5073
|
const prevSigFails = this._peerDecryptFails.get(peerForSig) || 0;
|
|
5049
5074
|
this._peerDecryptFails.set(peerForSig, prevSigFails + 1);
|
|
@@ -5073,6 +5098,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
5073
5098
|
});
|
|
5074
5099
|
} catch {
|
|
5075
5100
|
this._decryptFailCount++;
|
|
5101
|
+
failedIds.push(msg.id);
|
|
5076
5102
|
const peerForCatch = msg.from || "unknown";
|
|
5077
5103
|
const prevCatchFails = this._peerDecryptFails.get(peerForCatch) || 0;
|
|
5078
5104
|
this._peerDecryptFails.set(peerForCatch, prevCatchFails + 1);
|
|
@@ -5087,7 +5113,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
5087
5113
|
this._persistRatchetState().catch(() => {
|
|
5088
5114
|
});
|
|
5089
5115
|
}
|
|
5090
|
-
return decrypted;
|
|
5116
|
+
return { decrypted, failedIds };
|
|
5091
5117
|
}
|
|
5092
5118
|
// ─── Message Management ─────────────────────────────────────────────────────
|
|
5093
5119
|
/**
|
|
@@ -6443,7 +6469,13 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
6443
6469
|
if (eventType === "message" && dataStr) {
|
|
6444
6470
|
try {
|
|
6445
6471
|
const rawMsg = JSON.parse(dataStr);
|
|
6446
|
-
const decrypted = await this._decryptMessages([rawMsg]);
|
|
6472
|
+
const { decrypted, failedIds } = await this._decryptMessages([rawMsg]);
|
|
6473
|
+
for (const id of failedIds) {
|
|
6474
|
+
try {
|
|
6475
|
+
await this.markRead(id);
|
|
6476
|
+
} catch {
|
|
6477
|
+
}
|
|
6478
|
+
}
|
|
6447
6479
|
if (decrypted.length > 0) {
|
|
6448
6480
|
consecutiveEmpty = 0;
|
|
6449
6481
|
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);
|
|
@@ -4954,6 +4977,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
4954
4977
|
}
|
|
4955
4978
|
if (!rawPlaintext) {
|
|
4956
4979
|
this._decryptFailCount++;
|
|
4980
|
+
failedIds.push(msg.id);
|
|
4957
4981
|
const senderForFail = msg.from || "unknown";
|
|
4958
4982
|
const prevFails = this._peerDecryptFails.get(senderForFail) || 0;
|
|
4959
4983
|
this._peerDecryptFails.set(senderForFail, prevFails + 1);
|
|
@@ -5034,6 +5058,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
5034
5058
|
}
|
|
5035
5059
|
if (this.requireSignatures && !signatureValid) {
|
|
5036
5060
|
this._decryptFailCount++;
|
|
5061
|
+
failedIds.push(msg.id);
|
|
5037
5062
|
const peerForSig = msg.from || "unknown";
|
|
5038
5063
|
const prevSigFails = this._peerDecryptFails.get(peerForSig) || 0;
|
|
5039
5064
|
this._peerDecryptFails.set(peerForSig, prevSigFails + 1);
|
|
@@ -5063,6 +5088,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
5063
5088
|
});
|
|
5064
5089
|
} catch {
|
|
5065
5090
|
this._decryptFailCount++;
|
|
5091
|
+
failedIds.push(msg.id);
|
|
5066
5092
|
const peerForCatch = msg.from || "unknown";
|
|
5067
5093
|
const prevCatchFails = this._peerDecryptFails.get(peerForCatch) || 0;
|
|
5068
5094
|
this._peerDecryptFails.set(peerForCatch, prevCatchFails + 1);
|
|
@@ -5077,7 +5103,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
5077
5103
|
this._persistRatchetState().catch(() => {
|
|
5078
5104
|
});
|
|
5079
5105
|
}
|
|
5080
|
-
return decrypted;
|
|
5106
|
+
return { decrypted, failedIds };
|
|
5081
5107
|
}
|
|
5082
5108
|
// ─── Message Management ─────────────────────────────────────────────────────
|
|
5083
5109
|
/**
|
|
@@ -6433,7 +6459,13 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
6433
6459
|
if (eventType === "message" && dataStr) {
|
|
6434
6460
|
try {
|
|
6435
6461
|
const rawMsg = JSON.parse(dataStr);
|
|
6436
|
-
const decrypted = await this._decryptMessages([rawMsg]);
|
|
6462
|
+
const { decrypted, failedIds } = await this._decryptMessages([rawMsg]);
|
|
6463
|
+
for (const id of failedIds) {
|
|
6464
|
+
try {
|
|
6465
|
+
await this.markRead(id);
|
|
6466
|
+
} catch {
|
|
6467
|
+
}
|
|
6468
|
+
}
|
|
6437
6469
|
if (decrypted.length > 0) {
|
|
6438
6470
|
consecutiveEmpty = 0;
|
|
6439
6471
|
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.1",
|
|
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",
|