From bankr-agent-dev
Signs messages (personal_sign), EIP-712 typed data, transactions via Bankr API /agent/sign endpoint and submits raw transactions via /agent/submit using TypeScript fetch patterns.
npx claudepluginhub bankrbot/claude-plugins --plugin bankr-agent-devThis skill uses the workspace's default tool permissions.
Synchronous endpoints for signing and submitting transactions directly — no job polling required.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Checks Next.js compilation errors using a running Turbopack dev server after code edits. Fixes actionable issues before reporting complete. Replaces `next build`.
Synchronous endpoints for signing and submitting transactions directly — no job polling required.
| Endpoint | Purpose | Returns |
|---|---|---|
POST /agent/sign | Sign messages, typed data, or transactions | Signature |
POST /agent/submit | Submit raw transactions to chain | Transaction hash |
| Type | Use Case |
|---|---|
personal_sign | Plain text messages (auth, verification) |
eth_signTypedData_v4 | EIP-712 typed data (permits, orders) |
eth_signTransaction | Sign transactions for later broadcast |
// personal_sign
const signMessage = await fetch(`${API_URL}/agent/sign`, {
method: "POST",
headers: { "x-api-key": API_KEY, "Content-Type": "application/json" },
body: JSON.stringify({
signatureType: "personal_sign",
message: "Sign in to MyApp\nNonce: abc123",
}),
});
// → { success: true, signature: "0x...", signer: "0x...", signatureType: "personal_sign" }
// eth_signTypedData_v4 (EIP-2612 permit)
const signPermit = await fetch(`${API_URL}/agent/sign`, {
method: "POST",
headers: { "x-api-key": API_KEY, "Content-Type": "application/json" },
body: JSON.stringify({
signatureType: "eth_signTypedData_v4",
typedData: {
domain: { name: "USD Coin", version: "2", chainId: 8453, verifyingContract: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" },
types: {
Permit: [
{ name: "owner", type: "address" },
{ name: "spender", type: "address" },
{ name: "value", type: "uint256" },
{ name: "nonce", type: "uint256" },
{ name: "deadline", type: "uint256" },
],
},
primaryType: "Permit",
message: { owner: "0x...", spender: "0x...", value: "1000000", nonce: "0", deadline: "1735689600" },
},
}),
});
// eth_signTransaction
const signTx = await fetch(`${API_URL}/agent/sign`, {
method: "POST",
headers: { "x-api-key": API_KEY, "Content-Type": "application/json" },
body: JSON.stringify({
signatureType: "eth_signTransaction",
transaction: { to: "0x...", chainId: 8453, value: "0", data: "0xa9059cbb..." },
}),
});
| Status | Error | Cause |
|---|---|---|
| 400 | Missing required field | Missing message, typedData, or transaction |
| 401 | Authentication required | Missing or invalid API key |
| 403 | Read-only API key | Key lacks write permissions |
| Field | Type | Required | Description |
|---|---|---|---|
to | string | Yes | Destination address |
chainId | number | Yes | Chain ID (8453=Base, 1=Ethereum, 137=Polygon) |
value | string | No | Value in wei |
data | string | No | Calldata (hex) |
gas | string | No | Gas limit |
maxFeePerGas | string | No | EIP-1559 max fee |
maxPriorityFeePerGas | string | No | EIP-1559 priority fee |
| Field | Type | Default | Description |
|---|---|---|---|
description | string | — | Human-readable description for logging |
waitForConfirmation | boolean | true | Wait for on-chain confirmation |
// Submit a transaction and wait for confirmation
const result = await fetch(`${API_URL}/agent/submit`, {
method: "POST",
headers: { "x-api-key": API_KEY, "Content-Type": "application/json" },
body: JSON.stringify({
transaction: { to: "0x...", chainId: 8453, value: "1000000000000000000" },
description: "Send 1 ETH",
waitForConfirmation: true,
}),
});
// → { success: true, transactionHash: "0x...", status: "success", blockNumber: "123", gasUsed: "21000" }
// Fire-and-forget (don't wait for confirmation)
const pending = await fetch(`${API_URL}/agent/submit`, {
method: "POST",
headers: { "x-api-key": API_KEY, "Content-Type": "application/json" },
body: JSON.stringify({
transaction: { to: "0x...", chainId: 8453, value: "100000000000000000" },
waitForConfirmation: false,
}),
});
// → { success: true, transactionHash: "0x...", status: "pending" }
// Approve + Swap sequence
async function approveAndSwap(approveTx: object, swapTx: object) {
// 1. Approve token spending
const approval = await submitTransaction(approveTx);
if (approval.status !== "success") throw new Error("Approval failed");
// 2. Execute swap
const swap = await submitTransaction(swapTx);
if (swap.status !== "success") throw new Error("Swap failed");
return swap;
}
| Status | Description |
|---|---|
success | Confirmed and succeeded |
reverted | Confirmed but reverted |
pending | Submitted, not yet confirmed |
| Feature | /agent/prompt | /agent/sign | /agent/submit |
|---|---|---|---|
| Input | Natural language | Structured data | Transaction object |
| Response | Async (job ID) | Sync (signature) | Sync (tx hash) |
| Executes on-chain | Via AI agent | No | Yes |
| Best for | General queries | Auth, permits | Raw transactions |
/agent/submit executes immediately — no confirmation promptwaitForConfirmation: true for critical transactionsbankr-api-basics - API fundamentalsbankr-client-patterns - Client setupbankr-safety - Security best practicesbankr-arbitrary-transaction - Constructing raw transaction JSON