mcpField
W
walrus-quilts

walrus-quilts

github.com/mystenlabs云与 DevOps343 次安装1 周前更新
代码仓库

关于 walrus-quilts

walrus-quilts 是面向使用 Walrus 存储的开发者的技能,说明如何将多个小文件打包为一个存储单元,并通过标识符、标签或 QuiltPatchId 读取。内容涵盖 CLI、TypeScript SDK 与 HTTP API 的操作及适用场景。

主要功能

  1. 01将多个小文件打包为一个 quilt
  2. 02通过标识符、标签或 QuiltPatchId 读取
  3. 03介绍 CLI、TypeScript SDK 和 HTTP API
  4. 04说明整组 quilt 的生命周期限制

适用场景

  1. 01批量存储许多小文件以摊销元数据开销
  2. 02按标识符或标签检索 quilt 中的文件
  3. 03判断文件是否适合打包存储

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mystenlabs/walrus-skills --skill walrus-quilts

安装后在 Claude Code 中输入/walrus-quilts确认已加载。

附带文件evals/evals.json

详细介绍

Walrus 拼布

来源限制: 本技能的所有信息均来自 Walrus 拼布 CLI 文档和 拼布 HTTP API 文档。 扩展本技能时,只能引用这些来源。

拼布会将多个 blob 批量打包成一个 Walrus 存储单元,从而显著降低存储大量小文件的开销和成本。通过 QuiltPatchId 或标识符(而非标准 BlobId)检索拼布中的单个 blob。

本技能中的所有模式均源自:

如果不确定某项拼布操作,请先获取相关页面,再作答。


相关技能

主题技能在以下情况下加载
CLI 基础walrus-cliCLI 的常规安装、配置和单 blob 操作
HTTP API 基础walrus-http-api单 blob 的 HTTP 存储/读取
Blob 生命周期walrus-blob-lifecycle延长、删除、共享(适用于整个拼布)

技能内容

关键概念
  • 拼布。 一个包含多个 blob 的 Walrus 存储单元。在链上,拼布表示为一个 Blob Sui 对象。存储成本按拼布总大小计算,而非按每个 blob 计算,因此存储大量小文件时可以节省开销。

  • QuiltPatchId。 拼布中每个 blob 的唯一 ID。它由拼布内容派生,因此,如果重新创建的拼布内容不同,blob 的 QuiltPatchId 也会改变。它与标准 BlobId 不同。

  • 标识符。 拼布中 blob 的易读名称(例如文件名)。标识符在拼布内必须唯一,且不能以下划线 _ 开头。字段名 _metadata 保留给 Walrus 原生元数据使用。

  • 生命周期适用于整个拼布。 你无法删除、延长或共享拼布中的单个 blob。delete、extend 和 share 等操作适用于整个拼布。

选择指南

只有在所有条目都指向拼布时,拼布才是合适的选择;如果任何条目指向普通 blob,就应将该条目存储为普通 blob。

维度适合使用拼布的情况适合使用普通 blob 的情况
文件数量可以批量处理的多个项目(数十到数百个,QuiltV1 最多 666 个)单个项目,或不会同时到达的多个项目
单项大小每个项目都较小,通常低于 10 MiB某个项目接近每个 patch 约 4 GiB 的上限,或足够大,以至于开销可以忽略
生命周期项目具有相同的生命周期(一起存储、延长、退役)某个项目需要单独安排删除、延长或共享
寻址方式可以按标识符或标签查找需要由内容派生的 BlobId;QuiltPatchId 取决于整个拼布
检索方式单独读取项目,且读取频率不高每个项目都是高频访问、独立缓存的对象

文档指出的注意事项:单文件拼布会引入 QuiltPatchId 间接寻址,却没有成本优势;将生命周期不匹配的项目分组,会迫使你为了生命周期最长的项目保留整个拼布;而需要通过内容哈希查找项目的应用,则需要使用普通 blob,或自行维护标识符到内容的映射。

TypeScript SDK

client.walrus.writeFiles({ files, epochs, deletable, signer }) 会将一次调用中的所有文件存储为一个拼布;getFiles({ ids })/getBlob({ blobId }).files({ identifiers | tags | ids }) 则可按标识符、标签或拼布 ID 读取 patch。参见 walrus-ts-sdk。

CLI:存储拼布### CLI:存储拼布
使用 --paths 从目录存储
# Store all files from a directory recursively
walrus store-quilt --epochs 5 --paths ./my-assets/

# Store from multiple directories
walrus store-quilt --epochs 10 --paths ./images/ ./documents/ ./data.json

文件名会成为标识符。所有标识符在拼布内都必须唯一。支持 glob 模式。

使用 --blobs 配合自定义标识符和标签进行存储
walrus store-quilt \
  --blobs '{"path":"photo.jpg","identifier":"walrus","tags":{"color":"grey","size":"medium"}}' \
         '{"path":"icon.png","identifier":"seal","tags":{"color":"grey","size":"small"}}' \
  --epochs 5

如果省略 identifier 或将其设为 null,则使用文件名。

生命周期选项

与常规 walrus store 相同:--epochs、--earliest-expiry-time 或 --end-epoch。

CLI:从 quilt 中读取
按标识符读取
walrus read-quilt --out ./downloads/ \
  --quilt-id <QUILT_BLOB_ID> --identifiers walrus.jpg another-walrus.jpg
按标签读取
# Download all blobs tagged with species=cat
walrus read-quilt --out ./downloads/ \
  --quilt-id <QUILT_BLOB_ID> --tag species cat
按 QuiltPatchId 读取
walrus read-quilt --out ./downloads/ \
  --quilt-patch-ids <PATCH_ID_1> <PATCH_ID_2>
列出 quilt 中的所有补丁
walrus list-patches-in-quilt <QUILT_BLOB_ID>

返回所有补丁及其标识符和 QuiltPatchId 值。

HTTP API:存储 quilt

通过 multipart 表单上传将 quilt 存储到发布端:

# Store 2 files with custom identifiers
curl -X PUT "$PUBLISHER/v1/quilts?epochs=5" \
  -F "[email protected]" \
  -F "[email protected]"

表单字段名称将成为标识符。常规 blob 查询参数(epochs、permanent、deletable、send_object_to)也适用于 quilt。

使用 Walrus 原生元数据标签存储
curl -X PUT "$PUBLISHER/v1/quilts?epochs=5" \
  -F "[email protected]" \
  -F "[email protected]" \
  -F '_metadata=[
    {"identifier": "quilt-manual", "tags": {"creator": "walrus", "version": "1.0"}},
    {"identifier": "logo-2025", "tags": {"type": "logo", "format": "png"}}
  ]'
存储响应

响应包含 quilt 的 blobId 和各个 storedQuiltBlobs,其中包含 quiltPatchId 值:

{
  "blobStoreResult": {
    "newlyCreated": {
      "blobObject": {
        "id": "0xe6ac...bc02",
        "blobId": "6XUOE-Q5-nAXHRifN6n9nomVDtHZQbGuAkW3PjlBuKo",
        "size": 1782224,
        "storage": { "startEpoch": 103, "endEpoch": 104, "storageSize": 72040000 },
        "deletable": false
      },
      "cost": 12075000
    }
  },
  "storedQuiltBlobs": [
    { "identifier": "another_walrus.jpg", "quiltPatchId": "6XUOE-...BAQD..." },
    { "identifier": "walrus.jpg", "quiltPatchId": "6XUOE-...B0AB..." }
  ]
}
HTTP API:从 quilt 中读取
# Read by QuiltPatchId
curl "$AGGREGATOR/v1/blobs/by-quilt-patch-id/<PATCH_ID>"

# Read by quilt ID + identifier
curl "$AGGREGATOR/v1/blobs/by-quilt-id/<QUILT_BLOB_ID>/walrus.jpg"

目前每个请求仅支持读取一个 blob。尚不支持在单个请求中从 quilt 批量检索。

响应标头

这两种方法都会返回原始 blob 字节。元数据通过 HTTP 标头返回:

  • X-Quilt-Patch-Identifier:blob 在 quilt 中的标识符
  • ETag:用于缓存的补丁 ID 或 quilt ID
何时使用 quilt,何时使用单个 blob
场景建议
许多小文件(每个 <10 MB)Quilt。 每个单独的 blob 都有约 64 MB 的元数据开销。Quilt 可将这部分开销分摊到所有文件上。
大量小型 JSON 文档Quilt。 对微小 blob 单独调用存储接口,成本效率很低。
一个大文件(>10 MB)单个 blob。 为单个文件使用 quilt 没有好处。
需要独立生命周期的文件单个 blob。 你无法在 quilt 中删除或延长单个文件的生命周期。
静态网站资源Quilt。 Walrus Sites 内部也因此使用 quilt。

每个 blob 的元数据开销意味着,单独存储一个 1 KB 的 JSON blob,成本与存储一个 64 MB 文件大致相同。Quilt 会将所有内容打包成一个存储单元,从而消除这项开销。

规则
  1. 一个 quilt 中的标识符必须唯一。 标识符重复会导致存储操作失败。
  2. 标识符不能以下划线 _ 开头。 _metadata 字段名保留给 Walrus 原生元数据使用。
  3. 生命周期操作适用于整个 quilt。 你无法删除、延长或分享 quilt 中的单个 blob。
  4. QuiltPatchId 不是 BlobId。 blob 的 QuiltPatchId 专属于其所属的 quilt。同一文件内容存放在另一个 quilt 中时,会获得不同的 QuiltPatchId。
  5. 许多小文件应使用 quilt。 Quilt 可降低每个 blob 的开销。对于单个大文件,请使用常规 walrus store。
  6. 内容寻址仍然适用。 相同的 quilt 内容始终会生成相同的 quilt blob ID。
常见错误
  • 尝试从 quilt 中删除单个 blob。 你必须删除整个 quilt,无法移除单个 blob。
  • 使用 BlobId 从 quilt 中读取。 Quilt 中的 blob 使用 QuiltPatchId 或 identifier 标识,而不是标准的 BlobId。
  • 不同目录中存在重复文件名。 使用 --paths 指定多个目录时,如果两个文件同名,标识符就会冲突,导致存储失败。
  • 期望 HTTP 批量读取。 目前通过 HTTP 读取 quilt 时,每个请求仅支持一个 blob。
  • 将许多小 blob 单独存储,而不是存为 quilt。 这是最常见的成本错误。每个单独的 blob 都会产生约 64 MB 的元数据开销。将 100 个小型 JSON 文件单独存储,成本大约是将它们打包到同一个 quilt 中的 100 倍。

评论

支持 Markdown