Waldrop SDK · API Reference

client.blob

Eight methods — three for writing (upload, uploadBundle, registerOnly), three for reading (list, getStore, fetch), two for sharing checks (listViewers, canView).

Methods

upload
End-to-end single-blob upload + on-chain register.
uploadBundle
Pack N files into one tar, upload as one blob.
registerOnly
Resume a failed upload — register without re-PUT.
list
List the user's registered blobs, newest first.
getStore
BlobStore summary (totals, viewers) without per-blob walk.
fetch
GET blob bytes from a Walrus aggregator.
listViewers
Read the BlobStore viewer allowlist.
canView
Mirror of the on-chain seal_approve predicate.

upload

client.blob.upload(args: UploadBlobArgs): Promise<UploadBlobResult>

SHA-256 → optional SEAL encrypt → publisher PUT → register_blob PTB. One wallet signature (the PTB). Throws RegistrationError if the bytes upload succeeds but the on-chain step fails — pass the .checkpoint to registerOnly to retry.

const result = await client.blob.upload({
  data: bytes,
  fileName: "report.pdf",
  contentType: "application/pdf",
  epochs: 26,
  senderAddress: "0x…",
  subscriptionId: "0x…",
  signer,
  blobStoreId: "0x…",              // omit to create one
  encrypted: false,                // true ⇒ SEAL (requires blobStoreId)
  initialShareViewers: ["0x…"],    // bundled into the same PTB
  onProgress: (e) => console.log(e.stage, e.percent),
});

onProgress stages: "encrypting" → "uploading" → "registering" → "done".

uploadBundle

client.blob.uploadBundle(args: UploadBundleArgs): Promise<UploadBlobResult>

Tar-bundles args.files then runs the same pipeline as upload. Useful for many small files or archival groupings. Unpack on read via unpackTar(bytes).

await client.blob.uploadBundle({
  files: [
    { name: "users.csv",   data: csvBytes },
    { name: "config.json", data: configBytes },
  ],
  epochs: 26,
  senderAddress, subscriptionId, signer,
});

registerOnly

client.blob.registerOnly(args: RegisterBlobArgs): Promise<UploadBlobResult>

Runs only the on-chain register step using an UploadCheckpoint from a previous failed attempt. Safe to retry indefinitely.

try {
  await client.blob.upload({ … });
} catch (e) {
  if (e instanceof RegistrationError) {
    await client.blob.registerOnly({
      checkpoint: e.checkpoint,
      epochs, senderAddress, subscriptionId, signer, blobStoreId,
    });
  }
}

list

client.blob.list({ owner: string; limit?: number }): Promise<BlobRef[]>

Walks the on-chain BlobStore.blobs Table, BCS-decodes each BlobRef, returns newest-first. Pass limit to early-exit pagination once enough entries are collected.

getStore

client.blob.getStore({ owner: string }): Promise<BlobStoreSummary>

Cheap summary call — returns just the BlobStore id, total bytes, total blobs, and viewer allowlist. No per-blob Table walk. Throws BlobStoreNotFoundError if the user has never created a BlobStore.

fetch

client.blob.fetch({
  blobId: string;
  aggregatorUrl?: string;
  timeoutMs?: number;
}): Promise<FetchedBlob>

GETs the blob bytes from a Walrus aggregator with retry + per-call timeout. Returned bytes are exactly as uploaded — still encrypted if the blob was registered as encrypted (use client.crypto.decrypt after).

const { bytes, contentType, sizeBytes } = await client.blob.fetch({
  blobId: "vEYTwxx7e4JjjNLHpsUImiIYwhCVqk-opz3rr64gE7w",
});

listViewers · canView

client.blob.listViewers({ owner: string }): Promise<string[]>
client.blob.canView({ owner: string; address: string }): Promise<boolean>

Read-side mirrors of the on-chain viewer ACL. listViewers returns the allowlisted addresses (excludes the owner — that's implicit). canView is true when address is the owner or in the allowlist — same predicate the seal_approve Move function runs.

Per-blob shares

This is the store-level ACL. Per-blob shares (add_blob_share calls, marker-keyed) are a separate concept — see the Sharing guide for the full model.

Edit this page on GitHub ↗
Waldrop · 2026cryptokarigar