签名和提交 API
用于直接签名并提交交易的同步端点——无需轮询任务。
端点
| 端点 | 用途 | 返回值 |
|---|
POST /agent/sign | 为消息、类型化数据或交易签名 | 签名 |
POST /agent/submit | 向链提交原始交易 | 交易哈希 |
POST /agent/sign
签名类型
| 类型 | 使用场景 |
|---|
personal_sign | 纯文本消息(身份验证、验证) |
eth_signTypedData_v4 | EIP-712 类型化数据(授权、订单) |
eth_signTransaction | 为稍后广播而签署交易 |
用法
// 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..." },
}),
});
错误响应
| 状态 | 错误 | 原因 |
|---|
| 400 | 缺少必填字段 | 缺少 message、typedData 或 transaction |
| 401 | 需要身份验证 | 缺少或无效的 API 密钥 |
| 403 | 只读 API 密钥 | 密钥没有写入权限 |
POST /agent/submit
交易字段
| 字段 | 类型 | 必填 | 描述 |
|---|
to | string | 是 | 目标地址 |
chainId | number | 是 | 链 ID(8453=Base、1=Ethereum、137=Polygon) |
value | string | 否 | 以 wei 为单位的值 |
data | string | 否 | 调用数据(hex) |
gas | string | 否 | Gas 上限 |
maxFeePerGas | string | 否 | EIP-1559 最高费用 |
maxPriorityFeePerGas | string | 否 | EIP-1559 优先费用 |
选项
| 字段 | 类型 | 默认值 | 描述 |
|---|
description | string | — | 用于日志记录的易读描述 |
waitForConfirmation | boolean | true | 等待链上确认 |
用法
// 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;
}
交易状态值
| 状态 | 描述 |
|---|
success | 已确认且成功 |
reverted | 已确认但已回滚 |
pending | 已提交,尚未确认 |
与 /agent/prompt 的比较
| 功能 | /agent/prompt | /agent/sign | /agent/submit |
|---|
| 输入 | 自然语言 | 结构化数据 | 交易对象 |
| 响应 | 异步(任务 ID) | 同步(签名) | 同步(交易哈希) |
| 在链上执行 | 通过 AI Agent | 否 | 是 |
| 适用场景 | 常规查询 | 身份验证、授权 | 原始交易 |
安全说明
/agent/submit 会立即执行——不会提示确认
- 只读 API 密钥在两个端点上都会返回 403
- 提交前务必验证交易参数
- 对关键交易使用
waitForConfirmation: true
相关技能
bankr-api-basics - API 基础知识
bankr-client-patterns - 客户端设置
bankr-safety - 安全最佳实践
bankr-arbitrary-transaction - 构造原始交易 JSON