一键导入
siwa-circle
Circle developer-controlled wallet integration for SIWA authentication.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Circle developer-controlled wallet integration for SIWA authentication.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Magic server wallet integration for SIWA authentication.
SIWA (Sign-In With Agent) authentication for ERC-8004 registered agents.
Openfort backend wallet integration for SIWA authentication.
Use this skill to implement server-side SIWA verification. For backends and APIs that need to authenticate ERC-8004 agents without signing capabilities.
Bankr wallet integration for SIWA authentication.
Self-hosted keyring proxy signer with optional 2FA for secure key isolation.
| name | siwa-circle |
| version | 0.2.0 |
| description | Circle developer-controlled wallet integration for SIWA authentication. |
Sign SIWA messages using Circle's developer-controlled wallets.
npm install @buildersgarden/siwa @circle-fin/developer-controlled-wallets
import { createCircleSiwaSigner } from "@buildersgarden/siwa/signer";
const signer = await createCircleSiwaSigner({
apiKey: process.env.CIRCLE_API_KEY!,
entitySecret: process.env.CIRCLE_ENTITY_SECRET!,
walletId: process.env.CIRCLE_WALLET_ID!,
});
The wallet address is fetched automatically from Circle.
If you already have a Circle client instance:
import { initiateDeveloperControlledWalletsClient } from "@circle-fin/developer-controlled-wallets";
import { createCircleSiwaSignerFromClient } from "@buildersgarden/siwa/signer";
const client = initiateDeveloperControlledWalletsClient({
apiKey: process.env.CIRCLE_API_KEY!,
entitySecret: process.env.CIRCLE_ENTITY_SECRET!,
});
const signer = await createCircleSiwaSignerFromClient({
client,
walletId: process.env.CIRCLE_WALLET_ID!,
});
If your agent doesn't have an ERC-8004 identity yet, register onchain using Circle's contract execution API:
import { initiateDeveloperControlledWalletsClient } from "@circle-fin/developer-controlled-wallets";
const client = initiateDeveloperControlledWalletsClient({
apiKey: process.env.CIRCLE_API_KEY!,
entitySecret: process.env.CIRCLE_ENTITY_SECRET!,
});
const IDENTITY_REGISTRY_ADDRESS = "0x8004A818BFB912233c491871b3d84c89A494BD9e"; //According to the chain
// Prepare agent metadata
const metadata = {
name: "My Agent",
description: "A helpful AI assistant",
capabilities: ["chat", "analysis"],
};
const agentURI = `data:application/json;base64,${Buffer.from(JSON.stringify(metadata)).toString("base64")}`;
// Call the register(string agentURI) function on the registry
const response = await client.createContractExecutionTransaction({
walletId: process.env.CIRCLE_WALLET_ID!,
contractAddress: IDENTITY_REGISTRY_ADDRESS,
abiFunctionSignature: "register(string)",
abiParameters: [agentURI],
fee: {
type: "level",
config: {
feeLevel: "HIGH",
},
},
});
const tx = response.data;
console.log("Transaction ID:", tx?.id);
console.log("Transaction hash:", tx?.txHash);
The authentication flow consists of two steps:
Note: The URLs below (
api.example.com) are placeholders. Replace them with your own server that implements the SIWA verification endpoints. See the Server-Side Verification skill for implementation details.
/siwa/nonce endpoint/siwa/verifyconst nonceRes = await fetch("https://api.example.com/siwa/nonce", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
address: await signer.getAddress(),
agentId: 42,
agentRegistry: "eip155:84532:0x8004A818BFB912233c491871b3d84c89A494BD9e",
}),
});
const { nonce, nonceToken, issuedAt, expirationTime } = await nonceRes.json();
import { signSIWAMessage } from "@buildersgarden/siwa";
const { message, signature, address } = await signSIWAMessage({
domain: "api.example.com",
uri: "https://api.example.com/siwa",
agentId: 42,
agentRegistry: "eip155:84532:0x8004A818BFB912233c491871b3d84c89A494BD9e", //According to the chain
chainId: 84532,
nonce,
issuedAt,
expirationTime,
}, signer);
// Send to server for verification
const verifyRes = await fetch("https://api.example.com/siwa/verify", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ message, signature, nonceToken }),
});
const { receipt, agentId } = await verifyRes.json();
// Store the receipt for authenticated API calls
import { signAuthenticatedRequest } from "@buildersgarden/siwa/erc8128";
const request = new Request("https://api.example.com/action", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ action: "execute" }),
});
const signedRequest = await signAuthenticatedRequest(
request,
receipt, // from SIWA sign-in
signer,
84532,
);
const response = await fetch(signedRequest);
CIRCLE_API_KEY=your-circle-api-key
CIRCLE_ENTITY_SECRET=your-entity-secret
CIRCLE_WALLET_ID=your-wallet-id