mcpField
W
walrus-http-api

walrus-http-api

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

关于 walrus-http-api

walrus-http-api 是通过 REST 接口接入 Walrus 的技能,适用于能发送 HTTP 请求的各类语言应用。它说明写入与读取服务的分工、上传方式和响应处理。

主要功能

  1. 01通过 HTTP PUT 存储 Blob
  2. 02通过 HTTP GET 读取 Blob
  3. 03说明 Publisher 与 Aggregator 分工
  4. 04设置存储周期与是否可删除
  5. 05读取字节范围和属性
  6. 06处理赞助式上传

适用场景

  1. 01为 HTTP 应用接入 Walrus 存储
  2. 02通过 Aggregator 提供 Blob 内容
  3. 03用字节范围支持浏览器视频定位
  4. 04为无钱包用户接收上传

安装

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

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

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

附带文件evals/evals.json

详细介绍

Walrus HTTP API

来源限制: 本技能中的所有信息均来自 Walrus HTTP API 文档。 扩展本技能时,只能参考这些来源。

Walrus 通过发布者(写入)和聚合器(读取)服务提供 REST API。对于任何语言,这是最简单的集成方式:使用 HTTP PUT 存储 blob,使用 HTTP GET 读取 blob。无需安装 SDK。

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

如果不确定某个端点,请先获取相关页面再作答。


相关技能

主题技能适用场景
Quilt HTTP 端点walrus-quilts通过 HTTP 存储或读取批量 blob
CLIwalrus-cli使用 walrus 二进制文件,而非 HTTP
TypeScript SDKwalrus-ts-sdk使用官方 TS SDK
Blob 管理walrus-blob-lifecycle扩展、删除或共享 blob
加密walrus-data-security存储前加密

技能内容

关键概念
  • 发布者。 一种 HTTP 服务,可接收 blob 数据并处理编码、分片分发和链上注册。向发布者发送 PUT 请求即可存储数据。Mainnet 上没有公开且无需身份验证的发布者。在 Mainnet 上,请运行自己的经身份验证的发布者、使用上传中继,或直接使用 TypeScript SDK。公开发布者端点仅适用于 Testnet。

  • 聚合器。 一种 HTTP 服务,可从 Walrus 存储节点读取 blob,并通过 GET 请求返回。聚合器是只读的,可置于 CDN 前端。

  • Blob ID 与 object ID。 Blob ID 用于标识内容。Sui object ID 用于标识链上的 Blob 对象。两者均可用于读取。通过 object ID 读取还支持 HTTP 标头属性。

  • 一致性检查。 聚合器会在读取时验证 blob 的完整性。可使用 ?strict_consistency_check=true 启用严格检查;如果已知且信任写入者,也可使用 ?skip_consistency_check=true 跳过检查。

存储 blob(发布者)

使用 HTTP PUT 向发布者存储数据:

# Store a string for 1 epoch (default)
curl -X PUT "$PUBLISHER/v1/blobs" -d "some string"

# Store a file for 5 epochs
curl -X PUT "$PUBLISHER/v1/blobs?epochs=5" --upload-file "some/file"
查询参数
参数效果默认值
epochs存储周期数1
deletable=true所有者可在到期前删除 blob新 blob 的默认值
permanent=true到期前不可删除 blob必须显式指定
send_object_to将生成的 Blob Sui 对象发送到另一地址(赞助上传时,如何将所有权交给没有钱包的用户)发布者的钱包
reuse_resources=true复用发布者钱包已拥有的存储对象或 blob 对象,而非注册新的对象false;多个并发存储操作共用一个钱包时,请保持关闭
# Store as permanent for 5 epochs
curl -X PUT "$PUBLISHER/v1/blobs?epochs=5&permanent=true" --upload-file "file.dat"

# Store and send the blob object to another address
curl -X PUT "$PUBLISHER/v1/blobs?send_object_to=$ADDRESS" --upload-file "file.dat"
存储响应:新建

首次存储 blob 时:

{
  "newlyCreated": {
    "blobObject": {
      "id": "0xe91e...c50",
      "registeredEpoch": 34,
      "blobId": "M4hsZGQ1oCktdzegB6HnI6Mi28S2nqOPHxK-W7_4BUk",
      "size": 17,
      "encodingType": "RS2",
      "certifiedEpoch": 34,
      "storage": {
        "id": "0x4748...5faf",
        "startEpoch": 34,
        "endEpoch": 35,
        "storageSize": 66034000
      },
      "deletable": false
    },
    "resourceOperation": {
      "registerFromScratch": {
        "encodedLength": 66034000,
        "epochsAhead": 1
      }
    },
    "cost": 132300
  }
}
存储响应:已认证

相同内容已存在且剩余有效期足够时:

{
  "alreadyCertified": {
    "blobId": "M4hsZGQ1oCktdzegB6HnI6Mi28S2nqOPHxK-W7_4BUk",
    "event": {
      "txDigest": "4XQHFa9S324wTzYHF3vsBSwpUZuLpmwTHYMFv9nsttSs",
      "eventSeq": "0"
    },
    "endEpoch": 35
  }
}

event 字段包含 Sui 事件 ID,可用于在 Suiscan 上查找交易。

读取 blob(聚合器)

使用 HTTP GET 从聚合器读取 blob:

# Read by blob ID
curl "$AGGREGATOR/v1/blobs/<BLOB_ID>" -o output.file

# Read by Sui object ID (also returns HTTP header attributes)
curl "$AGGREGATOR/v1/blobs/by-object-id/<OBJECT_ID>" -o output.file

通过 object ID 读取时,会识别以下属性键,并将其作为 HTTP 标头返回:content-disposition、content-encoding、content-language、content-location、content-type 和 link。

发布器、聚合器和上传中继:如何选择
服务方向主网可用性是否需要钱包
发布器写入(PUT)没有公共发布器。请运行自己的发布器,或使用上传中继 / SDK。是(WAL + SUI)
上传中继写入(PUT)https://upload-relay.mainnet.walrus.space是(WAL + SUI + 可选小费)
聚合器读取(GET)有许多公共聚合器,无费用,无需钱包。否
  • 主网聚合器(Mysten Labs): https://aggregator.walrus-mainnet.walrus.space
  • 测试网聚合器(Mysten Labs): https://aggregator.walrus-testnet.walrus.space
  • 测试网发布器(Mysten Labs): https://publisher.walrus-testnet.walrus.space

公共聚合器的完整列表可在 docs.wal.app/operators.json(JSON)和公共服务页面中查看。公共聚合器会设置 CORS 标头,因此浏览器可以直接读取。

由他人赞助的上传和无需钱包的上传

大多数用户既没有 SUI,也没有 WAL。Walrus 没有内置的 Gas 赞助机制;赞助意味着由你的某个钱包执行存储操作并付费。以下是三种模式:

模式谁签名谁付费用户是否无需钱包最适用于
后端发布器发布器钱包应用是接受 HTTP 原始字节并支付存储费用的后端
上传中继客户端或应用签名者客户端或应用签名者,另加中继小费(如已配置)仅当应用管理签名时无法打开大量节点连接的浏览器和移动客户端
直接使用 SDK代码配置的签名者应用钱包是,前提是后端持有签名者直接集成 Walrus 并在代码中控制签名的后端

参考架构:客户端使用你自己的凭据向后端进行身份验证;后端应用策略(配额、大小、时长),并将字节转发给你的发布器;发布器使用其已注资的钱包存储数据,并通过 send_object_to=<address> 将 Blob 对象发送给用户;后端返回 Blob ID。每次存储都会消耗真实的 WAL 和 SUI(在一个交易中预留 + 注册,在第二个交易中认证);没有免费套餐。

文档中提到的运营注意事项:

  • 切勿在主网上公开未经过身份验证的发布器。 任何能够访问它的人都能花费你钱包中的 SUI 和 WAL。请在其前面设置经过身份验证的发布器 JWT 流程或你自己的网关。
  • 不要使用一个钱包签署大量并发存储操作。 并发交易会争用同一批自有 Gas 和存储对象。发布器通过内部子钱包处理此问题;如果你要构建自己的上传器,也应采用这种方式。
  • 共享钱包时,请关闭 reuse_resources。 启用重用会导致两个正在进行的上传争用同一批对象,并可能造成 Blob 已注册但从未认证。
  • 确保资金钱包余额充足。 监控主钱包中的 SUI 和 WAL;发布器会从主钱包为其子钱包补充资金。
字节范围和流媒体

聚合器支持 HTTP Range 标头,并返回 206 Partial Content,从而允许浏览器在视频中定位播放。也可以使用查询参数形式:

curl -H "Range: bytes=0-999" "$AGGREGATOR/v1/blobs/<BLOB_ID>"
curl "$AGGREGATOR/v1/blobs/<BLOB_ID>/byte-range?start=0&length=1024"

<video> 或 <audio> 元素可以将聚合器 URL 用作其 src。按 Blob ID 读取时不会返回内容类型,且聚合器会有意阻止类型嗅探,因此请在 Blob 上设置 content-type 属性,并按对象 ID(/v1/blobs/by-object-id/<OBJECT_ID>)读取,以便返回标头,让浏览器播放内容而不是下载。字节范围读取只会验证获取到的字节,不会验证整个 Blob。

查询系统信息### 查询系统信息
# Get current epoch, storage cost, and network parameters
curl "$AGGREGATOR/v1/info"

返回 epoch 编号、epoch 时长和系统参数。可用于计算成本,并在存储请求中设置 epochs 之前检查当前 epoch。

规则
  1. Mainnet 上没有公共 Publisher。 在 Mainnet 上,请运行自己的经过身份验证的 Publisher,或使用 TypeScript SDK/上传中继。公共端点仅适用于 Testnet。
  2. 新 Blob 默认可删除。 如果需要保证可用性,请明确设置 permanent=true。
  3. 立即上传后重试读取。 CDN 前置的聚合器可能会短暂缓存 Blob 传播前的 404。请采用退避策略重试。
  4. 读取内容时使用 Blob ID,读取属性时使用对象 ID。 使用对象 ID 读取会返回 Blob 属性中的自定义 HTTP 标头。使用 Blob ID 读取则不会。
  5. 检查响应类型。 存储响应为 newlyCreated 或 alreadyCertified。两种情况都表示成功。
常见错误
  • 以为 Mainnet 上有公共 Publisher。 实际上没有。你必须运行自己的 Publisher、使用上传中继,或直接使用 TypeScript SDK。https://upload-relay.mainnet.walrus.space 上的上传中继是最简单的 Mainnet 写入途径。
  • 未检查响应中的 alreadyCertified。 当相同内容已有足够的有效期时,Publisher 会返回此状态。这不是错误。
  • 存储后立即读取,却收到 404。 CDN 缓存可能会导致短暂的 404。请采用退避策略重试。
  • 省略 epochs,导致仅存储 1 个 epoch。 默认值为 1 个 epoch。请务必明确设置 epochs。
  • 混淆 Publisher 和 Aggregator 的作用。 Publisher 负责存储(PUT),Aggregator 负责读取(GET)。它们是 URL 不同的独立服务。
  • 将 503 BLOB_UNAVAILABLE 视为永久性错误。 从 v1.47 起,如果 Blob 只是暂时无法读取,Aggregator 会返回可重试的 503,而不是 500。请采用退避策略重试。
  • 期待读取 Blob ID 时获得内容类型。 只有通过对象 ID 读取才会返回 content-type 等属性标头。
  • 在 Publisher 上遇到 413 Payload Too Large。 某些 Publisher 会限制上传大小(例如,公共 Testnet Publisher 限制为 10 MiB)。对于大型文件,请使用 CLI、TypeScript SDK,或运行自己的 Publisher。
  • 不明白为什么微小 Blob 的 storageSize 约为 66 MB。 无论 Blob 大小如何,Walrus 都会为每个 Blob 增加约 64 MB 的固定元数据开销。对于小于约 10 MB 的 Blob,元数据成本占主导。大量小型 Blob 请使用 quilts。
  • 使用过时的 Aggregator URL。 aggregator.walrus.site 和 aggregator.devnet.walrus.space 已过时。Mainnet 请使用 aggregator.walrus-mainnet.walrus.space,Testnet 请使用 aggregator.walrus-testnet.walrus.space。

评论

支持 Markdown