// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; /// @dev Manifold Creator Core extension tokenURI interface. /// The creator core checks (via ERC165, at every tokenURI call) whether the /// extension that minted a token supports this interface, and if so delegates /// tokenURI to it. interfaceId == bytes4(keccak256("tokenURI(address,uint256)")). interface ICreatorExtensionTokenURI { function tokenURI(address creator, uint256 tokenId) external view returns (string memory); } /// @dev Minimal surface of the Manifold ERC721 Creator Core contract used here. interface IERC721CreatorCore { /// @notice Mint one token attributed to the calling (registered) extension. function mintExtension(address to) external returns (uint256); /// @notice Mint `count` tokens attributed to the calling (registered) extension. function mintExtensionBatch(address to, uint16 count) external returns (uint256[] memory); /// @notice Burn a token. Caller must be owner or approved. function burn(uint256 tokenId) external; /// @notice Extension that minted a token. function tokenExtension(uint256 tokenId) external view returns (address); } /// @dev Minimal ERC721 surface. interface IERC721Lite { function ownerOf(uint256 tokenId) external view returns (address); function isApprovedForAll(address owner, address operator) external view returns (bool); function getApproved(uint256 tokenId) external view returns (address); } /// @dev Chunked blob storage: bytes held as SSTORE2 pointers under a key. /// Implemented by ColorgasmStorage; the same shape covers EthFS-style and /// Scripty-style stores, since all a renderer needs is the pointer list. interface IColorgasmBlobStorage { /// @notice The SSTORE2 pointers holding a blob, in order. function chunksOf(bytes32 key) external view returns (address[] memory); /// @notice Total bytes stored under a key. function sizeOf(bytes32 key) external view returns (uint256); /// @notice The whole blob, assembled. function read(bytes32 key) external view returns (bytes memory); } /// @dev What a renderer needs from the redeem extension: where a token's /// artwork lives, and its metadata fragment. Keyed by the ORIGINAL /// tokenId (1..editionSize). interface IColorgasmArtworkSource { /// @notice Storage key holding this token's artwork bytes, 0 if unset. function artworkKeyOf(uint256 originalTokenId) external view returns (bytes32); /// @notice Per-token metadata JSON fragment (no surrounding braces, no image /// field), e.g. `"name":"COLORGASM #001","description":"..."`. function metadataOf(uint256 originalTokenId) external view returns (bytes memory); /// @notice Original tokenId for a redeemed (new) tokenId, 0 if unknown. function originalOf(uint256 tokenId) external view returns (uint256); } /// @dev Read side of the onchain artwork store (implemented by the redeem /// extension). Everything is keyed by the ORIGINAL tokenId (1..editionSize). interface IColorgasmArtworkStore { /// @notice Full image bytes for an original tokenId (all SSTORE2 chunks concatenated). function imageData(uint256 originalTokenId) external view returns (bytes memory); /// @notice SSTORE2 pointers holding the image. function imageChunks(uint256 originalTokenId) external view returns (address[] memory); /// @notice Per-token metadata JSON fragment (no surrounding braces, no image field), /// e.g. `"name":"COLORGASM #001","created_by":"...","description":"...","attributes":[...]`. function metadataOf(uint256 originalTokenId) external view returns (bytes memory); /// @notice Original tokenId for a redeemed (new) tokenId, 0 if unknown. function originalOf(uint256 tokenId) external view returns (uint256); } /// @dev Swappable metadata renderer. interface IColorgasmRenderer { function tokenURI(address creator, uint256 tokenId, uint256 originalTokenId) external view returns (string memory); }