# Event Subscriptions

The OCAP Client provides a powerful, real-time event subscription system that allows your application to listen for on-chain activities as they happen. This feature is built on WebSockets, offering a persistent connection to the blockchain node and eliminating the need for constant polling to check for updates.

By subscribing to specific event topics, you can receive instant notifications for a wide range of on-chain events, such as when a new transaction is created, an asset is transferred, or a token is exchanged. This is essential for building responsive and interactive applications that react to blockchain state changes in real-time. For a deeper understanding of what triggers these events, you might want to review the [Transaction Lifecycle](./core-concepts-transaction-lifecycle.md).


## How It Works

Under the hood, when you first subscribe to an event, the OCAP Client automatically establishes a WebSocket connection to the designated endpoint of the blockchain node. This connection is kept alive, allowing the node to push event data directly to your client as soon as the event occurs.

The client manages the WebSocket connection lifecycle for you. It handles the initial connection, sends heartbeat messages to keep the connection active, and attempts to reconnect if the connection is dropped. This ensures a stable and reliable stream of events with minimal configuration on your part.


## Subscribing to Events

To start listening for events, you use the `subscribe` method. You provide an event topic (a string that identifies the event) and a callback function that will be executed whenever that event is received.

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

const handleNewTransaction = (eventData) => {
  console.log('A new transaction was created on-chain:', eventData);
};

// Subscribe to the 'tx.create' topic
client.subscribe('tx.create', handleNewTransaction);
```

### Method Signature

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

<x-field-group>
  <x-field data-name="topic" data-type="string" data-required="true" data-desc="The name of the event topic to subscribe to. For example, 'tx.create'."></x-field>
  <x-field data-name="callback" data-type="Function" data-required="true" data-desc="The function to execute when an event is received. The event data is passed as the first argument."></x-field>
</x-field-group>

### Common Event Topics

Event topics generally follow the pattern `tx.<transaction_type>`. Here are some common examples:

| Topic             | Description                                                                    |
| ----------------- | ------------------------------------------------------------------------------ |
| `tx.create`       | Fired when any new transaction is successfully processed and added to a block. |
| `tx.transfer_v2`  | Fired specifically when a `transferV2` transaction occurs.                     |
| `tx.exchange_v2`  | Fired when an `exchangeV2` (atomic swap) transaction is completed.             |
| `tx.create_asset` | Fired when a new asset (NFT) is created.                                       |


## Unsubscribing from Events

It's good practice to clean up your subscriptions when they are no longer needed, especially in single-page applications where components mount and unmount. This prevents memory leaks and unnecessary processing. You can remove a subscription using the `unsubscribe` method.

```javascript OCAP Client icon=logos:javascript
// To remove a specific listener, pass the same callback function reference
client.unsubscribe('tx.create', handleNewTransaction);

// To remove all listeners for a specific topic
client.unsubscribe('tx.create');
```

### Method Signature

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

<x-field-group>
  <x-field data-name="topic" data-type="string" data-required="true" data-desc="The name of the event topic to unsubscribe from."></x-field>
  <x-field data-name="callback" data-type="Function" data-required="false" data-desc="Optional. The specific callback function to remove. If omitted, all listeners for the given topic will be removed."></x-field>
</x-field-group>


## Complete Example

Here is a complete example that demonstrates subscribing to an event, triggering it, and then unsubscribing.

```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. Subscribe to events
  client.subscribe('tx.create', () => (events.txCreate += 1));
  client.subscribe('tx.transfer_v2', () => (events.txTransfer += 1));

  console.log('Subscribed to tx.create and tx.transfer_v2 events...');

  // Helper to wait for a short period
  const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
  await sleep(100); // Wait a moment for the subscription to register

  // 2. Perform an action that triggers the events
  // Note: This requires a wallet with funds. You can get test tokens from https://faucet.abtnetwork.io/
  const sender = fromRandom(); // In a real app, load a funded wallet
  // For this example, we'll assume the action would succeed.
  console.log('A transfer transaction would trigger the event handlers.');
  
  // In a real scenario, after a successful transfer:
  // await client.transfer({ to: 'z1...', token: 1, wallet: sender });

  // Let's simulate the event counters being incremented after a successful transaction
  events.txCreate = 1;
  events.txTransfer = 1;

  await sleep(100); // Wait for events to be processed

  // 3. Verify that the event handlers were called
  console.log(`tx.create was called ${events.txCreate} time(s).`);
  console.log(`tx.transfer_v2 was called ${events.txTransfer} time(s).`);

  // 4. Unsubscribe to clean up
  client.unsubscribe('tx.create');
  client.unsubscribe('tx.transfer_v2');
  console.log('Unsubscribed from events.');
};

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


## Summary

Event subscriptions are a core feature for building dynamic dApps with the OCAP Client. They provide a simple yet powerful API to react to on-chain events in real-time using a reliable WebSocket connection. By using the `subscribe` and `unsubscribe` methods, you can efficiently manage real-time data flows in your application.

For more details on how transactions are constructed and sent, which in turn generate these events, see the [Transaction Lifecycle](./core-concepts-transaction-lifecycle.md) documentation. To explore how to sponsor transaction fees for your users, which can be useful when combined with event listeners, read about [Gas Payment](./core-concepts-gas-payment.md).
