> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sqd.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Event logs

> Subscribe to EVM event log data with addLog() — filter by contract address and topics.

<h4 id="add-log">
  `addLog(options)`
</h4>

Get event logs emitted by some *or all* contracts in the network. `options` has the following structure:

```typescript theme={"system"}
{
  // item filters
  where?: {
    address?: string[]
    topic0?: string[]
    topic1?: string[]
    topic2?: string[]
    topic3?: string[]
  }

  // related data retrieval
  include?: {
    transaction?: boolean
    transactionLogs?: boolean
    transactionTraces?: boolean
    transactionStateDiffs?: boolean
  }

  // block range override
  range?: {from: number, to?: number}
}
```

Item filters (`where`):

* `address`: the set of addresses of contracts emitting the logs. Omit to subscribe to events from all contracts in the network.
* `topicN`: the set of accepted values of topicN.

<Warning>
  Filter values are matched as exact strings by the Portal — always pass addresses and topics as lowercase hex strings. `@subsquid/evm-stream` does not normalize the case for you.
</Warning>

Related data retrieval (`include`):

* `transaction = true`: retrieve the parent transaction of each matching log and add it to the `transactions` iterable within the [block data](./context-interfaces).
* `transactionLogs = true`: retrieve all "sibling" logs, that is, all logs emitted by transactions that emitted at least one matching log. The logs are added to the regular `logs` iterable.
* `transactionTraces = true`: retrieve the traces of all transactions that emitted at least one matching log. The traces are added to the regular `traces` iterable.
* `transactionStateDiffs = true`: retrieve state diffs of all transactions that emitted at least one matching log. They are added to the regular `stateDiffs` iterable.

All related items arrive in the flat per-block iterables. To navigate between them conveniently (e.g. `log.transaction`, `transaction.logs`), call `augmentBlock()` from `@subsquid/evm-objects` on the block data — see [Block data](./context-interfaces#augmented-blocks).

`range` overrides the global [`setBlockRange()`](../evm-stream) for this particular request.

Note that logs can also be requested by the [`addTransaction()`](./transactions) and [`addTrace()`](./traces) methods as related data.

Selection of the exact fields to be retrieved for each log and its optional parent transaction is done with the `setFields()` method documented on the [Field selection](./field-selection) page. There are no default fields — request everything your handler reads. Some examples are available below.

## Examples

1. Fetch `NewGravatar(uint256,address,string,string)` and `UpdateGravatar(uint256,address,string,string)` event logs emitted by `0x2E645469f354BB4F5c8a05B3b30A929361cf77eC`. For each log, fetch the topic set and log data. Fetch parent transactions with their inputs.

```ts theme={"system"}
import {DataSourceBuilder} from '@subsquid/evm-stream'

const dataSource = new DataSourceBuilder()
  .setPortal('https://portal.sqd.dev/datasets/ethereum-mainnet')
  .addLog({
    where: {
      address: ['0x2e645469f354bb4f5c8a05b3b30a929361cf77ec'],
      topic0: [
        // topic: 'NewGravatar(uint256,address,string,string)'
        '0x9ab3aefb2ba6dc12910ac1bce4692cf5c3c0d06cff16327c64a3ef78228b130b',
        // topic: 'UpdatedGravatar(uint256,address,string,string)'
        '0x76571b7a897a1509c641587568218a290018fbdc8b9a724f17b77ff0eec22c0c',
      ]
    },
    include: {
      transaction: true
    }
  })
  .setFields({
    log: {
      topics: true,
      data: true
    },
    transaction: {
      input: true
    }
  })
  .build()
```

<Tip>
  Typescript ABI modules generated by [`squid-evm-typegen`](../evm-typegen/generating-utility-modules) provide event signatures/topic0 values as constants, e.g.

  ```ts theme={"system"}
    import * as gravatarAbi from './abi/gravatar'
    // ...
        topic0: [
          gravatarAbi.events.NewGravatar.topic,
          gravatarAbi.events.UpdatedGravatar.topic,
        ],
    // ...
  ```
</Tip>

2. Fetch every `Transfer(address,address,uint256)` event on Ethereum mainnet where *topic2* is set to the destination address (a common but [non-standard](https://eips.ethereum.org/EIPS/eip-20) practice) and the destination is `vitalik.eth` a.k.a. `0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045`. For each log, fetch the transaction hash.

```ts theme={"system"}
const dataSource = new DataSourceBuilder()
  .setPortal('https://portal.sqd.dev/datasets/ethereum-mainnet')
  .addLog({
    where: {
      topic0: [
        // topic0: 'Transfer(address,address,uint256)'
        '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'
      ],
      topic2: [
        // vitalik.eth
        '0x000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045'
      ]
    }
  })
  .setFields({
    log: {
      transactionHash: true
    }
  })
  .build()
```

<Tip>
  As you may observe, the address in the `topic2` is a bit longer than usual (`0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045`, 42 chars).
  This is caused by the fact that Squid SDK expects `Bytes32[]`; therefore, the length has to be 66 chars long.
  The possible quick fix is to pad the original address with zeros and prepend `0x`.

  ```ts theme={"system"}
    const address = '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'
    const topic = '0x' + address.replace('x', '0').padStart(64, '0').toLowerCase()
  ```
</Tip>
