MeshKit

Files

Store encrypted files and retrieve them by CID.

Use mesh.files for named binary or text content: uploads, reports, attachments, browser Blobs, exports, and any payload your app wants to retrieve by CID.

import { meshkit } from "@meshkit/meshkit";

const mesh = await meshkit({ identity: "finance-device" });

const report = await mesh.files.put("reports/q1.json", JSON.stringify({ ok: true }), {
  contentType: "application/json",
  metadata: { workspace: "finance", source: "dashboard" },
});

const opened = await mesh.files.get(report.cid);
const parsed = await opened.json<{ ok: boolean }>();

console.log({
  cid: report.cid,
  size: report.size,
  provider: report.proof.provider,
  ok: parsed.ok,
});

How File Storage Works

files.put accepts plaintext content, encrypts it into a MeshKit envelope, writes encrypted bytes to the provider, writes the matching proof and metadata, and returns a MeshFile. files.get reads the envelope by CID and decrypts it for the current identity.

The CID identifies encrypted envelope bytes, not raw plaintext. Store it in your application database when a user, job, or audit trail needs to retrieve the file later.

Inputs

InputUse it for
string contentText, JSON, Markdown, logs, small exports
Uint8ArrayBinary data from Node, native bridges, or generated files
BlobBrowser file picker results and web APIs
putMany batchSmall sets of related files that should be tracked together
putStreamLarge or chunked content; see Streaming

Store Multiple Files

const batch = await mesh.files.putMany([
  {
    name: "docs/a.txt",
    content: "Alpha",
    options: { contentType: "text/plain" },
  },
  {
    name: "docs/b.txt",
    content: "Beta",
    options: { contentType: "text/plain" },
  },
]);

console.log(batch.cid, batch.files.map((file) => file.cid));

putMany writes every child file and then stores a batch manifest. Keep both the batch CID and child CIDs if users need to browse individual files later.

API

await mesh.files.put(input, contentOrOptions, options);
await mesh.files.putMany(files);
await mesh.files.get(cid);
APIReturnsNotes
files.put(...)MeshFileContains cid, name, size, encrypted, proof, and persistence helpers
files.putMany(...)MeshBatchStores child files plus a batch manifest
files.get(cid)MeshContentProvides helpers such as text(), json<T>(), and binary access

What To Persist

  • cid
  • name
  • contentType
  • size
  • proof.provider and proof summary
  • Any app-level owner, workspace, retention, or sharing state

Do not persist provider tokens, private keys, capability secrets, or decrypted content in logs.

Failure Modes

SymptomLikely causeAction
files.get cannot open a CIDCID was not created in this MeshKit provider and metadata boundaryConfirm provider config and metadata service
CID verification failsProvider returned bytes that do not match the requested CIDRetry only after checking the provider or gateway
key_unwrap_failedCurrent identity does not have a wrapped key for the envelopeOpen as the right identity or create a share capsule
Works locally but not in productionLocal-dev provider was replaced without matching metadata supportValidate provider setup with the CLI

Production Notes

  • Use contentType; it becomes authenticated envelope metadata.
  • Decide whether application metadata is safe to store as metadata. Do not put secrets in metadata.
  • Validate the provider, metadata service, and retrieval path before relying on stored CIDs.
  • Use Sharing when another identity needs access. Passing recipients during writes should still be backed by an identity model you control.

Next Steps

On this page