// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {CheckpointExtensionBase} from "./CheckpointExtensionBase.sol"; import {CheckpointStorage} from "../storage/CheckpointStorage.sol"; import {CheckpointLeaf} from "../libraries/CheckpointLeaf.sol"; /// @notice Per-tx detail storage (v1 TransactionMirror compat + V2 ERC-20 amounts). contract MirrorDetailExtension is CheckpointExtensionBase { struct MirroredTx { bytes32 txHash; address from; address to; uint256 value; uint256 blockNumber; uint64 blockTimestamp; uint256 gasUsed; bool success; } mapping(bytes32 => MirroredTx) public transactions; mapping(uint64 => bytes32[]) public batchTxHashes; mapping(bytes32 => address) public txToken; mapping(bytes32 => uint32) public txLogIndex; function HOOK_BEFORE_SUBMIT() external pure override returns (uint32) { return 0; } function HOOK_AFTER_SUBMIT() external pure override returns (uint32) { return 1 << 1; } function HOOK_ON_CCIP() external pure override returns (uint32) { return 0; } function beforeSubmit(CheckpointStorage.CheckpointHeader calldata, bytes calldata) external pure override {} function afterSubmit(CheckpointStorage.CheckpointHeader calldata header, bytes calldata data) external { if (data.length == 0) return; if (data.length > 0 && data[0] == bytes1(0x02)) { (, CheckpointLeaf.PaymentLeafV2[] memory v2Leaves) = abi.decode(data, (bytes1, CheckpointLeaf.PaymentLeafV2[])); for (uint256 i = 0; i < v2Leaves.length; i++) { CheckpointLeaf.PaymentLeafV2 memory leaf = v2Leaves[i]; transactions[leaf.txHash] = MirroredTx({ txHash: leaf.txHash, from: leaf.from, to: leaf.to, value: leaf.value, blockNumber: leaf.blockNumber, blockTimestamp: leaf.blockTimestamp, gasUsed: leaf.gasUsed, success: leaf.success }); txToken[leaf.txHash] = leaf.token; txLogIndex[leaf.txHash] = leaf.logIndex; batchTxHashes[header.batchId].push(leaf.txHash); } return; } CheckpointLeaf.PaymentLeafV1[] memory leaves = abi.decode(data, (CheckpointLeaf.PaymentLeafV1[])); for (uint256 i = 0; i < leaves.length; i++) { CheckpointLeaf.PaymentLeafV1 memory leaf = leaves[i]; transactions[leaf.txHash] = MirroredTx({ txHash: leaf.txHash, from: leaf.from, to: leaf.to, value: leaf.value, blockNumber: leaf.blockNumber, blockTimestamp: leaf.blockTimestamp, gasUsed: leaf.gasUsed, success: leaf.success }); batchTxHashes[header.batchId].push(leaf.txHash); } } function onCCIPReceive(bytes calldata) external pure override {} }