Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
ijonas committed Oct 22, 2022
0 parents commit 40fcac1
Show file tree
Hide file tree
Showing 9 changed files with 1,961 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules/
config.yaml
dist/
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules/
config.yaml
dist/
7 changes: 7 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM node:18-alpine
WORKDIR /app
COPY package.json package.json
RUN npm install
COPY . .
RUN npm run build
ENTRYPOINT ["node", "dist/index.js"]
42 changes: 42 additions & 0 deletions lib/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
export class Config {

webhookURL: string;
abis: ABI[];
allContracts: ChainContracts[];
chains: Chain[];

constructor({webhookURL, abis, allContracts, chains}: any) {
this.abis = abis;
this.allContracts = allContracts;
this.chains = chains;
this.webhookURL = webhookURL;
}

findABIByType(type: string): ABI | undefined {
return this.abis.find(abi => abi.type === type);
}

findChainById(id: number): Chain | undefined {
return this.chains.find(chain => chain.network.chainId === id);
}
}

export class ABI {
constructor(public type: string, public definition: any) {}
}

class ChainContracts {
constructor(public chainId: number, public contracts: ContractDefinition[]) {}
}

class ContractDefinition {
constructor(public address: string, public type: string, public name: string) {}
}

class Network {
constructor(public name: string, public chainId: number) {}
}

class Chain {
constructor(public network: Network, public rpcWS: string, public rpcHTTPS: string) {}
}
95 changes: 95 additions & 0 deletions lib/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { ethers } from "ethers";
import YAML from 'yaml'
import { promises as fsPromises } from 'fs';
import { Config, ABI } from './config';
import logger from "./logger";

const loadConfig = async (configFilePath: string): Promise<Config> => {
const configYaml = await fsPromises.readFile(configFilePath, 'utf8');
return YAML.parse(configYaml).config;
}

const contractEventsFromABI = (abi: ABI): string[] => {
const events: string[] = [];

for (const line of abi.definition) {
const match = line.match(/event\s+(\w+)/);
if (match) {
events.push(match[1]);
}
}
return events;
}

const callWebhook = async (url: string, data: any) => fetch(url, {method: 'POST', body: JSON.stringify(data), headers: {'Content-Type': 'application/json'}})


const run = async () => {

try {
const configFilePath = process.env.CONFIG_FILE_PATH || './config.yaml';
const config = new Config(await loadConfig(configFilePath));
logger.info('Config loaded');
logger.info('Notfications will be sent to ' + config.webhookURL);


for (const contractsOnChain of config.allContracts) {
const chain = config.findChainById(contractsOnChain.chainId);
if (chain) {
logger.info(`Processing Chain: ${chain.network.name}`)
const provider = new ethers.providers.JsonRpcProvider( chain.rpcWS, chain.network )
for (const contractDefn of contractsOnChain.contracts) {
logger.info(`Processing Contract: ${contractDefn.name}`)

const abi = config.findABIByType(contractDefn.type);
if (abi) {
const contract = new ethers.Contract(contractDefn.address, abi.definition, provider);

const eventNames = contractEventsFromABI(abi);
for (const eventName of eventNames) {
logger.info(`Registering interest in ${eventName}`)
contract.on(eventName, (...args: any) => {

const event = args[args.length - 1];
const params = args.slice(0, args.length - 1);

const data = {
contractDefn, eventName, params, event: {
blockNumber: event.blockNumber,
blockHash: event.blockHash,
transactionHash: event.transactionHash,
logIndex: event.logIndex,
transactionIndex: event.transactionIndex,
removed: event.removed,
address: event.address,
data: event.data,
event: event.event,
eventSignature: event.eventSignature,
args: event.args
}, chain: {
chainId: chain.network.chainId,
network: chain.network.name
}
}

logger.info(`Sending notification for ${eventName} on ${contractDefn.name} on ${chain.network.name} during txn ${event.transactionHash}`)
callWebhook(config.webhookURL, data)

})
}
}
}

} else {
console.log(`No chain found for ${contractsOnChain.chainId}`)
}


}

} catch (error) {
console.error(error)
}
}
run()

6 changes: 6 additions & 0 deletions lib/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class Logger {
info(message: string | Object) {
console.log(message);
}
}
export default new Logger();
Loading

0 comments on commit 40fcac1

Please sign in to comment.