@voidly/agent-sdk 1.0.0 → 1.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
@@ -140,6 +140,35 @@ declare class VoidlyAgent {
140
140
  * Get relay network statistics.
141
141
  */
142
142
  stats(): Promise<Record<string, unknown>>;
143
+ /**
144
+ * Register a webhook for real-time message delivery.
145
+ * Instead of polling receive(), messages are POSTed to your URL with HMAC signatures.
146
+ */
147
+ registerWebhook(webhookUrl: string, options?: {
148
+ events?: string[];
149
+ }): Promise<{
150
+ id: string;
151
+ secret: string;
152
+ webhook_url: string;
153
+ }>;
154
+ /**
155
+ * List registered webhooks.
156
+ */
157
+ listWebhooks(): Promise<Array<{
158
+ id: string;
159
+ webhook_url: string;
160
+ events: string[];
161
+ enabled: boolean;
162
+ }>>;
163
+ /**
164
+ * Delete a webhook.
165
+ */
166
+ deleteWebhook(webhookId: string): Promise<void>;
167
+ /**
168
+ * Verify a webhook payload signature (for use in your webhook handler).
169
+ * Returns true if the HMAC-SHA256 signature matches.
170
+ */
171
+ static verifyWebhookSignature(payload: string, signature: string, secret: string): Promise<boolean>;
143
172
  /**
144
173
  * Rotate this agent's keypairs. Old messages encrypted with old keys cannot be re-decrypted.
145
174
  */
package/dist/index.d.ts CHANGED
@@ -140,6 +140,35 @@ declare class VoidlyAgent {
140
140
  * Get relay network statistics.
141
141
  */
142
142
  stats(): Promise<Record<string, unknown>>;
143
+ /**
144
+ * Register a webhook for real-time message delivery.
145
+ * Instead of polling receive(), messages are POSTed to your URL with HMAC signatures.
146
+ */
147
+ registerWebhook(webhookUrl: string, options?: {
148
+ events?: string[];
149
+ }): Promise<{
150
+ id: string;
151
+ secret: string;
152
+ webhook_url: string;
153
+ }>;
154
+ /**
155
+ * List registered webhooks.
156
+ */
157
+ listWebhooks(): Promise<Array<{
158
+ id: string;
159
+ webhook_url: string;
160
+ events: string[];
161
+ enabled: boolean;
162
+ }>>;
163
+ /**
164
+ * Delete a webhook.
165
+ */
166
+ deleteWebhook(webhookId: string): Promise<void>;
167
+ /**
168
+ * Verify a webhook payload signature (for use in your webhook handler).
169
+ * Returns true if the HMAC-SHA256 signature matches.
170
+ */
171
+ static verifyWebhookSignature(payload: string, signature: string, secret: string): Promise<boolean>;
143
172
  /**
144
173
  * Rotate this agent's keypairs. Old messages encrypted with old keys cannot be re-decrypted.
145
174
  */
package/dist/index.js CHANGED
@@ -2555,6 +2555,72 @@ var VoidlyAgent = class _VoidlyAgent {
2555
2555
  const res = await fetch(`${this.baseUrl}/v1/agent/stats`);
2556
2556
  return await res.json();
2557
2557
  }
2558
+ // ─── Webhooks ──────────────────────────────────────────────────────────────
2559
+ /**
2560
+ * Register a webhook for real-time message delivery.
2561
+ * Instead of polling receive(), messages are POSTed to your URL with HMAC signatures.
2562
+ */
2563
+ async registerWebhook(webhookUrl, options = {}) {
2564
+ const res = await fetch(`${this.baseUrl}/v1/agent/webhooks`, {
2565
+ method: "POST",
2566
+ headers: {
2567
+ "Content-Type": "application/json",
2568
+ "X-Agent-Key": this.apiKey
2569
+ },
2570
+ body: JSON.stringify({
2571
+ webhook_url: webhookUrl,
2572
+ events: options.events
2573
+ })
2574
+ });
2575
+ if (!res.ok) {
2576
+ const err = await res.json().catch(() => ({}));
2577
+ throw new Error(`Webhook registration failed: ${err.error?.message || err.error || res.statusText}`);
2578
+ }
2579
+ return await res.json();
2580
+ }
2581
+ /**
2582
+ * List registered webhooks.
2583
+ */
2584
+ async listWebhooks() {
2585
+ const res = await fetch(`${this.baseUrl}/v1/agent/webhooks`, {
2586
+ headers: { "X-Agent-Key": this.apiKey }
2587
+ });
2588
+ if (!res.ok) return [];
2589
+ const data = await res.json();
2590
+ return data.webhooks;
2591
+ }
2592
+ /**
2593
+ * Delete a webhook.
2594
+ */
2595
+ async deleteWebhook(webhookId) {
2596
+ await fetch(`${this.baseUrl}/v1/agent/webhooks/${webhookId}`, {
2597
+ method: "DELETE",
2598
+ headers: { "X-Agent-Key": this.apiKey }
2599
+ });
2600
+ }
2601
+ /**
2602
+ * Verify a webhook payload signature (for use in your webhook handler).
2603
+ * Returns true if the HMAC-SHA256 signature matches.
2604
+ */
2605
+ static async verifyWebhookSignature(payload, signature, secret) {
2606
+ const encoder = new TextEncoder();
2607
+ if (typeof globalThis.crypto?.subtle !== "undefined") {
2608
+ const key = await globalThis.crypto.subtle.importKey(
2609
+ "raw",
2610
+ encoder.encode(secret),
2611
+ { name: "HMAC", hash: "SHA-256" },
2612
+ false,
2613
+ ["sign"]
2614
+ );
2615
+ const sig = await globalThis.crypto.subtle.sign("HMAC", key, encoder.encode(payload));
2616
+ const expectedSig2 = `sha256=${Array.from(new Uint8Array(sig)).map((b) => b.toString(16).padStart(2, "0")).join("")}`;
2617
+ return signature === expectedSig2;
2618
+ }
2619
+ const { createHmac } = await import("crypto");
2620
+ const expectedSig = `sha256=${createHmac("sha256", secret).update(payload).digest("hex")}`;
2621
+ return signature === expectedSig;
2622
+ }
2623
+ // ─── Key Management ───────────────────────────────────────────────────────
2558
2624
  /**
2559
2625
  * Rotate this agent's keypairs. Old messages encrypted with old keys cannot be re-decrypted.
2560
2626
  */
package/dist/index.mjs CHANGED
@@ -2545,6 +2545,72 @@ var VoidlyAgent = class _VoidlyAgent {
2545
2545
  const res = await fetch(`${this.baseUrl}/v1/agent/stats`);
2546
2546
  return await res.json();
2547
2547
  }
2548
+ // ─── Webhooks ──────────────────────────────────────────────────────────────
2549
+ /**
2550
+ * Register a webhook for real-time message delivery.
2551
+ * Instead of polling receive(), messages are POSTed to your URL with HMAC signatures.
2552
+ */
2553
+ async registerWebhook(webhookUrl, options = {}) {
2554
+ const res = await fetch(`${this.baseUrl}/v1/agent/webhooks`, {
2555
+ method: "POST",
2556
+ headers: {
2557
+ "Content-Type": "application/json",
2558
+ "X-Agent-Key": this.apiKey
2559
+ },
2560
+ body: JSON.stringify({
2561
+ webhook_url: webhookUrl,
2562
+ events: options.events
2563
+ })
2564
+ });
2565
+ if (!res.ok) {
2566
+ const err = await res.json().catch(() => ({}));
2567
+ throw new Error(`Webhook registration failed: ${err.error?.message || err.error || res.statusText}`);
2568
+ }
2569
+ return await res.json();
2570
+ }
2571
+ /**
2572
+ * List registered webhooks.
2573
+ */
2574
+ async listWebhooks() {
2575
+ const res = await fetch(`${this.baseUrl}/v1/agent/webhooks`, {
2576
+ headers: { "X-Agent-Key": this.apiKey }
2577
+ });
2578
+ if (!res.ok) return [];
2579
+ const data = await res.json();
2580
+ return data.webhooks;
2581
+ }
2582
+ /**
2583
+ * Delete a webhook.
2584
+ */
2585
+ async deleteWebhook(webhookId) {
2586
+ await fetch(`${this.baseUrl}/v1/agent/webhooks/${webhookId}`, {
2587
+ method: "DELETE",
2588
+ headers: { "X-Agent-Key": this.apiKey }
2589
+ });
2590
+ }
2591
+ /**
2592
+ * Verify a webhook payload signature (for use in your webhook handler).
2593
+ * Returns true if the HMAC-SHA256 signature matches.
2594
+ */
2595
+ static async verifyWebhookSignature(payload, signature, secret) {
2596
+ const encoder = new TextEncoder();
2597
+ if (typeof globalThis.crypto?.subtle !== "undefined") {
2598
+ const key = await globalThis.crypto.subtle.importKey(
2599
+ "raw",
2600
+ encoder.encode(secret),
2601
+ { name: "HMAC", hash: "SHA-256" },
2602
+ false,
2603
+ ["sign"]
2604
+ );
2605
+ const sig = await globalThis.crypto.subtle.sign("HMAC", key, encoder.encode(payload));
2606
+ const expectedSig2 = `sha256=${Array.from(new Uint8Array(sig)).map((b) => b.toString(16).padStart(2, "0")).join("")}`;
2607
+ return signature === expectedSig2;
2608
+ }
2609
+ const { createHmac } = await import("crypto");
2610
+ const expectedSig = `sha256=${createHmac("sha256", secret).update(payload).digest("hex")}`;
2611
+ return signature === expectedSig;
2612
+ }
2613
+ // ─── Key Management ───────────────────────────────────────────────────────
2548
2614
  /**
2549
2615
  * Rotate this agent's keypairs. Old messages encrypted with old keys cannot be re-decrypted.
2550
2616
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voidly/agent-sdk",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "E2E encrypted agent-to-agent communication SDK — true client-side encryption",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",