parseEventLogs 
Extracts & decodes logs matching the provided abi (and optional eventName) from a set of opaque logs.
Useful for decoding logs on Transaction Receipts.
Install 
import { parseEventLogs } from 'viem'import { parseEventLogs } from 'viem'Usage 
import { parseEventLogs } from 'viem'
import { erc20Abi } from './abi'
import { client } from './client'
const receipt = await getTransactionReceipt(client, {
  hash: '0xec23b2ba4bc59ba61554507c1b1bc91649e6586eb2dd00c728e8ed0db8bb37ea',
})
const logs = parseEventLogs({ 
  abi: erc20Abi, 
  logs: receipt.logs,
})
// [
//   { args: { ... }, eventName: 'Transfer', logIndex: 3 ... },  
//   { args: { ... }, eventName: 'Approval', logIndex: 5 ... },
//   ...
// ]import { parseEventLogs } from 'viem'
import { erc20Abi } from './abi'
import { client } from './client'
const receipt = await getTransactionReceipt(client, {
  hash: '0xec23b2ba4bc59ba61554507c1b1bc91649e6586eb2dd00c728e8ed0db8bb37ea',
})
const logs = parseEventLogs({ 
  abi: erc20Abi, 
  logs: receipt.logs,
})
// [
//   { args: { ... }, eventName: 'Transfer', logIndex: 3 ... },  
//   { args: { ... }, eventName: 'Approval', logIndex: 5 ... },
//   ...
// ]export const erc20Abi = [
  ...
  {
    inputs: [
      {
        indexed: true,
        name: 'from',
        type: 'address',
      },
      { indexed: true, name: 'to', type: 'address' },
      {
        indexed: false,
        name: 'value',
        type: 'uint256',
      },
    ],
    name: 'Transfer',
    type: 'event',
  },
  {
    inputs: [
      {
        indexed: true,
        name: 'owner',
        type: 'address',
      },
      {
        indexed: true,
        name: 'spender',
        type: 'address',
      },
      {
        indexed: false,
        name: 'value',
        type: 'uint256',
      },
    ],
    name: 'Approval',
    type: 'event',
  }
  ...
] as const;export const erc20Abi = [
  ...
  {
    inputs: [
      {
        indexed: true,
        name: 'from',
        type: 'address',
      },
      { indexed: true, name: 'to', type: 'address' },
      {
        indexed: false,
        name: 'value',
        type: 'uint256',
      },
    ],
    name: 'Transfer',
    type: 'event',
  },
  {
    inputs: [
      {
        indexed: true,
        name: 'owner',
        type: 'address',
      },
      {
        indexed: true,
        name: 'spender',
        type: 'address',
      },
      {
        indexed: false,
        name: 'value',
        type: 'uint256',
      },
    ],
    name: 'Approval',
    type: 'event',
  }
  ...
] as const;import { createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'
export const client = createPublicClient({
  chain: mainnet,
  transport: http()
})import { createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'
export const client = createPublicClient({
  chain: mainnet,
  transport: http()
})Scoping to Event Name(s) 
You can scope the logs to a specific event name by providing the eventName argument:
import { parseEventLogs } from 'viem'
import { erc20Abi } from './abi'
import { client } from './client'
const receipt = await getTransactionReceipt(client, {
  hash: '0xec23b2ba4bc59ba61554507c1b1bc91649e6586eb2dd00c728e8ed0db8bb37ea',
})
const logs = parseEventLogs({ 
  abi: erc20Abi, 
  eventName: 'Transfer', 
  logs: receipt.logs,
})
// [
//   { args: { ... }, eventName: 'Transfer', logIndex: 3, ... },  
//   { args: { ... }, eventName: 'Transfer', logIndex: 7, ... },
//   ...
// ]import { parseEventLogs } from 'viem'
import { erc20Abi } from './abi'
import { client } from './client'
const receipt = await getTransactionReceipt(client, {
  hash: '0xec23b2ba4bc59ba61554507c1b1bc91649e6586eb2dd00c728e8ed0db8bb37ea',
})
const logs = parseEventLogs({ 
  abi: erc20Abi, 
  eventName: 'Transfer', 
  logs: receipt.logs,
})
// [
//   { args: { ... }, eventName: 'Transfer', logIndex: 3, ... },  
//   { args: { ... }, eventName: 'Transfer', logIndex: 7, ... },
//   ...
// ]export const erc20Abi = [
  ...
  {
    inputs: [
      {
        indexed: true,
        name: 'from',
        type: 'address',
      },
      { indexed: true, name: 'to', type: 'address' },
      {
        indexed: false,
        name: 'value',
        type: 'uint256',
      },
    ],
    name: 'Transfer',
    type: 'event',
  },
  {
    inputs: [
      {
        indexed: true,
        name: 'owner',
        type: 'address',
      },
      {
        indexed: true,
        name: 'spender',
        type: 'address',
      },
      {
        indexed: false,
        name: 'value',
        type: 'uint256',
      },
    ],
    name: 'Approval',
    type: 'event',
  }
  ...
] as const;export const erc20Abi = [
  ...
  {
    inputs: [
      {
        indexed: true,
        name: 'from',
        type: 'address',
      },
      { indexed: true, name: 'to', type: 'address' },
      {
        indexed: false,
        name: 'value',
        type: 'uint256',
      },
    ],
    name: 'Transfer',
    type: 'event',
  },
  {
    inputs: [
      {
        indexed: true,
        name: 'owner',
        type: 'address',
      },
      {
        indexed: true,
        name: 'spender',
        type: 'address',
      },
      {
        indexed: false,
        name: 'value',
        type: 'uint256',
      },
    ],
    name: 'Approval',
    type: 'event',
  }
  ...
] as const;import { createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'
export const client = createPublicClient({
  chain: mainnet,
  transport: http()
})import { createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'
export const client = createPublicClient({
  chain: mainnet,
  transport: http()
})You can also pass an array to scope multiple event names:
import { parseEventLogs } from 'viem'
import { erc20Abi } from './abi'
import { client } from './client'
const receipt = await getTransactionReceipt(client, {
  hash: '0xec23b2ba4bc59ba61554507c1b1bc91649e6586eb2dd00c728e8ed0db8bb37ea',
})
const logs = parseEventLogs({ 
  abi: erc20Abi, 
  eventName: ['Transfer', 'Approval'], 
  logs: receipt.logs,
})
// [
//   { args: { ... }, eventName: 'Transfer', logIndex: 3, ... },  
//   { args: { ... }, eventName: 'Approval', logIndex: 5, ... },  
//   { args: { ... }, eventName: 'Transfer', logIndex: 7, ... },
//   ...
// ]import { parseEventLogs } from 'viem'
import { erc20Abi } from './abi'
import { client } from './client'
const receipt = await getTransactionReceipt(client, {
  hash: '0xec23b2ba4bc59ba61554507c1b1bc91649e6586eb2dd00c728e8ed0db8bb37ea',
})
const logs = parseEventLogs({ 
  abi: erc20Abi, 
  eventName: ['Transfer', 'Approval'], 
  logs: receipt.logs,
})
// [
//   { args: { ... }, eventName: 'Transfer', logIndex: 3, ... },  
//   { args: { ... }, eventName: 'Approval', logIndex: 5, ... },  
//   { args: { ... }, eventName: 'Transfer', logIndex: 7, ... },
//   ...
// ]export const erc20Abi = [
  ...
  {
    inputs: [
      {
        indexed: true,
        name: 'from',
        type: 'address',
      },
      { indexed: true, name: 'to', type: 'address' },
      {
        indexed: false,
        name: 'value',
        type: 'uint256',
      },
    ],
    name: 'Transfer',
    type: 'event',
  },
  {
    inputs: [
      {
        indexed: true,
        name: 'owner',
        type: 'address',
      },
      {
        indexed: true,
        name: 'spender',
        type: 'address',
      },
      {
        indexed: false,
        name: 'value',
        type: 'uint256',
      },
    ],
    name: 'Approval',
    type: 'event',
  }
  ...
] as const;export const erc20Abi = [
  ...
  {
    inputs: [
      {
        indexed: true,
        name: 'from',
        type: 'address',
      },
      { indexed: true, name: 'to', type: 'address' },
      {
        indexed: false,
        name: 'value',
        type: 'uint256',
      },
    ],
    name: 'Transfer',
    type: 'event',
  },
  {
    inputs: [
      {
        indexed: true,
        name: 'owner',
        type: 'address',
      },
      {
        indexed: true,
        name: 'spender',
        type: 'address',
      },
      {
        indexed: false,
        name: 'value',
        type: 'uint256',
      },
    ],
    name: 'Approval',
    type: 'event',
  }
  ...
] as const;import { createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'
export const client = createPublicClient({
  chain: mainnet,
  transport: http()
})import { createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'
export const client = createPublicClient({
  chain: mainnet,
  transport: http()
})Partial Decode 
By default, if the topics and data does not conform to the ABI (a mismatch between the number of indexed/non-indexed arguments), parseEventLogs will not return return the decoded log.
For example, the following will not return the nonconforming log as there is a mismatch in non-indexed arguments & data length.
parseEventLogs({
  abi: parseAbi(['event Transfer(address indexed, address, uint256)']),
  logs: [{
    // `data` should be 64 bytes, but is only 32 bytes. 
    data: '0x0000000000000000000000000000000000000000000000000000000000000001', 
    topics: [
      '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
      '0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266',
    ]
    // ...
  }]
})
// []parseEventLogs({
  abi: parseAbi(['event Transfer(address indexed, address, uint256)']),
  logs: [{
    // `data` should be 64 bytes, but is only 32 bytes. 
    data: '0x0000000000000000000000000000000000000000000000000000000000000001', 
    topics: [
      '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
      '0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266',
    ]
    // ...
  }]
})
// []It is possible for parseEventLogs to try and partially decode the Log, this can be done by setting the strict argument to false:
parseEventLogs({
  abi: parseAbi(['event Transfer(address indexed, address, uint256)']),
  logs: [{
    data: '0x0000000000000000000000000000000000000000000000000000000000000001',
    topics: [
      '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
      '0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266',
    ]
    // ...
  }]
  strict: false 
})
/**
 * [
 *  {
 *    eventName: 'Transfer',
 *    args: ['0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266'],
 *    blockNumber: 42069420n,
 *    logIndex: 69,
 *    ...
 *  }
 * ]
 */parseEventLogs({
  abi: parseAbi(['event Transfer(address indexed, address, uint256)']),
  logs: [{
    data: '0x0000000000000000000000000000000000000000000000000000000000000001',
    topics: [
      '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
      '0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266',
    ]
    // ...
  }]
  strict: false 
})
/**
 * [
 *  {
 *    eventName: 'Transfer',
 *    args: ['0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266'],
 *    blockNumber: 42069420n,
 *    logIndex: 69,
 *    ...
 *  }
 * ]
 */Return Value 
Log[]
Decoded logs.
Parameters 
abi 
- Type: Abi
The contract's ABI.
const topics = parseEventLogs({
  abi: wagmiAbi, 
  logs: [{
    blockNumber: 69420n,
    data: '0x0000000000000000000000000000000000000000000000000000000000000001',
    logIndex: 1,
    topics: [
      '0x406dade31f7ae4b5dbc276258c28dde5ae6d5c2773c5745802c493a2360e55e0', 
      '0x00000000000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266', 
      '0x0000000000000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8'
    ]
    // ...
  }]
})const topics = parseEventLogs({
  abi: wagmiAbi, 
  logs: [{
    blockNumber: 69420n,
    data: '0x0000000000000000000000000000000000000000000000000000000000000001',
    logIndex: 1,
    topics: [
      '0x406dade31f7ae4b5dbc276258c28dde5ae6d5c2773c5745802c493a2360e55e0', 
      '0x00000000000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266', 
      '0x0000000000000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8'
    ]
    // ...
  }]
})logs 
- Type: Log[]
An array of logs to parse.
const topics = parseEventLogs({
  abi: wagmiAbi,
  logs: [{ 
    blockNumber: 69420n, 
    data: '0x0000000000000000000000000000000000000000000000000000000000000001', 
    logIndex: 1, 
    topics: [ 
      '0x406dade31f7ae4b5dbc276258c28dde5ae6d5c2773c5745802c493a2360e55e0',  
      '0x00000000000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266', 
      '0x0000000000000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8' 
    ] 
    // ... 
  }] 
})const topics = parseEventLogs({
  abi: wagmiAbi,
  logs: [{ 
    blockNumber: 69420n, 
    data: '0x0000000000000000000000000000000000000000000000000000000000000001', 
    logIndex: 1, 
    topics: [ 
      '0x406dade31f7ae4b5dbc276258c28dde5ae6d5c2773c5745802c493a2360e55e0',  
      '0x00000000000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266', 
      '0x0000000000000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8' 
    ] 
    // ... 
  }] 
})eventName (optional) 
- Type: string
An event name from the ABI.
const topics = parseEventLogs({
  abi: wagmiAbi,
  eventName: 'Transfer', 
  logs: [{
    blockNumber: 69420n,
    data: '0x0000000000000000000000000000000000000000000000000000000000000001',
    logIndex: 1,
    topics: [
      '0x406dade31f7ae4b5dbc276258c28dde5ae6d5c2773c5745802c493a2360e55e0', 
      '0x00000000000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266', 
      '0x0000000000000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8'
    ]
    // ...
  }]
})const topics = parseEventLogs({
  abi: wagmiAbi,
  eventName: 'Transfer', 
  logs: [{
    blockNumber: 69420n,
    data: '0x0000000000000000000000000000000000000000000000000000000000000001',
    logIndex: 1,
    topics: [
      '0x406dade31f7ae4b5dbc276258c28dde5ae6d5c2773c5745802c493a2360e55e0', 
      '0x00000000000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266', 
      '0x0000000000000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8'
    ]
    // ...
  }]
})strict (optional) 
- Type: boolean
- Default: true
If true, parseEventLogs will not return nonconforming logs. If false, parseEventLogs will try and partially decode nonconforming logs.
const topics = parseEventLogs({
  abi: wagmiAbi,
  eventName: 'Transfer',
  logs: [{
    blockNumber: 69420n,
    data: '0x0000000000000000000000000000000000000000000000000000000000000001',
    logIndex: 1,
    topics: [
      '0x406dade31f7ae4b5dbc276258c28dde5ae6d5c2773c5745802c493a2360e55e0', 
      '0x00000000000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266', 
      '0x0000000000000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8'
    ]
    // ...
  }],
  strict: false 
})const topics = parseEventLogs({
  abi: wagmiAbi,
  eventName: 'Transfer',
  logs: [{
    blockNumber: 69420n,
    data: '0x0000000000000000000000000000000000000000000000000000000000000001',
    logIndex: 1,
    topics: [
      '0x406dade31f7ae4b5dbc276258c28dde5ae6d5c2773c5745802c493a2360e55e0', 
      '0x00000000000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266', 
      '0x0000000000000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8'
    ]
    // ...
  }],
  strict: false 
})
