用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/johnalbertini14-glitch/openclaw-skills --skill siwa命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Use this skill to create a Polymarket wallet for your agent and trade on prediction markets. Browse markets, place bets, manage positions — all without exposing private keys.
ClawSec suite manager with embedded advisory-feed monitoring, cryptographic signature verification, approval-gated malicious-skill response, and guided setup for additional security skills.
Automated daily security audits for OpenClaw agents with email reporting. Runs deep audits and sends formatted reports.
基于 SOC 职业分类
正在显示 SKILL.md
| name | siwa |
| version | 0.2.0 |
| description | SIWA (Sign-In With Agent) authentication for ERC-8004 registered agents. |
Sign-In With Agent (SIWA) lets AI agents authenticate with services using their ERC-8004 onchain identity.
npm install @buildersgarden/siwa
Choose based on your wallet provider:
| Import | Description |
|---|---|
@buildersgarden/siwa | Core: signSIWAMessage, verifySIWA, createSIWANonce, parseSIWAMessage, buildSIWAMessage, createClientResolver, parseChainId |
@buildersgarden/siwa/signer | Signer factories (see wallet-specific skills above) |
@buildersgarden/siwa/erc8128 | ERC-8128 HTTP signing/verification |
@buildersgarden/siwa/receipt | HMAC receipt helpers |
@buildersgarden/siwa/nonce-store | Nonce stores (Memory, Redis, KV) |
@buildersgarden/siwa/identity | SIWA_IDENTITY.md helpers |
@buildersgarden/siwa/registry | Onchain agent registration |
@buildersgarden/siwa/client-resolver | Dynamic PublicClient resolution for multi-chain servers |
@buildersgarden/siwa/next | Next.js middleware (withSiwa, siwaOptions) |
@buildersgarden/siwa/express | Express middleware (siwaMiddleware, siwaJsonParser, siwaCors) |
@buildersgarden/siwa/hono | Hono middleware (siwaMiddleware, siwaCors) |
@buildersgarden/siwa/fastify | Fastify middleware (siwaPlugin, siwaAuth) |
@buildersgarden/siwa/x402 | x402 payment helpers |
@buildersgarden/siwa/captcha | Reverse CAPTCHA (prove you're an AI) |
When an API requires payment, it returns HTTP 402 with a Payment-Required header. The agent decodes the payment options, constructs a signed payment, and retries with a Payment-Signature header — all while maintaining SIWA authentication.
import {
encodeX402Header,
decodeX402Header,
type PaymentRequired,
type PaymentPayload,
} from "@buildersgarden/siwa/x402";
import { signAuthenticatedRequest } from "@buildersgarden/siwa/erc8128";
// 1. Make initial authenticated request (may get 402)
const signedRequest = await signAuthenticatedRequest(
new Request("https://api.example.com/premium", { method: "POST" }),
receipt,
signer,
84532,
);
const res = await fetch(signedRequest);
if (res.status === 402) {
// 2. Decode payment requirements from header
const header = res.headers.get("Payment-Required");
const { accepts, resource } = decodeX402Header<PaymentRequired>(header!);
// 3. Pick a payment option and construct payload
const option = accepts[0];
const payload: PaymentPayload = {
signature: "0x...", // sign the payment with your wallet
payment: {
scheme: option.scheme,
network: option.network,
: option.,
: option.,
: option.,
},
resource,
};
retryRequest = (
(, {
: ,
: {
: (payload),
},
}),
receipt,
signer,
,
);
paidRes = (retryRequest);
}
| Header | Direction | Description |
|---|---|---|
Payment-Required | Server → Agent | Base64-encoded JSON with accepted payment options. Sent with 402. |
Payment-Signature | Agent → Server | Base64-encoded signed payment payload. |
Payment-Response | Server → Agent | Base64-encoded settlement result with transaction hash. |
Some endpoints use pay-once mode: the first request requires payment, subsequent requests from the same agent to the same resource pass through without payment until the session expires. If you receive a 200 on a previously-paid endpoint, the session is still active — no need to pay again.
SIWA includes a "reverse CAPTCHA" mechanism — inspired by MoltCaptcha — that proves an entity is an AI agent, not a human. Challenges exploit how LLMs generate text in a single autoregressive pass (satisfying multiple constraints simultaneously), while humans must iterate.
Two integration points:
The SDK provides two convenience wrappers for the captcha retry pattern:
solveCaptchaChallenge()import { solveCaptchaChallenge } from "@buildersgarden/siwa/captcha";
// 1. Request nonce
const nonceRes = await fetch("/api/siwa/nonce", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ address, agentId, agentRegistry }),
});
const data = await nonceRes.json();
// 2. Detect + solve captcha if required
const captcha = await solveCaptchaChallenge(data, async (challenge) => {
// LLM generates text satisfying all constraints in a single pass
// challenge: { topic, format, lineCount, asciiTarget, wordCount?, timeLimitSeconds, ... }
// Your LLM generates text satisfying all constraints in one pass.
// Use any provider (Anthropic, OpenAI, etc.) — the solver just returns a string.
return await generateText(challenge);
});
if (captcha.solved) {
// 3. Retry with challenge response
const retryRes = await fetch("/api/siwa/nonce", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.({ address, agentId, agentRegistry, : captcha. }),
});
}
retryWithCaptcha()import { signAuthenticatedRequest, retryWithCaptcha } from "@buildersgarden/siwa/erc8128";
const url = "https://api.example.com/action";
const body = JSON.stringify({ key: "value" });
// 1. Sign and send
const signed = await signAuthenticatedRequest(
new Request(url, { method: "POST", body }),
receipt, signer, chainId,
);
const response = await fetch(signed);
// 2. Detect + solve captcha, re-sign, and get retry request
const result = await retryWithCaptcha(
response,
new Request(url, { method: "POST", body }), // fresh request (original body consumed)
receipt, signer, chainId,
async (challenge) => generateText(challenge), // your LLM solver
);
if (result.retry) {
const retryResponse = await fetch(result.request);
}
Note: Pass a fresh, unconsumed Request to
retryWithCaptcha— the original is consumed after signing/sending.
| Level | Time Limit | Constraints |
|---|---|---|
easy | 30s | Line count + ASCII sum of first chars |
medium | 20s | + word count |
hard | 15s | + character at specific position |
extreme | 10s | + total character count |