// SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.24; /// @title EveryChannelRail /// @notice Storage-light Ethereum rails for every.channel stream identity, manifest, and /// transport attestations. The intended deployment target is a private Ethereum-compatible /// network where iroh remains the transport/control plane and this contract carries compact /// settlement metadata only. contract EveryChannelRail { struct ManifestPointer { bytes32 streamIdHash; bytes32 epochIdHash; bytes32 manifestId; bytes32 bodyCommitment; bytes32 dataRoot; uint64 createdUnixMs; address announcer; } struct AnnouncementPointer { bytes32 streamIdHash; bytes32 announcementCommitment; uint64 updatedUnixMs; uint64 ttlMs; address announcer; } mapping(bytes32 => ManifestPointer) public latestManifestByEpoch; mapping(bytes32 => AnnouncementPointer) public latestAnnouncementByStream; event ManifestCommitted( bytes32 indexed streamIdHash, bytes32 indexed epochIdHash, bytes32 indexed manifestId, bytes32 bodyCommitment, bytes32 dataRoot, uint64 createdUnixMs, address announcer ); event TransportAnnounced( bytes32 indexed streamIdHash, bytes32 indexed announcementCommitment, uint64 updatedUnixMs, uint64 ttlMs, address announcer ); function commitManifest( string calldata streamId, string calldata epochId, bytes32 manifestId, bytes32 bodyCommitment, bytes32 dataRoot, uint64 createdUnixMs ) external { bytes32 streamIdHash = keccak256(bytes(streamId)); bytes32 epochIdHash = keccak256(bytes(epochId)); bytes32 slot = keccak256(abi.encode(streamIdHash, epochIdHash)); latestManifestByEpoch[slot] = ManifestPointer({ streamIdHash: streamIdHash, epochIdHash: epochIdHash, manifestId: manifestId, bodyCommitment: bodyCommitment, dataRoot: dataRoot, createdUnixMs: createdUnixMs, announcer: msg.sender }); emit ManifestCommitted( streamIdHash, epochIdHash, manifestId, bodyCommitment, dataRoot, createdUnixMs, msg.sender ); } function announceTransport( string calldata streamId, bytes32 announcementCommitment, uint64 updatedUnixMs, uint64 ttlMs ) external { bytes32 streamIdHash = keccak256(bytes(streamId)); latestAnnouncementByStream[streamIdHash] = AnnouncementPointer({ streamIdHash: streamIdHash, announcementCommitment: announcementCommitment, updatedUnixMs: updatedUnixMs, ttlMs: ttlMs, announcer: msg.sender }); emit TransportAnnounced( streamIdHash, announcementCommitment, updatedUnixMs, ttlMs, msg.sender ); } }