Skip to content

FlashClient SDK Reference โ€‹

The FlashClient class is the primary entry point for developers. It handles client-side key derivation, encryption, trapdoor compilation, streaming aggregations, backup/restore, multi-tenancy, and AAD (Additional Authenticated Data) field binding.


Constructor โ€‹

javascript
import { FlashClient } from "flash-zk";

const client = new FlashClient(options);

Clear errors (reportError) โ€‹

The same guard is injected into FlashClient, FlashDatabase, and FlashServer. reportError prints one line with the exact bad-option file, line, and column (not new FlashClient, not FLASH internals):

FLASH ERROR: unknown FlashClient option: enabled @ /Users/โ€ฆ/generate_1gb_knowledge.mjs:8:3
javascript
import { reportError, FlashClient } from "flash-zk";

// Automatic: bad FlashClient options print, then throw.
// Manual: print any error yourself, then rethrow if needed.
try {
  await col.restoreOne(id);
} catch (err) {
  throw reportError(err);
}

// Print a whole chain (cause + AggregateError) โ€” no error left out:
reportError(err);
reportError.all([errA, errB, errC]);

// Catch every wild process error (uncaught + unhandled rejection):
reportError.watch();

Options โ€‹

ParameterTypeRequiredDefaultDescription
secretKeystring | BufferNo*โ€”Master passphrase. *Omit when .flash-take + .flash-wrap / FLASH_WRAP_KEY exist (flashsh wrap-key).
wrapKeyDirstringNoprocess.cwd()Directory containing .flash-take / .flash-wrap.
dbNamestringNo'flash_db'Database cluster name.
storagePathstringNo'./data'Directory path for persistent WAL and SSTables.
uristringNoโ€”Flash Server URI (e.g., flash://localhost:6742).
authKeystringNoโ€”Authentication key for Flash Server connections.
pqcHardenedbooleanNofalseEnable post-quantum hardened key derivation.
autoTimestampsbooleanNotrueAuto-set createdAt / updatedAt on insert/update.
engineOptionsFlashEngineOptionsNo{ durability: 'balanced' }Memtable, WAL sync, worker flush tuning.
fieldPolicyRecord<string, FieldPolicyType>No{}Custom per-field encryption policy mappings.

Recommended setup (1.3.0):

bash
flashsh wrap-key
javascript
import { FlashClient } from "flash-zk";

const client = new FlashClient({
  storagePath: "./flash_data",
});

Explicit secret (env / secret manager):

javascript
const client = new FlashClient({
  storagePath: "./flash_data",
});

Field Policy Types โ€‹

javascript
const client = new FlashClient({
  storagePath: "./flash_data",
  fieldPolicy: {
    email: "searchable", // AES-256-GCM + blind exact/ngram trapdoors
    balance: "counter", // Additive homomorphic encryption ($sum/$inc)
    status: "exact", // Encrypted exact-match trapdoor โ€” not plaintext
    ssn: "zk-secret", // Randomized encryption without indexes
  },
});

Methods โ€‹

collection(name, options?) โ€‹

Initializes or opens a collection wrapper. Supports optional schema definition.

  • Parameters:
    • name: string โ€” collection name
    • options?: { schema?: SchemaDefinition | FlashSchema } โ€” optional schema
  • Returns: FlashClientCollection<T>
javascript
const users = client.collection("users", {
  schema: {
    name: { type: "string", required: true, trim: true },
    email: { type: "string", required: true, unique: true },
  },
});

model(name, schema?) โ€‹

Create an ODM model for a collection.

  • Returns: FlashModelInterface<T>
javascript
const User = client.model("users", {
  name: { type: "string", required: true },
  email: { type: "string", required: true, unique: true },
});

await User.create({ name: "Alice", email: "alice@example.com" });
const user = await User.findOne({ email: "alice@example.com" });

tenant(tenantId) โ€‹

Create a tenant-scoped client for multi-tenant isolation. Tenant key is derived as HMAC-SHA256(masterKey, dbName + tenantId + version).

  • Parameters:
    • tenantId: string
  • Returns: FlashClient
javascript
const tenantClient = client.tenant("org-123");
const collection = tenantClient.collection("users");
// All data is encrypted with a tenant-specific key

startSession() โ€‹

Start a new transaction session with ACID guarantees.

  • Returns: FlashSession
javascript
const session = client.startSession();
session.startTransaction();
try {
  await users.insertOne({ name: "Alice" });
  await session.commitTransaction();
} catch (err) {
  await session.abortTransaction();
  throw err;
}

backup(destinationPath) โ€‹

Create a backup of all collections.

  • Parameters:
    • destinationPath: string
  • Returns: Promise<BackupResult>
javascript
const result = await client.backup("/backups/flash-2024-01-15");
console.log(result);
// { bytesWritten: 1048576, files: ['users.sst', 'orders.sst'], timestamp: '2024-01-15T10:00:00Z' }

restore(backupPath) โ€‹

Restore from a backup.

  • Parameters:
    • backupPath: string
  • Returns: Promise<RestoreResult>
javascript
const result = await client.restore("/backups/flash-2024-01-15");
console.log(result);
// { filesRestored: 2, destinationPath: './data' }

purgeTrash() โ€‹

Clear the bounded undo archive (.flash-trash) for the whole database.

  • Returns: Promise<{ purged: boolean }>
javascript
await client.purgeTrash();

listDeletions(options?) โ€‹

List metadata-only deletion activity when engineOptions.deletionLog.enabled is true. The on-disk log is encrypted; returns [] when disabled.

  • Parameters (optional):
    • limit?: number
    • collection?: string
    • action?: "delete" | "restore" | "drop_collection"
  • Returns: Promise<FlashDeletionLogEntry[]>
javascript
const log = await client.listDeletions({ limit: 50, action: "delete" });
// [{ collection: "notes", docId: "n1", action: "delete", at: 173..., restorable: true }]

purgeDeletionLog() โ€‹

Clear the permanent deletion activity log (.flash-deletion-log). Entries are not auto-evicted; this is the only way to wipe history besides deletionLog.purgeCollection(name).

  • Returns: Promise<{ purged: boolean }>
javascript
await client.purgeDeletionLog();

listCollections() โ€‹

List all collection names in the database.

  • Returns: Promise<string[]>
javascript
const names = await client.listCollections();
// ['users', 'orders', 'products']

encryptDocument(doc) โ€‹

Encrypt a document with AAD binding (uses record _id as AAD). Returns an EncryptedDocument.

  • Returns: EncryptedDocument
javascript
const encrypted = client.encryptDocument({
  _id: "doc-1",
  name: "Alice",
  email: "alice@example.com",
});
// { _id: 'doc-1', _enc: { name: '...', email: '...' }, _blind: {...}, _homo: {...}, _plain: {...} }

decryptDocument(encryptedRecord) โ€‹

Decrypt an EncryptedDocument or FlashBinary Buffer back to plaintext.

  • Parameters: EncryptedDocument | Buffer
  • Returns: Record<string, unknown>
javascript
const doc = client.decryptDocument(encrypted);
// or
const doc = client.decryptDocument(bufferFromEngine);

encryptToBuffer(doc) ยท decryptFromBuffer(buf) (v1.3.2+) โ€‹

Default performance path โ€” encrypt/serialize once on write, partial decode on read.

javascript
const buf = client.encryptToBuffer({ name: "Alice", email: "a@b.com" });
await col.raw.insertOne(buf);

const raw = await col.raw.findOne({ _id: "..." });
const plain = client.decryptFromBuffer(raw);

See Buffer Pipeline.

buildQueryEnvelope(query?) โ€‹

Build a query envelope for encrypted queries.

  • Returns: QueryEnvelope
javascript
const envelope = client.buildQueryEnvelope({ status: "active" });
// { $plain: { status: 'active' } } or { $exact: { status: '...' } } if blind-indexed

openDashboard(options?) โ€‹

Open the Flash Dashboard GUI server.

  • Parameters:
    • options: { port?: number, host?: string, token: string, allowDataExplorer?: boolean }
  • Returns: Dashboard HTTP server
javascript
client.openDashboard({
  port: 6742,
  token: "console-token-at-least-16",
});
// Console at http://localhost:6742 โ€” send x-flash-token on /api routes

close() โ€‹

Gracefully closes WAL file handles and flushes open collections.

  • Returns: Promise<void>
javascript
await client.close();

Universal Foundations (v1.3.0+) โ€‹

MethodReturnsDescription
lifecycle(name, opts?)FlashLifecycleTTL, max docs, archive
maintenance(opts?)FlashMaintenanceBackground flush/compact/sweep
pipeline()FlashPipelineNDJSON / collection ETL
events()FlashEventHubPub/sub on mutations
use(plugin)FlashPluginHostbeforeInsert, beforeUpdate, afterInsert, afterUpdate
eventLog(name, opts?)FlashEventLogAppend-only stream
counter(name, opts?)FlashCounterAtomic counter
queue(name, opts?)FlashQueueFIFO job queue
health()Promise<object>Engine stats
snapshot()FlashSnapshot.flashpack backup

Full guide: Universal Foundations ยท Release Notes


FLASH-Exclusive Intelligence Methods โ€‹

MethodReturnsDescription
privateRAG(name, opts?)FlashPrivateRAGEncrypted RAG pipeline
embeddingVault(name, opts?)FlashEmbeddingVaultVectors on server, text client-side
agentMemory(namespace, opts?)FlashAgentMemoryAI agent episodic memory
sealedVault(name, opts?)FlashSealedVaultPassphrase vault + auto-lock
integrityProof(collection, opts?)Promise<Proof>Signed Merkle manifest
portableBundle()FlashPortableBundle.flashpack export/import
langChainAdapter(opts?)FlashLangChainAdapterAI framework adapter
federatedQuery()FlashFederatedQueryMulti-peer query merge
multiAgentSync(namespace)FlashMultiAgentSyncShared agent memory
complianceExport()FlashComplianceExportGDPR export/erase
timeSeal(path?)FlashTimeSealTamper-evident timestamps
cloudSync(remoteDir)FlashCloudSyncCloud folder sync
encryptedCRDT(name, nodeId)FlashEncryptedCRDTEncrypted CRDT sync
browserVault()FlashBrowserVaultBrowser encrypted KV
auditStream(collection)FlashAuditStreamChange stream + audit chain

See FLASH-Exclusive Stack for full documentation.


AAD (Additional Authenticated Data) Field Binding โ€‹

FLASH DB v2 encrypts each field with AAD bound to the record _id and field key, preventing ciphertext swapping between records.

How It Works โ€‹

  1. Encrypt: Each field gets AAD = recordId:fieldName
  2. Format: v2 payload prefixed with magic 0xF44C4532 + length bytes + nonce + ciphertext + auth tag
  3. Decrypt: AAD is verified โ€” if ciphertext was moved to a different record, decryption fails
  4. Legacy support: v1 payloads (without prefix) decrypt transparently without AAD
js
// AAD binding is automatic
const users = client.collection("users");
await users.insertOne({ _id: "user-1", name: "Alice" });

// Swapping ciphertext between records fails
// The ciphertext for user-1's name won't decrypt in user-2's context

Migrating from v1 โ€‹

v1 payloads are detected by the absence of the v2 magic prefix and decrypted without AAD verification. Existing data continues to work โ€” no migration required.

Zero-knowledge encrypted intelligence ยท Apache 2.0