NestJS Event Listeners
Although we covered a simple way to listen to events in the previous sections, the recommended way to listen to events is by using NestJS aware subscribers. This allows you to use the full power of the NestJS dependency injection framework. The following examples cover how to use nestjs managed event listeners where you're able to access and inject services into the subscriber. These achieve the same result as the event listening and block listening pages but with the added benefits of NestJS.
Event Subscribers
To create an event subscriber, extend the AbstractEventSubscriber
class:
import { Injectable } from '@nestjs/common';
import {
AbstractEventSubscriber,
LogEvent,
LogContext,
} from '@open-ethereum/indexer';
import { MyCustomService } from './my-custom.service';
@Injectable()
export class TransferSubscriber extends AbstractEventSubscriber {
// Required: Specify the event pattern to listen for
readonly eventPattern = 'ERC20:Transfer';
constructor(
private myCustomService: MyCustomService, // Inject your services
) {
super();
}
// Optional: Handle indexing events
async onIndex(payload: LogEvent, context: LogContext): Promise<void> {
const { parsedEvent } = payload;
const { from, to, value } = parsedEvent.args;
await this.myCustomService.processTransfer(from, to, value);
}
// Optional: Handle de-indexing events (e.g., on chain reorganizations)
async onDeindex(payload: LogEvent, context: LogContext): Promise<void> {
// Handle event removal
}
}
You can see here we've injected the MyCustomService
service into the subscriber. This service is now available to use within the subscriber. This service must be registered in your app as a provider (opens in a new tab).
Block Subscribers
For block-level events, extend the AbstractBlockSubscriber
class:
import { Injectable } from '@nestjs/common';
import {
AbstractBlockSubscriber,
BlockEvent,
LogContext,
} from '@open-ethereum/indexer';
import { BlockAnalyticsService } from './block-analytics.service';
@Injectable()
export class BlockMetricsSubscriber extends AbstractBlockSubscriber {
constructor(
private blockAnalytics: BlockAnalyticsService, // Inject your services
) {
super();
}
// Optional: Handle new blocks
async onIndex(payload: BlockEvent, context: LogContext): Promise<void> {
const { number, timestamp, transactions } = payload;
await this.blockAnalytics.recordBlockMetrics(
number,
timestamp,
transactions.length,
);
}
// Optional: Handle block removals
async onDeindex(payload: BlockEvent, context: LogContext): Promise<void> {
// Handle block removal
}
}
Registering Subscribers
Once you have your subscribers, you can register them in your NestJS module:
import { Module } from '@nestjs/common';
import { IndexerModule } from '@open-ethereum/indexer';
import { TransferSubscriber } from './transfer.subscriber';
import { BlockMetricsSubscriber } from './block-metrics.subscriber';
import { MyCustomService } from './my-custom.service';
import { BlockAnalyticsService } from './block-analytics.service';
@Module({
imports: [IndexerModule.forRoot(indexerConfig)],
providers: [
TransferSubscriber,
BlockMetricsSubscriber,
MyCustomService,
BlockAnalyticsService,
],
})
export class AppModule {}
Now they behave exactly the same as the event listeners and block listeners but have full access to the NestJS dependency injection framework.