mcpField
P
public-relayer

public-relayer

github.com/1shot-api開発163 回インストール今日更新
リポジトリ

public-relayer について

このスキルは、ガス抽象化されたERC-7710委任トランザクションを送信するため、コーディングエージェントによる1Shot Public Relayer JSON-RPC APIの統合を支援します。シングルチェーンとマルチチェーンの送信、手数料見積もり、委任署名、Webhook検証を扱います。

主な機能

  1. 01対応チェーンと決済トークンの確認
  2. 02ERC-7710委任の構築と署名
  3. 03手数料見積もりと価格ロック
  4. 04シングル/マルチチェーン取引の送信
  5. 05署名付きWebhookイベントの検証

活用シーン

  1. 01ウォレットやアプリへの中継取引の追加
  2. 02EOAから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 Public Relayer(EIP-7710)統合

このスキルでは、クライアント側のコーディングエージェントが1Shot public relayerのJSON-RPC APIと統合し、ガス代を抽象化したERC-7710委任トランザクションを送信する方法を説明します。

このスキルのインストール(利用者向け/グローバル)

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

リレイヤーは、7702StatelessDelegatorスマートアカウントから署名済みのMetaMask委任を受け取り、対象ウォレットを介してオンチェーンで引き換えます。また、同一チェーン(シングルチェーン)または別のチェーン(マルチチェーン)上のERC-20トークンで支払いを受け付けます。

このスキルを使用する場合

  • 1Shotリレイヤー経由でトランザクションを送信するクライアントアプリ/SDK/ウォレット/エージェントを構築する場合
  • EIP-7702を使用してEOAをMetaMaskの7702StatelessDelegatorスマートアカウントにアップグレードする場合
  • ERC-7710委任を作成、署名、送信する場合
  • 送信前にトランザクションのリレイヤー手数料を見積もる、または取得する場合
  • 見積もり期間中のリレイヤーのガス価格を固定する場合
  • リレイヤーから署名済み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。
    • createPublicClient、encodeFunctionData、signAuthorization、privateKeyToAccount用のviem。
    • Webhook署名の検証用の@noble/ed25519(または任意のEd25519検証ツール)。

**メソッド名について:**マルチチェーン版は、ベースメソッド名に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 を実行して、その結果を relayer_send7710Transaction の permissionContext として渡します。

ウォレットの前提条件(MetaMask ユーザーに代わって実行するを参照):

  • ERC-20 の定期的な権限には、MetaMask Flask ≥13.5 または MetaMask 本番版 ≥13.23 が必要です。
  • ユーザーは MetaMask Smart Account(EIP-7702)にアップグレードされている必要があります。publicClient.getCode(address) で確認してください。コードがある場合は、委任者のアドレス(0xef0100 のプレフィックスを除去)を getSmartAccountsEnvironment(chainId).implementations.EIP7702StatelessDeleGatorImpl と比較します。必要に応じて、ユーザーにアップグレードを促してください。

この方法が重要な理由:拡張機能ウォレットは鍵と権限 UX を管理します。signDelegation のようなローカル/内部の署名ヘルパーは、バックエンドやスクリプト駆動の署名者に適していますが、拡張機能を使うフローでは失敗したり、誤解を招いたりする可能性があります。

requestExecutionPermissions が利用できない場合は、その旨を明確に表示してください。接続中のウォレットは EIP-7715 をサポートしていない可能性が高いため、アプリはユーザーにウォレットの切り替えを促す必要があります。

操作の順序

新しい統合では、次の手順を順番どおりに実行してください。

ステップ 1 — relayer_getCapabilities:チェーン、受け入れ可能なトークン、targetAddress を確認する

サポートするチェーンごとに 1 回呼び出します。レスポンスには次の情報が含まれます。

  • サポートされている 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" }]
  }
}}
Step 2 — バンドルを構築して署名する(クライアント側)

見積もりまたは送信の前に、完全な ERC-7710 バンドルを組み立てます。

  1. スマートアカウントを初期化します。toMetaMaskSmartAccount({ implementation: Implementation.Stateless7702, address: <delegator EOA address>, signer }) を使用します。
  2. (初回使用時) EIP-7702 の authorizationList エントリーに署名します。account.signAuthorization({ chainId, contractAddress: getSmartAccountsEnvironment(chainId).implementations.EIP7702StatelessDeleGatorImpl, nonce }) を使用し、見積もりと送信の両方に含めます。
  3. 権限コンテキストを生成します。
    • ブラウザー拡張機能を使用する場合:requestExecutionPermissions(to: targetAddress を指定)を呼び出し、granted[0].context を decodeDelegations でデコードして、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. 各実行のコールデータをエンコードします(手数料用の feeCollector 宛て transfer と、ユーザーの主な処理には encodeFunctionData を使用します)。

モックの手数料支払い実行を含めます。これは、そのトークンの minFee 以上の金額を feeCollector に送る ERC-20 transfer です(relayer_getFeeData を使用するか、保守的な仮値として 0.01 USDC などを指定します)。リレイヤーはこの処理を解析して、支払いトークンを判定します。マルチチェーンの場合、手数料チェーンのパラメーターにのみ手数料処理が必要です。処理チェーンのパラメーターでは省略できます。

ユーザーが入力したトークン金額は、まずトークンの小数桁数を使って小数文字列を解析します(たとえば、USDC の場合は parseUnits("0.01", 6))。小数文字列を BigInt に直接渡さないでください。"0.01" は無効なため、実行時エラーが発生します。

Step 3 — relayer_estimate7710Transaction または relayer_estimate7710TransactionMultichain:手数料を見積もる(推奨)

署名済みバンドルができたら、送信と同じ params 形式で対応する見積もりメソッドを呼び出します(context と delegationSecret は省略します。taskId、destinationUrl、memo は任意で、料金計算には使用されません)。

必要な処理 …使用するメソッド
同じチェーンで手数料を支払い、処理を実行するrelayer_estimate7710Transaction
チェーン A で手数料を支払い、チェーン B で処理を実行する(または複数チェーンを一括で実行する)relayer_estimate7710TransactionMultichain

リレイヤーは委任を検証し、1Shot のガスシミュレーションを実行して、同期的に結果を返します(タスクは作成されません)。

  • success(ブール値)— 検証またはシミュレーションが失敗した場合は false です。結果の error を確認してください(常に JSON-RPC エラーとは限りません)。
  • requiredPaymentAmount(文字列、トークン最小単位)— モックの支払いトークンで支払う手数料です。チェーン/トークンの minFee を下限とします。
  • gasUsed — チェーン ID から合計ガス単位(10 進文字列)へのマップです。
  • context — 最初の支払いチェーン用の署名済み価格ロック見積もりです。単一チェーンで送信する際に params.context として渡します。
  • contextByChainId — チェーンごとの署名済み見積もりです。マルチチェーンで送信する際は、各 params[i].context = contextByChainId[params[i].chainId] を設定します。

本番環境でのループ:

  1. 現在のバンドル(モック手数料は minFee 以上)で見積もりを POST します。
  2. success === false の場合は、error に基づいてバンドルを修正します(支払いの不足、minFee 未満、シミュレーションのリバート、無効な委任)。
  3. requiredPaymentAmount がモック手数料と異なる場合は、手数料処理の金額と委任の maxAmount を更新し、委任に再署名します。
  4. 見積もりレスポンスの context/contextByChainId を使用して、すぐに送信し、見積もりをロックします(有効期限は30 秒)。

完全なバンドルが準備できている場合は、クライアント側の eth_estimateGas と手動の手数料計算の代わりに、この方法を使用します。

Step 2b(フォールバック)— relayer_getFeeData:バンドル作成前の概算見積もり

バンドルがまだ作成されていない場合に使用します。たとえば、ユーザーが署名する前に概算手数料が必要なブラウザー権限の UX や、簡易的な価格表示などです。(chainId, paymentToken) ごとに 1 回呼び出します。レスポンスには次の項目が含まれます。

  • gasPrice(16 進数の wei)— ネイティブガス単位での現在のリレイヤーのガス価格です。
  • rate(数値)— ネイティブガスのコストを支払いトークンの額に換算する為替レートです。
  • minFee(文字列、トークンの最小単位)— 最低手数料で、支払いトークンでの $0.01 相当額です。
  • expiry(Unix 秒)— 見積もりの有効期限です(デフォルトは30 秒です。expiry を過ぎた見積もりは期限切れとして扱ってください)。
  • context(文字列)— 署名済みの価格固定コンテキストです(バンドルが作成された後は、見積もりから返される context を優先してください)。

手数料を手動で計算する方法(見積もりを取得できない場合):

  1. 実行トランザクションの gasUsed を見積もります(eth_estimateGas を使うか、既知の上限値を使用します)。
  2. nativeFee = gasPrice * gasUsed(wei)。
  3. rate を使用して、支払いトークンの最小単位に換算します。
  4. 下限:feeAmount = max(converted, minFee)。

委任の制限範囲では、少なくとも feeAmount を feeCollector に送金できる必要があります。支払いが不足すると、InsufficientPayment(4200)が発生します。

Step 4 — relayer_send7710Transaction または relayer_send7710TransactionMultichain:バンドルを送信する

まず、署名方法を選択します。

  • ブラウザー拡張機能を使う方法(UI アプリに推奨): requestExecutionPermissions で権限をリクエストし、decodeDelegations でデコードして、デコードした委任を permissionContext で送信します。
  • ローカル署名者を使う方法(バックエンド/スクリプト): createDelegation と smartAccount.signDelegation を使って委任を作成し、署名します(Step 2 を参照)。

Step 2~3 で作成した JSON-RPC ボディを POST します。params.context フィールドには、対応する見積もりレスポンスの署名済み価格ロック context(単一チェーンの場合は result.context、マルチチェーンの場合は各パラメーターに対する result.contextByChainId[chainId])を指定する必要があります。自由形式の文字列は指定しないでください。

適切なメソッドを選択します。

必要な処理 …使用するメソッド
同じチェーンで手数料を支払い、処理を実行するrelayer_send7710Transaction
チェーン A で手数料を支払い、チェーン B で処理を実行する(または複数チェーンを一括でアトミックに処理する)relayer_send7710TransactionMultichain

どちらのメソッドも、任意の destinationUrl(256 文字以下)を受け付けます。設定すると、リレイヤーはステータスが変わるたびに、その URL に署名済み Ed25519 Webhook イベントを POST します。ポーリングよりも destinationUrl の使用を推奨してください。こちらのほうがスケーラビリティに優れ、1 秒未満で更新を受け取れます。

どちらのメソッドも、任意の memo(256 文字以下)も受け付けます。これは不透明なクライアント相関文字列(注文 ID、内部参照など)です。実行、価格、オンチェーン calldata には影響しません。リレイヤーはこれを保存し、設定されている場合は relayer_getStatus と Webhook ペイロードで返します。見積もりでは省略してください(同じパラメーター型を指定できますが、taskId/destinationUrl と同様、価格設定には無視されます)。マルチチェーンでは、各配列エントリーに独自の memo を指定できます(それぞれが個別のタスクになります)。

送信時は、 delegationSecret(指定する場合は 10~1024 文字)の使用を推奨します。クライアントまたはアプリごとに 1 つのシークレットを選択してください(委任ごとではありません)。一度生成してアプリ設定またはセキュアなクライアントストレージに保存し、その送信元から送信するたびに同じ値を渡します。委任ごとに異なるシークレットや、委任からシークレットへのマップを用意する必要はありません。リレイヤーは、シークレットが指定された初回送信時に使用されたシークレットに各委任を紐付けます。その後、同じ委任を再送信する際は、同じシークレットを使用する必要があります。アプリのシークレットを知らない第三者がオンチェーンの委任をリプレイしても、拒否されます(4216)。省略した場合、未紐付けの委任は引き続き機能します(従来の動作)。すでに紐付けられている委任は、シークレットなしでは拒否されます。見積もりでは省略してください。マルチチェーンでは、各チェーンのエントリーに同じアプリシークレットを繰り返し指定できます。

結果は TaskId(単一チェーン)または TaskId[](マルチチェーン。送信順)です。

ステップ 5 — relayer_getStatus:ステータスを確認する(または Webhook を利用する)

destinationUrl が設定されている場合は、Webhook を優先してください。リレイヤーはステータスが変わるたびに、署名付き JSON を POST します。送信される Webhook の本文では、文字列のイベント名ではなく、数値の type フィールドを使用します。

type意味
4送信済み(オンチェーンの tx ハッシュが利用可能)
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 バイトの分離署名として扱います。

ポーリングが避けられない場合は、{ id: <TaskId>, logs: true|false } を指定して relayer_getStatus を 2~3 秒ごとに呼び出し、終端ステータスになったら停止します。params.memo を指定して送信した場合、すべてのステータスコードでステータスオブジェクトに memo が含まれます。送信時に省略した場合、このフィールドは存在しません(null ではありません)。ステータスコード:

コードラベル終端か?
100保留中いいえ
110送信済みいいえ(hash あり)
200確認済みはい(receipt あり)
400拒否はい(message あり)
500リバートはい(data あり)

判断の早見表

  • 手数料の見積もり方法:署名済みバンドルがある場合は、relayer_estimate7710Transaction(単一チェーン)または relayer_estimate7710TransactionMultichain(マルチチェーン)を優先します。リレイヤーがガスをシミュレートし、requiredPaymentAmount と署名済みの context を返します。バンドルの作成前(ブラウザー権限の UX など)に概算を得る場合、または見積もりを利用できない場合に限り、relayer_getFeeData を使用してください。
  • 未署名の見積もり(署名前の見積もり):見積もり時に限り、各委任の signature を ""、bytes32(0)(0x に 64 個のゼロの 16 進数を続けたもの)、または推奨される 65 バイトの全ゼロのプレースホルダーに設定します。リレイヤーは Geth の stateOverride を通じて、各委任者に見積もり専用の DelegatorEstimateShim コードを挿入します(チェーン上でまだ EIP-7702 にアップグレードされていない EOA も含みます)。実際のオンチェーンのトークン残高と使用許可は引き続き適用され、偽装されることはありません。初回の EIP-7702 アップグレードでは、address、chainId、nonce が正しく、r/s がプレースホルダー(32 バイトのゼロの 16 進数)、yParity が 0 の authorizationList を送信することもできます。ただし、委任署名がプレースホルダーの場合に限ります。リレイヤーは見積もりに固定の認証ガス(デフォルトで 40100 ガス)を加算し、無効な認証情報をシミュレーションには転送しません。送信には実際の委任署名と認証署名が必要です。relayer_send7710Transaction* ではプレースホルダーは拒否されます。
  • 自己負担とスポンサー負担:同じアカウントが手数料を支払い、処理も実行する場合は、feeAmount + workAmount を対象とする単一の委任に署名し、2 つの executions(手数料の送金と処理)をバンドルします。別のスポンサーが手数料を支払う場合は、2 つの委任(スポンサーと委任者からそれぞれ 1 つ)に署名し、それぞれ独自の permissionContext を持つ 2 つの transactions[] エントリーを送信します。リレイヤーはそれらを単一の redeemDelegations バッチにまとめます。
  • ScopeType の選択:ScopeType.Erc20TransferAmount は最もシンプルで、手数料と処理の両方の送金に使えます。1 つのバッチでより幅広い関数を対象にする必要がある場合は、ScopeType.FunctionCall(トークン + セレクター)を使用してください。バッチ化された一部の呼び出しパターンでは、Erc20TransferAmount エンフォーサーが CaveatEnforcer:invalid-call-type でリバートすることがあります。
  • EIP-7702 認証:リクエストごとに許可される authorizationList エントリーは 1 つだけです。委任者とスポンサーの両方にアップグレードが必要な場合は、2 回に分けて呼び出すか、先に一方を別の方法でアップグレードしてください。
  • Salt:リプレイの衝突を避けるため、createDelegation には常に新しいランダムな 32 バイトの 16 進数 salt を渡してください。
  • memo と context、taskId、delegationSecret の違い:context は見積もりで得た手数料の見積もり額を固定します。taskId はリレイヤーが割り当てる(またはクライアントが指定する)タスク識別子です。memo はステータスや Webhook にそのまま返される、不透明な照合用ラベルです。delegationSecret は公開リプレイを防ぐためにオープンな委任を紐付ける、アプリレベルで再利用する単一のシークレットです(委任ごとに 1 つ用意するものではなく、送信時のみ使用します)。
  • BigInt の JSON 変換:リレイヤーの JSON-RPC では通常の JSON が必要です。送信前に、署名済み委任構造体内の bigint 値を 0x で始まる 16 進数文字列に変換してください。Uint8Array は viem/utils の bytesToHex で変換します。

最小限のエンドツーエンド構成

// 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 を下回る、ガス見積もり時のリバート)に対して、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 のエントリーは最大1つです。nonce が最新であることを確認してください。
4211シミュレーション失敗リレイヤーは事前にシミュレーションを実行します。リバートの理由を data で確認してください。
4212マルチチェーン非対応チェーンごとに relayer_send7710Transaction を使う方法に切り替えてください。
4214タスク ID の重複taskId を省略してリレイヤーに割り当てさせるか、新しいランダムな16進数を送信してください。
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":まずトークンの小数桁数に基づいて10進数の入力を解析し、その後に変換してください。

エラーカタログとリクエスト/レスポンスの完全なスキーマについては、references/schemas.md を参照してください。

1shot-wallet との統合方法

方法は3つあります。コードを書く前に1つ選択してください。

方法スキルホストは relayer_* を呼び出すか
A — 埋め込みのみ1shot-walletいいえ
B — 埋め込み+委任の実行1shot-wallet + public-relayerはい(付与を引き換え)
C — 埋め込みウォレットなしpublic-relayerはい
方法 A — 埋め込みのみ(最も一般的)

1shot-wallet のみをインストールします。OWSProxy を接続し、eth_sendTransaction を呼び出すと、ウォレットが内部で委任に署名してリレイヤーに送信します。ホスト側にリレイヤーの JSON-RPC コードは不要です。ガス抽象化された送信や、任意の configure.destinationUrl ウェブフックは、このスキルなしで利用できます。

Path B — 埋め込み+実行の委任(両方のスキル)

ホストまたはバックエンドが、ユーザーから付与された委任(セッションキー、オフライン実行、定期的な ERC-20 許可)を使って処理を実行する場合に使用します。両方のスキルをインストールし、OWSProxy のセットアップについては 1shot-wallet/SKILL.md をお読みください。relayer_getCapabilities から始め、targetAddress(そのチェーン上のリレイヤーの償還用ウォレット)を確認します。

サブパスGrant toホストによる再委任例
B1 — 直接targetAddressいいえ例 0b
B2 — セッションキー(推奨)ホストのセッションアカウントはい → targetAddress例 0c
Path B1 — リレイヤーへの直接付与

よりシンプルなプロトタイプ向けの方法です。ユーザーがリレイヤーに直接許可を付与します。

  1. wallet_requestExecutionPermissions を to: targetAddress と定期的な ERC-20 の範囲(予算は手数料+処理費用以上)で実行します。
  2. ウォレットが response.context(署名済みの委任を1つ)を返します。ホストは decodeDelegations と toRelayerJson でデコードし、executions[] を構築してから、relayer_estimate7710Transaction / relayer_send7710Transaction を実行します。

ユーザーはリレイヤーアドレスに直接委任します。デモには適していますが、本番環境では B2 のセッションキーを推奨します。

Path B2 — セッションキー+再委任(推奨)

本番向けのセッションキー方式です。ユーザーはホストが制御するセッションアカウントに許可を付与し、ホストは送信前に、より限定的で実行固有の範囲を設定してリレイヤーに再委任します。

  1. ホストはセッションアカウントを生成するか読み込みます(ローカル署名者。秘密鍵はユーザーのパスキーではなく、ホストのメモリ内に保持されます)。
  2. wallet_requestExecutionPermissions を to: sessionAccountAddress と定期的な ERC-20 の範囲(オフライン/エージェント用の予算)で実行します。
  3. ウォレットが response.context(親の許可)を返します。ホストはこれをデコードし、セッションアカウントが今回の実行に対する、より限定的な条件(FunctionCall と exactCalldata、または手数料+処理費用を上限とする Erc20TransferAmount。ウォレット内送信と同じ範囲縮小の考え方)を設定して、targetAddress に再委任します。
  4. encodeDelegations を使って、エンコードされた委任チェーン(親の委任+署名済みの再委任)を permissionContext として構築します。チェーン全体を含む permissionContext を指定して、見積もりを取得し、relayer_send7710Transaction を実行します。
  5. 初回使用時に、セッションアカウントを EIP-7702 スマートアカウント形式にする必要がある場合があります。アップグレード時は、送信時に authorizationList を含めてください(このスキルの他の箇所と同じ制約です)。

再委任で親の範囲を広げることはできず、狭めることだけが可能です(条件は累積して適用されます)。MetaMask kit の再委任の作成(redelegatePermissionContext または createDelegation({ parentDelegation }))をご覧ください。

ウォレットは、ウォレット内の送信と、取り消し用の wallet_revokeExecutionPermission でも内部的にリレイヤーを使用します。これは Path B とは別の機能です。

開発者から、オフライン時にユーザーに代わって実行する、リレイヤー経由で定期的な ERC-20 許可を償還する、または埋め込みウォレットからのパスキー署名済み委任を使ってリレイヤーバンドルを送信するよう求められた場合に Path B を使用します。一般的な「パスキーウォレットの埋め込み」には使用しません。セッションキーとエージェントによる実行には B2 を推奨します。

パブリックリレイヤーはオープンな JSON-RPC サービスです(API キー不要)。同じ relayer_* メソッドに対応する別のリレイヤーは、誰でも実行できます。

Path 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 のブラウザーフロー(Example 0)、埋め込みウォレットの直接付与(Example 0b、Path B1)、埋め込みウォレットのセッションキーと再委任(Example 0c、Path B2)、見積もりを先に行う単一チェーンおよびマルチチェーンのフロー、自己スポンサー型、スポンサー型、Ed25519 検証を行う Webhook 受信側。クライアントコードを書くときや、実績のある統合パターンをコピーしたいときに参照してください。
  • 1shot-wallet スキル — 1Shot Wallet(OWS Host Layer)を埋め込みます。Path A と Path B では必須です。Path B の委任実行では補助的に使用します(埋め込みのみの送信では不要です)。
  • webauthn-prf-wallet スキル — 隔離された iframe 内に保持する、パスキー由来のクライアント側 EVM 鍵のための補助スキルです。完全なノンカストディアル構成では、このスキルと併用してください。
  • MetaMask Smart Accounts Kit — インストール、ブラウザー/EIP-7715 フロー、ローカル署名者/委任フロー、Advanced Permissions ウォレットクライアントのリファレンス。

コメント