# Detail of blockchain monitors

### Overview

This document provides a detailed explanation of how a blockchain listener based on ethers.js works, covering key concepts such as event triggers, data processing, and performance optimization.

### How the Listener Works

#### 1. Event Trigger Mechanism

```tsx
provider.on("block", sharedNativeListener);
```

This line of code registers a **"block" event listener**. The workflow is as follows:

1. **A new block is generated on the blockchain** → Contains multiple transactions.
2. **WebSocket push notification** → ethers.js receives the new block event.
3. **Automatic invocation of the listener** → `sharedNativeListener(blockNumber)` is called.

#### 2. Detailed Analysis of the Listener Function

```tsx
sharedNativeListener = async (blockNumber: number) => {
    // Step 1: Fetch the full block data (including all transactions)
    const block = await provider.getBlockWithTransactions(blockNumber);

    // Step 2: Iterate through each transaction in the block
    for (const tx of block.transactions) {
        // Step 3: Check if the transaction has a recipient address
        if (tx.to) {
            const toAddr = tx.to.toLowerCase();

            // Step 4: Check if the recipient address is in our watch list
            if (subscribedWallets.has(toAddr)) {
                // Step 5: If it matches, log the transfer information
                console.log(`💰 Wallet ${toAddr} received BNB...`);
            }
        }
    }
};
```

### Data Flow Explanation

#### Example of Block Structure

```jsx
// Data structure of a block
{
  number: 41234567,           // Block number
  hash: "0xabc123...",        // Block hash
  timestamp: 1703123456,      // Timestamp
  transactions: [             // 📦 All included transactions
    {
      hash: "0x111...",
      from: "0xAAA...",
      to: "0xBBB...",         // 🎯 The field we need to check
      value: "1000000000000000000", // 1 BNB (in wei)
      // ... other fields
    },
    {
      hash: "0x222...",
      from: "0xCCC...",
      to: "0xDDD...",         // 🎯 Continue checking
      value: "500000000000000000",  // 0.5 BNB
    },
    // ... more transactions
  ]
}
```

#### Listener's Processing Flow

```tsx
// Assuming we are listening to these addresses
subscribedWallets = {
  "0xbbb..." => {},  // Address 1
  "0xddd..." => {},  // Address 2
}

// When a new block arrives
sharedNativeListener(41234567) {
  // 1. Get the block
  const block = await provider.getBlockWithTransactions(41234567);

  // 2. Iterate through transactions
  for (const tx of block.transactions) {
    // Transaction 1: from=0xAAA, to=0xBBB, value=1BNB
    if (tx.to === "0xBBB") {  // After converting to lowercase: "0xbbb"
      if (subscribedWallets.has("0xbbb")) {  // ✅ Match!
        console.log("💰 Wallet 0xbbb received BNB: 1.0 from 0xAAA");
      }
    }

    // Transaction 2: from=0xCCC, to=0xDDD, value=0.5BNB
    if (tx.to === "0xDDD") {  // After converting to lowercase: "0xddd"
      if (subscribedWallets.has("0xddd")) {  // ✅ Match!
        console.log("💰 Wallet 0xddd received BNB: 0.5 from 0xCCC");
      }
    }

    // Other transactions that do not match are skipped
  }
}
```

### Hierarchical Structure of the Listener Mechanism

#### Layer 1: Blockchain Network

```
Blockchain nodes generate new blocks → Broadcast to all connected clients
```

#### Layer 2: WebSocket Connection

```
WebSocket receives block notification → {"method": "eth_subscription", "params": {...}}
```

#### Layer 3: ethers.js Provider

```
ethers.js parses WebSocket message → Triggers "block" event
```

#### Layer 4: Your Listener

```
sharedNativeListener is called → Processes block data → Checks target address
```

### Why Is This Design Efficient?

#### 1. Batch Processing

```tsx
// Instead of triggering for every transaction, we trigger once for each block
// A block may contain hundreds of transactions, but the listener is triggered only once
```

#### 2. Precise Filtering

```tsx
// Only process transactions sent to the addresses we care about
if (subscribedWallets.has(toAddr)) {  // O(1) lookup
    // Only handle matching transactions
}
```

#### 3. Real-Time

```tsx
// Every time a new block is generated (approximately every 3 seconds), it checks immediately
// No polling, it's push-based
```

### Listener Lifecycle

```tsx
// 1. Register the listener
provider.on("block", sharedNativeListener);

// 2. Continuous operation
// Each new block → Automatically called → Checks transactions → Logs matching transfers

// 3. Remove the listener
provider.off("block", sharedNativeListener);
```

### Data Flow Diagram

```
Blockchain Network → WebSocket → ethers.js → Your Listener
     ↓           ↓           ↓           ↓
  New Block    Receive block data   Extract block number  blockNumber
```

### Core Code Examples

#### Event Registration

```tsx
// Register the listener
provider.on("block", sharedNativeListener);
```

#### Fetching Block Data

```tsx
// Fetch the block with full transactions
const block = await provider.getBlockWithTransactions(blockNumber);
```

#### Address Match Check

```tsx
// Efficient address matching (O(1) time complexity)
if (subscribedWallets.has(toAddr)) {
    // Process the matching transaction
}
```

### Performance Optimization Tips

1. **Use a Map structure**: `subscribedWallets` is implemented using Map for O(1) lookup.
2. **Batch Processing**: Process once per block, not per transaction.
3. **Early Exit**: Skip unmatched transactions immediately.
4. **Shared Listener**: Multiple addresses share the same listener.

### Error Handling Recommendations

```tsx
// Add error handling
sharedNativeListener = async (blockNumber: number) => {
    try {
        const block = await provider.getBlockWithTransactions(blockNumber);
        // ... processing logic
    } catch (error) {
        console.error(`Error processing block ${blockNumber}:`, error);
        // Retry logic can be added here
    }
};
```

### Conclusion

The core idea of this listener is:

1. **Listen to blocks** rather than individual transactions.
2. **Batch check** all transactions within a block.
3. **Filter matches** by only processing transactions sent to target addresses.
4. **Respond in real-time** when new blocks are generated.

This mechanism ensures both real-time responsiveness and avoids excessive network requests, making it a classic model for blockchain listening.

### Extended Applications

* **Exchange Deposit Listening**: Monitor user deposit addresses.
* **DeFi Protocol Monitoring**: Track smart contract events.
* **Wallet Applications**: Real-time balance changes.
* **Analysis Tools**: Track on-chain data activity.
