> For the complete documentation index, see [llms.txt](https://dzhelezov.gitbook.io/hydra/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://dzhelezov.gitbook.io/hydra/hydra-docs/docs/mappings.md).

# Mappings

Mappings describe how Substate events and transactions should be handled by Hydra processor

A mapping file is a standalone typescript module defining how the Substrate events of interest should be handled by the Hydra indexer.

The event handlers (aka *mappings*) should be defined in the manifest file:

```yaml
mappings:
  eventHandlers:
    - event: balances.Transfer 
      handler: balancesTransfer
  extrinsicHandlers:
    - extrinsic: timestamp.set 
      handler: timestampCall
```

Handers receive a signle argument of type defined in `@dzlzv/hydra-common`

* `eventHanlder` receives a single argument of type `EventContext & StoreContext`
* `extrinsicHandler`receives a single argument of type `ExtrinsicContext & StoreContext`
* `pre/postBlockHooks`receive a single argument of type `BlockContext & StoreContext`

Let us look at the sample mapping generated by the scaffolder

```typescript
import {
  Transfer,
  BlockTimestamp,
  BlockHook,
  HookType,
} from '../generated/graphql-server/model'

// run 'NODE_URL=<RPC_ENDPOINT> EVENTS=<comma separated list of events> yarn codegen:mappings-types'
// to genenerate typescript classes for events, such as Balances.TransferEvent
import { Balances, Timestamp } from './generated/types'
import BN from 'bn.js'
import {
  ExtrinsicContext,
  EventContext,
  BlockContext,
  StoreContext,
} from '@dzlzv/hydra-common'

export async function balancesTransfer({
  store,
  event,
  block,
  extrinsic,
}: EventContext & StoreContext) {
  const transfer = new Transfer()
  const [from, to, value] = new Balances.TransferEvent(event).params
  transfer.from = Buffer.from(from.toHex())
  transfer.to = Buffer.from(to.toHex())
  transfer.value = value.toBn()
  transfer.tip = extrinsic ? new BN(extrinsic.tip.toString(10)) : new BN(0)
  transfer.insertedAt = new Date(block.timestamp)

  transfer.block = block.height
  transfer.comment = `Transferred ${transfer.value} from ${transfer.from} to ${transfer.to}`
  transfer.timestamp = new BN(block.timestamp)
  console.log(`Saving transfer: ${JSON.stringify(transfer, null, 2)}`)
  await store.save<Transfer>(transfer)
}

export async function timestampCall({
  store,
  event,
  block,
}: ExtrinsicContext & StoreContext) {
  const call = new Timestamp.SetCall(event)
  ...
}

export async function preBlockHook({
  block: { height },
  store,
}: BlockContext & StoreContext) {
  ...
}

export async function postBlockHook({
  block: { height },
  store,
}: BlockContext & StoreContext) {
  ...
}
```

Note that required entity classes are exported from

```
../generated/graphql-server/model
```

and this is where all the auto-generated classes live by default.

Note how the handlers create the typed classes `Balances.TransferEvent` and `Timestamp.SetCall` generated by typegen

All the events and extrinsics for which we need the generate the types, should be defined in the typegen section like below.

```yaml
typegen:
  metadata:
    source: wss://rpc.polkadot.io
    blockHash: '0xab5c9230a7dde8bb90a6728ba4a0165423294dac14336b1443f865b796ff682c'
  events:
    - balances.Transfer
  calls:
    - timestamp.set
  outDir: ./mappings/generated/types
```
