# chain_subscribeFinalizedHeads - Neuroweb RPC Method

Subscribe to receive notifications when blocks are finalized on Neuroweb. Finalized blocks are guaranteed to never be reverted by the GRANDPA finality gadget, making this the safest way to track confirmed state changes.

> **Why Neuroweb?** Build on the decentralized AI blockchain powering 125M+ Knowledge Assets with MIT-awarded technology with OriginTrail DKG V8 with 500-1000x scalability, 40% of US imports secured, EVM compatibility, and Best Decentralized AI Project (MIT).

## When to Use This Method

`chain_subscribeFinalizedHeads` is critical for AI developers, knowledge graph builders, and teams requiring verifiable AI solutions:

- **Exchange Deposits** - Only credit funds after finalization for decentralized knowledge graphs (DKG), verifiable AI, supply chain audits, and knowledge mining
- **Bridge Operations** - Wait for finality before executing cross-chain transfers
- **Critical State Changes** - Ensure irreversibility before acting on important transactions
- **Compliance Workflows** - Record-keeping that requires provably irreversible state

## Best Practices

- Requires a WebSocket connection at `wss://api-neuroweb.n.dwellir.com/YOUR_API_KEY`
- Finalized headers are irreversible and safe for bridge relay operations
- Notification frequency is lower than `chain_subscribeNewHeads`
- Unsubscribe when done to free connection resources

## Request Parameters

This method accepts no parameters.

## Request Example

```json
{
  "jsonrpc": "2.0",
  "method": "chain_subscribeFinalizedHeads",
  "params": [],
  "id": 1
}
```

## Response Fields

- `parentHash` (`Hash, required`): Parent block hash
- `number` (`BlockNumber, required`): Block number (hex-encoded)
- `stateRoot` (`Hash, required`): State trie root hash after this block
- `extrinsicsRoot` (`Hash, required`): Extrinsics trie root hash
- `digest` (`Digest, required`): Block digest with consensus engine logs

## Successful Response

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "subscription_id_here"
}
```

## Code Examples

cURL
JavaScript
Python
Rust

```bash
# WebSocket subscription (requires wscat or similar tool)
wscat -c wss://api-neuroweb.n.dwellir.com/YOUR_API_KEY -x '{
  "jsonrpc": "2.0",
  "method": "chain_subscribeFinalizedHeads",
  "params": [],
  "id": 1
}'
```

```javascript
import { ApiPromise, WsProvider } from '@polkadot/api';

const provider = new WsProvider('wss://api-neuroweb.n.dwellir.com/YOUR_API_KEY');
const api = await ApiPromise.create({ provider });

// Subscribe to finalized heads
const unsubscribe = await api.rpc.chain.subscribeFinalizedHeads((header) => {
  console.log(`Finalized block #${header.number}`);
  console.log(`  Hash: ${header.hash.toHex()}`);
  console.log(`  State root: ${header.stateRoot.toHex()}`);
  console.log(`  Parent: ${header.parentHash.toHex()}`);
});

// Unsubscribe after 60 seconds
setTimeout(() => {
  unsubscribe();
  api.disconnect();
}, 60000);
```

```python
import asyncio
import websockets
import json

async def subscribe_finalized():
    uri = 'wss://api-neuroweb.n.dwellir.com/YOUR_API_KEY'

    async with websockets.connect(uri) as ws:
        # Subscribe
        await ws.send(json.dumps({
            'jsonrpc': '2.0',
            'method': 'chain_subscribeFinalizedHeads',
            'params': [],
            'id': 1
        }))

        # Get subscription ID
        response = json.loads(await ws.recv())
        sub_id = response['result']
        print(f'Subscribed with ID: {sub_id}')

        # Listen for finalized headers
        while True:
            message = json.loads(await ws.recv())
            if 'params' in message:
                header = message['params']['result']
                block_num = int(header['number'], 16)
                print(f'Finalized: #{block_num}')
                print(f"  State root: {header['stateRoot']}")

asyncio.run(subscribe_finalized())
```

```rust
use subxt::{OnlineClient, PolkadotConfig};
use futures::StreamExt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let api = OnlineClient::<PolkadotConfig>::from_url(
        "wss://api-neuroweb.n.dwellir.com/YOUR_API_KEY"
    ).await?;

    let mut finalized_heads = api.rpc()
        .subscribe_finalized_block_headers()
        .await?;

    while let Some(Ok(header)) = finalized_heads.next().await {
        println!(
            "Finalized block #{}: {:?}",
            header.number,
            header.hash()
        );
    }

    Ok(())
}
```

## Common Use Cases

### 1. Exchange Deposit Watcher

Watch for finalized transfers and credit user accounts on Neuroweb:

```javascript
async function watchDeposits(api, depositAddresses) {
  const unsub = await api.rpc.chain.subscribeFinalizedHeads(async (header) => {
    const blockHash = header.hash;
    const block = await api.rpc.chain.getBlock(blockHash);
    const apiAt = await api.at(blockHash);
    const events = await apiAt.query.system.events();

    // Check for transfer events in the finalized block
    events.forEach((record) => {
      const { event } = record;
      if (event.section === 'balances' && event.method === 'Transfer') {
        const [from, to, amount] = event.data;
        if (depositAddresses.includes(to.toString())) {
          console.log(`Finalized deposit: ${amount} from ${from} to ${to}`);
          // Credit user account - this block will never be reverted
        }
      }
    });
  });

  return unsub;
}
```

### 2. Finality Lag Tracker

Monitor the gap between best and finalized blocks:

```javascript
async function trackFinalityLag(api) {
  let bestNumber = 0;

  api.rpc.chain.subscribeNewHeads((header) => {
    bestNumber = header.number.toNumber();
  });

  api.rpc.chain.subscribeFinalizedHeads((header) => {
    const finalizedNumber = header.number.toNumber();
    const lag = bestNumber - finalizedNumber;

    console.log(`Best: #${bestNumber} | Finalized: #${finalizedNumber} | Lag: ${lag} blocks`);

    if (lag > 10) {
      console.warn('WARNING: High finality lag detected - GRANDPA may be stalling');
    }
  });
}
```

### 3. Cross-Chain Bridge Relay

Relay finalized headers to a bridge contract:

```javascript
async function relayFinalizedHeaders(api, bridgeContract) {
  const unsub = await api.rpc.chain.subscribeFinalizedHeads(async (header) => {
    const headerData = {
      number: header.number.toNumber(),
      stateRoot: header.stateRoot.toHex(),
      extrinsicsRoot: header.extrinsicsRoot.toHex(),
      parentHash: header.parentHash.toHex()
    };

    console.log(`Relaying finalized header #${headerData.number}`);
    await bridgeContract.submitHeader(headerData);
  });

  return unsub;
}
```

## Finality Lag

Finalized blocks typically lag behind the best block by a few blocks due to GRANDPA consensus requirements. This lag is normal and ensures Byzantine fault tolerance. The typical lag is 2-3 blocks under healthy network conditions.

## Related Methods

- [`chain_subscribeNewHeads`](https://www.dwellir.com/docs/neuroweb/chain_subscribeNewHeads) - Subscribe to all new blocks (not just finalized)
- [`chain_getFinalizedHead`](https://www.dwellir.com/docs/neuroweb/chain_getFinalizedHead) - Get current finalized block hash (one-shot)
- [`grandpa_roundState`](https://www.dwellir.com/docs/neuroweb/grandpa_roundState) - Monitor GRANDPA consensus progress
- [`chain_getBlock`](https://www.dwellir.com/docs/neuroweb/chain_getBlock) - Get full block data for a finalized hash
