description |
---|
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:
mappings:
eventHandlers:
- event: balances.Transfer
handler: balancesTransfer
extrinsicHandlers:
- extrinsic: timestamp.set
handler: timestampCall
Handers receive a signle argument of type defined in @joystream/hydra-common
eventHanlder
receives a single argument of typeEventContext & StoreContext
extrinsicHandler
receives a single argument of typeExtrinsicContext & StoreContext
pre/postBlockHooks
receive a single argument of typeBlockContext & StoreContext
Let us look at the sample mapping generated by the scaffolder
import {
Transfer,
} 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 } from './generated/types'
import BN from 'bn.js'
import {
ExtrinsicContext,
EventContext,
BlockContext,
StoreContext,
} from '@joystream/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 = from.toHuman()
transfer.to = to.toHuman()
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)
}
Note that the 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 use the type-safe event classes Balances.TransferEvent
provided by typegen, and so native methods like toHuman()
become available
All the events and extrinsics for which we need the generate the types should be defined in the typegen section like below and can be imported from ./generated/types
. See also Hydra Typegen.
typegen:
metadata:
source: wss://rpc.polkadot.io
blockHash: '0xab5c9230a7dde8bb90a6728ba4a0165423294dac14336b1443f865b796ff682c'
events:
- balances.Transfer
calls:
- timestamp.set
outDir: ./mappings/generated/types