# [ERC7795] dAppsがウォレットにトークン前提条件を指定できるWallet Call Token Capabilitiesの仕組みを理解しよう！

> ERC7795とは、EIP5792のwallet_sendCallsメソッドを拡張し、dAppsがウォレットに対してトークンに関する前提条件を指定できるようにする仕組みのことです。

- URL: https://cardene.dev/articles/eab82f94332e974f2c5d
- 公開日: 2026-03-08
- 更新日: 2026-03-08
- トピック: Blockchain
- タグ: ethereum, smartcontract, ブロックチェーン, erc

## はじめに

『DApps開発入門』という本や色々記事を書いているかるでねです。

https://amzn.asia/d/gxvJ0Pw

今回は、EIP5792の`wallet_sendCalls`を拡張し、dAppsがウォレット呼び出しに必要なトークン残高や承認などの前提条件を指定できるようにする仕組みを提案している**ERC7795**についてまとめていきます！

:::message
以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。
:::

https://eips.ethereum.org/EIPS/eip-7795

他にも様々なEIP・BIP・SLIP・CAIP・ENSIP・RFC・ACPについてまとめています。

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4

## 概要

**ERC7795**とは、**EIP5792**の`wallet_sendCalls`メソッドを拡張し、dAppsがウォレットに対してトークンに関する前提条件を指定できるようにする仕組みのことです。

:::message
**EIP5792**は、dAppsがウォレットに対して複数の呼び出しをバッチで送信できるようにする`wallet_sendCalls`メソッドを定義した規格です。
:::

**ERC7795**では、**ERC20**トークンの残高・承認要件を指定できます。

:::message
**ERC20**については以下の記事を参考にしてください。
:::

[\[ERC20\] ERC20を1からわかりやすく解説](/articles/aeefe2d89dd5332c9f43)

また、**ERC721**（NFT）の所有権・承認要件も指定できます。

:::message
**ERC721**については以下の記事を参考にしてください。
:::

[\[ERC721\] ERC721を1からわかりやすく解説](/articles/0570a8d05bc7c9b9593f)

さらに、**ERC1155**トークンの残高・承認要件も指定可能です。

:::message
**ERC1155**については以下の記事を参考にしてください。
:::

https://qiita.com/cardene/items/5c37b0c51e1b9c458c67

これらの機能は`wallet_sendCalls`と`wallet_getCapabilities`RPCメソッドを通じて実装されます。

この規格の特徴は、ウォレットが前提条件を自動的に処理できる点にあります。
dAppsがトークン要件を指定すると、ウォレットはその要件を満たすために必要なトランザクション（承認やスワップなど）を自動的に先頭に追加します。

**ERC7795**では、ERC20の残高・承認、ERC721の所有権・承認、ERC1155の残高・承認に対応する6種類のケーパビリティを定義しています。
これらは**EIP5792**の既存のケーパビリティ発見メカニズム（`wallet_getCapabilities`）を活用するため、ウォレットは対応可能な要件のみを選択的に実装できます。
また、複数のケーパビリティを組み合わせて使用することも可能で、将来的に新しい要件タイプを段階的に追加できる拡張性も備えています。

![ERC7795 ケーパビリティ概要](/images/qiita-043149d4-6b72-4b93-8199-d0a8b6c89aec.webp)

## 動機

この提案が生まれた背景には以下のような課題がありました。

#### 単一ネットワーク依存による流動性の縮小

dAppsが1つのネットワーク上にのみ存在することはよくありますが、これによりdAppsがアクセスできる直接的な流動性が縮小します。
ほとんどのユーザーは限られた数のネットワークにのみ資金を持っており、ネットワーク数が増えるほど、dAppsが選択したネットワークとユーザーの資金があるネットワークが一致する可能性は低くなります。

#### 「最終意図」を伝える手段の欠如

dAppsにはウォレットに対して「**最終意図（final intent）**」を伝える方法がないため、ユーザーに実行してほしい最後のアクション（トランザクションリクエスト）しか伝えることができません。
そのため、最終アクションの前提条件を満たすために必要な事前アクション（資金の統合やアセットの交換など）をユーザー自身が推測しなければなりません。
この推測プロセスはユーザーにとって煩雑で、UXの大幅な低下につながっています。

#### この提案による解決策

**ERC7795**は、dAppsが`wallet_sendCalls`のケーパビリティとしてトークン前提条件を指定できるようにします。
ウォレットはこれらの前提条件を解釈し、必要に応じてトランザクション（ブリッジ、スワップ、承認など）を自動的に先頭に追加することで、シームレスなユーザー体験を提供できます。

## 仕様

### ケーパビリティ一覧

**ERC7795**では、以下の6つのケーパビリティを定義しています。

| ケーパビリティ | 対象トークン | 説明 |
|--------------|------------|------|
| `erc20MinBalance` | ERC20 | 最小残高要件 |
| `erc20MinAllowance` | ERC20 | 最小承認額要件 |
| `erc721Ownership` | ERC721 | NFT所有権要件 |
| `erc721Approval` | ERC721 | NFT承認要件 |
| `erc1155MinBalance` | ERC1155 | 最小残高要件 |
| `erc1155MinAllowance` | ERC1155 | 最小承認要件 |

### ERC20

ERC20トークンに関するケーパビリティとして、最小残高要件と最小承認額要件の2つが定義されています。

#### erc20MinBalance

ERC20トークンの最小残高要件を指定するケーパビリティです。
dAppsはこのケーパビリティを使用して、呼び出しを実行する前にアカウントが特定のERC20トークンの最小残高を持っている必要があることをウォレットに通知します。
ウォレットはこの要件を満たすために、ブリッジやスワップなどのトランザクションを先頭に追加する場合があります。

##### パラメータ

| フィールド | 型 | 説明 |
|-----------|-----|------|
| `version` | `string` | ケーパビリティのバージョン |
| `chainId` | `0x${string}` | チェーンID（16進数） |
| `owner` | `0x${string}` | 残高を確認するアドレス |
| `token` | `0x${string}` | ERC20トークンのコントラクトアドレス |
| `minAmount` | `0x${string}` | 必要な最小残高（16進数） |

##### 使用例

```javascript
{
  "capabilities": {
    "erc20MinBalance": {
      "version": "1.0",
      "chainId": "0x01",
      "owner": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
      "token": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
      "minAmount": "0x0f4240" // 1,000,000 = 1 USDC (6 decimals)
    }
  }
}
```

#### erc20MinAllowance

ERC20トークンの最小承認額要件を指定するケーパビリティです。
dAppsはこのケーパビリティを使用して、呼び出しを実行する前に特定のアドレスに対するERC20トークンの最小承認額が必要であることをウォレットに通知します。
ウォレットはこの要件を満たすために、`approve`トランザクションを先頭に追加する場合があります。

##### パラメータ

| フィールド | 型 | 説明 |
|-----------|-----|------|
| `version` | `string` | ケーパビリティのバージョン |
| `chainId` | `0x${string}` | チェーンID（16進数） |
| `owner` | `0x${string}` | 承認元のアドレス |
| `operator` | `0x${string}` | 承認先のオペレーターアドレス |
| `token` | `0x${string}` | ERC20トークンのコントラクトアドレス |
| `minAmount` | `0x${string}` | 必要な最小承認額（16進数） |

:::message
このケーパビリティはオーナーがトークンの残高を持っていることを意味しません。承認額が指定した量以上であることのみを要求します。
:::

##### 使用例

```javascript
{
  "capabilities": {
    "erc20MinAllowance": {
      "version": "1.0",
      "chainId": "0x01",
      "owner": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
      "token": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
      "operator": "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D",
      "minAmount": "0x0f4240" // Uniswap Router に USDC を承認
    }
  }
}
```

### ERC721

ERC721トークン（NFT）に関するケーパビリティとして、所有権要件と承認要件の2つが定義されています。

#### erc721Ownership

ERC721トークン（NFT）の所有権要件を指定するケーパビリティです。
dAppsはこのケーパビリティを使用して、呼び出しを実行する前にアカウントが特定のNFTを所有している必要があることをウォレットに通知します。
ウォレットはこの要件を満たすために、NFTの購入などのトランザクションを先頭に追加する場合があります。

##### パラメータ

| フィールド | 型 | 説明 |
|-----------|-----|------|
| `version` | `string` | ケーパビリティのバージョン |
| `chainId` | `0x${string}` | チェーンID（16進数） |
| `owner` | `0x${string}` | 所有者のアドレス |
| `token` | `0x${string}` | ERC721トークンのコントラクトアドレス |
| `tokenId` | `0x${string}` | 必要なトークンID（16進数） |

##### 使用例

```javascript
{
  "capabilities": {
    "erc721Ownership": {
      "version": "1.0",
      "chainId": "0x01",
      "owner": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
      "token": "0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d",
      "tokenId": "0x10" // BAYC #16 の所有権が必要
    }
  }
}
```

#### erc721Approval

ERC721トークン（NFT）の承認要件を指定するケーパビリティです。
dAppsはこのケーパビリティを使用して、呼び出しを実行する前に特定のオペレーターに対するNFTの承認が必要であることをウォレットに通知します。

:::message
このケーパビリティはオーナーがトークンを所有していることを意味しません。承認が設定されていることのみを要求します。
:::

##### パラメータ

| フィールド | 型 | 説明 |
|-----------|-----|------|
| `version` | `string` | ケーパビリティのバージョン |
| `chainId` | `0x${string}` | チェーンID（16進数） |
| `owner` | `0x${string}` | 承認元のアドレス |
| `operator` | `0x${string}` | 承認先のオペレーターアドレス |
| `token` | `0x${string}` | ERC721トークンのコントラクトアドレス |
| `tokenId` | `0x${string}` | 承認が必要なトークンID（16進数） |

##### 使用例

```javascript
{
  "capabilities": {
    "erc721Approval": {
      "version": "1.0",
      "chainId": "0x01",
      "owner": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
      "operator": "0x00000000006c3852cbEf3e08E8dF289169EdE581",
      "token": "0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d",
      "tokenId": "0x10" // OpenSea Seaport に BAYC #16 を承認
    }
  }
}
```

### ERC1155

ERC1155トークンに関するケーパビリティとして、最小残高要件と最小承認要件の2つが定義されています。

#### erc1155MinBalance

ERC1155トークンの最小残高要件を指定するケーパビリティです。
dAppsはこのケーパビリティを使用して、呼び出しを実行する前にアカウントが特定のERC1155トークンの最小残高を持っている必要があることをウォレットに通知します。

##### パラメータ

| フィールド | 型 | 説明 |
|-----------|-----|------|
| `version` | `string` | ケーパビリティのバージョン |
| `chainId` | `0x${string}` | チェーンID（16進数） |
| `owner` | `0x${string}` | 残高を確認するアドレス |
| `token` | `0x${string}` | ERC1155トークンのコントラクトアドレス |
| `tokenId` | `0x${string}` | トークンID（16進数） |
| `minAmount` | `0x${string}` | 必要な最小残高（16進数） |

##### 使用例

```javascript
{
  "capabilities": {
    "erc1155MinBalance": {
      "version": "1.0",
      "chainId": "0x01",
      "owner": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
      "token": "0x631998e91476da5b870d741192fc5cbc55f5a52e",
      "tokenId": "0x10",
      "minAmount": "0x0f4240" // Token ID 16 の残高が指定量以上必要
    }
  }
}
```

#### erc1155MinAllowance

ERC1155トークンの最小承認要件を指定するケーパビリティです。
dAppsはこのケーパビリティを使用して、呼び出しを実行する前に特定のアドレスに対するERC1155トークンの承認が必要であることをウォレットに通知します。

:::message
このケーパビリティはオーナーがトークンの残高を持っていることを意味しません。承認額が指定した量以上であることのみを要求します。
:::

##### パラメータ

| フィールド | 型 | 説明 |
|-----------|-----|------|
| `version` | `string` | ケーパビリティのバージョン |
| `chainId` | `0x${string}` | チェーンID（16進数） |
| `owner` | `0x${string}` | 承認元のアドレス |
| `operator` | `0x${string}` | 承認先のオペレーターアドレス |
| `token` | `0x${string}` | ERC1155トークンのコントラクトアドレス |
| `tokenId` | `0x${string}` | トークンID（16進数） |
| `minAmount` | `0x${string}` | 必要な最小承認額（16進数） |

##### 使用例

```javascript
{
  "capabilities": {
    "erc1155MinAllowance": {
      "version": "1.0",
      "chainId": "0x01",
      "owner": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
      "operator": "0x00000000006c3852cbEf3e08E8dF289169EdE581",
      "token": "0x631998e91476da5b870d741192fc5cbc55f5a52e",
      "tokenId": "0x10",
      "minAmount": "0x0f4240" // OpenSea Seaport に承認
    }
  }
}
```

## 補足

#### 完全な使用例

以下は、複数のケーパビリティを組み合わせた`wallet_sendCalls`の完全な使用例です。

```javascript
{
  "method": "wallet_sendCalls",
  "params": [{
    "version": "1.0",
    "from": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
    "calls": [
      {
        "to": "0xDeFiProtocol",
        "data": "0x...",
        "value": "0x0",
        "chainId": "0x01"
      }
    ],
    "capabilities": {
      "erc20MinBalance": {
        "version": "1.0",
        "chainId": "0x01",
        "owner": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
        "token": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
        "minAmount": "0x5F5E100"
      },
      "erc20MinAllowance": {
        "version": "1.0",
        "chainId": "0x01",
        "owner": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
        "token": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
        "operator": "0xDeFiProtocol",
        "minAmount": "0x5F5E100"
      }
    }
  }]
}
```

この例では、以下の前提条件を指定しています。

- USDCの残高が100以上であること
- DeFiプロトコルに対してUSDCの承認が100以上であること

#### ウォレットの動作

ウォレットは指定されたケーパビリティに基づいて、以下のように動作します。

```mermaid
sequenceDiagram
    participant dApp
    participant Wallet
    participant Blockchain

    dApp->>Wallet: wallet_sendCalls (with capabilities)
    Wallet->>Wallet: 前提条件を確認
    alt 前提条件が満たされていない場合
        Wallet->>Wallet: 必要なトランザクションを生成
        Wallet->>Blockchain: 前提条件を満たすTx
    end
    Wallet->>Blockchain: 元のcallsを実行
    Blockchain-->>Wallet: 結果
    Wallet-->>dApp: レスポンス
```

この図は、dAppsが`wallet_sendCalls`でケーパビリティを指定した場合のウォレットの処理フローを示しています。

1. dAppsがケーパビリティ付きの`wallet_sendCalls`をウォレットに送信します。
2. ウォレットは指定された前提条件（残高要件、承認要件など）を確認します。
3. 前提条件が満たされていない場合、ウォレットは必要なトランザクション（スワップ、ブリッジ、approve呼び出しなど）を自動的に生成します。
4. 前提条件を満たすトランザクションを先に実行し、その後に元のcallsを実行します。
5. すべてのトランザクションが完了したら、結果をdAppsに返します。

この仕組みにより、dAppsは複雑なトランザクション順序を自分で管理する必要がなくなり、ウォレットが最適な方法で前提条件を処理できます。

#### ケーパビリティのサポート確認

ウォレットがこれらのケーパビリティをサポートしているかどうかは、`wallet_getCapabilities`メソッドで確認できます。

```javascript
{
  "method": "wallet_getCapabilities",
  "params": ["0xUserAddress"]
}
```

レスポンス例を以下に示します。

```javascript
{
  "0x1": {
    "erc20MinBalance": { "supported": true, "versions": ["1.0"] },
    "erc20MinAllowance": { "supported": true, "versions": ["1.0"] },
    "erc721Ownership": { "supported": true, "versions": ["1.0"] },
    "erc721Approval": { "supported": true, "versions": ["1.0"] },
    "erc1155MinBalance": { "supported": true, "versions": ["1.0"] },
    "erc1155MinAllowance": { "supported": true, "versions": ["1.0"] }
  }
}
```

## 互換性

#### EIP5792との関係

**ERC7795**は以下の規格と関係があります。

| 規格 | 関係性 | 備考 |
|------|--------|------|
| **EIP5792** | 拡張 | `wallet_sendCalls`のケーパビリティとして実装 |
| **ERC20** | 対象 | 残高・承認要件を指定可能 |
| **ERC721** | 対象 | 所有権・承認要件を指定可能 |
| **ERC1155** | 対象 | 残高・承認要件を指定可能 |

#### ユースケース

以下の2つの具体的なユースケースが紹介されています。

##### EOAウォレットでのブリッジを使ったマーケットプレイス購入

ユーザーが**チェーンA**上でERC721トークンを購入したいが、資金は**チェーンB**にしかない場合を考えます。
dAppsは`wallet_sendCalls`を使い、マーケットプレイスのトランザクションとともにチェーンA上の資金要件をケーパビリティとして指定します。
EOAウォレットは、前提条件を満たすために必要なトランザクション（ブリッジなど）への署名をユーザーに促し、メインのトランザクションを実行する前にそれらが完了していることを保証します。

![EOAウォレットでのブリッジを使ったマーケットプレイス購入](https://raw.githubusercontent.com/ethereum/ERCs/master/assets/erc-7795/eoa_example.svg)

##### スマートコントラクトウォレットでのブリッジ・スワップ・支払い

dAppsがユーザーに対して**チェーンB**上の**トークンZ**での支払いを要求するが、ユーザーは**チェーンA**上に**トークンY**しか持っていない場合を考えます。
dAppsは支払いトランザクションとともにチェーンB上のトークンZ残高要件をケーパビリティとして指定します。
スマートコントラクトウォレットは、必要なすべてのトランザクション（ブリッジ・スワップ・支払い）に一度に署名することをユーザーに求め、適切な順序で実行します。
署名済みトランザクションはバンドラーに同時に送信でき、ウォレットが切断されても操作が完了できます。

![スマートコントラクトウォレットでのブリッジ・スワップ・支払い](https://raw.githubusercontent.com/ethereum/ERCs/master/assets/erc-7795/sc_example.svg)

## 後方互換性

**ERC7795**は**EIP5792**のケーパビリティシステムを使用しているため、このケーパビリティをサポートしていないウォレットでも、単純にケーパビリティを無視して通常の`wallet_sendCalls`として処理することができます。

## セキュリティ

:::message alert
セキュリティに関する考慮事項として、以下の点に注意が必要です。
:::

#### 過度な承認

dAppsが必要以上の承認額を要求する可能性があります。

ウォレットは要求された承認額をユーザーに明示し、必要に応じて調整できるようにすべきです。
また、無制限承認（`type(uint256).max`）の要求には特に注意が必要です。

#### 悪意のあるdApps

悪意のあるdAppsがユーザーの資産を狙った前提条件を設定する可能性があります。

ウォレットは前提条件を満たすために実行するトランザクションの詳細をユーザーに表示し、明示的な承認を得るべきです。

#### トランザクション順序の操作

前提条件を満たすトランザクションと元のcallsの間でフロントランニング攻撃が発生する可能性があります。

ウォレットは可能な限りアトミックな実行（バッチトランザクション）を使用すべきです。

ウォレット開発者は、前提条件を満たすために自動的に実行するトランザクションについて、ユーザーに明確な同意を求める必要があります。

## 引用

https://eips.ethereum.org/EIPS/eip-7795

https://eips.ethereum.org/EIPS/eip-5792

https://eips.ethereum.org/EIPS/eip-20

https://eips.ethereum.org/EIPS/eip-721

https://eips.ethereum.org/EIPS/eip-1155

## 最後に

今回は「**ERC7795によるdAppsがウォレットにトークン前提条件を指定できる仕組み**」についてまとめてきました！
いかがだったでしょうか？

質問などがある方は以下のTwitterのDMなどからお気軽に質問してください！

[Twitter @cardene777](https://twitter.com/cardene777)

他の媒体でも情報発信しているのでぜひ他も見ていってください！

https://zenn.dev/heku

https://cardene.substack.com/

https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4
