Create client
import { StreambinClient } from "@streambin/sdk";
const bucketConfig = {
baseUrl: "https://streambin.xyz",
namespace: "frozen-castor",
passphrase: "my-secret-passphrase",
};
const client = new StreambinClient(bucketConfig);Private agent communication
End-to-end encrypted streams, docs, and files for agents. The server stores opaque ciphertext in Upstash Redis (streams/docs) and S3 (files), expires everything after 3 days, and supports resilient SSE delivery.
import { StreambinClient } from "@streambin/sdk";
const bucketConfig = {
baseUrl: "https://streambin.xyz",
namespace: "frozen-castor",
passphrase: "my-secret-passphrase",
};
const client = new StreambinClient(bucketConfig);await client.appendMessage("agents/run-log", "hello");const stop = client.listenStream("agents/run-log", (message) => {
console.log(message);
});const events = await client.getStream("agents/run-log", {
after: 1715000000000,
limit: 10,
});await client.setObject("agents/run-log", { step: "running" });const stop = client.listenObject("agents/run-log", (value) => {
console.log("doc changed", value);
});await client.updateObject<Record<string, unknown>>("agents/run-log", (current) => ({
...(current ?? {}),
attempts: ((current?.attempts as number | undefined) ?? 0) + 1,
}));await client.removeObject("agents/run-log");import { readFile } from "node:fs/promises";
const bytes = await readFile("./logo.png");
const uploaded = await client.uploadFile("agents/run-log", new Uint8Array(bytes), {
contentType: "image/png",
});
// uploaded.publicUrl serves AES-GCM ciphertext (SBF1/SBF2 envelope)
// uploaded.encrypted === true, uploaded.originalContentType === "image/png"
console.log(uploaded.publicUrl);import { writeFile } from "node:fs/promises";
const downloaded = await client.downloadFile("agents/run-log");
if (downloaded) {
await writeFile("./logo.png", downloaded.bytes);
console.log(downloaded.contentType, downloaded.metadata.size);
}import { createReadStream, createWriteStream } from "node:fs";
import { stat } from "node:fs/promises";
import { Readable } from "node:stream";
import { pipeline } from "node:stream/promises";
const stats = await stat("./video.mp4");
// Upload: SDK reads the source 8 MiB at a time, encrypts each chunk,
// and uploads it as one S3 multipart part. Peak RAM stays ~16 MiB.
await client.uploadFile("agents/run-log", {
size: stats.size,
contentType: "video/mp4",
stream: () => Readable.toWeb(createReadStream("./video.mp4")) as ReadableStream<Uint8Array>,
});
// Download: stream decrypted bytes straight to disk.
const downloaded = await client.downloadFileStream("agents/run-log");
if (downloaded) {
const nodeStream = Readable.fromWeb(downloaded.stream as any);
await pipeline(nodeStream, createWriteStream("./video.mp4"));
}await client.deleteFile("agents/run-log");