# Subscribe Events

## WebSocket Subscription Overview

Our API facilitates real-time event tracking through WebSocket connections. By subscribing to specific topics, you can receive immediate notifications as events occur. Maintaining an active connection is crucial; most WebSocket libraries handle this by sending periodic ping messages to the server.

### Available Topics and Notifications

You can subscribe to the following topics:

* **Opportunity Transactions (`opportunityTxs`)**: Notifies you when a new opportunity transaction is available.
* **Solver Operations (`solverOperations`)**: Alerts you to solver-related operations, such as bids or validations.

Each notification includes detailed event data, enabling you to take appropriate actions.

## Response Data Details

Upon subscribing, you'll receive structured data for each event. Fields representing large integers are encoded as hexadecimal strings to ensure precision and compatibility.

### **Opportunity Transactions (`opportunityTxs`)**

Events in this topic provide:

* **Hex-encoded Binary**: The transaction's binary data, encoded in hexadecimal format.
* **Transaction Hash**: A unique identifier for the transaction.

### **Solver Operations (`solverOperations`)**

Events in this topic include:

* **From**: Sender's address, represented as a hexadecimal string.
* **To**: Recipient's address, represented as a hexadecimal string.
* **Value**: Operation value in Wei, encoded as a hexadecimal string.
* **Gas**: Allocated gas, encoded as a hexadecimal string.
* **MaxFeePerGas**: Maximum fee per gas unit, encoded as a hexadecimal string.
* **Deadline**: Operation deadline timestamp, encoded as a hexadecimal string.
* **Solver**: Solver's address, represented as a hexadecimal string.
* **Control**: Controlling address for the transaction, represented as a hexadecimal string.
* **UserOpHash**: Unique hash of the user's operation, represented as a hexadecimal string.
* **BidToken**: Address of the token being bid, represented as a hexadecimal string.
* **BidAmount**: Bid amount in the specified token, encoded as a hexadecimal string.
* **Data**: Additional arbitrary data, encoded as a hexadecimal string.
* **Signature**: Signature verifying the operation, encoded as a hexadecimal string.

### **Example Response**

```json
{
  "topic": "solverOperations",
  "data": {
    "From": "0xSenderAddress",
    "To": "0xRecipientAddress",
    "Value": "0xde0b6b3a7640000", // 1 Ether in Wei
    "Gas": "0x7a120", // 500,000 in decimal
    "MaxFeePerGas": "0x77359400", // 2 Gwei in decimal
    "Deadline": "0x64c6f8c0", // Unix timestamp
    "Solver": "0xSolverAddress",
    "Control": "0xControlAddress",
    "UserOpHash": "0xUniqueHash",
    "BidToken": "0xTokenAddress",
    "BidAmount": "0x3782dace9d900000", // 0.25 Ether in Wei
    "Data": "0xEncodedData",
    "Signature": "0xSignatureData"
  }
}
```

In this example, fields like `Value`, `Gas`, `MaxFeePerGas`, `Deadline`, and `BidAmount` are represented as hexadecimal strings, corresponding to their `*big.Int` values. This encoding ensures that large integer values are accurately transmitted without loss of precision. When processing these fields, ensure your application correctly decodes the hexadecimal strings back into numerical values as needed.

## Minimal TypeScript Example

The following TypeScript example demonstrates how to establish a WebSocket connection, subscribe to the `opportunityTxs` and `solverOperations` topics, and handle incoming messages:

{% tabs %}
{% tab title="JavaScript" %}

```javascript
import WebSocket from 'ws';

// Define your WebSocket endpoint
const wsEndpoint = 'wss://polygon-rpc.fastlane.xyz/ws';

// Topics to subscribe to
enum WebSocketTopic {
  OpportunityTxs = 'opportunityTxs',
  SolveOperations = 'solverOperations'
}

// Subscribe to specified topics
function subscribeToTopics(ws: WebSocket, topics: WebSocketTopic[]) {
  ws.send(JSON.stringify({ action: 'subscribe', params: topics }));
  console.log(`Subscribed to topics: ${topics.join(', ')}`);
}

// Connect and subscribe to topics
(async () => {
  const ws = new WebSocket(wsEndpoint);

  ws.on('open', () => {
    console.log('WebSocket connection established');
    // Subscribe to topics
    subscribeToTopics(ws, [WebSocketTopic.OpportunityTxs, WebSocketTopic.SolveOperations]);
  });

  ws.on('message', (data) => {
    const message = JSON.parse(data.toString());
    console.log('Received message:', message);
  });

  ws.on('close', () => {
    console.log('WebSocket connection closed');
  });

  ws.on('error', (error) => {
    console.error('WebSocket error:', error);
  });
})();


// Define your WebSocket endpoint
const wsEndpoint = 'wss://polygon-rpc.fastlane.xyz/ws';

// Topics to subscribe to
enum WebSocketTopic {
  OpportunityTxs = 'opportunityTxs',
  SolveOperations = 'solverOperations'
}

// Subscribe to specified topics
function subscribeToTopics(ws: WebSocket, topics: WebSocketTopic[]) {
  topics.forEach((topic) => {
    ws.send(JSON.stringify({ action: 'subscribe', topic }));
    console.log(`Subscribed to topic: ${topic}`);
  });
}

// Connect and subscribe to topics
(async () => {
  const ws = new WebSocket(wsEndpoint);

  ws.on('open', () => {
    console.log('WebSocket connection established');
    // Subscribe to topics
    subscribeToTopics(ws, [WebSocketTopic.OpportunityTxs, WebSocketTopic.SolveOperations]);
  });

  ws.on('message', (data) => {
    const message = JSON.parse(data.toString());
    console.log('Received message:', message);
  });

  ws.on('close', () => {
    console.log('WebSocket connection closed');
  });

  ws.on('error', (error) => {
    console.error('WebSocket error:', error);
  });
})();

```

{% endtab %}

{% tab title="Python" %}

```python
import asyncio
import websockets
import json
from typing import List

# Define your WebSocket endpoint
ws_endpoint = "wss://polygon-rpc.fastlane.xyz/ws"

# Topics to subscribe to
topics = ["opportunityTxs", "solverOperations"]


async def wait_for_subscription_confirmation(ws, topic: str):
    """Wait for subscription confirmation message for a specific topic"""
    async for message in ws:
        try:
            data = json.loads(message)
            # Check if this is a subscription confirmation
            if (
                data.get("jsonrpc") == "2.0"
                and "result" in data
                and data.get("id") == 1
            ):
                print(f"Subscription confirmed for topic: {topic}")
                return
        except json.JSONDecodeError:
            print(f"Failed to parse message: {message}")


async def subscribe_to_topics(ws, topics: List[str]):
    """Subscribe to multiple topics with proper JSON-RPC format"""
    for topic in topics:
        subscription_message = {
            "jsonrpc": "2.0",
            "id": 1,
            "method": "subscribe",
            "params": [topic],
        }

        print(f"Sending subscription request for {topic}:", subscription_message)
        await ws.send(json.dumps(subscription_message))
        await wait_for_subscription_confirmation(ws, topic)


async def handle_messages(ws):
    """Handle incoming WebSocket messages"""
    async for message in ws:
        try:
            data = json.loads(message)
            print("Received message:", data)
        except json.JSONDecodeError:
            print(f"Failed to parse message: {message}")


async def main():
    try:
        async with websockets.connect(ws_endpoint) as ws:
            print("WebSocket connection established")
            await subscribe_to_topics(ws, topics)
            await handle_messages(ws)
    except websockets.exceptions.WebSocketException as e:
        print(f"WebSocket error occurred: {e}")
    except Exception as e:
        print(f"An unexpected error occurred: {e}")


if __name__ == "__main__":
    asyncio.run(main())
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://fastlane-labs.gitbook.io/polygon-fastlane/searcher-guides/bundles-backruns/subscribe-events.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
