ワンクリックで
siwa-keyring-proxy
Self-hosted keyring proxy signer with optional 2FA for secure key isolation.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Self-hosted keyring proxy signer with optional 2FA for secure key isolation.
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.
Circle developer-controlled wallet integration for SIWA authentication.
| name | siwa-keyring-proxy |
| version | 0.2.0 |
| description | Self-hosted keyring proxy signer with optional 2FA for secure key isolation. |
Sign SIWA messages using a self-hosted keyring proxy. The private key is stored securely in the proxy — your agent never touches it.
One-click deploy to Railway:
Or run with Docker:
docker run -p 3100:3100 \
-e KEYRING_PROXY_SECRET=your-shared-secret \
-e KEYSTORE_PASSWORD=your-keystore-password \
ghcr.io/builders-garden/siwa-keyring-proxy
npm install @buildersgarden/siwa
import { createKeyringProxySigner } from "@buildersgarden/siwa/signer";
const signer = createKeyringProxySigner({
proxyUrl: process.env.KEYRING_PROXY_URL!,
proxySecret: process.env.KEYRING_PROXY_SECRET!,
});
If your agent doesn't have an ERC-8004 identity yet, register onchain first:
import { registerAgent } from "@buildersgarden/siwa/registry";
const result = await registerAgent({
agentURI: "data:application/json;base64,...", // or ipfs://...
chainId: 84532, // Base Sepolia
signer,
});
console.log("Agent ID:", result.agentId);
console.log("Registry:", result.agentRegistry);
console.log("Tx Hash:", result.txHash);
The agentURI contains your agent's metadata (name, description, capabilities). You can use a base64 data URI or IPFS.
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);
Create and manage wallets via the keystore module:
import { createWallet, getAddress } from "@buildersgarden/siwa/keystore";
// Create a new wallet (stored encrypted in the proxy)
const address = await createWallet({
proxyUrl: process.env.KEYRING_PROXY_URL!,
proxySecret: process.env.KEYRING_PROXY_SECRET!,
});
// Get the wallet address
const addr = await getAddress({
proxyUrl: process.env.KEYRING_PROXY_URL!,
proxySecret: process.env.KEYRING_PROXY_SECRET!,
});
KEYRING_PROXY_URL=https://your-proxy.up.railway.app
KEYRING_PROXY_SECRET=your-shared-hmac-secret
Agent Keyring Proxy Target API
| | |
+-- signMessage() --------> | |
| (HMAC authenticated) | Signs with private key |
| | Returns signature only |
| | |
+-- fetch(signedRequest) ---|-----------------------> |
| | Verifies signature
KEYSTORE_PASSWORD