/ Docs
/

Implementing handlers

After defining the index in the configuration file and initializing the project, you can start implementing handlers. DipDup generates callback stubs for all handlers specified in the configuration file. You can find them in the handlers directory.

Callback signature

This partial callback definition matches two contract calls in the same transaction:

callback: on_transaction
pattern:
- type: transaction
  destination: contract
  entrypoint: foo
- type: transaction
  destination: contract
  entrypoint: bar

The callback stub will look like the following:

async def on_transaction(
    ctx: HandlerContext,
    foo: TzktTransaction[FooParameter, ContractStorage],
    bar: TzktTransaction[BarParameter, ContractStorage],
) -> None:
    ...

Don't rename module and function names, as DipDup uses them to find the callback.

The first argument is always HandlerContext. It provides useful helpers and contains an internal state (see Context Reference). The rest of the arguments are generated according to the handler pattern. Payloads of some arguments are typed, and DipDup generates corresponding models for them in the types directory.

Processing data

Define the callback body to process the data. The most common case is to perform some calculations and store the result in the database. DipDup provides a convenient ORM to work with the database.

demo_raw/handlers/on_operation.py
from demo_raw import models
from dipdup.context import HandlerContext
from dipdup.models.tezos_tzkt import TzktOperationData


async def on_operation(
    ctx: HandlerContext,
    operation: TzktOperationData,
) -> None:
    await models.Operation.create(
        hash=operation.hash,
        level=operation.level,
        type=operation.type,
    )

Handling name collisions

Indexing operations of multiple contracts with the same entrypoints can lead to name collisions during code generation. In this case DipDup raises a ConfigurationError and suggests to set alias for each conflicting handler. Currently, it applies to tezos.tzkt.operation indexes only. Consider the following index definition, some kind of "chain minting" contract:

callback: on_mint
pattern:
- type: transaction
  entrypoint: mint
  alias: foo_mint
- type: transaction
  entrypoint: mint
  alias: bar_mint

The following code will be generated for on_mint callback (shortened):

on_transaction.py
from example.types.foo.parameter.mint import MintParameter as FooMintParameter
from example.types.bar.parameter.mint import MintParameter as BarMintParameter


async def on_transaction(
    ctx: HandlerContext,
    foo_mint: TzktTransaction[FooMintParameter, FooStorage],
    bar_mint: TzktTransaction[BarMintParameter, BarStorage],
) -> None:
    ...

You can also change argument names (but not the order) manually if you want to.

Help and tips -> Join our Discord
Ideas or suggestions -> Issue Tracker