diff --git a/blockchain-watcher/docs/asyncapi.yaml b/blockchain-watcher/docs/asyncapi.yaml index 2fa6c762..4ae7be1b 100644 --- a/blockchain-watcher/docs/asyncapi.yaml +++ b/blockchain-watcher/docs/asyncapi.yaml @@ -66,7 +66,7 @@ components: nonce: 0x1 r: 0xf5794b0970386d73b693b17f147fae0427db278e951e45465ac2c9835537e5a9 s: 0x6dccc8cfee216bc43a9d66525fa94905da234ad32d6cc3220845bef78f25dd42 - status: 0x1 + status: completed timestamp: 1702663079 to: 0x3ee18b2214aff97000d974cf647e7c347e8fa585 transactionIndex: 0x6f diff --git a/blockchain-watcher/src/domain/actions/evm/GetEvmLogs.ts b/blockchain-watcher/src/domain/actions/evm/GetEvmLogs.ts index 4692785d..e9df67a9 100644 --- a/blockchain-watcher/src/domain/actions/evm/GetEvmLogs.ts +++ b/blockchain-watcher/src/domain/actions/evm/GetEvmLogs.ts @@ -47,5 +47,6 @@ export type GetEvmOpts = { addresses?: string[]; topics?: string[]; chain: string; + chainId: number; environment: string; }; diff --git a/blockchain-watcher/src/domain/actions/evm/GetEvmTransactions.ts b/blockchain-watcher/src/domain/actions/evm/GetEvmTransactions.ts index 116edafc..fb22e433 100644 --- a/blockchain-watcher/src/domain/actions/evm/GetEvmTransactions.ts +++ b/blockchain-watcher/src/domain/actions/evm/GetEvmTransactions.ts @@ -1,5 +1,4 @@ -import { methodNameByAddressMapper } from "./mappers/methodNameByAddressMapper"; -import { EvmBlock, EvmTransaction } from "../../entities"; +import { EvmBlock, EvmTransaction, ReceiptTransaction } from "../../entities"; import { EvmBlockRepository } from "../../repositories"; import { GetEvmOpts } from "./GetEvmLogs"; import winston from "winston"; @@ -23,7 +22,6 @@ export class GetEvmTransactions { } let populateTransactions: EvmTransaction[] = []; - const environment = opts.environment; const isTransactionsPresent = true; const chain = opts.chain; @@ -31,19 +29,30 @@ export class GetEvmTransactions { const evmBlock = await this.blockRepo.getBlock(chain, block, isTransactionsPresent); const transactions = evmBlock.transactions ?? []; - // Only process transactions to the contract address - const transactionsFilter = transactions.filter( + // Only process transactions to the contract address configured + const transactionsByAddressConfigured = transactions.filter( (transaction) => opts.addresses?.includes(String(transaction.to).toLowerCase()) || opts.addresses?.includes(String(transaction.from).toLowerCase()) ); - if (transactionsFilter.length > 0) { + if (transactionsByAddressConfigured.length > 0) { + const hashNumbers = new Set( + transactionsByAddressConfigured.map((transaction) => transaction.hash) + ); + const receiptTransaction = await this.blockRepo.getTransactionReceipt(chain, hashNumbers); + + const filterTransactions = this.filterTransactions( + opts, + transactionsByAddressConfigured, + receiptTransaction + ); + populateTransactions = await this.populateTransaction( - chain, - environment, + opts, evmBlock, - transactionsFilter + receiptTransaction, + filterTransactions ); } } @@ -57,23 +66,59 @@ export class GetEvmTransactions { } private async populateTransaction( - chain: string, - environment: string, + opts: GetEvmOpts, evmBlock: EvmBlock, - transactionsFilter: EvmTransaction[] + receiptTransaction: Record, + filterTransactions: EvmTransaction[] ): Promise { - const hashNumbers = new Set(transactionsFilter.map((transaction) => transaction.hash)); - const receiptTransaction = await this.blockRepo.getTransactionReceipt(chain, hashNumbers); + filterTransactions.forEach((transaction) => { + // TODO: Move this logic inside evm mappers + const redeemedTopic = opts.topics?.[1]; + const logs = receiptTransaction[transaction.hash].logs; + + logs + .filter((log) => redeemedTopic && log.topics.includes(redeemedTopic)) + .map((log) => { + transaction.emitterChain = Number(log.topics[1]); + transaction.emitterAddress = BigInt(log.topics[2]) + .toString(16) + .toUpperCase() + .padStart(64, "0"); + transaction.sequence = Number(log.topics[3]); + }); - transactionsFilter.forEach((transaction) => { - transaction.chainId = Number(transaction.chainId); - transaction.timestamp = evmBlock.timestamp; transaction.status = receiptTransaction[transaction.hash].status; - transaction.environment = environment; - transaction.chain = chain; + transaction.timestamp = evmBlock.timestamp; + transaction.environment = opts.environment; + transaction.chainId = opts.chainId; + transaction.chain = opts.chain; + transaction.logs = logs; + + this.logger.info( + `[${opts.chain}][exec] Transaction populated:[hash:${transaction.hash}][VAA:${transaction.emitterChain}/${transaction.emitterAddress}/${transaction.sequence}]` + ); }); - return transactionsFilter; + return filterTransactions; + } + + /** + * This method filter the transactions in base your logs with the topic and address configured in the job + * For example: Redeemed or MintAndWithdraw transactions + */ + private filterTransactions( + opts: GetEvmOpts, + transactionsByAddressConfigured: EvmTransaction[], + receiptTransaction: Record + ): EvmTransaction[] { + return transactionsByAddressConfigured.filter((transaction) => { + const optsTopics = opts.topics; + const logs = receiptTransaction[transaction.hash]?.logs || []; + + return logs.some((log) => { + return optsTopics?.find((topic) => log.topics?.includes(topic)); + }); + }); } private populateLog(opts: GetEvmOpts, fromBlock: bigint, toBlock: bigint): string { diff --git a/blockchain-watcher/src/domain/actions/evm/PollEvm.ts b/blockchain-watcher/src/domain/actions/evm/PollEvm.ts index 54bdaeaa..183ffb13 100644 --- a/blockchain-watcher/src/domain/actions/evm/PollEvm.ts +++ b/blockchain-watcher/src/domain/actions/evm/PollEvm.ts @@ -73,6 +73,7 @@ export class PollEvm extends RunPollingJob { const records = await this.getEvm.execute(range, { chain: this.cfg.chain, + chainId: this.cfg.chainId, addresses: this.cfg.addresses, topics: this.cfg.topics, environment: this.cfg.environment, @@ -156,6 +157,7 @@ export interface PollEvmLogsConfigProps { topics: string[]; id?: string; chain: string; + chainId: number; environment: string; } @@ -222,7 +224,18 @@ export class PollEvmLogsConfig { return this.props.environment; } + public get chainId() { + return this.props.chainId; + } + static fromBlock(chain: string, fromBlock: bigint) { - return new PollEvmLogsConfig({ chain, fromBlock, addresses: [], topics: [], environment: "" }); + return new PollEvmLogsConfig({ + chain, + fromBlock, + addresses: [], + topics: [], + environment: "", + chainId: 0, + }); } } diff --git a/blockchain-watcher/src/domain/entities/events.ts b/blockchain-watcher/src/domain/entities/events.ts index 37ca77cd..b09c0069 100644 --- a/blockchain-watcher/src/domain/entities/events.ts +++ b/blockchain-watcher/src/domain/entities/events.ts @@ -40,6 +40,7 @@ export type TransactionFoundEvent = { txHash: string; blockHeight: bigint; chainId: number; + blockTime: number; attributes: T; }; @@ -64,4 +65,7 @@ export type TransactionFound = { type: string; v: string; value: string; + sequence: number; + emitterChain: number; + emitterAddress: string; }; diff --git a/blockchain-watcher/src/domain/entities/evm.ts b/blockchain-watcher/src/domain/entities/evm.ts index 2172ae13..428a29fa 100644 --- a/blockchain-watcher/src/domain/entities/evm.ts +++ b/blockchain-watcher/src/domain/entities/evm.ts @@ -42,6 +42,10 @@ export type EvmTransaction = { timestamp: number; environment: string; chain: string; + logs: { address: string; topics: string[] }[]; + sequence: number; + emitterChain: number; + emitterAddress: string; }; export type EvmTag = "finalized" | "latest" | "safe"; @@ -61,4 +65,5 @@ export type EvmLogFilter = { export type ReceiptTransaction = { status: string; transactionHash: string; + logs: { address: string; topics: string[] }[]; }; diff --git a/blockchain-watcher/src/domain/entities/jobs.ts b/blockchain-watcher/src/domain/entities/jobs.ts index 050d03cd..7e29002c 100644 --- a/blockchain-watcher/src/domain/entities/jobs.ts +++ b/blockchain-watcher/src/domain/entities/jobs.ts @@ -1,6 +1,7 @@ export class JobDefinition { id: string; chain: string; + chainId: number; source: { action: string; records: string; @@ -16,12 +17,14 @@ export class JobDefinition { constructor( id: string, chain: string, + chainId: number, source: { action: string; records: string; config: Record }, handlers: { action: string; target: string; mapper: string; config: Record }[] ) { this.id = id; this.chain = chain; this.source = source; + this.chainId = chainId; this.handlers = handlers; } } diff --git a/blockchain-watcher/src/infrastructure/mappers/evmLogMessagePublishedMapper.ts b/blockchain-watcher/src/infrastructure/mappers/evm/evmLogMessagePublishedMapper.ts similarity index 97% rename from blockchain-watcher/src/infrastructure/mappers/evmLogMessagePublishedMapper.ts rename to blockchain-watcher/src/infrastructure/mappers/evm/evmLogMessagePublishedMapper.ts index aec91401..533388c8 100644 --- a/blockchain-watcher/src/infrastructure/mappers/evmLogMessagePublishedMapper.ts +++ b/blockchain-watcher/src/infrastructure/mappers/evm/evmLogMessagePublishedMapper.ts @@ -1,5 +1,5 @@ import { BigNumber } from "ethers"; -import { EvmLog, LogFoundEvent, LogMessagePublished } from "../../domain/entities"; +import { EvmLog, LogFoundEvent, LogMessagePublished } from "../../../domain/entities"; export const evmLogMessagePublishedMapper = ( log: EvmLog, diff --git a/blockchain-watcher/src/infrastructure/mappers/evmTransactionFoundMapper.ts b/blockchain-watcher/src/infrastructure/mappers/evm/evmTransactionFoundMapper.ts similarity index 59% rename from blockchain-watcher/src/infrastructure/mappers/evmTransactionFoundMapper.ts rename to blockchain-watcher/src/infrastructure/mappers/evm/evmTransactionFoundMapper.ts index 2904b5e1..8ddeefd4 100644 --- a/blockchain-watcher/src/infrastructure/mappers/evmTransactionFoundMapper.ts +++ b/blockchain-watcher/src/infrastructure/mappers/evm/evmTransactionFoundMapper.ts @@ -1,5 +1,8 @@ -import { methodNameByAddressMapper } from "../../domain/actions/evm/mappers/methodNameByAddressMapper"; -import { EvmTransaction, TransactionFound, TransactionFoundEvent } from "../../domain/entities"; +import { methodNameByAddressMapper } from "./methodNameByAddressMapper"; +import { EvmTransaction, TransactionFound, TransactionFoundEvent } from "../../../domain/entities"; + +const TX_STATUS_CONFIRMED = "0x1"; +const TX_STATUS_FAILED = "0x0"; export const evmTransactionFoundMapper = ( transaction: EvmTransaction @@ -10,17 +13,20 @@ export const evmTransactionFoundMapper = ( transaction ); + const status = mappedStatus(transaction); + return { name: "evm-transaction-found", address: transaction.to, chainId: transaction.chainId, txHash: transaction.hash, blockHeight: BigInt(transaction.blockNumber), + blockTime: transaction.timestamp, attributes: { name: protocol?.name, from: transaction.from, to: transaction.to, - status: transaction.status, + status: status, blockNumber: transaction.blockNumber, input: transaction.input, methodsByAddress: protocol?.method, @@ -37,6 +43,26 @@ export const evmTransactionFoundMapper = ( type: transaction.type, v: transaction.v, value: transaction.value, + sequence: transaction.sequence, + emitterAddress: transaction.emitterAddress, + emitterChain: transaction.emitterChain, }, }; }; + +const mappedStatus = (transaction: EvmTransaction): string => { + switch (transaction.status) { + case TX_STATUS_CONFIRMED: + return status.TxStatusConfirmed; + case TX_STATUS_FAILED: + return status.TxStatusFailed; + default: + return status.TxStatusUnkonwn; + } +}; + +export enum status { + TxStatusConfirmed = "completed", + TxStatusUnkonwn = "unknown", + TxStatusFailed = "failed", +} diff --git a/blockchain-watcher/src/domain/actions/evm/mappers/methodNameByAddressMapper.ts b/blockchain-watcher/src/infrastructure/mappers/evm/methodNameByAddressMapper.ts similarity index 83% rename from blockchain-watcher/src/domain/actions/evm/mappers/methodNameByAddressMapper.ts rename to blockchain-watcher/src/infrastructure/mappers/evm/methodNameByAddressMapper.ts index e47ccd37..ddb141ca 100644 --- a/blockchain-watcher/src/domain/actions/evm/mappers/methodNameByAddressMapper.ts +++ b/blockchain-watcher/src/infrastructure/mappers/evm/methodNameByAddressMapper.ts @@ -1,4 +1,4 @@ -import { EvmTransaction } from "../../../entities"; +import { EvmTransaction } from "../../../domain/entities"; const TESTNET_ENVIRONMENT = "testnet"; @@ -31,6 +31,9 @@ const methodsByAddressTestnet = ( [String("0x9563a59C15842a6f322B10f69d1dD88b41f2E97B").toLowerCase()]: completeTransferWithRelay, }, + { + [String("0x4cb69FaE7e7Af841e44E1A1c30Af640739378bb2").toLowerCase()]: ccttp, + }, ], polygon: [ { @@ -43,6 +46,9 @@ const methodsByAddressTestnet = ( { [String("0xc3D46e0266d95215589DE639cC4E93b79f88fc6C").toLowerCase()]: receiveTbtc, }, + { + [String("0x4cb69fae7e7af841e44e1a1c30af640739378bb2").toLowerCase()]: ccttp, + }, ], bsc: [ { @@ -70,6 +76,9 @@ const methodsByAddressTestnet = ( [String("0x9563a59C15842a6f322B10f69d1dD88b41f2E97B").toLowerCase()]: completeTransferWithRelay, }, + { + [String("0x4cb69fae7e7af841e44e1a1c30af640739378bb2").toLowerCase()]: ccttp, + }, ], oasis: [ { @@ -98,16 +107,25 @@ const methodsByAddressTestnet = ( { [String("0xe3e0511EEbD87F08FbaE4486419cb5dFB06e1343").toLowerCase()]: receiveTbtc, }, + { + [String("0x4cb69fae7e7af841e44e1a1c30af640739378bb2").toLowerCase()]: ccttp, + }, ], optimism: [ { [String("0xc3D46e0266d95215589DE639cC4E93b79f88fc6C").toLowerCase()]: receiveTbtc, }, + { + [String("0x4cb69fae7e7af841e44e1a1c30af640739378bb2").toLowerCase()]: ccttp, + }, ], base: [ { [String("0xA31aa3FDb7aF7Db93d18DDA4e19F811342EDF780").toLowerCase()]: base, }, + { + [String("0x4cb69fae7e7af841e44e1a1c30af640739378bb2").toLowerCase()]: ccttp, + }, ], }; @@ -131,6 +149,9 @@ const methodsByAddressMainnet = ( { [String("0xd8E1465908103eD5fd28e381920575fb09beb264").toLowerCase()]: receiveMessageAndSwap, }, + { + [String("0x4cb69fae7e7af841e44e1a1c30af640739378bb2").toLowerCase()]: ccttp, + }, ], polygon: [ { @@ -146,6 +167,9 @@ const methodsByAddressMainnet = ( { [String("0xf6C5FD2C8Ecba25420859f61Be0331e68316Ba01").toLowerCase()]: receiveMessageAndSwap, }, + { + [String("0x4cb69fae7e7af841e44e1a1c30af640739378bb2").toLowerCase()]: ccttp, + }, ], bsc: [ { @@ -173,6 +197,9 @@ const methodsByAddressMainnet = ( [String("0xcafd2f0a35a4459fa40c0517e17e6fa2939441ca").toLowerCase()]: completeTransferWithRelay, }, + { + [String("0x4cb69fae7e7af841e44e1a1c30af640739378bb2").toLowerCase()]: ccttp, + }, ], oasis: [ { @@ -204,6 +231,9 @@ const methodsByAddressMainnet = ( { [String("0xf8497FE5B0C5373778BFa0a001d476A21e01f09b").toLowerCase()]: receiveMessageAndSwap, }, + { + [String("0x4cb69fae7e7af841e44e1a1c30af640739378bb2").toLowerCase()]: ccttp, + }, ], optimism: [ { @@ -212,6 +242,9 @@ const methodsByAddressMainnet = ( { [String("0xcF205Fa51D33280D9B70321Ae6a3686FB2c178b2").toLowerCase()]: receiveMessageAndSwap, }, + { + [String("0x4cb69fae7e7af841e44e1a1c30af640739378bb2").toLowerCase()]: ccttp, + }, ], base: [ { @@ -220,6 +253,9 @@ const methodsByAddressMainnet = ( { [String("0x9816d7C448f79CdD4aF18c4Ae1726A14299E8C75").toLowerCase()]: receiveMessageAndSwap, }, + { + [String("0x4cb69fae7e7af841e44e1a1c30af640739378bb2").toLowerCase()]: ccttp, + }, ], }; @@ -260,6 +296,9 @@ export enum MethodID { MethodIDReceiveTbtc = "0x5d21a596", // Method id for Portico contract MethodIDReceiveMessageAndSwap = "0x3d528f35", + // Method id for CTTP contract + MethodIDRedeemTokensCCTP = "0x0a55d735", // Automatic relayer process + MethodIDReceiveMessageCCTP = "0x57ecfd28", // Manual process } const ethBase = new Map([ @@ -292,6 +331,17 @@ const receiveTbtc = new Map([ const base = new Map([...ethBase, ...completeTransferWithRelay]); +const ccttp = new Map([ + [ + MethodID.MethodIDRedeemTokensCCTP, + { method: "MethodRedeemTokensCCTP", name: "transfer-redeemed" }, + ], + [ + MethodID.MethodIDReceiveMessageCCTP, + { method: "MethodReceiveMessageCCTP", name: "transfer-redeemed" }, + ], +]); + type MethodsByAddress = { [chain: string]: { [address: string]: Map; diff --git a/blockchain-watcher/src/infrastructure/mappers/index.ts b/blockchain-watcher/src/infrastructure/mappers/index.ts index a5fc061d..842e5c3e 100644 --- a/blockchain-watcher/src/infrastructure/mappers/index.ts +++ b/blockchain-watcher/src/infrastructure/mappers/index.ts @@ -1,4 +1,4 @@ -export * from "./evmLogMessagePublishedMapper"; -export * from "./evmTransactionFoundMapper"; -export * from "./solanaLogMessagePublishedMapper"; -export * from "./solanaTransferRedeemedMapper"; +export * from "./evm/evmLogMessagePublishedMapper"; +export * from "./evm/evmTransactionFoundMapper"; +export * from "./solana/solanaLogMessagePublishedMapper"; +export * from "./solana/solanaTransferRedeemedMapper"; diff --git a/blockchain-watcher/src/infrastructure/mappers/solanaLogMessagePublishedMapper.ts b/blockchain-watcher/src/infrastructure/mappers/solana/solanaLogMessagePublishedMapper.ts similarity index 96% rename from blockchain-watcher/src/infrastructure/mappers/solanaLogMessagePublishedMapper.ts rename to blockchain-watcher/src/infrastructure/mappers/solana/solanaLogMessagePublishedMapper.ts index dca2ab54..ec0dc776 100644 --- a/blockchain-watcher/src/infrastructure/mappers/solanaLogMessagePublishedMapper.ts +++ b/blockchain-watcher/src/infrastructure/mappers/solana/solanaLogMessagePublishedMapper.ts @@ -1,9 +1,9 @@ import { decode } from "bs58"; import { Connection, Commitment } from "@solana/web3.js"; import { getPostedMessage } from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole"; -import { solana, LogFoundEvent, LogMessagePublished } from "../../domain/entities"; -import { CompiledInstruction, MessageCompiledInstruction } from "../../domain/entities/solana"; -import { configuration } from "../config"; +import { solana, LogFoundEvent, LogMessagePublished } from "../../../domain/entities"; +import { CompiledInstruction, MessageCompiledInstruction } from "../../../domain/entities/solana"; +import { configuration } from "../../config"; const connection = new Connection(configuration.chains.solana.rpcs[0]); // TODO: should be better to inject this to improve testability diff --git a/blockchain-watcher/src/infrastructure/mappers/solanaTransferRedeemedMapper.ts b/blockchain-watcher/src/infrastructure/mappers/solana/solanaTransferRedeemedMapper.ts similarity index 94% rename from blockchain-watcher/src/infrastructure/mappers/solanaTransferRedeemedMapper.ts rename to blockchain-watcher/src/infrastructure/mappers/solana/solanaTransferRedeemedMapper.ts index 4b2075f3..9e9755c9 100644 --- a/blockchain-watcher/src/infrastructure/mappers/solanaTransferRedeemedMapper.ts +++ b/blockchain-watcher/src/infrastructure/mappers/solana/solanaTransferRedeemedMapper.ts @@ -1,8 +1,8 @@ import { decode } from "bs58"; import { Connection, Commitment } from "@solana/web3.js"; -import { solana, LogFoundEvent, TransferRedeemed } from "../../domain/entities"; -import { CompiledInstruction, MessageCompiledInstruction } from "../../domain/entities/solana"; -import { configuration } from "../config"; +import { solana, LogFoundEvent, TransferRedeemed } from "../../../domain/entities"; +import { CompiledInstruction, MessageCompiledInstruction } from "../../../domain/entities/solana"; +import { configuration } from "../../config"; import { getPostedMessage } from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole"; enum Instruction { diff --git a/blockchain-watcher/src/infrastructure/repositories/evm/EvmJsonRPCBlockRepository.ts b/blockchain-watcher/src/infrastructure/repositories/evm/EvmJsonRPCBlockRepository.ts index 1a47bfc3..05e8d408 100644 --- a/blockchain-watcher/src/infrastructure/repositories/evm/EvmJsonRPCBlockRepository.ts +++ b/blockchain-watcher/src/infrastructure/repositories/evm/EvmJsonRPCBlockRepository.ts @@ -219,7 +219,9 @@ export class EvmJsonRPCBlockRepository implements EvmBlockRepository { }; } throw new Error( - `Unable to parse result of eth_getBlockByNumber for ${blockNumberOrTag} on ${chainCfg.rpc}` + `Unable to parse result of eth_getBlockByNumber for ${blockNumberOrTag} on ${ + chainCfg.rpc + }. Response error: ${JSON.stringify(response)}` ); } @@ -232,15 +234,17 @@ export class EvmJsonRPCBlockRepository implements EvmBlockRepository { ): Promise> { const chainCfg = this.getCurrentChain(chain); let results: { result: ReceiptTransaction; error?: ErrorBlock }[]; - const reqs: any[] = []; + let id = 1; + for (let hash of hashNumbers) { reqs.push({ jsonrpc: "2.0", - id: 1, + id, method: "eth_getTransactionReceipt", params: [hash], }); + id++; } try { @@ -260,6 +264,7 @@ export class EvmJsonRPCBlockRepository implements EvmBlockRepository { return { status: response.result.status, transactionHash: response.result.transactionHash, + logs: response.result.logs, }; } @@ -280,7 +285,9 @@ export class EvmJsonRPCBlockRepository implements EvmBlockRepository { ); } throw new Error( - `Unable to parse result of eth_getTransactionReceipt for ${hashNumbers} on ${chainCfg.rpc}` + `Unable to parse result of eth_getTransactionReceipt for ${hashNumbers} on ${ + chainCfg.rpc + }. Result error: ${JSON.stringify(results)}` ); } diff --git a/blockchain-watcher/test/domain/actions/evm/GetEvmTransactions.test.ts b/blockchain-watcher/test/domain/actions/evm/GetEvmTransactions.test.ts index 691064b1..ca1b0620 100644 --- a/blockchain-watcher/test/domain/actions/evm/GetEvmTransactions.test.ts +++ b/blockchain-watcher/test/domain/actions/evm/GetEvmTransactions.test.ts @@ -29,6 +29,7 @@ describe("GetEvmTransactions", () => { addresses: [], topics: [], chain: "ethereum", + chainId: 1, environment: "testnet", }; @@ -54,6 +55,7 @@ describe("GetEvmTransactions", () => { addresses: ["0x1ee18b2214aff97000d974cf647e7c545e8fa585"], topics: [], chain: "ethereum", + chainId: 1, environment: "mainnet", }; @@ -79,8 +81,9 @@ describe("GetEvmTransactions", () => { const opts = { addresses: ["0x3ee18b2214aff97000d974cf647e7c347e8fa585"], - topics: [], + topics: ["0xbccc00b713f54173962e7de6098f643d8ebf53d488d71f4b2a5171496d038f9e"], chain: "ethereum", + chainId: 1, environment: "mainnet", }; @@ -101,9 +104,91 @@ describe("GetEvmTransactions", () => { expect(getBlockSpy).toHaveReturnedTimes(1); }); }); + + it("should be return array with one transaction filter and populated with redeemed and MintAndWithdraw transaction log", async () => { + // Given + const range = { + fromBlock: 1n, + toBlock: 1n, + }; + + const opts = { + addresses: [ + "0x4cb69fae7e7af841e44e1a1c30af640739378bb2", + "0xBd3fa81B58Ba92a82136038B25aDec7066af3155", + ], + topics: [ + "0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6", + "0xf02867db6908ee5f81fd178573ae9385837f0a0a72553f8c08306759a7e0f00e", + ], + chain: "ethereum", + chainId: 1, + environment: "mainnet", + }; + + const logs = [ + { + address: "0xBd3fa81B58Ba92a82136038B25aDec7066af3155", + topics: ["0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6"], + }, + { + address: "0xBd3fa81B58Ba92a82136038B25aDec7066af3155", + topics: [ + "0xf02867db6908ee5f81fd178573ae9385837f0a0a72553f8c08306759a7e0f00e", + "0x0000000000000000000000000000000000000000000000000000000000000017", + "0x0000000000000000000000002703483b1a5a7c577e8680de9df8be03c6f30e3c", + "0x000000000000000000000000000000000000000000000000000000000000250f", + ], + }, + ]; + + givenEvmBlockRepository( + range.fromBlock, + range.toBlock, + logs, + "0x4cb69fae7e7af841e44e1a1c30af640739378bb2" + ); + givenPollEvmLogs(); + + // When + const result = getEvmTransactions.execute(range, opts); + + // Then + result.then((response) => { + expect(response.length).toEqual(1); + expect(response[0].chainId).toEqual(1); + expect(response[0].status).toEqual("0x1"); + expect(response[0].from).toEqual("0x3ee123456786797000d974cf647e7c347e8fa585"); + expect(response[0].to).toEqual("0x4cb69fae7e7af841e44e1a1c30af640739378bb2"); + expect(response[0].emitterChain).toEqual(23); + expect(response[0].emitterAddress).toEqual( + "0000000000000000000000002703483B1A5A7C577E8680DE9DF8BE03C6F30E3C" + ); + expect(response[0].sequence).toEqual(9487); + expect(getTransactionReceipt).toHaveReturnedTimes(1); + expect(getBlockSpy).toHaveReturnedTimes(1); + }); + }); }); -const givenEvmBlockRepository = (height?: bigint, blocksAhead?: bigint) => { +const givenEvmBlockRepository = ( + height?: bigint, + blocksAhead?: bigint, + logs?: any, + to?: string +) => { + let logsMock = logs; + const toMock = to ?? "0x3ee18b2214aff97000d974cf647e7c347e8fa585"; + + if (!logs) { + logsMock = [ + { + address: "0xf890982f9310df57d00f659cf4fd87e65aded8d7", + topics: ["0xbccc00b713f54173962e7de6098f643d8ebf53d488d71f4b2a5171496d038f9e"], + }, + ]; + } + const logsResponse: EvmLog[] = []; const blocksResponse: Record = {}; const receiptResponse: Record = {}; @@ -143,19 +228,24 @@ const givenEvmBlockRepository = (height?: bigint, blocksAhead?: bigint) => { s: "0x6dccc8cfee216bc43a9d66525fa94905da234ad32d6cc3220845bef78f25dd42", status: "0x1", timestamp: 12313123, - to: "0x3ee18b2214aff97000d974cf647e7c347e8fa585", + to: toMock, transactionIndex: "0x6f", type: "0x2", v: "0x1", value: "0x5b09cd3e5e90000", environment: "testnet", chain: "ethereum", + logs: logsMock, + sequence: 9255, + emitterAddress: "0000000000000000000000002703483B1A5A7C577E8680DE9DF8BE03C6F30E3C", + emitterChain: 23, }, ], }; receiptResponse["dasdasfpialsfijlasfsahuf"] = { status: "0x1", transactionHash: "dasdasfpialsfijlasfsahuf", + logs: logsMock, }; } } diff --git a/blockchain-watcher/test/domain/actions/evm/PollEvm.test.ts b/blockchain-watcher/test/domain/actions/evm/PollEvm.test.ts index 33cf113a..c36047cc 100644 --- a/blockchain-watcher/test/domain/actions/evm/PollEvm.test.ts +++ b/blockchain-watcher/test/domain/actions/evm/PollEvm.test.ts @@ -129,6 +129,12 @@ const givenEvmBlockRepository = (height?: bigint, blocksAhead?: bigint) => { receiptResponse[`0x0${index}`] = { status: "0x1", transactionHash: `0x0${index}`, + logs: [ + { + address: "0xf890982f9310df57d00f659cf4fd87e65aded8d7", + topics: ["0xbccc00b713f54173962e7de6098f643d8ebf53d488d71f4b2a5171496d038f9e"], + }, + ], }; } } diff --git a/blockchain-watcher/test/infrastructure/mappers/evmLogMessagePublished.test.ts b/blockchain-watcher/test/infrastructure/mappers/evm/evmLogMessagePublished.test.ts similarity index 92% rename from blockchain-watcher/test/infrastructure/mappers/evmLogMessagePublished.test.ts rename to blockchain-watcher/test/infrastructure/mappers/evm/evmLogMessagePublished.test.ts index 772c41c9..81f48752 100644 --- a/blockchain-watcher/test/infrastructure/mappers/evmLogMessagePublished.test.ts +++ b/blockchain-watcher/test/infrastructure/mappers/evm/evmLogMessagePublished.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from "@jest/globals"; -import { evmLogMessagePublishedMapper } from "../../../src/infrastructure/mappers/evmLogMessagePublishedMapper"; -import { HandleEvmLogs } from "../../../src/domain/actions"; +import { evmLogMessagePublishedMapper } from "../../../../src/infrastructure/mappers/evm/evmLogMessagePublishedMapper"; +import { HandleEvmLogs } from "../../../../src/domain/actions"; const address = "0x98f3c9e6e3face36baad05fe09d375ef1464288b"; const topic = "0x6eb224fb001ed210e379b335e35efe88672a8ce935d981a6896b27ffdf52a3b2"; diff --git a/blockchain-watcher/test/infrastructure/mappers/evmTransactionFoundMapper.test.ts b/blockchain-watcher/test/infrastructure/mappers/evm/evmTransactionFoundMapper.test.ts similarity index 83% rename from blockchain-watcher/test/infrastructure/mappers/evmTransactionFoundMapper.test.ts rename to blockchain-watcher/test/infrastructure/mappers/evm/evmTransactionFoundMapper.test.ts index 99685ebf..309fb10f 100644 --- a/blockchain-watcher/test/infrastructure/mappers/evmTransactionFoundMapper.test.ts +++ b/blockchain-watcher/test/infrastructure/mappers/evm/evmTransactionFoundMapper.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from "@jest/globals"; -import { evmTransactionFoundMapper } from "../../../src/infrastructure/mappers/evmTransactionFoundMapper"; -import { HandleEvmTransactions } from "../../../src/domain/actions"; +import { evmTransactionFoundMapper } from "../../../../src/infrastructure/mappers/evm/evmTransactionFoundMapper"; +import { HandleEvmTransactions } from "../../../../src/domain/actions"; const address = "0xf890982f9310df57d00f659cf4fd87e65aded8d7"; const topic = "0xbccc00b713f54173962e7de6098f643d8ebf53d488d71f4b2a5171496d038f9e"; @@ -43,6 +43,15 @@ describe("evmTransactionFoundMapper", () => { value: "0x5b09cd3e5e90000", environment: "testnet", chain: "ethereum", + logs: [ + { + address: "0xf890982f9310df57d00f659cf4fd87e65aded8d7", + topics: ["0xbccc00b713f54173962e7de6098f643d8ebf53d488d71f4b2a5171496d038f9e"], + }, + ], + sequence: 9255, + emitterAddress: "0000000000000000000000002703483B1A5A7C577E8680DE9DF8BE03C6F30E3C", + emitterChain: 23, }, ]); diff --git a/blockchain-watcher/test/domain/actions/evm/mappers/methodNameByAddressMapper.test.ts b/blockchain-watcher/test/infrastructure/mappers/evm/methodNameByAddressMapper.test.ts similarity index 87% rename from blockchain-watcher/test/domain/actions/evm/mappers/methodNameByAddressMapper.test.ts rename to blockchain-watcher/test/infrastructure/mappers/evm/methodNameByAddressMapper.test.ts index 8a592a67..c4b2cc56 100644 --- a/blockchain-watcher/test/domain/actions/evm/mappers/methodNameByAddressMapper.test.ts +++ b/blockchain-watcher/test/infrastructure/mappers/evm/methodNameByAddressMapper.test.ts @@ -1,4 +1,4 @@ -import { methodNameByAddressMapper } from "../../../../../src/domain/actions/evm/mappers/methodNameByAddressMapper"; +import { methodNameByAddressMapper } from "../../../../src/infrastructure/mappers/evm/methodNameByAddressMapper"; import { describe, it, expect } from "@jest/globals"; describe("methodNameByAddressMapper", () => { @@ -92,5 +92,14 @@ const getTransactions = (to: string, input: string) => { value: "0x5b09cd3e5e90000", environment: "testnet", chain: "ethereum", + logs: [ + { + address: "0xf890982f9310df57d00f659cf4fd87e65aded8d7", + topics: ["0xbccc00b713f54173962e7de6098f643d8ebf53d488d71f4b2a5171496d038f9e"], + }, + ], + sequence: 9255, + emitterAddress: "0000000000000000000000002703483B1A5A7C577E8680DE9DF8BE03C6F30E3C", + emitterChain: 23, }; }; diff --git a/blockchain-watcher/test/infrastructure/mappers/solanaLogMessagePublishedMapper.test.ts b/blockchain-watcher/test/infrastructure/mappers/solana/solanaLogMessagePublishedMapper.test.ts similarity index 97% rename from blockchain-watcher/test/infrastructure/mappers/solanaLogMessagePublishedMapper.test.ts rename to blockchain-watcher/test/infrastructure/mappers/solana/solanaLogMessagePublishedMapper.test.ts index 8630d5e8..dfa01a25 100644 --- a/blockchain-watcher/test/infrastructure/mappers/solanaLogMessagePublishedMapper.test.ts +++ b/blockchain-watcher/test/infrastructure/mappers/solana/solanaLogMessagePublishedMapper.test.ts @@ -1,6 +1,6 @@ import { expect, describe, it, jest } from "@jest/globals"; -import { solana } from "../../../src/domain/entities"; -import { solanaLogMessagePublishedMapper } from "../../../src/infrastructure/mappers/solanaLogMessagePublishedMapper"; +import { solana } from "../../../../src/domain/entities"; +import { solanaLogMessagePublishedMapper } from "../../../../src/infrastructure/mappers/solana/solanaLogMessagePublishedMapper"; import { getPostedMessage } from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole"; jest.mock("@certusone/wormhole-sdk/lib/cjs/solana/wormhole"); diff --git a/blockchain-watcher/test/infrastructure/mappers/solanaTransferRedeemedMapper.test.ts b/blockchain-watcher/test/infrastructure/mappers/solana/solanaTransferRedeemedMapper.test.ts similarity index 99% rename from blockchain-watcher/test/infrastructure/mappers/solanaTransferRedeemedMapper.test.ts rename to blockchain-watcher/test/infrastructure/mappers/solana/solanaTransferRedeemedMapper.test.ts index c4983fcd..3f8755ea 100644 --- a/blockchain-watcher/test/infrastructure/mappers/solanaTransferRedeemedMapper.test.ts +++ b/blockchain-watcher/test/infrastructure/mappers/solana/solanaTransferRedeemedMapper.test.ts @@ -1,6 +1,6 @@ import { expect, describe, it, jest } from "@jest/globals"; -import { solana } from "../../../src/domain/entities"; -import { solanaTransferRedeemedMapper } from "../../../src/infrastructure/mappers"; +import { solana } from "../../../../src/domain/entities"; +import { solanaTransferRedeemedMapper } from "../../../../src/infrastructure/mappers"; import { getPostedMessage } from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole"; jest.mock("@certusone/wormhole-sdk/lib/cjs/solana/wormhole"); diff --git a/deploy/blockchain-watcher/workers/ethereum-1.yaml b/deploy/blockchain-watcher/workers/ethereum-1.yaml index 0ab14bf5..467dab7e 100644 --- a/deploy/blockchain-watcher/workers/ethereum-1.yaml +++ b/deploy/blockchain-watcher/workers/ethereum-1.yaml @@ -46,7 +46,8 @@ data: "commitment": "latest", "interval": 15000, "addresses": ["0x6b9C8671cdDC8dEab9c719bB87cBd3e782bA6a35"], - "chain": "optimism" + "chain": "optimism", + "chainId": 24 } }, "handlers": [ @@ -74,7 +75,8 @@ data: "commitment": "finalized", "interval": 15000, "addresses": ["0x23908A62110e21C04F3A4e011d24F901F911744A"], - "chain": "base" + "chain": "base", + "chainId": 30 } }, "handlers": [ @@ -102,7 +104,8 @@ data: "commitment": "latest", "interval": 15000, "addresses": ["0x88505117CA88e7dd2eC6EA1E13f0948db2D50D56"], - "chain": "celo" + "chain": "celo", + "chainId": 14 } }, "handlers": [ @@ -130,7 +133,8 @@ data: "commitment": "latest", "interval": 15000, "addresses": ["0xc1C338397ffA53a2Eb12A7038b4eeb34791F8aCb"], - "chain": "oasis" + "chain": "oasis", + "chainId": 7 } }, "handlers": [ @@ -158,7 +162,8 @@ data: "commitment": "latest", "interval": 15000, "addresses": ["0x1830CC6eE66c84D2F177B94D544967c774E624cA"], - "chain": "klaytn" + "chain": "klaytn", + "chainId": 13 } }, "handlers": [ @@ -186,7 +191,8 @@ data: "commitment": "latest", "interval": 30000, "addresses": ["0xC7A204bDBFe983FCD8d8E61D02b475D4073fF97e"], - "chain": "arbitrum" + "chain": "arbitrum", + "chainId": 23 } }, "handlers": [ @@ -214,7 +220,8 @@ data: "commitment": "latest", "interval": 15000, "addresses": ["0x0CBE91CF822c73C2315FB05100C2F714765d5c20"], - "chain": "polygon" + "chain": "polygon", + "chainId": 5 } }, "handlers": [ @@ -245,7 +252,8 @@ data: "commitment": "latest", "interval": 5000, "addresses": ["0xEe91C335eab126dF5fDB3797EA9d6aD93aeC9722"], - "chain": "optimism" + "chain": "optimism", + "chainId": 24 } }, "handlers": [ @@ -273,7 +281,8 @@ data: "commitment": "finalized", "interval": 5000, "addresses": ["0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6"], - "chain": "base" + "chain": "base", + "chainId": 30 } }, "handlers": [ @@ -301,7 +310,8 @@ data: "commitment": "latest", "interval": 5000, "addresses": ["0xa321448d90d4e5b0A732867c18eA198e75CAC48E"], - "chain": "celo" + "chain": "celo", + "chainId": 14 } }, "handlers": [ @@ -329,7 +339,8 @@ data: "commitment": "latest", "interval": 5000, "addresses": ["0xfE8cD454b4A1CA468B57D79c0cc77Ef5B6f64585"], - "chain": "oasis" + "chain": "oasis", + "chainId": 7 } }, "handlers": [ @@ -357,7 +368,8 @@ data: "commitment": "latest", "interval": 5000, "addresses": ["0x0C21603c4f3a6387e241c0091A7EA39E43E90bb7"], - "chain": "klaytn" + "chain": "klaytn", + "chainId": 13 } }, "handlers": [ @@ -385,7 +397,8 @@ data: "commitment": "latest", "interval": 30000, "addresses": ["0xa5f208e072434bC67592E4C49C1B991BA79BCA46"], - "chain": "arbitrum" + "chain": "arbitrum", + "chainId": 23 } }, "handlers": [ @@ -413,7 +426,8 @@ data: "commitment": "latest", "interval": 5000, "addresses": ["0x7A4B5a56256163F07b2C80A7cA55aBE66c4ec4d7"], - "chain": "polygon" + "chain": "polygon", + "chainId": 5 } }, "handlers": [ @@ -478,6 +492,22 @@ spec: - name: BASE_RPCS value: '{{ .BASE_RPCS }}' {{ end }} + {{ if .OPTIMISM_RPCS }} + - name: OPTIMISM_RPCS + value: '{{ .OPTIMISM_RPCS }}' + {{ end }} + {{ if .ARBITRUM_RPCS }} + - name: ARBITRUM_RPCS + value: '{{ .ARBITRUM_RPCS }}' + {{ end }} + {{ if .POLYGON_RPCS }} + - name: POLYGON_RPCS + value: '{{ .POLYGON_RPCS }}' + {{ end }} + {{ if .AVALANCHE_RPCS }} + - name: AVALANCHE_RPCS + value: '{{ .AVALANCHE_RPCS }}' + {{ end }} resources: limits: memory: {{ .RESOURCES_LIMITS_MEMORY }} diff --git a/deploy/blockchain-watcher/workers/ethereum-2.yaml b/deploy/blockchain-watcher/workers/ethereum-2.yaml new file mode 100644 index 00000000..61a81ea5 --- /dev/null +++ b/deploy/blockchain-watcher/workers/ethereum-2.yaml @@ -0,0 +1,498 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .NAME }}-eth-2 + namespace: {{ .NAMESPACE }} + labels: + app: {{ .NAME }}-eth-2 +spec: + selector: + app: {{ .NAME }}-eth-2 + ports: + - port: {{ .PORT }} + targetPort: {{ .PORT }} + name: {{ .NAME }}-eth-2 + protocol: TCP +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: blockchain-watcher-eth-2-pvc + namespace: {{ .NAMESPACE }} +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Mi + storageClassName: gp2 +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .NAME }}-eth-2-jobs + namespace: {{ .NAMESPACE }} +data: + testnet-jobs.json: |- + [ + { + "id": "poll-redeemed-transactions-optimism", + "chain": "optimism", + "source": { + "action": "PollEvm", + "records": "GetEvmTransactions", + "config": { + "blockBatchSize": 10, + "commitment": "latest", + "interval": 5000, + "addresses": ["0x4cb69FaE7e7Af841e44E1A1c30Af640739378bb2", "0x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5"], + "chain": "optimism", + "chainId": 24, + "topics": ["0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6", "0xf02867db6908ee5f81fd178573ae9385837f0a0a72553f8c08306759a7e0f00e"] + } + }, + "handlers": [ + { + "action": "HandleEvmTransactions", + "target": "sns", + "mapper": "evmTransactionFoundMapper", + "config": { + "abi": "", + "filter": { + "addresses": ["0x4cb69FaE7e7Af841e44E1A1c30Af640739378bb2", "0x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5"], + "topics": ["0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6", "0xf02867db6908ee5f81fd178573ae9385837f0a0a72553f8c08306759a7e0f00e"] + } + } + } + ] + }, + { + "id": "poll-redeemed-transactions-base", + "chain": "base", + "source": { + "action": "PollEvm", + "records": "GetEvmTransactions", + "config": { + "blockBatchSize": 10, + "commitment": "finalized", + "interval": 5000, + "addresses": ["0x4cb69FaE7e7Af841e44E1A1c30Af640739378bb2", "0x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5"], + "chain": "base", + "chainId": 30, + "topics": ["0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6", "0xf02867db6908ee5f81fd178573ae9385837f0a0a72553f8c08306759a7e0f00e"] + } + }, + "handlers": [ + { + "action": "HandleEvmTransactions", + "target": "sns", + "mapper": "evmTransactionFoundMapper", + "config": { + "abi": "", + "filter": { + "addresses": ["0x4cb69FaE7e7Af841e44E1A1c30Af640739378bb2", "0x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5"], + "topics": ["0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6", "0xf02867db6908ee5f81fd178573ae9385837f0a0a72553f8c08306759a7e0f00e"] + } + } + } + ] + }, + { + "id": "poll-redeemed-transactions-arbitrum", + "chain": "arbitrum", + "source": { + "action": "PollEvm", + "records": "GetEvmTransactions", + "config": { + "blockBatchSize": 10, + "commitment": "latest", + "interval": 30000, + "addresses": ["0xbf683d541e11320418ca78ec13309938e6c5922f", "0x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5"], + "chain": "arbitrum", + "chainId": 23, + "topics": ["0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6", "0xf02867db6908ee5f81fd178573ae9385837f0a0a72553f8c08306759a7e0f00e"] + } + }, + "handlers": [ + { + "action": "HandleEvmTransactions", + "target": "sns", + "mapper": "evmTransactionFoundMapper", + "config": { + "abi": "", + "filter": { + "addresses": ["0xbf683d541e11320418ca78ec13309938e6c5922f", "0x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5"], + "topics": ["0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6", "0xf02867db6908ee5f81fd178573ae9385837f0a0a72553f8c08306759a7e0f00e"] + } + } + } + ] + }, + { + "id": "poll-redeemed-transactions-polygon", + "chain": "polygon", + "source": { + "action": "PollEvm", + "records": "GetEvmTransactions", + "config": { + "blockBatchSize": 10, + "commitment": "latest", + "interval": 5000, + "addresses": ["0x4cb69FaE7e7Af841e44E1A1c30Af640739378bb2", "0x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5"], + "chain": "polygon", + "chainId": 5, + "topics": ["0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6", "0xf02867db6908ee5f81fd178573ae9385837f0a0a72553f8c08306759a7e0f00e"] + } + }, + "handlers": [ + { + "action": "HandleEvmTransactions", + "target": "sns", + "mapper": "evmTransactionFoundMapper", + "config": { + "abi": "", + "filter": { + "addresses": ["0x4cb69FaE7e7Af841e44E1A1c30Af640739378bb2", "0x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5"], + "topics": ["0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6", "0xf02867db6908ee5f81fd178573ae9385837f0a0a72553f8c08306759a7e0f00e"] + } + } + } + ] + }, + { + "id": "poll-redeemed-transactions-avalanche", + "chain": "avalanche", + "source": { + "action": "PollEvm", + "records": "GetEvmTransactions", + "config": { + "blockBatchSize": 10, + "commitment": "finalized", + "interval": 5000, + "addresses": ["0x774a70bbd03327c21460b60f25b677d9e46ab458", "0xeb08f243e5d3fcff26a9e38ae5520a669f4019d0"], + "chain": "avalanche", + "chainId": 6, + "topics": ["0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6", "0xf02867db6908ee5f81fd178573ae9385837f0a0a72553f8c08306759a7e0f00e"] + } + }, + "handlers": [ + { + "action": "HandleEvmTransactions", + "target": "sns", + "mapper": "evmTransactionFoundMapper", + "config": { + "abi": "", + "filter": { + "addresses": ["0x774a70bbd03327c21460b60f25b677d9e46ab458", "0xeb08f243e5d3fcff26a9e38ae5520a669f4019d0"], + "topics": ["0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6", "0xf02867db6908ee5f81fd178573ae9385837f0a0a72553f8c08306759a7e0f00e"] + } + } + } + ] + }, + { + "id": "poll-redeemed-transactions-ethereum", + "chain": "ethereum", + "source": { + "action": "PollEvm", + "records": "GetEvmTransactions", + "config": { + "blockBatchSize": 10, + "commitment": "latest", + "interval": 15000, + "addresses": ["0x17da1ff5386d044c63f00747b5b8ad1e3806448d", "0x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5"], + "chain": "ethereum", + "chainId": 2, + "topics": ["0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6", "0xf02867db6908ee5f81fd178573ae9385837f0a0a72553f8c08306759a7e0f00e"] + } + }, + "handlers": [ + { + "action": "HandleEvmTransactions", + "target": "sns", + "mapper": "evmTransactionFoundMapper", + "config": { + "abi": "", + "filter": { + "addresses": ["0x17da1ff5386d044c63f00747b5b8ad1e3806448d", "0x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5"], + "topics": ["0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6", "0xf02867db6908ee5f81fd178573ae9385837f0a0a72553f8c08306759a7e0f00e"] + } + } + } + ] + } + ] + mainnet-jobs.json: |- + [ + { + "id": "poll-redeemed-transactions-optimism", + "chain": "optimism", + "source": { + "action": "PollEvm", + "records": "GetEvmTransactions", + "config": { + "blockBatchSize": 10, + "commitment": "latest", + "interval": 5000, + "addresses": ["0x4cb69fae7e7af841e44e1a1c30af640739378bb2", "0x2B4069517957735bE00ceE0fadAE88a26365528f"], + "chain": "optimism", + "chainId": 24, + "topics": ["0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6", "0xf02867db6908ee5f81fd178573ae9385837f0a0a72553f8c08306759a7e0f00e"] + } + }, + "handlers": [ + { + "action": "HandleEvmTransactions", + "target": "sns", + "mapper": "evmTransactionFoundMapper", + "config": { + "abi": "", + "filter": { + "addresses": ["0x4cb69fae7e7af841e44e1a1c30af640739378bb2", "0x2B4069517957735bE00ceE0fadAE88a26365528f"], + "topics": ["0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6", "0xf02867db6908ee5f81fd178573ae9385837f0a0a72553f8c08306759a7e0f00e"] + } + } + } + ] + }, + { + "id": "poll-redeemed-transactions-base", + "chain": "base", + "source": { + "action": "PollEvm", + "records": "GetEvmTransactions", + "config": { + "blockBatchSize": 10, + "commitment": "finalized", + "interval": 5000, + "addresses": ["0x4cb69fae7e7af841e44e1a1c30af640739378bb2", "0x1682Ae6375C4E4A97e4B583BC394c861A46D8962"], + "chain": "base", + "chainId": 30, + "topics": ["0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6", "0xf02867db6908ee5f81fd178573ae9385837f0a0a72553f8c08306759a7e0f00e"] + } + }, + "handlers": [ + { + "action": "HandleEvmTransactions", + "target": "sns", + "mapper": "evmTransactionFoundMapper", + "config": { + "abi": "", + "filter": { + "addresses": ["0x4cb69fae7e7af841e44e1a1c30af640739378bb2", "0x1682Ae6375C4E4A97e4B583BC394c861A46D8962"], + "topics": ["0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6", "0xf02867db6908ee5f81fd178573ae9385837f0a0a72553f8c08306759a7e0f00e"] + } + } + } + ] + }, + { + "id": "poll-redeemed-transactions-arbitrum", + "chain": "arbitrum", + "source": { + "action": "PollEvm", + "records": "GetEvmTransactions", + "config": { + "blockBatchSize": 10, + "commitment": "latest", + "interval": 30000, + "addresses": ["0x4cb69fae7e7af841e44e1a1c30af640739378bb2", "0x19330d10D9Cc8751218eaf51E8885D058642E08A"], + "chain": "arbitrum", + "chainId": 23, + "topics": ["0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6", "0xf02867db6908ee5f81fd178573ae9385837f0a0a72553f8c08306759a7e0f00e"] + } + }, + "handlers": [ + { + "action": "HandleEvmTransactions", + "target": "sns", + "mapper": "evmTransactionFoundMapper", + "config": { + "abi": "", + "filter": { + "addresses": ["0x4cb69fae7e7af841e44e1a1c30af640739378bb2", "0x19330d10D9Cc8751218eaf51E8885D058642E08A"], + "topics": ["0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6", "0xf02867db6908ee5f81fd178573ae9385837f0a0a72553f8c08306759a7e0f00e"] + } + } + } + ] + }, + { + "id": "poll-redeemed-transactions-polygon", + "chain": "polygon", + "source": { + "action": "PollEvm", + "records": "GetEvmTransactions", + "config": { + "blockBatchSize": 10, + "commitment": "latest", + "interval": 5000, + "addresses": ["0x4cb69fae7e7af841e44e1a1c30af640739378bb2", "0x9daF8c91AEFAE50b9c0E69629D3F6Ca40cA3B3FE"], + "chain": "polygon", + "chainId": 5, + "topics": ["0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6", "0xf02867db6908ee5f81fd178573ae9385837f0a0a72553f8c08306759a7e0f00e"] + } + }, + "handlers": [ + { + "action": "HandleEvmTransactions", + "target": "sns", + "mapper": "evmTransactionFoundMapper", + "config": { + "abi": "", + "filter": { + "addresses": ["0x4cb69fae7e7af841e44e1a1c30af640739378bb2", "0x9daF8c91AEFAE50b9c0E69629D3F6Ca40cA3B3FE"], + "topics": ["0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6", "0xf02867db6908ee5f81fd178573ae9385837f0a0a72553f8c08306759a7e0f00e"] + } + } + } + ] + }, + { + "id": "poll-redeemed-transactions-avalanche", + "chain": "avalanche", + "source": { + "action": "PollEvm", + "records": "GetEvmTransactions", + "config": { + "blockBatchSize": 10, + "commitment": "finalized", + "interval": 5000, + "addresses": ["0x4cb69fae7e7af841e44e1a1c30af640739378bb2", "0x6b25532e1060ce10cc3b0a99e5683b91bfde6982"], + "chain": "avalanche", + "chainId": 6, + "topics": ["0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6", "0xf02867db6908ee5f81fd178573ae9385837f0a0a72553f8c08306759a7e0f00e"] + } + }, + "handlers": [ + { + "action": "HandleEvmTransactions", + "target": "sns", + "mapper": "evmTransactionFoundMapper", + "config": { + "abi": "", + "filter": { + "addresses": ["0x4cb69fae7e7af841e44e1a1c30af640739378bb2", "0x6b25532e1060ce10cc3b0a99e5683b91bfde6982"], + "topics": ["0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6", "0xf02867db6908ee5f81fd178573ae9385837f0a0a72553f8c08306759a7e0f00e"] + } + } + } + ] + }, + { + "id": "poll-redeemed-transactions-ethereum", + "chain": "ethereum", + "source": { + "action": "PollEvm", + "records": "GetEvmTransactions", + "config": { + "blockBatchSize": 10, + "commitment": "latest", + "interval": 15000, + "addresses": ["0x4cb69fae7e7af841e44e1a1c30af640739378bb2", "0xbd3fa81b58ba92a82136038b25adec7066af3155"], + "chain": "ethereum", + "chainId": 2, + "topics": ["0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6", "0xf02867db6908ee5f81fd178573ae9385837f0a0a72553f8c08306759a7e0f00e"] + } + }, + "handlers": [ + { + "action": "HandleEvmTransactions", + "target": "sns", + "mapper": "evmTransactionFoundMapper", + "config": { + "abi": "", + "filter": { + "addresses": ["0x4cb69fae7e7af841e44e1a1c30af640739378bb2", "0xbd3fa81b58ba92a82136038b25adec7066af3155"], + "topics": ["0x1b2a7ff080b8cb6ff436ce0372e399692bbfb6d4ae5766fd8d58a7b8cc6142e6", "0xf02867db6908ee5f81fd178573ae9385837f0a0a72553f8c08306759a7e0f00e"] + } + } + } + ] + } + ] +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .NAME }}-eth-2 + namespace: {{ .NAMESPACE }} +spec: + replicas: 1 + selector: + matchLabels: + app: {{ .NAME }}-eth-2 + template: + metadata: + labels: + app: {{ .NAME }}-eth-2 + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "{{ .PORT }}" + spec: + restartPolicy: Always + terminationGracePeriodSeconds: 30 + serviceAccountName: event-watcher + containers: + - name: {{ .NAME }} + image: {{ .IMAGE_NAME }} + env: + - name: NODE_ENV + value: {{ .NODE_ENV }} + - name: PORT + value: "{{ .PORT }}" + - name: LOG_LEVEL + value: {{ .LOG_LEVEL }} + - name: BLOCKCHAIN_ENV + value: {{ .BLOCKCHAIN_ENV }} + - name: DRY_RUN_ENABLED + value: "{{ .DRY_RUN_ENABLED }}" + - name: SNS_TOPIC_ARN + value: {{ .SNS_TOPIC_ARN }} + - name: SNS_REGION + value: {{ .SNS_REGION }} + - name: JOBS_DIR + value: /home/node/app/jobs + {{ if .BASE_RPCS }} + - name: BASE_RPCS + value: '{{ .BASE_RPCS }}' + {{ end }} + {{ if .OPTIMISM_RPCS }} + - name: OPTIMISM_RPCS + value: '{{ .OPTIMISM_RPCS }}' + {{ end }} + {{ if .ARBITRUM_RPCS }} + - name: ARBITRUM_RPCS + value: '{{ .ARBITRUM_RPCS }}' + {{ end }} + {{ if .POLYGON_RPCS }} + - name: POLYGON_RPCS + value: '{{ .POLYGON_RPCS }}' + {{ end }} + {{ if .AVALANCHE_RPCS }} + - name: AVALANCHE_RPCS + value: '{{ .AVALANCHE_RPCS }}' + {{ end }} + resources: + limits: + memory: {{ .RESOURCES_LIMITS_MEMORY }} + cpu: {{ .RESOURCES_LIMITS_CPU }} + requests: + memory: {{ .RESOURCES_REQUESTS_MEMORY }} + cpu: {{ .RESOURCES_REQUESTS_CPU }} + volumeMounts: + - name: metadata-volume + mountPath: /home/node/app/metadata-repo + - name: jobs-volume + mountPath: /home/node/app/jobs + volumes: + - name: metadata-volume + persistentVolumeClaim: + claimName: blockchain-watcher-eth-2-pvc + - name: jobs-volume + configMap: + name: {{ .NAME }}-eth-2-jobs + items: + - key: {{ .BLOCKCHAIN_ENV }}-jobs.json + path: jobs.json diff --git a/deploy/blockchain-watcher/workers/ethereum.yaml b/deploy/blockchain-watcher/workers/ethereum.yaml index aca89a2c..5201674d 100644 --- a/deploy/blockchain-watcher/workers/ethereum.yaml +++ b/deploy/blockchain-watcher/workers/ethereum.yaml @@ -47,7 +47,8 @@ data: "commitment": "latest", "interval": 15000, "addresses": ["0x706abc4E45D419950511e474C7B9Ed348A4a716c"], - "chain": "ethereum" + "chain": "ethereum", + "chainId": 2 } }, "handlers": [ @@ -77,7 +78,8 @@ data: "addresses": [ "0xE4eacc10990ba3308DdCC72d985f2a27D20c7d03" ], - "chain": "karura" + "chain": "karura", + "chainId": 11 } }, "handlers": [ @@ -111,7 +113,8 @@ data: "addresses": [ "0x1BB3B4119b7BA9dfad76B0545fb3F531383c3bB7" ], - "chain": "fantom" + "chain": "fantom", + "chainId": 10 } }, "handlers": [ @@ -145,7 +148,8 @@ data: "addresses": [ "0x4377B49d559c0a9466477195C6AdC3D433e265c0" ], - "chain": "acala" + "chain": "acala", + "chainId": 12 } }, "handlers": [ @@ -180,6 +184,7 @@ data: "0x7bbcE28e64B3F8b84d876Ab298393c38ad7aac4C" ], "chain": "avalanche", + "chainId": 6, "topics": [] } }, @@ -212,7 +217,8 @@ data: "commitment": "latest", "interval": 15000, "addresses": ["0x68605AD7b15c732a30b1BbC62BE8F2A509D74b4D"], - "chain": "bsc" + "chain": "bsc", + "chainId": 4 } }, "handlers": [ @@ -240,7 +246,8 @@ data: "commitment": "latest", "interval": 15000, "addresses": ["0xa5B7D85a8f27dd7907dc8FdC21FA5657D5E2F901"], - "chain": "moonbeam" + "chain": "moonbeam", + "chainId": 16 } }, "handlers": [ @@ -271,7 +278,8 @@ data: "commitment": "latest", "interval": 15000, "addresses": ["0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B", "0x27428dd2d3dd32a4d7f7c497eaaa23130d894911", "0x3ee18b2214aff97000d974cf647e7c347e8fa585"], - "chain": "ethereum" + "chain": "ethereum", + "chainId": 2 } }, "handlers": [ @@ -301,7 +309,8 @@ data: "addresses": [ "0xa321448d90d4e5b0A732867c18eA198e75CAC48E" ], - "chain": "karura" + "chain": "karura", + "chainId": 11 } }, "handlers": [ @@ -335,7 +344,8 @@ data: "addresses": [ "0x126783A6Cb203a3E35344528B26ca3a0489a1485" ], - "chain": "fantom" + "chain": "fantom", + "chainId": 10 } }, "handlers": [ @@ -369,7 +379,8 @@ data: "addresses": [ "0xa321448d90d4e5b0A732867c18eA198e75CAC48E" ], - "chain": "acala" + "chain": "acala", + "chainId": 12 } }, "handlers": [ @@ -404,6 +415,7 @@ data: "0x54a8e5f9c4CbA08F9943965859F6c34eAF03E26c" ], "chain": "avalanche", + "chainId": 6, "topics": [] } }, @@ -436,7 +448,8 @@ data: "commitment": "latest", "interval": 5000, "addresses": ["0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B"], - "chain": "bsc" + "chain": "bsc", + "chainId": 4 } }, "handlers": [ @@ -464,7 +477,8 @@ data: "commitment": "latest", "interval": 5000, "addresses": ["0xC8e2b0cD52Cf01b0Ce87d389Daa3d414d4cE29f3"], - "chain": "moonbeam" + "chain": "moonbeam", + "chainId": 16 } }, "handlers": [ @@ -529,6 +543,10 @@ spec: - name: FANTOM_RPCS value: '{{ .FANTOM_RPCS }}' {{ end }} + {{ if .ETHEREUM_RPCS }} + - name: ETHEREUM_RPCS + value: '{{ .ETHEREUM_RPCS }}' + {{ end }} resources: limits: memory: {{ .RESOURCES_LIMITS_MEMORY }}