[ERC1328] アプリとウォレットを接続するURIフォーマットの仕組みを理解しよう！

# はじめに

初めまして。
**CryptoGames**というブロックチェーンゲーム企業でエンジニアをしている **cardene（かるでね）** です！
スマートコントラクトを書いたり、フロントエンド・バックエンド・インフラと幅広く触れています。

https://cryptogames.co.jp/

代表的なゲームは**クリプトスペルズ**というブロックチェーンゲームです。

https://cryptospells.jp/

今回は、アプリケーションとウォレット間の接続を開始するためのURIフォーマットの定義を提案している規格である**ERC1328**についてまとめていきます！

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

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

:::note warn
**1328**は現在（2024年1月5日）では「**Review**」段階です。
:::

他にも様々なERCについてまとめています。

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

# 概要

この規格は、アプリ（ソフトウェア）とウォレット（お金や仮想通貨を管理する財布）を繋ぐための情報を、URIという特別なアドレス形式でどう書くかを決めています。
このURIは、QRコード（バーコードの一種）やインターネットのリンクとして表示できます。

:::note info
この方法を使えば、特定のアドレス（URI）をスマホでスキャンするかクリック一つで、アプリとウォレットがすぐに連携することができます。
これにより、異なるデジタルのサービス間でお金や情報をスムーズにやり取りできるようになり、使い勝手が良くなります。
:::

# 仕様

## 構文

WalletConnectのリクエストURIは、特定のフォーマットとパラメータを使って構成されます。
これは、アプリケーションとウォレットを接続する時のアドレスのようなものです。
以下がその構造です。

- **request**
    - "wc"から始まる文字列で、これはWalletConnectの接続リクエストを意味します。
- **topic**
    - 会話や接続の特定のセッションを識別するための文字列です。
- **version**
    - 使用しているWalletConnectのバージョンを示す数字です。
    - バージョンが指定されていない場合は省略可能です。
- **parameters**
    - 接続に関する追加情報を含む、一連のパラメータです。
    - 各パラメータはキーと値のペアで、"&"記号で区切られます。
- **key**
    - パラメータの名前を示す文字列です。
- **value**
    - パラメータの値を示す文字列です。

:::note info
このURIは次のような形になります。

```
request       = "wc" ":" topic [ "@" version ][ "?" parameters ]
topic         = STRING
version       = 1*DIGIT
parameters    = parameter *( "&" parameter )
parameter     = key "=" value
key           = STRING
value         = STRING
```

この形式に従ってURIを作成し、それをQRコードやリンクとして使用することで、アプリケーションとウォレット間のスムーズな接続が可能になります。
:::

## Semantics

WalletConnectプロトコルでは、使用するバージョンによって必要なパラメータが異なります。
以下は、それぞれのバージョンで必要なパラメータについての説明です。

### WalletConnect v1.0プロトコル（version=1）の場合
- **key**
    - メッセージを暗号化するために使用される対称鍵です。
- **bridge**
    - メッセージを中継するためのブリッジサーバーのURLです。

### WalletConnect v2.0プロトコル（version=2）の場合
- **symKey**
    - リレー経由でメッセージを暗号化するために使用される対称鍵です。
- **methods**
    - ペアリングトピックでサポートされている`jsonrpc`メソッドです。
- **relay-protocol**
    - メッセージを中継するためのトランスポートプロトコルです。
- **relay-data**
    - メッセージを中継するためのトランスポートデータです。
    - オプション機能。

:::note info
WalletConnect v1.0では、暗号化とメッセージ中継のための基本的な情報が必要です。
一方でWalletConnect v2.0では、より高度な機能とオプションが追加され、暗号化キー、サポートされるメソッド、メッセージの中継方法に関するより詳細な設定が可能になっています。
これにより、ユーザーはより安全かつ柔軟にウォレットとアプリケーションを接続できるようになります。
:::

## 例

以下はWalletConnectプロトコルのバージョン1.0と2.0の具体的なURIの例です。

### 1.0の例
```
wc:8a5e5bdc-a0e4-4702-ba63-8f1a5655744f@1?bridge=https%3A%2F%2Fbridge.walletconnect.org&key=41791102999c339c844880b23950704cc43aa840f3739e365323cda4dfa89e7a
```
- **wc**
    - WalletConnectの接続を意味します。
- **8a5e5bdc-a0e4-4702-ba63-8f1a5655744f**
    - トピックを特定するための一意の識別子です。
- **@1**
    - これはバージョン1.0を使用していることを示します。
- **bridge=https%3A%2F%2Fbridge.walletconnect.org**
    - メッセージを中継するブリッジサーバーのURLです（URLエンコードされています）。
- **key=417...89e7a**
    - メッセージを暗号化するための対称鍵です。

### 2.0の例
```
wc:7f6e504bfad60b485450578e05678ed3e8e8c4751d3c6160be17160d63ec90f9@2?relay-protocol=irn&symKey=587d5484ce2a2a6ee3ba1962fdd7e8588e06200c46823bd18fbd67def96ad303&methods=[wc_sessionPropose],[wc_authRequest,wc_authBatchRequest]"
```
- **wc**
    - WalletConnectの接続を意味します。
- **7f6e504b...ec90f9**
    - トピックを特定するための一意の識別子です。
- **@2**
    - これはバージョン2.0を使用していることを示します。
- **relay-protocol=irn**
    - メッセージを中継するためのトランスポートプロトコルです。
- **symKey=587d...d303**
    - メッセージを暗号化するための対称鍵です。
- **methods=[wc_sessionPropose],[wc_authRequest,wc_authBatchRequest]**
    - サポートされているjsonrpcメソッドのリストです。

これらのURIは、アプリケーションとウォレットが互いに正確に通信するための情報を含んでおり、バージョンや使用される技術に応じて異なる情報が必要になります。

# 補足

この提案では、WalletConnectプロトコルのアルファバージョンで使用されていたJSONフォーマットから離れています。
その理由は、QRコードの意図を解析するのが非常に非効率的であったためです。
この変更により、ウォレットが実装しやすいより良いQRコード解析APIを作成することが容易になります。
また、QRコード内でJSONの代わりにURIを使用することで、AndroidのIntentシステムを活用できるようになります。

具体的には、この提案によって、QRコードから直接情報を読み取る時の処理が改善されます。
従来のJSON形式では、QRコードのデータを解析してウォレットへの指示を理解するプロセスが複雑で非効率的でした。
URIを使用することで、このプロセスが簡潔かつ効率的になり、ウォレットアプリがより簡単にこれらの指示を解釈できるようになります。
さらに、Androidデバイスでは、Intentシステムを利用してアプリ間のデータ共有や操作がよりスムーズに行えるようになります。
これは、アプリが特定の種類のリンクやデータを自動的に認識して、適切なアクションを取ることを可能にするAndroidの機能です。

:::note info
### AndroidのIntent
AndroidのIntentシステムは、アプリケーション間でのコミュニケーションや、アプリケーション内のさまざまな活動（アクティビティ）間でのメッセージ送信を可能にする仕組みです。
Intentは、アプリケーションが何をしたいかを表す「**意図**」を示すオブジェクトで、主に以下の2つの目的で使用されます。

1. **アクティビティの起動**
    - Intentを使用して、同じアプリケーション内、または異なるアプリケーションのアクティビティ（例えば、ユーザーインターフェース画面）を開始することができます。
    - 例えば、ユーザーがボタンをタップしたときに新しい画面を表示するためにIntentが使われます。

2. **ブロードキャスト送信**
    - Intentを使用して、アプリケーションはシステム全体または特定のアプリケーションにメッセージを送信できます。
    - これは、デバイスの状態が変わったときや、特定のイベントが発生したときに他のアプリケーションに通知を送るためによく使用されます。

Intentは、明示的または暗黙的に使用することができます。

- **明示的Intent**
    - 明示的Intentは、アクティビティやサービスの正確なクラス名を指定するときに使用します。
    - つまり、どのアクティビティを起動したいか、どのサービスを使用したいかを開発者が正確に知っている場合に使います。

- **暗黙的Intent**
    - 暗黙的Intentは、特定のアクションを実行するために使用されますが、それを処理するアプリケーションやコンポーネントは指定しません。
    - 代わりに、Intentのアクションやデータタイプに基づいて、システムが適切なコンポーネントを選択します。
    - 例えば、ユーザーにウェブページを表示させたいとき、どのブラウザアプリを使用するかを指定せずにIntentを送ることができます。

AndroidのIntentシステムは非常に強力で、アプリケーションの柔軟性と機能性を大幅に高めることができます。
ユーザーの操作に応じてさまざまなアクティビティを簡単に起動したり、アプリケーション間でデータを共有したりすることができます。
:::

# 互換性

このURI仕様において、バージョニング（バージョン管理）は必須とされています。
その理由は、WalletConnectプロトコルが進化し続ける中で、新しいバージョンが導入されたときにも、古いバージョンとの後方互換性を保つことができるようにするためです。

:::note info
このURIにはバージョン情報が含まれています。
これにより、WalletConnectプロトコルが更新されたり新しい機能が追加されたりしても、古いバージョンを使っているアプリケーションやウォレットは引き続き動作することが保証されます。
つまり、プロトコルが発展しても、既存のシステムやユーザーに影響を与えずに済むので、安心して新しいバージョンへと移行することができます。
バージョニングは、技術の発展に伴う適応をスムーズにし、古いシステムと新しいシステムが共存できるようにするための重要な仕組みです。
:::

# セキュリティ

この規格では、URIがユーザーのデバイスやアプリケーション間で共有されるべきであり、そのURI内には通信を危険にさらしたり、ユーザーのプライベートキーのコントロールを可能にするような機密情報を含むべきではないと述べています。

つまり、URIを通じて情報を共有する時には、安全性が非常に重要です。
URI内には、ユーザーの安全を脅かす可能性のある機密データや、ユーザーのデジタル資産やプライベートキーを不正に操作できる情報は含まれていてはなりません。
このような情報が露呈すると、セキュリティ上のリスクが生じ、ユーザーがサイバー攻撃や詐欺の犠牲になる可能性があります。

したがって、URIを設計する際には、必要な情報のみを含め、機密情報が外部に漏れないようにすることが非常に重要です。
これにより、ユーザーのデバイスやアプリケーション間で安全に情報を共有できるようになります。

# 引用

ligi (@ligi), Pedro Gomes (@pedrouid), "ERC-1328: WalletConnect URI Format [DRAFT]," Ethereum Improvement Proposals, no. 1328, August 2018. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-1328.

# 最後に

今回は「アプリケーションとウォレット間の接続を開始するためのURIフォーマットの定義を提案している規格である**ERC1328**」についてまとめてきました！
いかがだったでしょうか？

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

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

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

https://chaldene.net/

https://zenn.dev/heku

https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58


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