> ## 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.

# The Frontier package

> Decode Frontier EVM events and transactions on Substrate with @subsquid/frontier.

<Warning>
  V2 gateway requests require an API key. Set `SQD_API_KEY` in `.env` before running gateway-based examples, or pass `apiKey: process.env.SQD_API_KEY` in `GatewaySettings`.
</Warning>

# `@subsquid/frontier`

The way the Frontier EVM pallet exposes EVM logs and transactions may change across runtime upgrades. [`@subsquid/frontier`](https://github.com/subsquid/squid-sdk/tree/master/substrate/frontier) provides helpers that account for those changes.

#### `getEvmLog(event: Event): EvmLog`

Extract the EVM log data from `EVM.Log` event.

#### `getTransaction(call: Call): LegacyTransaction | EIP2930Transaction | EIP1559Transaction`

Extract the transaction data from `Ethereum.transact` call with additional fields depending on the EVM transaction type.

<h4 id="get-transaction-result">
  `getTransactionResult(ethereumExecuted: Event): {from: string, to: string, transactionHash: string, status: 'Succeed' | 'Error' | 'Revert' | 'Fatal', statusReason: string}`
</h4>

Extract transaction result from an `Ethereum.Executed` event.

## Transaction types

`getTransaction()` returns the `Transaction` discriminated union. Check its `type` field with the exported `TransactionType` enum to narrow the result:

```typescript theme={"system"}
import {getTransaction, TransactionType} from '@subsquid/frontier'

const transaction = getTransaction(call)

switch (transaction.type) {
  case TransactionType.Legacy:
    console.log(transaction.gasPrice)
    break
  case TransactionType.EIP2930:
    console.log(transaction.gasPrice, transaction.accessList)
    break
  case TransactionType.EIP1559:
    console.log(transaction.maxFeePerGas, transaction.maxPriorityFeePerGas)
    break
}
```

The package exports these transaction interfaces:

| Type                 | Additional fields                                               |
| -------------------- | --------------------------------------------------------------- |
| `LegacyTransaction`  | `gasPrice`                                                      |
| `EIP2930Transaction` | `gasPrice`, `accessList`, `chainId`                             |
| `EIP1559Transaction` | `maxPriorityFeePerGas`, `maxFeePerGas`, `accessList`, `chainId` |

All three include `hash`, `from`, optional `to`, `nonce`, `gasLimit`, `input`, `value`, signature fields `r`, `s`, and `v`, and the `type` discriminator. The package also exports the `Transaction` union and `AccessListItem` interface.

## Transaction normalizers

Most handlers should call `getTransaction()` because it detects the runtime encoding and transaction variant. If you already have a decoded raw Frontier transaction, the package exports the underlying normalizers:

```typescript theme={"system"}
normalizeLegacyTransaction(raw): LegacyTransaction
normalizeEIP2930Transaction(raw): EIP2930Transaction
normalizeEIP1559Transaction(raw): EIP1559Transaction
```

Each normalizer reconstructs canonical fields such as the transaction hash and sender address from the raw payload and signature.

See also the [Frontier EVM guide](../guides/substrate/frontier-evm).

## Complete processor example

```typescript theme={"system"}
import {getEvmLog, getTransaction} from '@subsquid/frontier'
import {SubstrateBatchProcessor} from '@subsquid/substrate-processor'
import {TypeormDatabase} from '@subsquid/typeorm-store'

const processor = new SubstrateBatchProcessor()
  .setGateway({
    url: 'https://v2.archive.subsquid.io/network/astar-substrate',
    apiKey: process.env.SQD_API_KEY,
  })
  .setRpcEndpoint('https://astar-rpc.dwellir.com')
  .addEthereumTransaction({})
  .addEvmLog({})

processor.run(new TypeormDatabase(), async ctx => {
  for (const block of ctx.blocks) {
    for (const event of block.events) {
      if (event.name === 'EVM.Log') {
        const {address, data, topics} = getEvmLog(event)
        ctx.log.info({address, data, topics}, 'decoded EVM log')
      }
    }
    for (const call of block.calls) {
      if (call.name === 'Ethereum.transact') {
        const transaction = getTransaction(call)
        ctx.log.info({hash: transaction.hash}, 'decoded EVM transaction')
      }
    }
  }
})
```
