|
| 1 | +import { providers } from "ethers"; |
| 2 | +import { EventDecoder } from "../web3/EventDecoder"; |
| 3 | +import { entities } from "@repo/indexer-database"; |
| 4 | + |
| 5 | +export const TARGET_CHAIN_ACTION_ADDRESSES: Record<string, string> = { |
| 6 | + "0x200000000000000000000000000000000000010C": "1337", // HyperCore |
| 7 | +}; |
| 8 | + |
| 9 | +export interface FillTargetChainActionPair { |
| 10 | + fill: entities.FilledV3Relay; |
| 11 | + actionsTargetChainId: string; |
| 12 | +} |
| 13 | + |
| 14 | +/** |
| 15 | + * Matches fill events with Transfer events to target chain action destinations |
| 16 | + * @param fills - Array of fill events |
| 17 | + * @param transactionReceipts - Map of transaction receipts |
| 18 | + * @returns Array of matched fill and target chain action pairs |
| 19 | + */ |
| 20 | +export function matchFillEventsWithTargetChainActions( |
| 21 | + fills: entities.FilledV3Relay[], |
| 22 | + transactionReceipts: Record<string, providers.TransactionReceipt>, |
| 23 | +): FillTargetChainActionPair[] { |
| 24 | + const transactionReceiptsList = Object.values(transactionReceipts); |
| 25 | + const targetChainActionEvents = transactionReceiptsList |
| 26 | + .map((transactionReceipt) => |
| 27 | + EventDecoder.decodeTransferEvents(transactionReceipt), |
| 28 | + ) |
| 29 | + .flat(); |
| 30 | + |
| 31 | + const fillsAndTargetChainActionsByTxHash = targetChainActionEvents.reduce( |
| 32 | + (acc, targetChainAction) => { |
| 33 | + acc[targetChainAction.transactionHash] = { |
| 34 | + fills: fills.filter( |
| 35 | + (f) => |
| 36 | + f.transactionHash.toLowerCase() === |
| 37 | + targetChainAction.transactionHash.toLowerCase(), |
| 38 | + ), |
| 39 | + targetChainActions: targetChainActionEvents.filter( |
| 40 | + (t) => |
| 41 | + t.transactionHash.toLowerCase() === |
| 42 | + targetChainAction.transactionHash.toLowerCase(), |
| 43 | + ), |
| 44 | + }; |
| 45 | + return acc; |
| 46 | + }, |
| 47 | + {} as Record< |
| 48 | + string, |
| 49 | + { |
| 50 | + fills: entities.FilledV3Relay[]; |
| 51 | + targetChainActions: any[]; |
| 52 | + } |
| 53 | + >, |
| 54 | + ); |
| 55 | + |
| 56 | + // Match fills with their corresponding target chain action events |
| 57 | + const fillTargetChainActionPairs: FillTargetChainActionPair[] = Object.values( |
| 58 | + fillsAndTargetChainActionsByTxHash, |
| 59 | + ) |
| 60 | + .map((fillAndTargetChainAction) => { |
| 61 | + const { fills: txFills, targetChainActions } = fillAndTargetChainAction; |
| 62 | + const sortedFills = txFills.sort((a, b) => a.logIndex - b.logIndex); |
| 63 | + const sortedTargetChainActions = targetChainActions.sort( |
| 64 | + (a, b) => a.logIndex - b.logIndex, |
| 65 | + ); |
| 66 | + const matchedPairs: FillTargetChainActionPair[] = []; |
| 67 | + const usedTargetChainActions = new Set<number>(); // Track used target chain actions by their log index |
| 68 | + |
| 69 | + sortedFills.forEach((fill) => { |
| 70 | + const matchingTargetChainAction = sortedTargetChainActions.find( |
| 71 | + (targetChainAction) => |
| 72 | + targetChainAction.logIndex > fill.logIndex && |
| 73 | + !usedTargetChainActions.has(targetChainAction.logIndex) && |
| 74 | + targetChainAction.args.value.toString() === fill.outputAmount && |
| 75 | + Object.keys(TARGET_CHAIN_ACTION_ADDRESSES).some( |
| 76 | + (targetChainAddress) => |
| 77 | + targetChainAction.args.to.toLowerCase() === |
| 78 | + targetChainAddress.toLowerCase(), |
| 79 | + ), |
| 80 | + ); |
| 81 | + if (matchingTargetChainAction) { |
| 82 | + // Get the target chain action chain ID |
| 83 | + const targetChainAddress = Object.keys( |
| 84 | + TARGET_CHAIN_ACTION_ADDRESSES, |
| 85 | + ).find( |
| 86 | + (addr) => |
| 87 | + addr.toLowerCase() === |
| 88 | + matchingTargetChainAction.args.to.toLowerCase(), |
| 89 | + ); |
| 90 | + const actionsTargetChainId = targetChainAddress |
| 91 | + ? TARGET_CHAIN_ACTION_ADDRESSES[targetChainAddress] |
| 92 | + : null; |
| 93 | + |
| 94 | + if (actionsTargetChainId) { |
| 95 | + matchedPairs.push({ fill, actionsTargetChainId }); |
| 96 | + usedTargetChainActions.add(matchingTargetChainAction.logIndex); // Mark this target chain action as used |
| 97 | + } |
| 98 | + } |
| 99 | + }); |
| 100 | + |
| 101 | + return matchedPairs; |
| 102 | + }) |
| 103 | + .flat(); |
| 104 | + |
| 105 | + return fillTargetChainActionPairs; |
| 106 | +} |
0 commit comments