Skip to main content
<Tabs queryString="typegen">
<Tab value="evm" label="squid-evm-typegen">
Decoding events:
import * as depositsAbi from './abi/deposits'

processor.run(new TypeormDatabase(), async (ctx) => {
  for (let c of ctx.blocks) {
    for (let log of c.logs) {
      if (log.address === CONTRACT_ADDRESS &&
          log.topics[0] == depositsAbi.events.Deposit.topic) {

        // type-safe decoding of the Deposit event data
        const amt = depositsAbi.events.Deposit.decode(log).wad
      }
    }
  }
})
Similar to events, transaction access is provided by the functions object for each contract method defined in the ABI.
</Tab>
<Tab value="substrate" label="squid-substrate-typegen">
To decode events and calls, first determine the appropriate runtime version with .is(), then decode them with .decode():
import \{events, calls\} from './types'

processor.run(new TypeormDatabase(), async ctx => {
  for (let block of ctx.blocks) {
     for (let event of block.events) {
      if (event.name == events.balances.transfer.name) {
let rec: "\{from: Bytes, to: Bytes, amount: bigint\}"
        if (events.balances.transfer.v1020.is(event)) {
          let [from, to, amount, fee] =
            events.balances.transfer.v1020.decode(event)
          rec = \{from, to, amount\}
        }
        // ... decode all runtime versions similarly
        // with events.balances.transfer.$\{ver\}.is/.decode
      }
    }
    for (let call of block.calls) {
      if (call.name == calls.balances.forceTransfer.name) {
let rec: "\{source: Bytes, dest: Bytes, value: bigint\} | undefined"
        if (calls.balances.forceTransfer.v1020.is(call)) {
          let res =
            calls.balances.forceTransfer.v1020.decode(call)
          assert(res.source.__kind === 'AccountId')
          assert(res.dest.__kind === 'AccountId')
          rec = {
            source: res.source.value,
            dest: res.dest.value,
            value: res.value
          }
        }
        // ... decode all runtime versions similarly
        // with calls.balances.forceTransfer.$\{ver\}.is/.decode
    }
  }
})
</Tab>
<Tab value="ink" label="squid-ink-typegen">
Here is an example of a utility module generated by the ink! typegen:
src/abi/erc20.ts
const _abi = new Abi(metadata)

export function decodeEvent(hex: string): Event {
  return _abi.decodeEvent(hex)
}

export function decodeMessage(hex: string): Message {
  return _abi.decodeMessage(hex)
}

export function decodeConstructor(hex: string): Constructor {
  return _abi.decodeConstructor(hex)
}
The usage in a batch handler is straightforward:
processor.run(new TypeormDatabase(), async ctx => {
  for (let block of ctx.blocks) {
    for (let event of block.events) {
      if (event.name==='Contracts.ContractEmitted' &&
          event.args.contract===CONTRACT_ADDRESS) {

        let event = erc20.decodeEvent(event.args.data)
        if (event.__kind==='Transfer') {
          // event is of type `Event_Transfer`
        }
      }
    }
  }
})
</Tab>
</Tabs>