# イベントサブスクリプション

OCAP Clientは、アプリケーションがオンチェーンアクティビティをリアルタイムでリッスンできるようにする、強力なリアルタイムイベントサブスクリプションシステムを提供します。この機能はWebSocket上に構築されており、ブロックチェーンノードへの永続的な接続を提供し、更新をチェックするための継続的なポーリングの必要性をなくします。

特定のイベントトピックをサブスクライブすることで、新しいトランザクションが作成されたとき、アセットが転送されたとき、またはトークンが交換されたときなど、さまざまなオンチェーンイベントの即時通知を受け取ることができます。これは、ブロックチェーンの状態変化にリアルタイムで反応する、レスポンシブでインタラクティブなアプリケーションを構築するために不可欠です。これらのイベントが何によってトリガーされるかをより深く理解するには、[トランザクションライフサイクル](./core-concepts-transaction-lifecycle.md)を確認することをお勧めします。


## 仕組み

内部では、イベントを最初にサブスクライブすると、OCAP Clientは自動的にブロックチェーンノードの指定されたエンドポイントへのWebSocket接続を確立します。この接続は維持され、イベントが発生するとすぐにノードがクライアントにイベントデータを直接プッシュできるようになります。

クライアントはWebSocket接続のライフサイクルを管理します。初回接続を処理し、接続をアクティブに保つためにハートビートメッセージを送信し、接続が切断された場合に再接続を試みます。これにより、最小限の設定で安定した信頼性の高いイベントストリームが保証されます。


## イベントのサブスクライブ

イベントのリッスンを開始するには、`subscribe` メソッドを使用します。イベントトピック（イベントを識別する文字列）と、そのイベントが受信されるたびに実行されるコールバック関数を提供します。

```javascript OCAP Client icon=logos:javascript
const client = new GraphQLClient('https://beta.abtnetwork.io/api/v2/gql');

const handleNewTransaction = (eventData) => {
  console.log('新しいトランザクションがオンチェーンで作成されました:', eventData);
};

// 'tx.create' トピックをサブスクライブ
client.subscribe('tx.create', handleNewTransaction);
```

### メソッドシグネチャ

**`subscribe(topic, callback)`**

<x-field-group>
  <x-field data-name="topic" data-type="string" data-required="true" data-desc="サブスクライブするイベントトピックの名前。例: 'tx.create'。"></x-field>
  <x-field data-name="callback" data-type="Function" data-required="true" data-desc="イベントが受信されたときに実行される関数。イベントデータは最初の引数として渡されます。"></x-field>
</x-field-group>

### 一般的なイベントトピック

イベントトピックは通常、`tx.<transaction_type>` のパターンに従います。以下にいくつかの一般的な例を示します。

| トピック              | 説明                                               |
| ----------------- | ------------------------------------------------ |
| `tx.create`       | 新しいトランザクションが正常に処理され、ブロックに追加されたときに発行されます。         |
| `tx.transfer_v2`  | 特に `transferV2` トランザクションが発生したときに発行されます。          |
| `tx.exchange_v2`  | `exchangeV2` (アトミックスワップ) トランザクションが完了したときに発行されます。 |
| `tx.create_asset` | 新しいアセット (NFT) が作成されたときに発行されます。                   |


## イベントのサブスクライブ解除

特にコンポーネントがマウントおよびアンマウントされるシングルページアプリケーションでは、不要になったサブスクリプションをクリーンアップすることをお勧めします。これにより、メモリリークや不要な処理を防ぐことができます。`unsubscribe` メソッドを使用してサブスクリプションを削除できます。

```javascript OCAP Client icon=logos:javascript
// 特定のリスナーを削除するには、同じコールバック関数の参照を渡します
client.unsubscribe('tx.create', handleNewTransaction);

// 特定のトピックのすべてのリスナーを削除するには
client.unsubscribe('tx.create');
```

### メソッドシグネチャ

**`unsubscribe(topic, [callback])`**

<x-field-group>
  <x-field data-name="topic" data-type="string" data-required="true" data-desc="サブスクライブを解除するイベントトピックの名前。"></x-field>
  <x-field data-name="callback" data-type="Function" data-required="false" data-desc="オプション。削除する特定のコールバック関数。省略した場合、指定されたトピックのすべてのリスナーが削除されます。"></x-field>
</x-field-group>


## 完全な例

イベントのサブスクライブ、トリガー、そしてサブスクライブ解除を実演する完全な例を以下に示します。

```javascript Event Subscription Lifecycle icon=logos:javascript
import GraphQLClient from '@ocap/client';
import { fromRandom } from '@ocap/wallet';

const main = async () => {
  const client = new GraphQLClient('https://beta.abtnetwork.io/api/v2/gql');
  const events = { txCreate: 0, txTransfer: 0 };

  // 1. イベントをサブスクライブ
  client.subscribe('tx.create', () => (events.txCreate += 1));
  client.subscribe('tx.transfer_v2', () => (events.txTransfer += 1));

  console.log('tx.create および tx.transfer_v2 イベントをサブスクライブしました...');

  // 短時間待機するためのヘルパー
  const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
  await sleep(100); // サブスクリプションが登録されるまで少し待機

  // 2. イベントをトリガーするアクションを実行
  // 注: これには資金のあるウォレットが必要です。テストトークンは https://faucet.abtnetwork.io/ から入手できます。
  const sender = fromRandom(); // 実際のアプリでは、資金のあるウォレットをロードします
  // この例では、アクションが成功することを前提とします。
  console.log('転送トランザクションはイベントハンドラをトリガーします。');
  
  // 実際のシナリオでは、転送が成功した後:
  // await client.transfer({ to: 'z1...', token: 1, wallet: sender });

  // 成功したトランザクションの後にイベントカウンターが増加するのをシミュレートしてみましょう
  events.txCreate = 1;
  events.txTransfer = 1;

  await sleep(100); // イベントが処理されるのを待機

  // 3. イベントハンドラが呼び出されたことを確認
  console.log(`tx.create は ${events.txCreate} 回呼び出されました。`);
  console.log(`tx.transfer_v2 は ${events.txTransfer} 回呼び出されました。`);

  // 4. クリーンアップのためにサブスクライブを解除
  client.unsubscribe('tx.create');
  client.unsubscribe('tx.transfer_v2');
  console.log('イベントのサブスクライブを解除しました。');
};

main().catch(console.error);
```


## まとめ

イベントサブスクリプションは、OCAP Clientを使用して動的なdAppを構築するためのコア機能です。信頼性の高いWebSocket接続を使用してオンチェーンイベントにリアルタイムで反応するための、シンプルかつ強力なAPIを提供します。`subscribe` および `unsubscribe` メソッドを使用することで、アプリケーション内のリアルタイムデータフローを効率的に管理できます。

トランザクションがどのように構築・送信され、それがこれらのイベントを生成するかの詳細については、[トランザクションライフサイクル](./core-concepts-transaction-lifecycle.md)のドキュメントを参照してください。イベントリスナーと組み合わせると便利な、ユーザーのトランザクション手数料をスポンサーする方法については、[ガス支払い](./core-concepts-gas-payment.md)をお読みください。
