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
| Input | Use it for |
|---|---|
string content | Text, JSON, Markdown, logs, small exports |
Uint8Array | Binary data from Node, native bridges, or generated files |
Blob | Browser file picker results and web APIs |
putMany batch | Small sets of related files that should be tracked together |
putStream | Large 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);| API | Returns | Notes |
|---|---|---|
files.put(...) | MeshFile | Contains cid, name, size, encrypted, proof, and persistence helpers |
files.putMany(...) | MeshBatch | Stores child files plus a batch manifest |
files.get(cid) | MeshContent | Provides helpers such as text(), json<T>(), and binary access |
What To Persist
cidnamecontentTypesizeproof.providerand 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
| Symptom | Likely cause | Action |
|---|---|---|
files.get cannot open a CID | CID was not created in this MeshKit provider and metadata boundary | Confirm provider config and metadata service |
| CID verification fails | Provider returned bytes that do not match the requested CID | Retry only after checking the provider or gateway |
key_unwrap_failed | Current identity does not have a wrapped key for the envelope | Open as the right identity or create a share capsule |
| Works locally but not in production | Local-dev provider was replaced without matching metadata support | Validate 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
recipientsduring writes should still be backed by an identity model you control.
Next Steps
- Store structured app objects with Records.
- Share a file with Sharing.
- Stream large files with Streaming.
- Understand CIDs and proofs in Proofs and CIDs.