wolfronix-sdk 1.3.2 → 2.4.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/README.md CHANGED
@@ -11,7 +11,7 @@ Official JavaScript/TypeScript SDK for Wolfronix - Zero-knowledge encryption mad
11
11
  - 🏢 **Enterprise Ready** - Seamless integration with your existing storage
12
12
  - 🚀 **Simple API** - Encrypt files in 2 lines of code
13
13
  - 📦 **TypeScript Native** - Full type definitions included
14
- - 🌐 **Universal** - Works in Node.js 16+ and modern browsers
14
+ - 🌐 **Universal** - Works in Node.js 18+ and modern browsers
15
15
  - 🔄 **Auto Retry** - Built-in retry logic with exponential backoff
16
16
 
17
17
  ## Backend Integration (Enterprise Mode)
@@ -43,7 +43,8 @@ import Wolfronix from 'wolfronix-sdk';
43
43
  // Initialize client
44
44
  const wfx = new Wolfronix({
45
45
  baseUrl: 'https://your-wolfronix-server:5002',
46
- clientId: 'your-enterprise-client-id'
46
+ clientId: 'your-enterprise-client-id',
47
+ wolfronixKey: 'your-api-key'
47
48
  });
48
49
 
49
50
  // Register (First time only) - Generates keys client-side
@@ -105,6 +106,7 @@ import * as fs from 'fs';
105
106
  const wfx = new Wolfronix({
106
107
  baseUrl: 'https://wolfronix-server:5002',
107
108
  clientId: 'your-client-id',
109
+ wolfronixKey: 'your-api-key',
108
110
  insecure: true // For self-signed certs in development
109
111
  });
110
112
 
@@ -126,12 +128,6 @@ async function main() {
126
128
  fs.writeFileSync('decrypted.pdf', Buffer.from(decrypted));
127
129
  }
128
130
 
129
- main();
130
- // Decrypt and save
131
- const decrypted = await wfx.decryptToBuffer(file_id);
132
- fs.writeFileSync('decrypted.pdf', Buffer.from(decrypted));
133
- }
134
-
135
131
  main();
136
132
  ```
137
133
 
@@ -182,9 +178,10 @@ new Wolfronix(config: WolfronixConfig | string)
182
178
  |--------|------|---------|-------------|
183
179
  | `baseUrl` | string | required | Wolfronix server URL |
184
180
  | `clientId` | string | `''` | Enterprise client ID |
181
+ | `wolfronixKey` | string | `''` | API key for X-Wolfronix-Key auth |
185
182
  | `timeout` | number | `30000` | Request timeout (ms) |
186
183
  | `retries` | number | `3` | Max retry attempts |
187
- | `insecure` | boolean | `false` | Skip SSL verification |
184
+ | `insecure` | boolean | `false` | Skip SSL verification (Node.js: uses undici Agent, or set `NODE_TLS_REJECT_UNAUTHORIZED=0`) |
188
185
 
189
186
  ### Authentication
190
187
 
@@ -202,8 +199,9 @@ new Wolfronix(config: WolfronixConfig | string)
202
199
  | Method | Description |
203
200
  |--------|-------------|
204
201
  | `encrypt(file, filename?)` | Encrypt and store file |
205
- | `decrypt(fileId)` | Decrypt file (returns Blob) |
206
- | `decryptToBuffer(fileId)` | Decrypt file (returns ArrayBuffer) |
202
+ | `decrypt(fileId, role?)` | Decrypt file (zero-knowledge, returns Blob) |
203
+ | `decryptToBuffer(fileId, role?)` | Decrypt file (zero-knowledge, returns ArrayBuffer) |
204
+ | `getFileKey(fileId)` | Get encrypted key_part_a for client-side decryption |
207
205
  | `listFiles()` | List user's encrypted files |
208
206
  | `deleteFile(fileId)` | Delete encrypted file |
209
207
 
@@ -211,7 +209,7 @@ new Wolfronix(config: WolfronixConfig | string)
211
209
 
212
210
  | Method | Description |
213
211
  |--------|-------------|
214
- | `getPublicKey(userId)` | Fetch a user's RSA public key |
212
+ | `getPublicKey(userId, clientId?)` | Fetch a user's RSA public key |
215
213
  | `encryptMessage(text, recipientId)` | Encrypt text for a recipient (returns packet string) |
216
214
  | `decryptMessage(packetString)` | Decrypt a received message packet |
217
215
 
@@ -222,6 +220,42 @@ new Wolfronix(config: WolfronixConfig | string)
222
220
  | `getMetrics()` | Get encryption/decryption stats |
223
221
  | `healthCheck()` | Check server availability |
224
222
 
223
+ ## Security Architecture (v2.0)
224
+
225
+ ### Zero-Knowledge Decryption Flow
226
+
227
+ In v2.0, the private key **never leaves the client**. The decrypt flow works as follows:
228
+
229
+ ```
230
+ Client Wolfronix Server
231
+ │ │
232
+ │ GET /files/{id}/key │
233
+ │──────────────────────────────────────>│
234
+ │ { key_part_a: "<RSA-OAEP encrypted>"}│
235
+ │<──────────────────────────────────────│
236
+ │ │
237
+ │ [Decrypt key_part_a locally │
238
+ │ with private key (RSA-OAEP)] │
239
+ │ │
240
+ │ POST /files/{id}/decrypt │
241
+ │ { decrypted_key_a: "<base64>" } │
242
+ │──────────────────────────────────────>│
243
+ │ │
244
+ │ [Server combines key_a + key_b, │
245
+ │ decrypts with AES-256-GCM] │
246
+ │ │
247
+ │ <decrypted file bytes> │
248
+ │<──────────────────────────────────────│
249
+ ```
250
+
251
+ ### Key Security Properties
252
+ - **AES-256-GCM** authenticated encryption (tamper-proof, replaces AES-CTR)
253
+ - **RSA-OAEP** with SHA-256 for key transport (replaces PKCS1v15)
254
+ - **API key authentication** via `X-Wolfronix-Key` header on all endpoints
255
+ - **Configurable CORS** origins (no more wildcard `*`)
256
+ - **Dual-key split**: AES key split in half, each half encrypted with different RSA key
257
+ - **Zero-knowledge key wrapping**: Private keys wrapped with PBKDF2-derived keys, server never sees raw private keys
258
+
225
259
  ## Error Handling
226
260
 
227
261
  The SDK provides specific error types for different scenarios:
@@ -278,7 +312,8 @@ import Wolfronix, {
278
312
  // All methods are fully typed
279
313
  const config: WolfronixConfig = {
280
314
  baseUrl: 'https://server:5002',
281
- clientId: 'my-client'
315
+ clientId: 'my-client',
316
+ wolfronixKey: 'my-api-key'
282
317
  };
283
318
 
284
319
  const wfx = new Wolfronix(config);
@@ -292,12 +327,12 @@ const response: EncryptResponse = await wfx.encrypt(file);
292
327
  import { useState, useCallback, useMemo } from 'react';
293
328
  import Wolfronix, { FileInfo as WolfronixFile } from 'wolfronix-sdk';
294
329
 
295
- export function useWolfronix(baseUrl: string, clientId?: string) {
330
+ export function useWolfronix(baseUrl: string, clientId?: string, wolfronixKey?: string) {
296
331
  const [isLoading, setIsLoading] = useState(false);
297
332
  const [error, setError] = useState<Error | null>(null);
298
333
  const [files, setFiles] = useState<WolfronixFile[]>([]);
299
334
 
300
- const client = useMemo(() => new Wolfronix({ baseUrl, clientId }), [baseUrl, clientId]);
335
+ const client = useMemo(() => new Wolfronix({ baseUrl, clientId, wolfronixKey }), [baseUrl, clientId, wolfronixKey]);
301
336
 
302
337
  const login = useCallback(async (email: string, password: string) => {
303
338
  setIsLoading(true);
@@ -395,7 +430,7 @@ Wolfronix can be integrated into **any application** that handles sensitive data
395
430
 
396
431
  ## Requirements
397
432
 
398
- - Node.js 16+ (for Node.js usage)
433
+ - Node.js 18+ (for Node.js usage)
399
434
  - Modern browser with Web Crypto API support
400
435
 
401
436
  ## License
@@ -0,0 +1,33 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __typeError = (msg) => {
4
+ throw TypeError(msg);
5
+ };
6
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
8
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
9
+ }) : x)(function(x) {
10
+ if (typeof require !== "undefined") return require.apply(this, arguments);
11
+ throw Error('Dynamic require of "' + x + '" is not supported');
12
+ });
13
+ var __commonJS = (cb, mod) => function __require2() {
14
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
15
+ };
16
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
17
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
18
+ var __privateIn = (member, obj) => Object(obj) !== obj ? __typeError('Cannot use the "in" operator on this value') : member.has(obj);
19
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
20
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
21
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
22
+ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
23
+
24
+ export {
25
+ __require,
26
+ __commonJS,
27
+ __publicField,
28
+ __privateIn,
29
+ __privateGet,
30
+ __privateAdd,
31
+ __privateSet,
32
+ __privateMethod
33
+ };
package/dist/index.d.mts CHANGED
@@ -3,13 +3,15 @@
3
3
  * Zero-knowledge encryption made simple
4
4
  *
5
5
  * @package @wolfronix/sdk
6
- * @version 1.3.0
6
+ * @version 2.4.0
7
7
  */
8
8
  interface WolfronixConfig {
9
9
  /** Wolfronix server base URL */
10
10
  baseUrl: string;
11
11
  /** Your enterprise client ID (optional for self-hosted) */
12
12
  clientId?: string;
13
+ /** API key for authentication (X-Wolfronix-Key header) */
14
+ wolfronixKey?: string;
13
15
  /** Request timeout in milliseconds (default: 30000) */
14
16
  timeout?: number;
15
17
  /** Retry failed requests (default: 3) */
@@ -44,6 +46,11 @@ interface DeleteResponse {
44
46
  success: boolean;
45
47
  message: string;
46
48
  }
49
+ interface KeyPartResponse {
50
+ file_id: string;
51
+ key_part_a: string;
52
+ message: string;
53
+ }
47
54
  interface MetricsResponse {
48
55
  success: boolean;
49
56
  total_encryptions: number;
@@ -56,6 +63,117 @@ interface EncryptMessagePacket {
56
63
  iv: string;
57
64
  msg: string;
58
65
  }
66
+ interface ServerEncryptResult {
67
+ /** Base64-encoded ciphertext */
68
+ encrypted_message: string;
69
+ /** Base64-encoded nonce */
70
+ nonce: string;
71
+ /** Base64-encoded client key half (Layer 4) or full key (Layer 3) */
72
+ key_part_a: string;
73
+ /** Tag for server's key_part_b lookup (Layer 4 only, empty for Layer 3) */
74
+ message_tag: string;
75
+ /** Unix timestamp */
76
+ timestamp: number;
77
+ }
78
+ interface ServerDecryptParams {
79
+ /** Base64-encoded ciphertext (from ServerEncryptResult) */
80
+ encryptedMessage: string;
81
+ /** Base64-encoded nonce */
82
+ nonce: string;
83
+ /** Base64-encoded key_part_a */
84
+ keyPartA: string;
85
+ /** Message tag for Layer 4 (omit for Layer 3) */
86
+ messageTag?: string;
87
+ }
88
+ interface ServerBatchEncryptResult {
89
+ results: Array<{
90
+ id: string;
91
+ encrypted_message: string;
92
+ nonce: string;
93
+ seq: number;
94
+ }>;
95
+ /** Shared key_part_a for the batch */
96
+ key_part_a: string;
97
+ /** Shared batch tag for key_part_b lookup (Layer 4) */
98
+ batch_tag: string;
99
+ timestamp: number;
100
+ }
101
+ interface StreamSession {
102
+ /** Client's key half (encrypt direction only) */
103
+ keyPartA?: string;
104
+ /** Stream tag for the session */
105
+ streamTag?: string;
106
+ }
107
+ interface StreamChunk {
108
+ data: string;
109
+ seq: number;
110
+ }
111
+ /** Supported managed connector database types */
112
+ type DBType = 'supabase' | 'mongodb' | 'mysql' | 'firebase' | 'postgresql' | 'custom_api';
113
+ interface WolfronixAdminConfig {
114
+ /** Wolfronix server base URL */
115
+ baseUrl: string;
116
+ /** Admin API key (X-Admin-Key header) */
117
+ adminKey: string;
118
+ /** Request timeout in milliseconds (default: 30000) */
119
+ timeout?: number;
120
+ /** Skip SSL verification for self-signed certs (default: false) */
121
+ insecure?: boolean;
122
+ }
123
+ interface EnterpriseClient {
124
+ id: number;
125
+ client_id: string;
126
+ client_name: string;
127
+ api_endpoint: string;
128
+ api_key: string;
129
+ wolfronix_key: string;
130
+ db_type: DBType;
131
+ db_config: string;
132
+ user_count: number;
133
+ is_active: boolean;
134
+ created_at: string;
135
+ updated_at: string;
136
+ }
137
+ interface RegisterClientRequest {
138
+ /** Unique client identifier */
139
+ client_id: string;
140
+ /** Human-readable client name */
141
+ client_name: string;
142
+ /** Database type — managed connector or custom_api */
143
+ db_type: DBType;
144
+ /** JSON string with database credentials (required for managed connectors) */
145
+ db_config?: string;
146
+ /** Client's storage API URL (required only for custom_api) */
147
+ api_endpoint?: string;
148
+ /** API key for client's custom API (optional) */
149
+ api_key?: string;
150
+ }
151
+ interface RegisterClientResponse {
152
+ status: string;
153
+ client_id: string;
154
+ wolfronix_key: string;
155
+ db_type: DBType;
156
+ message: string;
157
+ connector?: string;
158
+ api_endpoint?: string;
159
+ }
160
+ interface ListClientsResponse {
161
+ clients: EnterpriseClient[] | null;
162
+ count: number;
163
+ }
164
+ interface UpdateClientRequest {
165
+ api_endpoint?: string;
166
+ db_type?: DBType;
167
+ db_config?: string;
168
+ }
169
+ interface UpdateClientResponse {
170
+ status: string;
171
+ message: string;
172
+ }
173
+ interface DeactivateClientResponse {
174
+ status: string;
175
+ message: string;
176
+ }
59
177
  declare class WolfronixError extends Error {
60
178
  readonly code: string;
61
179
  readonly statusCode?: number;
@@ -85,6 +203,8 @@ declare class Wolfronix {
85
203
  private publicKey;
86
204
  private privateKey;
87
205
  private publicKeyPEM;
206
+ /** Expose private key status for testing */
207
+ hasPrivateKey(): boolean;
88
208
  /**
89
209
  * Create a new Wolfronix client
90
210
  *
@@ -156,7 +276,14 @@ declare class Wolfronix {
156
276
  */
157
277
  encrypt(file: File | Blob | ArrayBuffer | Uint8Array, filename?: string): Promise<EncryptResponse>;
158
278
  /**
159
- * Decrypt and retrieve a file
279
+ * Decrypt and retrieve a file using zero-knowledge flow.
280
+ *
281
+ * Flow:
282
+ * 1. GET /api/v1/files/{id}/key → encrypted key_part_a
283
+ * 2. Decrypt key_part_a client-side with private key (RSA-OAEP)
284
+ * 3. POST /api/v1/files/{id}/decrypt with { decrypted_key_a } in body
285
+ *
286
+ * The private key NEVER leaves the client.
160
287
  *
161
288
  * @example
162
289
  * ```typescript
@@ -169,11 +296,18 @@ declare class Wolfronix {
169
296
  * fs.writeFileSync('decrypted.pdf', buffer);
170
297
  * ```
171
298
  */
172
- decrypt(fileId: string): Promise<Blob>;
299
+ decrypt(fileId: string, role?: string): Promise<Blob>;
300
+ /**
301
+ * Decrypt and return as ArrayBuffer (zero-knowledge flow)
302
+ */
303
+ decryptToBuffer(fileId: string, role?: string): Promise<ArrayBuffer>;
173
304
  /**
174
- * Decrypt and return as ArrayBuffer
305
+ * Fetch the encrypted key_part_a for a file (for client-side decryption)
306
+ *
307
+ * @param fileId The file ID to get the key for
308
+ * @returns KeyPartResponse containing the RSA-OAEP encrypted key_part_a
175
309
  */
176
- decryptToBuffer(fileId: string): Promise<ArrayBuffer>;
310
+ getFileKey(fileId: string): Promise<KeyPartResponse>;
177
311
  /**
178
312
  * List all encrypted files for current user
179
313
  *
@@ -196,8 +330,9 @@ declare class Wolfronix {
196
330
  /**
197
331
  * Get another user's public key (for E2E encryption)
198
332
  * @param userId The ID of the recipient
333
+ * @param clientId Optional: override the configured clientId
199
334
  */
200
- getPublicKey(userId: string): Promise<string>;
335
+ getPublicKey(userId: string, clientId?: string): Promise<string>;
201
336
  /**
202
337
  * Encrypt a short text message for a recipient (Hybrid Encryption: RSA + AES)
203
338
  * Returns a secure JSON string (packet) to send via chat
@@ -212,6 +347,105 @@ declare class Wolfronix {
212
347
  * @param packetJson The secure JSON string packet
213
348
  */
214
349
  decryptMessage(packetJson: string): Promise<string>;
350
+ /**
351
+ * Encrypt a text message via the Wolfronix server (dual-key split).
352
+ * The server generates an AES key, encrypts the message, and splits the key —
353
+ * you get key_part_a, the server holds key_part_b.
354
+ *
355
+ * Use this for server-managed message encryption (e.g., stored encrypted messages).
356
+ * For true E2E (where the server never sees plaintext), use encryptMessage() instead.
357
+ *
358
+ * @param message The plaintext message to encrypt
359
+ * @param options.layer 3 = AES only (full key returned), 4 = dual-key split (default)
360
+ *
361
+ * @example
362
+ * ```typescript
363
+ * const result = await wfx.serverEncrypt('Hello, World!');
364
+ * // Store result.encrypted_message, result.nonce, result.key_part_a, result.message_tag
365
+ * ```
366
+ */
367
+ serverEncrypt(message: string, options?: {
368
+ layer?: number;
369
+ }): Promise<ServerEncryptResult>;
370
+ /**
371
+ * Decrypt a message previously encrypted via serverEncrypt().
372
+ *
373
+ * @param params The encrypted message data (from serverEncrypt result)
374
+ * @returns The decrypted plaintext message
375
+ *
376
+ * @example
377
+ * ```typescript
378
+ * const text = await wfx.serverDecrypt({
379
+ * encryptedMessage: result.encrypted_message,
380
+ * nonce: result.nonce,
381
+ * keyPartA: result.key_part_a,
382
+ * messageTag: result.message_tag,
383
+ * });
384
+ * ```
385
+ */
386
+ serverDecrypt(params: ServerDecryptParams): Promise<string>;
387
+ /**
388
+ * Encrypt multiple messages in a single round-trip (batch).
389
+ * All messages share one AES key (different nonce per message).
390
+ * Efficient for chat history encryption or bulk operations.
391
+ *
392
+ * @param messages Array of { id, message } objects (max 100)
393
+ * @param options.layer 3 or 4 (default: 4)
394
+ *
395
+ * @example
396
+ * ```typescript
397
+ * const result = await wfx.serverEncryptBatch([
398
+ * { id: 'msg1', message: 'Hello' },
399
+ * { id: 'msg2', message: 'World' },
400
+ * ]);
401
+ * // result.results[0].encrypted_message, result.key_part_a, result.batch_tag
402
+ * ```
403
+ */
404
+ serverEncryptBatch(messages: Array<{
405
+ id: string;
406
+ message: string;
407
+ }>, options?: {
408
+ layer?: number;
409
+ }): Promise<ServerBatchEncryptResult>;
410
+ /**
411
+ * Decrypt a single message from a batch result.
412
+ * Uses the shared key_part_a and batch_tag from the batch result.
413
+ *
414
+ * @param batchResult The batch encrypt result
415
+ * @param index The index of the message to decrypt
416
+ */
417
+ serverDecryptBatchItem(batchResult: ServerBatchEncryptResult, index: number): Promise<string>;
418
+ /**
419
+ * Create a streaming encryption/decryption session over WebSocket.
420
+ * Data flows in real-time: send chunks, receive encrypted/decrypted chunks back.
421
+ *
422
+ * @param direction 'encrypt' for plaintext→ciphertext, 'decrypt' for reverse
423
+ * @param streamKey Required for decrypt — the key_part_a and stream_tag from the encrypt session
424
+ *
425
+ * @example
426
+ * ```typescript
427
+ * // Encrypt stream
428
+ * const stream = await wfx.createStream('encrypt');
429
+ * stream.onData((chunk, seq) => console.log('Encrypted chunk', seq));
430
+ * stream.send('Hello chunk 1');
431
+ * stream.send('Hello chunk 2');
432
+ * const summary = await stream.end();
433
+ * // Save stream.keyPartA and stream.streamTag for decryption
434
+ *
435
+ * // Decrypt stream
436
+ * const dStream = await wfx.createStream('decrypt', {
437
+ * keyPartA: stream.keyPartA!,
438
+ * streamTag: stream.streamTag!,
439
+ * });
440
+ * dStream.onData((chunk, seq) => console.log('Decrypted:', chunk));
441
+ * dStream.send(encryptedChunk1);
442
+ * await dStream.end();
443
+ * ```
444
+ */
445
+ createStream(direction: 'encrypt' | 'decrypt', streamKey?: {
446
+ keyPartA: string;
447
+ streamTag: string;
448
+ }): Promise<WolfronixStream>;
215
449
  /**
216
450
  * Get encryption/decryption metrics
217
451
  *
@@ -227,6 +461,77 @@ declare class Wolfronix {
227
461
  */
228
462
  healthCheck(): Promise<boolean>;
229
463
  }
464
+ type StreamDataCallback = (data: string, seq: number) => void;
465
+ type StreamErrorCallback = (error: Error) => void;
466
+ /**
467
+ * Real-time streaming encryption/decryption over WebSocket.
468
+ * Each chunk is individually encrypted with AES-256-GCM using counter-based nonces.
469
+ *
470
+ * @example
471
+ * ```typescript
472
+ * const stream = await wfx.createStream('encrypt');
473
+ * stream.onData((chunk, seq) => sendToRecipient(chunk));
474
+ * stream.onError((err) => console.error(err));
475
+ * await stream.send('audio chunk data...');
476
+ * const summary = await stream.end();
477
+ * ```
478
+ */
479
+ declare class WolfronixStream {
480
+ private readonly config;
481
+ private readonly userId;
482
+ private ws;
483
+ private dataCallbacks;
484
+ private errorCallbacks;
485
+ private pendingChunks;
486
+ private seqCounter;
487
+ /** Client's key half (available after encrypt stream init) */
488
+ keyPartA: string | null;
489
+ /** Stream tag (available after encrypt stream init) */
490
+ streamTag: string | null;
491
+ /** @internal */
492
+ constructor(config: Required<WolfronixConfig>, userId: string);
493
+ /** @internal Connect and initialize the stream session */
494
+ connect(direction: 'encrypt' | 'decrypt', streamKey?: {
495
+ keyPartA: string;
496
+ streamTag: string;
497
+ }): Promise<void>;
498
+ /**
499
+ * Send a data chunk for encryption/decryption.
500
+ * Returns a promise that resolves with the processed (encrypted/decrypted) chunk.
501
+ *
502
+ * @param data String or base64-encoded binary data
503
+ * @returns The processed chunk (base64-encoded)
504
+ */
505
+ send(data: string): Promise<string>;
506
+ /**
507
+ * Send raw binary data for encryption/decryption.
508
+ *
509
+ * @param buffer ArrayBuffer or Uint8Array
510
+ * @returns The processed chunk (base64-encoded)
511
+ */
512
+ sendBinary(buffer: ArrayBuffer | Uint8Array): Promise<string>;
513
+ /**
514
+ * Register a callback for incoming data chunks.
515
+ *
516
+ * @param callback Called with (base64Data, sequenceNumber) for each chunk
517
+ */
518
+ onData(callback: StreamDataCallback): void;
519
+ /**
520
+ * Register a callback for stream errors.
521
+ */
522
+ onError(callback: StreamErrorCallback): void;
523
+ /**
524
+ * End the stream session. Returns the total number of chunks processed.
525
+ */
526
+ end(): Promise<{
527
+ chunksProcessed: number;
528
+ }>;
529
+ /**
530
+ * Close the stream immediately without sending an end message.
531
+ */
532
+ close(): void;
533
+ private isBase64;
534
+ }
230
535
  /**
231
536
  * Create a new Wolfronix client
232
537
  *
@@ -241,5 +546,65 @@ declare class Wolfronix {
241
546
  * ```
242
547
  */
243
548
  declare function createClient(config: WolfronixConfig | string): Wolfronix;
549
+ /**
550
+ * Admin client for managing enterprise clients.
551
+ * Uses X-Admin-Key authentication (not user auth).
552
+ *
553
+ * @example
554
+ * ```typescript
555
+ * import { WolfronixAdmin } from '@wolfronix/sdk';
556
+ *
557
+ * const admin = new WolfronixAdmin({
558
+ * baseUrl: 'https://wolfronix-server:9443',
559
+ * adminKey: 'your-admin-api-key'
560
+ * });
561
+ *
562
+ * // Register a client with managed Supabase connector
563
+ * const result = await admin.registerClient({
564
+ * client_id: 'acme_corp',
565
+ * client_name: 'Acme Corporation',
566
+ * db_type: 'supabase',
567
+ * db_config: JSON.stringify({
568
+ * supabase_url: 'https://xxx.supabase.co',
569
+ * supabase_service_key: 'eyJ...'
570
+ * })
571
+ * });
572
+ * console.log('Wolfronix key:', result.wolfronix_key);
573
+ * ```
574
+ */
575
+ declare class WolfronixAdmin {
576
+ private readonly baseUrl;
577
+ private readonly adminKey;
578
+ private readonly timeout;
579
+ private readonly insecure;
580
+ constructor(config: WolfronixAdminConfig);
581
+ private request;
582
+ /**
583
+ * Register a new enterprise client.
584
+ * For managed connectors (supabase, mongodb, mysql, firebase, postgresql),
585
+ * provide db_type + db_config. For custom APIs, use db_type: 'custom_api' + api_endpoint.
586
+ */
587
+ registerClient(params: RegisterClientRequest): Promise<RegisterClientResponse>;
588
+ /**
589
+ * List all registered enterprise clients.
590
+ */
591
+ listClients(): Promise<ListClientsResponse>;
592
+ /**
593
+ * Get details for a specific client.
594
+ */
595
+ getClient(clientId: string): Promise<EnterpriseClient>;
596
+ /**
597
+ * Update a client's configuration (api_endpoint, db_type, db_config).
598
+ */
599
+ updateClient(clientId: string, params: UpdateClientRequest): Promise<UpdateClientResponse>;
600
+ /**
601
+ * Deactivate (soft-delete) a client. Their wolfronix_key will stop working.
602
+ */
603
+ deactivateClient(clientId: string): Promise<DeactivateClientResponse>;
604
+ /**
605
+ * Check server health.
606
+ */
607
+ healthCheck(): Promise<boolean>;
608
+ }
244
609
 
245
- export { type AuthResponse, AuthenticationError, type DeleteResponse, type EncryptMessagePacket, type EncryptResponse, type FileInfo, FileNotFoundError, type ListFilesResponse, type MetricsResponse, NetworkError, PermissionDeniedError, ValidationError, Wolfronix, type WolfronixConfig, WolfronixError, createClient, Wolfronix as default };
610
+ export { type AuthResponse, AuthenticationError, type DBType, type DeactivateClientResponse, type DeleteResponse, type EncryptMessagePacket, type EncryptResponse, type EnterpriseClient, type FileInfo, FileNotFoundError, type KeyPartResponse, type ListClientsResponse, type ListFilesResponse, type MetricsResponse, NetworkError, PermissionDeniedError, type RegisterClientRequest, type RegisterClientResponse, type ServerBatchEncryptResult, type ServerDecryptParams, type ServerEncryptResult, type StreamChunk, type StreamSession, type UpdateClientRequest, type UpdateClientResponse, ValidationError, Wolfronix, WolfronixAdmin, type WolfronixAdminConfig, type WolfronixConfig, WolfronixError, WolfronixStream, createClient, Wolfronix as default };