Skip to content

Commit

Permalink
feat: include time-lock-id in notification msg
Browse files Browse the repository at this point in the history
  • Loading branch information
nvtaveras committed Aug 5, 2024
1 parent fda4892 commit a3e6d1c
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 81 deletions.
14 changes: 12 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,18 @@ export const watchdogNotifier: HttpFunction = async (
for (const parsedEvent of parsedEvents) {
switch (parsedEvent.event.eventName) {
case EventType.ProposalCreated:
await sendDiscordNotification(parsedEvent.event, parsedEvent.txHash);
await sendTelegramNotification(parsedEvent.event, parsedEvent.txHash);
await sendDiscordNotification(
parsedEvent.event,
// eslint-disable-next-line
parsedEvent.timeLockId!,
parsedEvent.txHash,
);
await sendTelegramNotification(
parsedEvent.event,
// eslint-disable-next-line
parsedEvent.timeLockId!,
parsedEvent.txHash,
);
break;
case EventType.MedianUpdated:
// Acts a health check/heartbeat for the service, as it's a frequently emitted event
Expand Down
3 changes: 3 additions & 0 deletions src/parse-transaction-receipts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import isHealthCheckEvent from "./utils/is-health-check-event.js";
import isProposalCreatedEvent from "./utils/is-proposal-created-event.js";
import isTransactionReceipt from "./utils/is-transaction-receipt.js";
import SortedOraclesABI from "./sorted-oracles-abi.js";
import getProposalTimeLockId from "./utils/get-time-lock-id.js";

/**
* Parse request body containing raw transaction receipts
Expand All @@ -21,6 +22,7 @@ export default function parseTransactionReceipts(
): {
block?: number;
event: ProposalCreatedEvent | HealthCheckEvent;
timeLockId?: string;
txHash: string;
}[] {
const result = [];
Expand Down Expand Up @@ -72,6 +74,7 @@ export default function parseTransactionReceipts(

result.push({
event,
timeLockId: getProposalTimeLockId(event),
txHash: log.transactionHash,
});
break;
Expand Down
5 changes: 5 additions & 0 deletions src/send-discord-notification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { ProposalCreatedEvent } from "./types";

export default async function sendDiscordNotification(
event: ProposalCreatedEvent,
timeLockId: string,
txHash: string,
) {
const { title, description } = JSON.parse(event.args.description) as {
Expand All @@ -28,6 +29,10 @@ export default async function sendDiscordNotification(
name: "Transaction",
value: `https://celoscan.io/tx/${txHash}`,
})
.addFields({
name: "Time Lock ID",
value: timeLockId,
})
.setColor(0xa6e5f6);

const discordWebhookClient = new WebhookClient({
Expand Down
2 changes: 2 additions & 0 deletions src/send-telegram-notification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ProposalCreatedEvent } from "./types";

export default async function sendTelegramNotification(
event: ProposalCreatedEvent,
timeLockId: string,
txHash: string,
) {
const botToken = await getSecret(config.TELEGRAM_BOT_TOKEN_SECRET_ID);
Expand All @@ -19,6 +20,7 @@ export default async function sendTelegramNotification(
Proposer: `https://celoscan.io/address/${event.args.proposer}`,
Event: event.eventName,
Transaction: `https://celoscan.io/tx/${txHash}`,
"Time Lock ID": timeLockId,
Description: description,
};

Expand Down
1 change: 0 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ export interface ProposalCreatedEvent {

export interface HealthCheckEvent {
eventName: EventType.MedianUpdated;
block: number;
args: {
token: `0x${string}`;
value: bigint;
Expand Down
95 changes: 17 additions & 78 deletions src/utils/get-time-lock-id.ts
Original file line number Diff line number Diff line change
@@ -1,79 +1,18 @@
import {
createPublicClient,
encodeAbiParameters,
parseAbiParameters,
http,
decodeEventLog,
TransactionReceipt,
PublicClient,
keccak256,
} from "viem";
import { mainnet } from "viem/chains";
import GovernorABI from "../governor-abi";

async function getTransactionReceiptAndDecodeLogs(
client: PublicClient,
txHash: `0x${string}`,
) {
try {
const receipt: TransactionReceipt = await client.getTransactionReceipt({
hash: txHash,
});

for (const log of receipt.logs) {
try {
const decodedLog = decodeEventLog({
abi: GovernorABI,
data: log.data,
topics: log.topics,
});

if (decodedLog.eventName !== "ProposalCreated") {
continue;
}

console.log("Decoded event log", decodedLog);

const { targets, values, calldatas, description } = decodedLog.args;
const descriptionHash = keccak256(Buffer.from(description));

const proposalId = keccak256(
encodeAbiParameters(
parseAbiParameters(
"address[], uint256[], bytes[], uint256, bytes32",
),
// _timelockIds[proposalId] = _timelock.hashOperationBatch(targets, values, calldatas, 0, descriptionHash);
[targets, values, calldatas, 0n, descriptionHash],
),
);

console.log("Proposal timeLockId:", proposalId.toString());
} catch (error) {
console.error("Error decoding log:", error);
}
}
} catch (error) {
console.error("Error fetching transaction receipt:", error);
}
import { encodeAbiParameters, parseAbiParameters, keccak256 } from "viem";

import { ProposalCreatedEvent } from "../types";

export default function getProposalTimeLockId(
event: ProposalCreatedEvent,
): string {
const { targets, values, calldatas, description } = event.args;
const descriptionHash = keccak256(Buffer.from(description));

return keccak256(
encodeAbiParameters(
parseAbiParameters("address[], uint256[], bytes[], uint256, bytes32"),
// _timelockIds[proposalId] = _timelock.hashOperationBatch(targets, values, calldatas, 0, descriptionHash);
[targets, values, calldatas, 0n, descriptionHash],
),
);
}

async function main() {
if (process.argv.length !== 4) {
console.error("Usage: npm run get-time-lock-id -- <RPC_URL> <TX_HASH>");
process.exit(1);
}

const RPC_URL = process.argv[2];
const TX_HASH = process.argv[3] as `0x${string}`;

const client = createPublicClient({
chain: mainnet,
transport: http(RPC_URL),
});

await getTransactionReceiptAndDecodeLogs(client, TX_HASH);
}

main().catch((error: unknown) => {
console.error("Error while getting time-lock id", error);
});

0 comments on commit a3e6d1c

Please sign in to comment.