mcpField
P
public-relayer

public-relayer

github.com/1shot-api开发163 次安装今天更新
代码仓库

关于 public-relayer

该技能指导编码 Agent 集成 1Shot 公共中继器的 JSON-RPC API,以提交 Gas 抽象化的 ERC-7710 委托交易。内容涵盖单链和多链提交、费用报价、委托签名及 Webhook 验证。

主要功能

  1. 01发现支持的链和支付代币
  2. 02构建并签署 ERC-7710 委托
  3. 03估算费用并锁定报价
  4. 04提交单链或多链交易
  5. 05验证签名的 Webhook 事件

适用场景

  1. 01为钱包或应用接入中继交易
  2. 02将 EOA 升级为 MetaMask 智能账户
  3. 03在用户确认前估算交易费用
  4. 04验证中继器 Webhook 通知

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/1shot-api/skills --skill public-relayer

安装后在 Claude Code 中输入/public-relayer确认已加载。

附带文件references/examples.mdreferences/schemas.md

详细介绍

1Shot 公共中继服务(EIP-7710)集成

本技能介绍如何让客户端编码 Agent 集成 1Shot 公共中继服务 JSON-RPC API,以提交 Gas 抽象的 ERC-7710 委托交易。

安装此技能(使用者 / 全局)

npx skills add 1Shot-API/skills/public-relayer -g -a cursor -y

中继服务接受来自 7702StatelessDelegator 智能账户的已签名 MetaMask 委托,通过目标钱包在链上兑换该委托,并接受在同一条链(单链)或不同链(多链)上支付的 ERC-20 代币。

何时使用此技能

  • 构建通过 1Shot 中继服务提交交易的客户端应用、SDK、钱包或 Agent
  • 通过 EIP-7702 将 EOA 升级为 MetaMask 7702StatelessDelegator 智能账户
  • 创建、签名并提交 ERC-7710 委托
  • 在提交交易前估算或查询中继服务费用
  • 在报价有效期内锁定中继服务 Gas 价格
  • 接收并验证来自中继服务的已签名 Webhook 事件
  • 兑换嵌入式 1Shot Wallet(wallet_requestExecutionPermissions)或 MetaMask(requestExecutionPermissions)返回的已签名委托 context

何时不使用此技能

  • 嵌入 1Shot Wallet 以进行标准转账——通过 OWSProxy 使用 eth_sendTransaction;钱包会在内部调用 relayer_*。仅使用 1shot-wallet 技能。
  • 主题设置、连接、凭据、分析——configure、eth_requestAccounts、OID4、proxy.analytics;仅使用 1shot-wallet。
  • 来自嵌入式钱包的可选交易状态 Webhook——设置 configure.destinationUrl;钱包会在发送时将其传给中继服务。仍然无需宿主端中继客户端。

端点和软件包

  • 中继服务 JSON-RPC URL:调用 relayer_getCapabilities、relayer_getFeeData、relayer_estimate7710Transaction、relayer_estimate7710TransactionMultichain、relayer_send7710Transaction、relayer_send7710TransactionMultichain 或 relayer_getStatus 前,根据链选择端点:
    • 主网:https://relayer.1shotapi.com/relayers
    • Sepolia(11155111)和 Base Sepolia(84532):https://relayer.1shotapi.dev/relayers
  • 用于 Webhook 验证的 JWKS:GET https://relayer.1shotapi.com/.well-known/jwks.json(Ed25519,kty: "OKP",crv: "Ed25519")。
  • 客户端软件包:
    • @metamask/smart-accounts-kit(推荐使用 ^2.0.0;Arc Testnet 和 Robinhood Chain 必须使用)——用于所有委托和智能账户流程的单一软件包:
      • 主导出项:toMetaMaskSmartAccount、createDelegation、ScopeType、Implementation.Stateless7702、getSmartAccountsEnvironment。
      • @metamask/smart-accounts-kit/actions:用于浏览器 EIP-7715 流程的 erc7715ProviderActions。
      • @metamask/smart-accounts-kit/utils:用于解码钱包权限上下文的 decodeDelegations。
    • viem,用于 createPublicClient、encodeFunctionData、signAuthorization、privateKeyToAccount。
    • @noble/ed25519(或任何 Ed25519 验证器),用于验证 Webhook 签名。

方法命名: 多链变体直接在基础方法名后追加 Multichain(不加下划线),例如:relayer_send7710Transaction → relayer_send7710TransactionMultichain。

迁移说明: @metamask/delegation-toolkit 已弃用。请从客户端 package.json 中移除,并使用 @metamask/smart-accounts-kit 及上述子路径导入。

浏览器扩展集成(推荐用于 UI 应用)

当用户使用 MetaMask(或其他扩展钱包)在浏览器中登录时,优先采用扩展优先的流程:

  1. 使用 window.ethereum 和 createWalletClient({ transport: custom(window.ethereum) }) 创建钱包客户端。
  2. 使用 @metamask/smart-accounts-kit/actions 中的 erc7715ProviderActions() 扩展它。
  3. (可选)调用 getSupportedExecutionPermissions(),验证钱包是否支持所需的权限类型。
  4. 通过扩展使用 requestExecutionPermissions(...) 请求权限。将 to 设置为第 1 步中中继器的 targetAddress,而不是 DApp 会话账户。中继器会兑现在其赎回钱包上直接授予的委托。
  5. 使用 @metamask/smart-accounts-kit/utils 中的 decodeDelegations(context) 解码 context,通过 toRelayerJson 处理每个委托,并将结果作为 permissionContext 传入 relayer_send7710Transaction。

钱包前提条件(参阅代表 MetaMask 用户执行操作):

  • ERC-20 周期性权限要求 MetaMask Flask ≥13.5 或 MetaMask 正式版 ≥13.23。
  • 用户必须升级为 MetaMask Smart Account(EIP-7702)。使用 publicClient.getCode(address) 检查——如果存在代码,则将委托者地址(去掉 0xef0100 前缀)与 getSmartAccountsEnvironment(chainId).implementations.EIP7702StatelessDeleGatorImpl 进行比较。如有需要,提示用户升级。

这条路径之所以重要,是因为扩展钱包负责管理密钥和权限交互体验。本地/内部签名辅助函数(如 signDelegation)适用于后端或由脚本驱动的签名者,但在扩展流程中可能会失败或造成误导。

如果 requestExecutionPermissions 不可用,请明确告知用户:已连接的钱包可能不支持 EIP-7715,应用应提示用户切换钱包。

操作顺序

进行任何新集成时,请按顺序执行以下步骤。

步骤 1 — relayer_getCapabilities:发现链、接受的代币和 targetAddress

对每条要支持的链调用一次。响应会告知你:

  • 支持哪些 chainId。
  • 每条链上接受的 ERC-20 付款代币列表(address、symbol、decimals)。
  • feeCollector 地址(费用转账必须发送至此地址)。
  • targetAddress——这是客户端必须在委托 to 中签名的地址。它是中继器在该链上的赎回账户。如果不委托给这个确切地址,中继器就无法赎回。

在会话期间缓存结果;它很少变化。

// Request
{ "jsonrpc": "2.0", "id": 1, "method": "relayer_getCapabilities", "params": ["8453", "84532"] }

// Response (excerpt)
{ "result": {
  "8453": {
    "feeCollector": "0x1111...",
    "targetAddress": "0x2222...",     // ← delegate `to` this address
    "tokens": [{ "address": "0x036C...", "symbol": "USDC", "decimals": "6" }]
  }
}}
步骤 2 — 构建并签署捆绑包(客户端)

在报价或提交之前,组装完整的 ERC-7710 捆绑包:

  1. 初始化智能账户,使用 toMetaMaskSmartAccount({ implementation: Implementation.Stateless7702, address: <delegator EOA address>, signer })。
  2. **(首次使用时)**使用 account.signAuthorization({ chainId, contractAddress: getSmartAccountsEnvironment(chainId).implementations.EIP7702StatelessDeleGatorImpl, nonce }) 签署 EIP-7702 authorizationList 条目 — 在估算和发送时都要包含该条目。
  3. 生成权限上下文:
    • 浏览器扩展路径:调用 requestExecutionPermissions(传入 to: targetAddress),使用 decodeDelegations 解码 granted[0].context,再使用 toRelayerJson 序列化。
    • 本地签名者路径:使用 createDelegation({ to: targetAddress (from Step 1), from: smartAccount.address, environment: smartAccount.environment, salt, scope: { type: ScopeType.Erc20TransferAmount | ScopeType.FunctionCall, ... maxAmount: feeAmount + workAmount } }) 创建委托,并使用 smartAccount.signDelegation({ delegation }) 签署。
  4. 编码每项执行的 calldata(对费用 transfer(转账至 feeCollector)和用户的主要工作使用 encodeFunctionData)。

加入一项模拟费用支付执行:向 feeCollector 转账 ERC-20,金额**≥**该代币的 minFee(使用 relayer_getFeeData,或使用保守的占位金额,例如 0.01 USDC)。中继器会解析此操作以确定支付代币。对于多链交易,只需在费用链参数中加入费用操作;工作链参数可以省略该操作。

对于用户输入的代币金额,先根据代币精度解析十进制字符串(例如,对 USDC 使用 parseUnits("0.01", 6))。切勿直接将十进制字符串传给 BigInt,因为 "0.01" 无效,会导致运行时故障。

步骤 3 — relayer_estimate7710Transaction 或 relayer_estimate7710TransactionMultichain:获取费用报价(首选)

签名后的捆绑包准备就绪后,调用对应的估算方法,使用与发送时相同的 params 结构(省略 context 和 delegationSecret;taskId、destinationUrl 和 memo 为可选项,且不影响定价):

需求……使用此方法
在同一条链上支付费用并执行工作relayer_estimate7710Transaction
在链 A 上支付费用,在链 B 上执行工作(或原子性地批量处理多条链)relayer_estimate7710TransactionMultichain

中继器会验证委托、运行 1Shot Gas 模拟,并同步返回结果(不会创建任务):

  • success(布尔值)— 验证或模拟失败时为 false;请读取结果中的 error(不一定是 JSON-RPC 错误)。
  • requiredPaymentAmount(字符串,以代币最小单位计)— 以模拟支付代币支付的费用,最低为该链/代币的 minFee。
  • gasUsed — 链 ID → 累计 Gas 单位数的映射(十进制字符串)。
  • context — 首个支付链的签名价格锁定报价;在单链发送时作为 params.context 传入。
  • contextByChainId — 各链对应的签名报价;多链发送时,将每个 params[i].context 设为 contextByChainId[params[i].chainId]。

生产环境工作流:

  1. 使用当前捆绑包(模拟费用 ≥ minFee)发送估算请求。
  2. 如果 success === false,根据 error 修复捆绑包(缺少支付、低于 minFee、模拟回滚、委托无效)。
  3. 如果 requiredPaymentAmount 与模拟费用不同,则更新费用执行金额和委托的 maxAmount,然后重新签署委托。
  4. 立即使用估算响应中的 context / contextByChainId 发送,以锁定报价(有效期 30 秒)。

完整捆绑包准备就绪后,此流程可取代客户端 eth_estimateGas 加手动费用计算。

步骤 2b(备用方案)— relayer_getFeeData:在 bundle 尚不存在时获取粗略报价

当 bundle 尚未构建时使用 — 例如,浏览器权限体验需要在用户签名之前获取粗略费用,或快速显示价格。每个 (chainId, paymentToken) 调用一次。响应包含:

  • gasPrice(十六进制 wei)— relayer 以原生 gas 单位计价的当前 gas 价格。
  • rate(数字)— 用于将原生 gas 成本换算为支付代币金额的汇率。
  • minFee(字符串,以代币最小单位计)— 最低费用,相当于支付代币中的 $0.01。
  • expiry(Unix 秒数)— 报价有效期(默认 30 秒;超过 expiry 的报价均视为过期)。
  • context(字符串)— 已签名的价格锁定上下文(bundle 存在时,优先使用 estimate 返回的 context)。

手动计算费用(estimate 不可用时):

  1. 估算工作交易的 gasUsed(使用 eth_estimateGas 或已知的上限值)。
  2. nativeFee = gasPrice * gasUsed(wei)。
  3. 使用 rate 将其换算为支付代币的最小单位。
  4. 下限:feeAmount = max(converted, minFee)。

委托的 caveat 范围必须允许向 feeCollector 转账至少 feeAmount。支付不足会导致 InsufficientPayment(4200)。

步骤 4 — relayer_send7710Transaction 或 relayer_send7710TransactionMultichain:提交交易包

首先选择签名路径:

  • 浏览器扩展路径(UI 应用推荐): 使用 requestExecutionPermissions 请求权限,使用 decodeDelegations 解码,并在 permissionContext 中发送解码后的委托。
  • 本地签名器路径(后端/脚本): 使用 createDelegation + smartAccount.signDelegation 构建并签署委托(参见步骤 2)。

POST 在步骤 2–3 中构建的 JSON-RPC 请求体。params.context 字段必须是对应估算响应中的已签名价格锁定 context(单链使用 result.context;多链则每个参数使用 result.contextByChainId[chainId]),不能是自由格式字符串。

选择合适的方法:

你的需求 …使用此方法
在同一条链上支付费用并执行任务relayer_send7710Transaction
在 A 链上支付费用,在 B 链上执行任务(或原子性地批处理多条链)relayer_send7710TransactionMultichain

两种方法都接受可选的 destinationUrl(≤256 个字符)。设置后,每当状态发生变化,relayer 都会向该 URL POST 已签名的 Ed25519 webhook 事件。建议使用 destinationUrl,而不是轮询——它的扩展性更好,且能提供亚秒级更新。

两种方法还都接受可选的 memo(≤256 个字符):不透明的客户端关联字符串(订单 ID、内部引用等)。它不会影响执行、定价或链上 calldata——relayer 会存储该值,并在设置后通过 relayer_getStatus 和 webhook 负载将其回传。估算时省略(同一参数类型也可接受,但会像 taskId / destinationUrl 一样被忽略,不影响定价)。对于多链,每个数组条目都可以携带自己的 memo(每个条目会成为一个单独的任务)。

发送时建议提供: delegationSecret(提供时长度为 10–1024 个字符)。为每个客户端或应用选择一个密钥(而不是每份委托一个):生成一次,将其存储在应用配置或安全的客户端存储中,并在来自该来源的每次发送中传入相同的值。你无需为每份委托使用不同的密钥,也无需维护委托→密钥映射——relayer 会在首次提交某份委托且提供密钥时,将其绑定到你使用的密钥;之后重新提交该委托时必须使用相同的密钥。第三方若没有你的应用密钥却重放你的链上委托,将被拒绝(4216)。省略该值时,尚未绑定的委托仍可使用(旧行为);已绑定的委托若未提供密钥,则会被拒绝。估算时省略。对于多链,你可以在每个链条目中重复使用相同的应用密钥。

结果为 TaskId(单链)或 TaskId[](多链,顺序与提交顺序一致)。

步骤 5 — relayer_getStatus:检查状态(或使用 Webhook)

如果设置了 destinationUrl,优先使用 Webhook——中继器会在每次状态变更时 POST 已签名的 JSON。出站 Webhook 正文使用数字 type 字段(而非字符串事件名称):

type含义
4已提交(链上交易哈希可用)
0已确认成功
1已回滚 / 执行失败

data 字段的对象结构与该任务的 relayer_getStatus 相同——如果提交时发送了 params.memo,则包含 data.memo 处的可选 memo(否则省略,绝不会为 null)。

验证每个 Webhook:

  1. 获取并缓存 GET https://relayer.1shotapi.com/.well-known/jwks.json(密钥轮换不频繁)。
  2. 根据 Webhook 正文中的 keyId,通过 kid 查找公钥。
  3. 移除 signature 字段以重建签名载荷,然后使用稳定的键排序 JSON进行序列化(使用 safe-stable-stringify 或等效工具——中继器会对规范形式签名)。
  4. 对 UTF-8 字节使用 Ed25519 验证;将 base64 格式的 signature 视为 64 字节的分离式签名。

如果无法避免轮询,每隔 2–3 秒使用 { id: <TaskId>, logs: true|false } 调用 relayer_getStatus,并在状态变为终态时停止。如果发送了 params.memo,则每种状态码对应的状态对象都包含 memo;如果发送时省略了该参数,则字段也会缺失(而非 null)。状态码:

代码标签是否为终态
100待处理否
110已提交否(包含 hash)
200已确认是(包含 receipt)
400已拒绝是(包含 message)
500已回滚是(包含 data)

决策速查表

  • 如何报价?:签名后的 bundle 已准备好时,优先使用 relayer_estimate7710Transaction(单链)或 relayer_estimate7710TransactionMultichain(多链)——中继器会模拟 Gas,并返回 requiredPaymentAmount 和已签名的 context。仅在 bundle 尚未构建、需要粗略报价时(例如浏览器权限 UX),或无法使用 estimate 时,才使用 relayer_getFeeData。
  • 未签名的 estimate(签名前报价):仅在 estimate 时,将每个 delegation 的 signature 设为 ""、bytes32(0)(0x + 64 个零十六进制数字),或推荐的 65 字节全零占位符;中继器会通过 Geth stateOverride,在每个 delegator 处注入仅用于 estimate 的 DelegatorEstimateShim 代码(包括链上尚未完成 EIP-7702 升级的 EOA)。真实的链上代币余额和授权仍会生效,不会伪造。对于首次 EIP-7702 升级,你也可以发送包含正确 address、chainId 和 nonce,但使用占位符 r/s(32 字节零十六进制)和 yParity 0 的 authorizationList——仅当 delegation 签名为占位符时才这样做;中继器会在报价中加入固定的授权 Gas(默认 40100 Gas),且不会将无效授权转发给模拟。发送时必须使用真实的 delegation 和授权签名——relayer_send7710Transaction* 会拒绝占位符。
  • 自行支付 vs. 赞助支付:如果同一账户既支付费用又执行工作,则签署一个 delegation,其范围涵盖 feeAmount + workAmount,并在 bundle 中包含两个 executions(费用转账 + 工作)。如果由单独的 sponsor 支付费用,则签署两个 delegation(分别来自 sponsor 和 delegator),并提交两个带有各自 permissionContext 的 transactions[] 条目。中继器会将它们合并到单个 redeemDelegations 批次中。
  • 选择 ScopeType:ScopeType.Erc20TransferAmount 最简单,适用于费用和工作转账。当你需要在一个批次中覆盖更广泛的函数时,使用 ScopeType.FunctionCall(代币 + selector)——对于某些批量调用模式,Erc20TransferAmount enforcer 可能会以 CaveatEnforcer:invalid-call-type 回滚。
  • EIP-7702 授权:每个请求只允许有一个 authorizationList 条目。如果 delegator 和 sponsor 都需要升级,则分两次单独调用(或先在其他地方升级其中一个)。
  • Salt:调用 createDelegation 时,始终传入新的随机 32 字节十六进制 salt,以避免重放冲突。
  • memo、context、taskId 和 delegationSecret 的区别:context 会锁定 estimate 中的费用报价;taskId 是由中继器分配(或由客户端提供)的任务标识符;memo 是不透明标签,会在状态和 webhook 中原样返回,用于关联;delegationSecret 是一个应用级密钥,可在所有发送操作中重复使用(不是每个 delegation 一个密钥),用于防止公开重放开放的 delegation(仅发送时使用)。
  • 将 BigInt 转换为 JSON:中继器 JSON-RPC 要求使用普通 JSON。发送前,将已签名 delegation 结构中的 bigint 值转换为带 0x 前缀的十六进制字符串。使用 viem/utils 中的 bytesToHex 转换 Uint8Array。

最简端到端结构

// 1. capabilities
const caps = await rpc("relayer_getCapabilities", [chainId]);
const { targetAddress, feeCollector, tokens } = caps[chainId];
const paymentToken = tokens.find((t) => t.symbol === "USDC")!;

// 2. build + sign bundle (mock fee ≥ minFee; see examples.md)
const sendParams = {
  chainId,
  transactions: [
    {
      permissionContext: [signedDelegation],
      executions: [feeTransfer, workCall],
    },
  ],
};

// 3. estimate (same params as send, no context)
const estimate = await rpc<Estimate7710Result>(
  "relayer_estimate7710Transaction",
  sendParams,
);
if (!estimate.success) throw new Error(estimate.error);
const feeAmount = BigInt(estimate.requiredPaymentAmount!);
// if feeAmount changed: rebuild fee execution + delegation scope, re-sign, re-estimate

// 4. submit with price lock from estimate
const taskId = await rpc("relayer_send7710Transaction", {
  ...sendParams,
  context: estimate.context,
  destinationUrl: "https://my-app.example.com/relayer-webhook", // optional, recommended
  memo: "order-abc123", // optional; echoed in relayer_getStatus and webhooks
  delegationSecret: APP_DELEGATION_SECRET, // one per app/client; reuse on every send, not per delegation
});

// Multichain: estimate with params array, then send each entry with
// context: estimate.contextByChainId![param.chainId]

// 5. either consume webhooks or poll relayer_getStatus

常见错误代码

估算响应:relayer_estimate7710Transaction 和 relayer_estimate7710TransactionMultichain 在验证和模拟失败(缺少模拟支付、费用低于 minFee、Gas 估算回滚)时,会返回 result.success: false 和一个 error 字符串。这些错误不一定是 JSON-RPC 错误——发送前请检查 result.success。

代码含义典型修复
4200支付金额不足将 feeAmount 增加到至少 requiredPaymentAmount / minFee;重新签名。
4201签名无效重新签署委托;确保 salt 是新生成的,且 signer 与 from 匹配。
4202不支持的支付代币从该链的 relayer_getCapabilities 中选择代币。
4204报价已过期重新运行估算(或重新获取 relayer_getFeeData),并在约 30 秒内重新提交。
4206不支持的链确认 chainId 出现在 relayer_getCapabilities 中。
4209不支持的能力调整委托范围/限制条件;检查中继器是否支持该调用类型。
4210授权列表无效authorizationList 条目最多只能有一个;确认 nonce 是最新值。
4211模拟失败中继器会预先模拟;检查 data 中的回滚原因。
4212不支持多链改为按链调用 relayer_send7710Transaction。
4214任务 ID 重复省略 taskId,由中继器分配一个,或发送新的随机十六进制值。
4216委托密钥不匹配使用应用的 delegationSecret(首次提交该委托时绑定的密钥),或者仅在从未绑定时省略。

浏览器流程中的常见问题及修复方法

  • "wallet_requestExecutionPermissions does not exist":钱包不支持 EIP-7715。提示用户切换到兼容的钱包。
  • "External signature requests cannot sign delegations for internal accounts":签名路径错误。请使用扩展权限请求,而非内部账户委托签名。
  • "Account does not support signMessage":签名者/账户不匹配。在扩展模式下,避免假设使用本地账户。
  • "Cannot convert 0.01 to a BigInt":先根据代币精度解析十进制输入,再进行转换。

完整的错误目录和请求/响应架构请参阅 references/schemas.md。

与 1shot-wallet 集成的路径

共有三种不同路径——编写代码前请选择一种:

路径技能宿主是否调用 relayer_*?
A — 仅嵌入1shot-wallet否
B — 嵌入并执行委托1shot-wallet + public-relayer是(兑换授权)
C — 不嵌入钱包public-relayer是
路径 A — 仅嵌入(最常见)

仅安装 1shot-wallet。接入 OWSProxy,调用 eth_sendTransaction——钱包会在内部签署委托并提交给中继器。无需编写宿主中继器 JSON-RPC 代码。无 Gas 抽象的交易发送以及可选的 configure.destinationUrl Webhook,无需此技能即可使用。

路径 B — 嵌入 + 执行委托(两项技能)

当宿主或后端使用用户授予的委托(会话密钥、离线执行、定期 ERC-20 授权)执行工作时使用。安装两项技能;阅读 1shot-wallet/SKILL.md 了解 OWSProxy 设置。从 relayer_getCapabilities 开始,并记下 targetAddress(该链上的中继器赎回钱包)。

子路径授权 to宿主是否重新委托?示例
B1 — 直接targetAddress否示例 0b
B2 — 会话密钥(推荐)宿主会话账户是 → targetAddress示例 0c
路径 B1 — 直接授权给中继器

更简单的原型路径:用户直接授权中继器。

  1. 使用 to: targetAddress 和定期 ERC-20 范围(预算 ≥ 费用 + 工作量)调用 wallet_requestExecutionPermissions。
  2. 钱包返回 response.context(单个已签名委托);宿主使用 decodeDelegations + toRelayerJson 解码,构建 executions[],然后调用 relayer_estimate7710Transaction / relayer_send7710Transaction。

用户直接委托给中继器地址——适用于演示;生产环境建议使用 B2 会话密钥。

路径 B2 — 会话密钥 + 重新委托(推荐)

生产环境的会话密钥路径:用户授权一个由宿主控制的会话账户;宿主在提交前,将权限重新委托给中继器,并采用范围更窄、针对具体执行的授权条件。

  1. 宿主生成或加载一个会话账户(本地签名者;私钥保留在宿主内存中,不是用户的通行密钥)。
  2. 使用 to: sessionAccountAddress 和定期 ERC-20 范围(离线/Agent 预算)调用 wallet_requestExecutionPermissions。
  3. 钱包返回 response.context(父级授权)。宿主解码后,会话账户将权限重新委托给 targetAddress,并针对本次执行采用范围更窄的限制条件(FunctionCall + exactCalldata,或将 Erc20TransferAmount 限定为费用 + 工作量上限——与钱包内发送采用相同的权限收窄思路)。
  4. 通过 encodeDelegations 将委托链(父级委托 + 已签名的重新委托)编码为 permissionContext;估算后调用 relayer_send7710Transaction,并在 permissionContext 中包含完整委托链。
  5. 首次使用时,会话账户可能需要采用 EIP-7702 智能账户形式;升级时发送请求应包含 authorizationList(与本技能其他部分的限制相同)。

重新委托只能收窄父级授权范围(限制条件会叠加)。请参阅 MetaMask kit 的创建重新委托(redelegatePermissionContext 或 createDelegation({ parentDelegation }))。

钱包也会在钱包内发送和 wallet_revokeExecutionPermission 取消操作中使用中继器;这与路径 B 无关。

当开发者要求在离线时代表用户执行操作、通过中继器兑现定期 ERC-20 授权,或使用来自嵌入式钱包、由通行密钥签名的委托提交中继器捆绑交易时,选择路径 B——不要将其用于一般性的“嵌入通行密钥钱包”。会话密钥和 Agent 执行场景优先选择 B2。

公共中继器是开放的 JSON-RPC 服务(无需 API 密钥)。任何人都可以运行一个支持相同 relayer_* 方法的备用中继器。

路径 C — 无嵌入式钱包

MetaMask 扩展(requestExecutionPermissions + window.ethereum)或本地/后端签名者(createDelegation + signDelegation)。本技能的其余内容仍按原样适用。参阅 references/examples.md 中的示例 0。

使用 webauthn-prf-wallet 组合构建完全非托管应用

公共中继服务与 webauthn-prf-wallet 技能(需单独安装)天然适配,可用于构建完全非托管的 Web3 应用,无供应商锁定,也无需企业账户:

  • webauthn-prf-wallet 通过 WebAuthn PRF 扩展从用户的通行密钥派生 EVM 私钥,并将其保存在隔离的 iframe 中——私钥绝不会到达父页面或任何服务端。
  • 在此技能的流程中,由通行密钥派生的账户自然就是委托方:让 iframe 对 EIP-7702 授权、7702StatelessDelegator 升级以及每个 createDelegation 负载进行签名。
  • 公共中继服务是一个开放的 JSON-RPC 服务(无需 API 密钥,也无需 Bearer 令牌),用户以稳定币按笔支付交易费用。无需绑定任何关系——任何人都可以搭建一个支持相同 relayer_* 方法的替代中继服务,客户端只需更改 RELAYER_URL 即可切换。

在整个流程中,用户拥有自己的密钥(通行密钥),只需支付按笔收取的费用(ERC-20),应用不涉及任何托管环节,也无需企业凭据。当开发者询问“无需持有 ETH 即可进行交易的通行密钥钱包”或“无需管理 API 密钥的非托管应用”时,可以采用这一组合。阅读 webauthn-prf-wallet/SKILL.md 了解客户端钱包模式,并使用此技能处理中继 JSON-RPC 流程。

其他资源

  • references/schemas.md — 完整的 JSON-RPC 方法签名、架构、状态/错误代码及 JWKS 请求体结构。需要准确的参数结构、完整的错误目录或线上 webhook 负载格式时,请阅读此文档。
  • references/examples.md — 可运行的 TypeScript 模式:MetaMask 浏览器流程(示例 0)、嵌入式钱包直接授权(示例 0b,路径 B1)、嵌入式钱包会话密钥与重新委托(示例 0c,路径 B2)、先估算费用的单链和多链流程、自行赞助、赞助,以及使用 Ed25519 验证的 webhook 接收器。即将编写客户端代码或想要复制经过验证的集成模式时,请阅读此文档。
  • 1shot-wallet 技能 — 嵌入 1Shot Wallet(OWS Host Layer)。路径 A 和路径 B 必需;仅用于路径 B 委托执行的配套技能(仅嵌入后直接发送时不需要)。
  • webauthn-prf-wallet 技能 — 用于在隔离的 iframe 中持有客户端通行密钥派生 EVM 密钥的配套技能。与此技能搭配使用,可实现完全非托管的设置。
  • MetaMask Smart Accounts Kit — 安装、浏览器/EIP-7715 流程、本地签名器/委托流程、Advanced Permissions 钱包客户端参考。

评论

支持 Markdown