EIP-5792 是以太坊的一项标准提案,全称为 "钱包调用 API"(Wallet Calls API) ,旨在为钱包和去中心化应用(DApps)之间的交互提供更高效、灵活的通信机制。该提案由 MetaMask、WalletConnect 等团队的核心成员共同制定,并于 2022 年 10 月提出,目前已在多个主流钱包和 DApp(如 Uniswap)中实现支持。
1. 核心功能
EIP-5792 定义了新的 JSON-RPC 方法,使 DApps 能够:
- 批量发送交易:在单个请求中提交多个链上调用(如授权 + 交易组合),减少用户操作步骤和 Gas 成本。
- 原子性执行:确保多个调用要么全部成功,要么全部回滚,避免部分失败导致的状态不一致问题。
- 能力发现机制:DApps 可以查询钱包支持的功能(如 Paymaster 支付、EIP-7702 授权等),并动态调整交互方式。
- 跨链兼容:支持多链交互,允许 DApp 在不同区块链上执行操作。
2. 主要 JSON-RPC 方法
EIP-5792 引入了以下关键 API:
(1) wallet_sendCalls
-
用途:请求钱包执行一批链上调用(如
approve+swap)。 -
参数示例:
json
{ "version": "2.0.0", "chainId": "0x1", // 以太坊主网 "atomicRequired": true, // 是否要求原子性 "calls": [ { "to": "0x...", // 合约地址 "data": "0x...", // 调用数据 "value": "0x0" } ], "capabilities": { "paymasterService": { "url": "https://..." } // 可选 Paymaster 配置 } } -
返回值:包含批处理 ID,用于后续状态查询。
(2) wallet_getCallsStatus
- 用途:查询批处理调用的执行状态(成功/失败/待处理)。
(3) wallet_getCapabilities
- 用途:获取钱包支持的功能(如是否支持 EIP-7702 授权、Paymaster 等)。
3. 实际应用案例
(1) Uniswap 的 "一键闪兑"
- Uniswap 已集成 EIP-5792,用户可单次签名完成授权 + 交易,无需多次确认,Gas 成本降低 30% 以上。
- 结合 EIP-7702,支持临时智能账户授权,提升安全性。
(2) MetaMask 批量交易
- 允许用户批量执行多笔交易,减少操作步骤。
4. 在Metamask中的实现
相关源码:
1. 整体架构层次
EIP-5792的实现分为三个主要层次:
UI层 (metamask-extension)
↓
EIP-5792 API层 (eip5792.ts)
↓
交易控制器层 (TransactionController.ts)
↓
批量处理工具层 (batch.ts)
↓
底层交易执行
2. 核心组件分析
2.1 EIP-5792 API层 (eip5792.ts)
主要功能:
- 提供
eth_sendCallsRPC方法 - 处理批量交易请求
- 查询交易状态
- 检测网络和账户能力
关键函数:
// 处理批量交易请求
export async function processSendCalls(
hooks: { /* 各种控制器钩子 */ },
messenger: EIP5792Messenger,
params: SendCalls,
req: JsonRpcRequest & { networkClientId: string; origin?: string },
): Promise<SendCallsResult>
// 查询交易状态
export function getCallsStatus(
messenger: EIP5792Messenger,
id: Hex,
): GetCallsStatusResult
// 检测能力
export async function getCapabilities(
hooks: { /* 能力检测钩子 */ },
messenger: EIP5792Messenger,
address: Hex,
chainIds: Hex[] | undefined,
)
2.2 交易控制器层 (TransactionController.ts)
核心方法:
// 添加批量交易
async addTransactionBatch(
request: TransactionBatchRequest,
): Promise<TransactionBatchResult>
// 检查原子批量支持
async isAtomicBatchSupported(
request: IsAtomicBatchSupportedRequest,
): Promise<IsAtomicBatchSupportedResult>
状态管理:
export type TransactionControllerState = {
transactions: TransactionMeta[];
transactionBatches: TransactionBatchMeta[]; // 批量交易元数据
// ... 其他状态
};
2.3 批量处理工具层 (batch.ts)
主要功能:
- 批量交易的核心逻辑
- 支持多种批量执行方式
- 与EIP-7702集成
3. 批量交易执行流程
3.1 执行路径选择
export async function addTransactionBatch(
request: AddTransactionBatchRequest,
): Promise<TransactionBatchResult> {
// 1. 优先尝试EIP-7702
if (!transactionBatchRequest.disable7702) {
try {
return await addTransactionBatchWith7702(request);
} catch (error) {
// 如果EIP-7702不支持,回退到钩子方式
}
}
// 2. 使用发布钩子
return await addTransactionBatchWithHook(request);
}
3.2 EIP-7702执行路径
async function addTransactionBatchWith7702(
request: AddTransactionBatchRequest,
) {
// 1. 检查链是否支持EIP-7702
const isChainSupported = doesChainSupportEIP7702(chainId, messenger);
// 2. 检查账户是否已升级
const { delegationAddress, isSupported } = await isAccountUpgradedToEIP7702(
from, chainId, publicKeyEIP7702, messenger, ethQuery
);
// 3. 生成批量交易参数
const batchParams = generateEIP7702BatchTransaction(from, nestedTransactions);
// 4. 如果账户未升级,添加升级逻辑
if (!isSupported) {
txParams.type = TransactionEnvelopeType.setCode;
txParams.authorizationList = [{ address: upgradeContractAddress }];
}
// 5. 添加交易到控制器
const { result } = await addTransaction(txParams, {
batchId,
nestedTransactions,
type: TransactionType.batch,
});
}
3.3 钩子执行路径
async function addTransactionBatchWithHook(
request: AddTransactionBatchRequest,
): Promise<TransactionBatchResult> {
// 1. 选择发布钩子类型
let publishBatchHook = null;
if (!disableHook && requestPublishBatchHook) {
publishBatchHook = requestPublishBatchHook; // 自定义钩子
} else if (!disableSequential) {
publishBatchHook = sequentialPublishBatchHook.getHook(); // 顺序执行钩子
}
// 2. 收集所有交易
const collectHook = new CollectPublishHook(transactionCount);
// 3. 处理每个交易
for (const nestedTransaction of nestedTransactions) {
const hookTransaction = await processTransactionWithHook(
batchId, nestedTransaction, publishHook, request, txBatchMeta
);
hookTransactions.push(hookTransaction);
}
// 4. 执行批量发布
const result = await publishBatchHook({ from, networkClientId, transactions });
}
4. 关键特性
4.1 多种执行模式
- EIP-7702模式:原子批量执行,智能账户升级
- 自定义钩子模式:完全自定义的批量处理逻辑
- 顺序执行模式:按顺序逐个执行交易
- 回退机制:自动选择最佳执行方式
4.2 智能账户集成
// 检查账户是否支持EIP-7702
const { delegationAddress, isSupported } = await isAccountUpgradedToEIP7702(
from, chainId, publicKeyEIP7702, messenger, ethQuery
);
// 如果未升级,自动添加升级逻辑
if (!isSupported) {
txParams.type = TransactionEnvelopeType.setCode;
txParams.authorizationList = [{ address: upgradeContractAddress }];
}
4.3 安全验证
// 安全验证请求
const securityRequest: ValidateSecurityRequest = {
method: 'eth_sendTransaction',
params: [{
...txParams,
authorizationList: undefined,
type: TransactionEnvelopeType.feeMarket,
}],
delegationMock: txParams.authorizationList?.[0]?.address,
origin,
};
// 异步安全验证
validateSecurity(securityRequest, chainId).catch((error) => {
log('Security validation failed', error);
});
5. 状态管理和事件
5.1 批量交易元数据
export type TransactionBatchMeta = {
id: string;
status: TransactionBatchStatus;
transactions: TransactionMeta[];
// ... 其他元数据
};
5.2 事件系统
// 批量交易相关事件
export type TransactionControllerEvents =
| TransactionControllerTransactionSubmittedEvent
| TransactionControllerTransactionConfirmedEvent
| TransactionControllerTransactionFailedEvent
// ... 其他事件
6. 总结
EIP-5792在MetaMask中的实现是一个多层次、多路径的架构:
- API层:提供标准的RPC接口
- 控制器层:管理批量交易状态和生命周期
- 工具层:实现具体的批量执行逻辑
- 集成层:与EIP-7702、智能账户等新技术无缝集成
这种设计确保了:
- 向后兼容性:支持传统的交易方式
- 向前扩展性:可以轻松集成新的批量执行技术
- 灵活性:支持多种执行模式和自定义逻辑
- 安全性:内置安全验证和审计机制
学习交流请添加vx: gh313061