erc8128: 以太坊 HTTP 身份验证与签名 - Openclaw Skills
作者:互联网
2026-04-05
什么是 erc8128?
ERC-8128 通过集成以太坊钱包签名功能,扩展了 RFC 9421 HTTP 消息签名标准。这允许开发者构建身份验证 API,用户或自动代理可以使用现有的以太坊密钥进行身份验证,而无需使用传统的 API 密钥或密码。通过利用 Openclaw Skills 提供的此类功能,您可以确保所有 HTTP 通信的加密完整性和真实性,而无需管理新的凭据集。
该技能既提供了一个用于无缝集成到 Web 应用程序的高级 JavaScript 库,也提供了一个用于手动或脚本交互的功能强大的 CLI 工具。它处理复杂的任务,如请求绑定、用于重放保护的随机数(nonce)管理以及详细的验证策略,使其成为现代去中心化基础设施和代理到服务器通信的重要组件。
下载入口:https://github.com/openclaw/skills/tree/main/skills/jacopo-eth/erc8128
安装与下载
1. ClawHub CLI
从源直接安装技能的最快方式。
npx clawhub@latest install erc8128
2. 手动安装
将技能文件夹复制到以下位置之一
全局模式~/.openclaw/skills/
工作区
/skills/
优先级:工作区 > 本地 > 内置
3. 提示词安装
将此提示词复制到 OpenClaw 即可自动安装。
请帮我使用 Clawhub 安装 erc8128。如果尚未安装 Clawhub,请先安装(npm i -g clawhub)。
erc8128 应用场景
- 使用操作密钥将去中心化代理验证到中心化后端服务器。
- 为 Web3 API 和 dApp 实现基于钱包的登录和会话管理。
- 使用加密签名的随机数和过期时间戳保护 API 端点免受重放攻击。
- 确保 HTTP 标头、方法和请求体的完整性,以防止中间人篡改。
- 使用以太坊账户初始化签名器,该账户可以衍生自私钥、环境变量或加密密钥库文件。
- 选择签名策略,例如请求绑定策略(签署 authority、方法、路径和正文摘要),或类绑定策略(用于可重用组件签名)。
- 生成包含安全元数据的签名,如唯一的随机数和创建时间戳。
- 根据 ERC-8128 规范将生成的签名附加到 HTTP 请求标头中。
- 在接收服务器上,使用验证器客户端根据提供的以太坊地址检查签名,并根据自定义验证策略进行校验。
erc8128 配置指南
使用 npm 安装核心库,以便集成到您的 JavaScript 或 TypeScript 项目中:
npm install @slicekit/erc8128
要使用命令行界面进行手动请求和测试,请全局安装 CLI 软件包:
npm install -g @slicekit/erc8128-cli
erc8128 数据架构与分类体系
该技能使用以下 HTTP 组件结构来组织签名数据和验证元数据:
| 组件 | 描述 |
|---|---|
| @authority | HTTP 请求的目标域名或主机。 |
| @method | 使用的 HTTP 方法(如 GET、POST、PUT)。 |
| @path | 服务器上的特定资源路径。 |
| content-digest | 请求体的 SHA-256 哈希值,用于确保数据完整性。 |
| nonce | 用于防止重放攻击的唯一字符串;通过 NonceStore 管理。 |
| created | 指示签名生成时间的 Unix 时间戳。 |
name: erc8128
description: Sign and verify HTTP requests with Ethereum wallets using ERC-8128. Use when building authenticated APIs that need wallet-based auth, making signed requests to ERC-8128 endpoints, implementing request verification in servers, or working with agent-to-server authentication. Covers both the @slicekit/erc8128 JS library and the erc8128 CLI.
ERC-8128: Ethereum HTTP Signatures
ERC-8128 extends RFC 9421 (HTTP Message Signatures) with Ethereum wallet signing. It enables HTTP authentication using existing Ethereum keys—no new credentials needed.
?? Full documentation: erc8128.slice.so
When to Use
- API authentication — Wallets already onchain can authenticate to your backend
- Agent auth — Bots and agents sign requests with their operational keys
- Replay protection — Signatures include nonces and expiration
- Request integrity — Sign URL, method, headers, and body
Packages
| Package | Purpose |
|---|---|
@slicekit/erc8128 |
JS library for signing and verifying |
@slicekit/erc8128-cli |
CLI for signed requests (erc8128 curl) |
Library: @slicekit/erc8128
Sign requests
import { createSignerClient } from '@slicekit/erc8128'
import type { EthHttpSigner } from '@slicekit/erc8128'
import { privateKeyToAccount } from 'viem/accounts'
const account = privateKeyToAccount('0x...')
const signer: EthHttpSigner = {
chainId: 1,
address: account.address,
signMessage: async (msg) => account.signMessage({ message: { raw: msg } }),
}
const client = createSignerClient(signer)
// Sign and send
const response = await client.fetch('https://api.example.com/orders', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ amount: '100' }),
})
// Sign only (returns new Request with signature headers)
const signedRequest = await client.signRequest('https://api.example.com/orders')
Verify requests
import { createVerifierClient } from '@slicekit/erc8128'
import type { NonceStore } from '@slicekit/erc8128'
import { createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'
// NonceStore interface for replay protection
const nonceStore: NonceStore = {
consume: async (key: string, ttlSeconds: number): Promise => {
// Return true if nonce was successfully consumed (first use)
// Return false if nonce was already used (replay attempt)
}
}
const publicClient = createPublicClient({ chain: mainnet, transport: http() })
const verifier = createVerifierClient(publicClient.verifyMessage, nonceStore)
const result = await verifier.verifyRequest(request)
if (result.ok) {
console.log(`Authenticated: ${result.address} on chain ${result.chainId}`)
} else {
console.log(`Failed: ${result.reason}`)
}
Sign options
| Option | Type | Default | Description |
|---|---|---|---|
binding |
"request-bound" | "class-bound" |
"request-bound" |
What to sign |
replay |
"non-replayable" | "replayable" |
"non-replayable" |
Include nonce |
ttlSeconds |
number |
60 |
Signature validity |
components |
string[] |
— | Additional components to sign |
contentDigest |
"auto" | "recompute" | "require" | "off" |
"auto" |
Content-Digest handling |
request-bound: Signs @authority, @method, @path, @query (if present), and content-digest (if body present). Each request is unique.
class-bound: Signs only the components you explicitly specify. Reusable across similar requests. Requires components array.
?? See Request Binding for details.
Verify policy
| Option | Type | Default | Description |
|---|---|---|---|
maxValiditySec |
number |
300 |
Max allowed TTL |
clockSkewSec |
number |
0 |
Allowed clock drift |
replayable |
boolean |
false |
Allow nonce-less signatures |
classBoundPolicies |
string[] | string[][] |
— | Accepted class-bound component sets |
?? See Verifying Requests and VerifyPolicy for full options.
CLI: erc8128 curl
For CLI usage, see references/cli.md.
Quick examples:
# GET with keystore
erc8128 curl --keystore ./key.json https://api.example.com/data
# POST with JSON
erc8128 curl -X POST r
-H "Content-Type: application/json" r
-d '{"foo":"bar"}' r
--keyfile ~/.keys/bot.key r
https://api.example.com/submit
# Dry run (sign only)
erc8128 curl --dry-run -d @body.json --keyfile ~/.keys/bot.key https://api.example.com
?? See CLI Guide for full documentation.
Common Patterns
Express middleware
import { verifyRequest } from '@slicekit/erc8128'
import type { NonceStore } from '@slicekit/erc8128'
import { createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'
const publicClient = createPublicClient({ chain: mainnet, transport: http() })
// Implement NonceStore (Redis example)
const nonceStore: NonceStore = {
consume: async (key, ttlSeconds) => {
const result = await redis.set(key, '1', 'EX', ttlSeconds, 'NX')
return result === 'OK'
}
}
async function erc8128Auth(req, res, next) {
const result = await verifyRequest(
toFetchRequest(req), // Convert Express req to Fetch Request
publicClient.verifyMessage,
nonceStore
)
if (!result.ok) {
return res.status(401).json({ error: result.reason })
}
req.auth = { address: result.address, chainId: result.chainId }
next()
}
Agent signing (with key file)
import { createSignerClient } from '@slicekit/erc8128'
import type { EthHttpSigner } from '@slicekit/erc8128'
import { privateKeyToAccount } from 'viem/accounts'
import { readFileSync } from 'fs'
const key = readFileSync(process.env.KEYFILE, 'utf8').trim()
const account = privateKeyToAccount(key as `0x${string}`)
const signer: EthHttpSigner = {
chainId: Number(process.env.CHAIN_ID) || 1,
address: account.address,
signMessage: async (msg) => account.signMessage({ message: { raw: msg } }),
}
const client = createSignerClient(signer)
// Use client.fetch() for all authenticated requests
Verify failure reasons
type VerifyFailReason =
| 'missing_headers'
| 'label_not_found'
| 'bad_signature_input'
| 'bad_signature'
| 'bad_keyid'
| 'bad_time'
| 'not_yet_valid'
| 'expired'
| 'validity_too_long'
| 'nonce_required'
| 'replayable_not_allowed'
| 'replayable_invalidation_required'
| 'replayable_not_before'
| 'replayable_invalidated'
| 'class_bound_not_allowed'
| 'not_request_bound'
| 'nonce_window_too_long'
| 'replay'
| 'digest_mismatch'
| 'digest_required'
| 'alg_not_allowed'
| 'bad_signature_bytes'
| 'bad_signature_check'
?? See VerifyFailReason for descriptions.
Key Management
For agents and automated systems:
| Method | Security | Use Case |
|---|---|---|
--keyfile |
Medium | Unencrypted key file, file permissions for protection |
--keystore |
High | Encrypted JSON keystore, password required |
ETH_PRIVATE_KEY |
Low | Environment variable, avoid in production |
| Signing service | High | Delegate to external service (SIWA, AWAL) |
Documentation
- Full docs: erc8128.slice.so
- Quick Start: erc8128.slice.so/getting-started/quick-start
- Concepts: erc8128.slice.so/concepts/overview
- API Reference: erc8128.slice.so/api/signRequest
- ERC-8128 Spec: GitHub
相关推荐
专题
+ 收藏
+ 收藏
+ 收藏
+ 收藏
+ 收藏
+ 收藏
最新数据
相关文章
OpenClaw 模型故障转移:自动 LLM 冗余 - Openclaw Skills
Prawnpt War Defender:AI 提示词攻防安全 - Openclaw Skills
Markdown 转 PDF:将 MD 转换为高质量 PDF - Openclaw Skills
YouTube 视频下载器:通过 Openclaw Skills 进行媒体管理
YouTube 视频下载器:专业的媒体提取工具 - Openclaw Skills
X 趋势:分析 Twitter 实时热门话题 - Openclaw Skills
X 趋势技能:实时 Twitter 分析 - Openclaw Skills
X (Twitter) 趋势工具:搜索与分析热门话题 - Openclaw Skills
x-trends: 分析 X 和 Twitter 趋势话题 - Openclaw Skills
PDF 工具:提取、OCR 和操作 PDF - Openclaw Skills
AI精选
Billie Eilish 卡通版 3D 渲染提示词
从程序员到AI工程师:距离有多远?附全套学习路线图
ArkClaw 养虾省钱攻略,这 10% 的返利你还不知道?
大模型就是你雇的员工:从职场管理学看 AI 协作范式的三次进化
MinerU JS/TS SDK 深度指南:JavaScript/TypeScript 开发者的 PDF/文档解析利器
AI 自动值夜班时代来了!Claude Code 刚刚推出 Routines
一天一个开源项目(第74篇):OpenCLI - 把任意网站变成零成本 CLI 工具的 AI Agent 基础设施
就在刚刚,腾讯版 Hermes Agent 来了!快速部署,安装即用!
