@wttp/site
Version:
Web3 Transfer Protocol (WTTP) - Site Contracts and deployment tools
1 lines • 2.91 MB
JSON
{"id":"5d4a4e0b231b14ad78fe5b2f72f347a0","_format":"hh-sol-build-info-1","solcVersion":"0.8.28","solcLongVersion":"0.8.28+commit.7893614a","input":{"language":"Solidity","sources":{"@openzeppelin/contracts/access/AccessControl.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.20;\n\nimport {IAccessControl} from \"./IAccessControl.sol\";\nimport {Context} from \"../utils/Context.sol\";\nimport {IERC165, ERC165} from \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n struct RoleData {\n mapping(address account => bool) hasRole;\n bytes32 adminRole;\n }\n\n mapping(bytes32 role => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with an {AccessControlUnauthorizedAccount} error including the required role.\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /// @inheritdoc IERC165\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual returns (bool) {\n return _roles[role].hasRole[account];\n }\n\n /**\n * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`\n * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`\n * is missing `role`.\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert AccessControlUnauthorizedAccount(account, role);\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `callerConfirmation`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address callerConfirmation) public virtual {\n if (callerConfirmation != _msgSender()) {\n revert AccessControlBadConfirmation();\n }\n\n _revokeRole(role, callerConfirmation);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual returns (bool) {\n if (!hasRole(role, account)) {\n _roles[role].hasRole[account] = true;\n emit RoleGranted(role, account, _msgSender());\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Attempts to revoke `role` from `account` and returns a boolean indicating if `role` was revoked.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {\n if (hasRole(role, account)) {\n _roles[role].hasRole[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n return true;\n } else {\n return false;\n }\n }\n}\n"},"@openzeppelin/contracts/access/IAccessControl.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (access/IAccessControl.sol)\n\npragma solidity >=0.8.4;\n\n/**\n * @dev External interface of AccessControl declared to support ERC-165 detection.\n */\ninterface IAccessControl {\n /**\n * @dev The `account` is missing a role.\n */\n error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);\n\n /**\n * @dev The caller of a function is not the expected one.\n *\n * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.\n */\n error AccessControlBadConfirmation();\n\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted to signal this.\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call. This account bears the admin role (for the granted role).\n * Expected in cases where the role was granted using the internal {AccessControl-_grantRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `callerConfirmation`.\n */\n function renounceRole(bytes32 role, address callerConfirmation) external;\n}\n"},"@openzeppelin/contracts/utils/Context.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n function _contextSuffixLength() internal view virtual returns (uint256) {\n return 0;\n }\n}\n"},"@openzeppelin/contracts/utils/introspection/ERC165.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n */\nabstract contract ERC165 is IERC165 {\n /// @inheritdoc IERC165\n function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n"},"@openzeppelin/contracts/utils/introspection/IERC165.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)\n\npragma solidity >=0.4.16;\n\n/**\n * @dev Interface of the ERC-165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"},"@tw3/esp/contracts/interfaces/IDataPointRegistry.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\n// Copyright (C) 2025 TechnicallyWeb3\n\nimport \"../types/ESPTypes.sol\";\nimport \"./IDataPointStorage.sol\";\nimport \"./IOwnable.sol\";\n\n/// @title Data Point Registry Contract\n/// @notice Manages data point publishing and royalty payments\n/// @dev Extends storage functionality with economic incentives\ninterface IDataPointRegistry is IOwnable {\n\n function royaltyRate() external view returns (uint256);\n\n function DPS() external view returns (IDataPointStorage);\n function setDPS(address _dps) external;\n function setRoyaltyRate(uint256 _royaltyRate) external;\n function updateRoyaltyRecord(bytes32 _dataPointAddress, DataPointRoyalty memory _dataPointRoyalty) external;\n function updatePublisherAddress(bytes32 _dataPointAddress, address _newPublisher) external;\n /// @notice Calculates the royalty amount for a data point with overflow protection\n /// @param _dataPointAddress The address of the data point\n /// @return The calculated royalty amount in wei\n function getDataPointRoyalty(bytes32 _dataPointAddress) external view returns (uint256);\n /// @notice Allows the owner to transfer royalties to a different address\n /// @param _publisher The address of the publisher\n /// @param _amount The amount to transfer\n /// @param _to The address to send the royalties to\n /// @dev Should be protected by a strong consensus mechanism\n function transfer(address _publisher, uint256 _amount, address _to) external;\n /// @notice Allows publishers to withdraw their earned royalties\n /// @param _amount The amount to withdraw\n /// @param _withdrawTo The address to send the royalties to\n function collectRoyalties(uint256 _amount, address _withdrawTo) external;\n /// @notice Checks the royalty balance of a publisher\n /// @param _publisher The address of the publisher\n /// @return The current balance in wei\n function royaltyBalance(address _publisher) external view returns (uint256);\n /// @notice Writes a new data point and handles royalty logic\n /// @dev Use address(0) as publisher to waive royalties\n /// @param _dataPoint The data point to write\n /// @param _publisher The publisher of the data point, can be address(0) to waive royalties\n /// @return dataPointAddress The address where the data point is stored\n function registerDataPoint(bytes memory _dataPoint, address _publisher) external payable returns (bytes32 dataPointAddress);\n}\n"},"@tw3/esp/contracts/interfaces/IDataPointStorage.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\n// Copyright (C) 2025 TechnicallyWeb3\n\n/// @title Data Point Storage Contract\n/// @notice Provides core storage functionality for data points\n/// @dev Basic implementation without collision handling\ninterface IDataPointStorage {\n\n function VERSION() external pure returns (uint8);\n\n /// @notice Calculates the storage address for a data point\n /// @param _data The data point to calculate address for\n /// @return _dataPointAddress The calculated storage address\n function calculateAddress(bytes memory _data) external pure returns (bytes32 _dataPointAddress);\n function dataPointSize(bytes32 _dataPointAddress) external view returns (uint256);\n function readDataPoint(bytes32 _dataPointAddress) external view returns (bytes memory);\n /// @notice Stores a new data point with user-specified version\n /// @dev Reverts if the calculated address is already occupied\n /// @param _data The data point to store\n /// @return _dataPointAddress The address where the data point is stored\n function writeDataPoint(bytes memory _data) external returns (bytes32 _dataPointAddress);\n}\n"},"@tw3/esp/contracts/interfaces/IOwnable.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\ninterface IOwnable {\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev The caller account is not authorized to perform an operation.\n */\n error OwnableUnauthorizedAccount(address account);\n /**\n * @dev The owner is not a valid owner account. (eg. `address(0)`)\n */\n error OwnableInvalidOwner(address owner);\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() external view returns (address);\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() external;\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) external;\n}\n"},"@tw3/esp/contracts/types/ESPTypes.sol":{"content":"/*\r\n * Ethereum Storage Protocol (ESP) - Core Types and Functions\r\n * Copyright (C) 2025 TechnicallyWeb3\r\n * \r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as published\r\n * by the Free Software Foundation, either version 3 of the License, or\r\n * (at your option) any later version.\r\n * \r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n * \r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\r\n */\r\n\r\n// SPDX-License-Identifier: AGPL-3.0\r\npragma solidity ^0.8.20;\r\n\r\nevent DataPointWritten(bytes32 indexed dataPointAddress);\r\n\r\nerror DataExists(bytes32 dataPointAddress);\r\nerror InvalidData();\r\nerror InvalidDPS();\r\nerror InsufficientRoyaltyPayment(uint256 royaltyCost);\r\nerror InvalidPublisher(address publisher);\r\n\r\nevent RoyaltiesCollected(address indexed publisher, uint256 amount, address indexed withdrawTo);\r\nevent RoyaltiesPaid(bytes32 indexed dataPointAddress, address indexed payer, uint256 amount);\r\nevent DataPointRegistered(bytes32 indexed dataPointAddress, address indexed publisher);\r\n\r\n\r\n/// @notice Calculates a unique address for a data point\r\n/// @dev Uses keccak256 hash of concatenated version and data\r\n/// @param _data The data point\r\n/// @param _version The version of the data point\r\n/// @return bytes32 The calculated address\r\nfunction calculateDataPointAddress(\r\n bytes memory _data,\r\n uint8 _version\r\n) pure returns (bytes32) {\r\n return keccak256(abi.encodePacked(_data, _version));\r\n}\r\n\r\n/// @notice Structure for tracking royalty information\r\n/// @dev Stores gas usage and publisher address for royalty calculations\r\nstruct DataPointRoyalty {\r\n uint256 gasUsed;\r\n address publisher;\r\n}"},"@wttp/core/contracts/interfaces/IBaseWTTPPermissions.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\nimport \"@openzeppelin/contracts/access/IAccessControl.sol\";\n\n/// @title WTTP Permissions Contract\n/// @author Web3 Transfer Protocol (WTTP) Development Team\n/// @notice Manages role-based access control for the WTTP protocol\ninterface IBaseWTTPPermissions is IAccessControl {\n\n /// @notice Check if an account has a specific role\n /// @dev Overrides the standard AccessControl implementation to grant DEFAULT_ADMIN_ROLE holders access to all roles\n /// @param role The role identifier to check\n /// @param account The address to check for the role\n /// @return bool True if the account has the role or is a DEFAULT_ADMIN_ROLE holder\n function hasRole(bytes32 role, address account) external view returns (bool);\n /// @notice Creates a new resource-specific admin role\n /// @dev Sets the SITE_ADMIN_ROLE as the admin of the new role, preventing creation of privileged roles\n /// @param _role The new role identifier to create\n function createResourceRole(bytes32 _role) external;\n /// @notice Changes the SITE_ADMIN_ROLE identifier\n /// @dev Allows wiping all current site admin permissions by changing the role hash\n /// @param _newSiteAdmin The new role identifier to use for site administrators\n function changeSiteAdmin(bytes32 _newSiteAdmin) external;\n function getSiteAdminRole() external view returns (bytes32);\n}\n"},"@wttp/core/contracts/interfaces/IBaseWTTPSite.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\nimport \"./IBaseWTTPStorage.sol\";\n\n/// @title WTTP Base Site Contract\n/// @author Web3 Transfer Protocol (WTTP) Development Team\n/// @notice Implements core WTTP protocol methods for HTTP-like operations on blockchain\ninterface IBaseWTTPSite is IBaseWTTPStorage {\n\n /// @notice Handles OPTIONS requests to check available methods\n /// @dev External interface for _OPTIONS with method enforcement\n /// @param _path Resource path to check\n /// @return optionsResponse Response with allowed methods info\n function OPTIONS(string memory _path) external view returns (OPTIONSResponse memory optionsResponse);\n /// @notice Handles WTTP HEAD requests for metadata\n /// @dev External interface for _HEAD with method enforcement\n /// @param headRequest Request information including conditional headers\n /// @return head Response with header and metadata information\n function HEAD(HEADRequest memory headRequest) external view returns (HEADResponse memory head);\n /// @notice Handles GET requests to retrieve resource content locations\n /// @param getRequest Request information\n /// @return getResponse Response containing resource and storage locations\n function GET(LOCATERequest memory getRequest) external view returns (LOCATEResponse memory getResponse);\n /// @notice Handles DEFINE requests to update resource headers\n /// @dev Only accessible to resource administrators, creates header if needed\n /// @param defineRequest Request information with new header data\n /// @return defineResponse Response containing updated header information\n function DEFINE(DEFINERequest memory defineRequest) external returns (DEFINEResponse memory defineResponse);\n /// @notice Handles DELETE requests to remove resources\n /// @dev Only accessible to resource administrators, checks resource mutability\n /// @param deleteRequest Request information\n /// @return deleteResponse Response confirming deletion\n function DELETE(HEADRequest memory deleteRequest) external returns (HEADResponse memory deleteResponse);\n /// @notice Handles PUT requests to create new resources\n /// @dev Only accessible to resource administrators, transfers any excess payment back\n /// @param putRequest Request information including content data\n /// @return putResponse Response containing created resource information\n function PUT(PUTRequest memory putRequest) external payable returns (LOCATEResponse memory putResponse);\n /// @notice Handles PATCH requests to update existing resources\n /// @dev Only accessible to resource administrators, checks resource mutability\n /// @param patchRequest Request information including update data\n /// @return patchResponse Response containing updated resource information\n function PATCH(PATCHRequest memory patchRequest) external payable returns (LOCATEResponse memory patchResponse);\n}\n"},"@wttp/core/contracts/interfaces/IBaseWTTPStorage.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\nimport \"./IBaseWTTPPermissions.sol\";\nimport \"../types/WTTPTypes.sol\";\n\n/// @title WTTP Base Storage Contract\n/// @author Web3 Transfer Protocol (WTTP) Development Team\n/// @notice Manages web resource storage and access control\n/// @dev Core storage functionality for the WTTP protocol, inheriting permission management\ninterface IBaseWTTPStorage is IBaseWTTPPermissions {\n\n /// @return IDataPointStorage The Data Point Storage contract\n function DPS() external view returns (IDataPointStorage);\n /// @notice Returns the Data Point Registry contract instance\n /// @dev Provides external access to the internal DPR_ reference\n /// @return IDataPointRegistry The Data Point Registry contract\n function DPR() external view returns (IDataPointRegistry);\n}\n"},"@wttp/core/contracts/types/WTTPTypes.sol":{"content":"/*\r\n * Web3 Transfer Protocol (WTTP) - Types and Structures\r\n * Copyright (C) 2025 TechnicallyWeb3\r\n * \r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as published\r\n * by the Free Software Foundation, either version 3 of the License, or\r\n * (at your option) any later version.\r\n * \r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n * \r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\r\n */\r\n\r\n// SPDX-License-Identifier: AGPL-3.0\r\npragma solidity ^0.8.20;\r\n\r\n/// @title WTTP Types Contract\r\n/// @notice Defines the types and structures used in the WTTP protocol\r\n/// @dev Provides common definitions for WTTP site and gateway contracts\r\n\r\n/// @notice Import the Data Point Storage and Registry interfaces\r\nimport \"@tw3/esp/contracts/interfaces/IDataPointRegistry.sol\";\r\n\r\n// ============ WTTP Permissions Contract ============\r\n// ============ Events ============\r\n\r\n/// @notice Emitted when the site admin role identifier is changed\r\n/// @param oldSiteAdmin Previous site admin role identifier\r\n/// @param newSiteAdmin New site admin role identifier\r\nevent SiteAdminChanged(bytes32 oldSiteAdmin, bytes32 newSiteAdmin);\r\n\r\n/// @notice Emitted when a new resource role is created\r\n/// @param role The role identifier that was created\r\nevent ResourceRoleCreated(bytes32 indexed role);\r\n\r\n// ============ Errors ============\r\n\r\n/// @notice Error thrown when an invalid role is used\r\n/// @param role The role identifier that caused the error\r\nerror InvalidRole(bytes32 role);\r\n\r\n// ============ WTTP Storage Contract ============\r\n\r\nuint256 constant CHUNK_RESPONSE_LIMIT = 100000; // 100K chunks per response\r\nuint256 constant BYTE_RESPONSE_LIMIT = 1000000; // 1 MB per response\r\n\r\n// ============ Events ============\r\n// event MalformedParameter(string parameter, bytes value);\r\n// event HeaderExists(bytes32 headerAddress);\r\n// event ResourceExists(string path);\r\n/// @notice Emitted when a header is created\r\n/// @param headerAddress Address of the created header\r\nevent HeaderCreated(bytes32 headerAddress);\r\n/// @notice Emitted when a header is updated\r\n/// @param headerAddress Address of the updated header\r\nevent HeaderUpdated(bytes32 headerAddress);\r\n/// @notice Emitted when resource metadata is updated\r\n/// @param path Path of the updated resource\r\nevent MetadataUpdated(string path);\r\n/// @notice Emitted when resource metadata is deleted\r\n/// @param path Path of the deleted metadata\r\nevent MetadataDeleted(string path);\r\n/// @notice Emitted when a new resource is created\r\n/// @param path Path of the created resource\r\nevent ResourceCreated(string path);\r\n/// @notice Emitted when a resource is updated\r\n/// @param path Path of the updated resource\r\n/// @param chunkIndex Index of the updated chunk\r\nevent ResourceUpdated(string path, uint256 chunkIndex);\r\n/// @notice Emitted when a resource is deleted\r\n/// @param path Path of the deleted resource\r\nevent ResourceDeleted(string path);\r\n\r\n// ============ Errors ============\r\n/// @notice Error thrown when an invalid header is used\r\n/// @param header The header that was invalid\r\nerror InvalidHeader(HeaderInfo header);\r\n\r\n/// @title Resource Response Structure\r\n/// @notice Contains response data for resource requests\r\n/// @param dataPoints Array of data point addresses for content chunks\r\n/// @param totalChunks Total number of chunks in the resource\r\n/// @dev Includes data point addresses and total number of chunks\r\nstruct ResourceResponse {\r\n bytes32[] dataPoints;\r\n uint256 totalChunks;\r\n}\r\n\r\n/// @notice Error thrown when a request is malformed\r\n/// @param reason Reason for the error\r\n/// @param body Body of the error, additional custom context\r\nerror _400(string reason, string body);\r\n/// @notice Error thrown when a request doesn't have the required value\r\n/// @param reason Reason for the error\r\n/// @param requiredValue The required value to call the requested method, negative ints means shortfall, positive ints means total cost\r\nerror _402(string reason, int256 requiredValue);\r\n/// @notice Error thrown when an account lacks permission for a role\r\n/// @param reason Reason for the error\r\n/// @param role Required role for the action\r\nerror _403(string reason, bytes32 role);\r\n/// @notice Error thrown when a resource does not exist\r\n/// @param reason Reason for the error\r\n/// @param isImmutable Whether the resource is immutable\r\nerror _404(string reason, bool isImmutable);\r\n/// @notice Error thrown when a method is not allowed for a resource\r\n/// @param reason Reason for the error\r\n/// @param methodsAllowed Bitmask of allowed methods\r\n/// @param isImmutable Whether the resource is immutable\r\nerror _405(string reason, uint16 methodsAllowed, bool isImmutable);\r\n/// @notice Error thrown when attempting to modify an immutable resource\r\n/// @param reason Reason for the error\r\n/// @param body Body of the error, additional custom context\r\nerror _409(string reason, string body);\r\n/// @notice Error thrown when a resource has been permanently deleted\r\n/// @param reason Reason for the error\r\nerror _410(string reason);\r\n/// @notice Error thrown when a range is out of bounds\r\n/// @param range The range that was out of bounds\r\n/// @param outOfBounds The index that was out of bounds\r\nerror _416(string reason, Range range, int256 outOfBounds);\r\n\r\n// ============ Enum Definitions ============\r\n\r\n/// @title WTTP Methods Enum\r\n/// @notice Defines supported WTTP methods in the WTTP protocol\r\n/// @dev Used for method-based access control and request handling\r\nenum Method {\r\n /// @notice Retrieve only resource headers and metadata\r\n HEAD,\r\n /// @notice Retrieve resource content\r\n GET,\r\n /// @notice Submit data to be processed (not fully implemented in WTTP)\r\n POST,\r\n /// @notice Create or replace a resource\r\n PUT,\r\n /// @notice Update parts of a resource\r\n PATCH,\r\n /// @notice Remove a resource\r\n DELETE,\r\n /// @notice Query which methods are supported for a resource\r\n OPTIONS,\r\n /// @notice Retrieve storage locations for resource data points\r\n LOCATE,\r\n /// @notice Update resource headers\r\n DEFINE\r\n}\r\n\r\n/// @title Cache Preset Enum\r\n/// @notice Defines preset cache control directives\r\n/// @dev Used for resource header management\r\nenum CachePreset {\r\n /// @notice No cache control directives\r\n NONE,\r\n /// @notice Cache control directives for a resource that should not be cached\r\n NO_CACHE,\r\n /// @notice Cache control directives for a resource that should be cached\r\n DEFAULT,\r\n /// @notice Cache control directives for a resource that should be cached for a short time\r\n SHORT,\r\n /// @notice Cache control directives for a resource that should be cached for a medium time\r\n MEDIUM,\r\n /// @notice Cache control directives for a resource that should be cached for a long time\r\n LONG,\r\n /// @notice Cache control directives for a resource that should be cached indefinitely\r\n PERMANENT\r\n}\r\n\r\n/// @title CORS Policy Presets for Common Use Cases\r\nenum CORSPreset {\r\n /// @notice No CORS policy\r\n NONE, // 0: Use custom configuration only\r\n /// @notice Public CORS policy\r\n PUBLIC, // 1: Wide open - any origin, basic methods\r\n /// @notice Restricted CORS policy\r\n RESTRICTED, // 2: Same-origin only \r\n /// @notice API CORS policy\r\n API, // 3: Common API configuration\r\n /// @notice Mixed access CORS policy\r\n MIXED_ACCESS, // 4: Public read, restricted write\r\n /// @notice Private CORS policy\r\n PRIVATE // 5: Admin/role access only\r\n}\r\n\r\n// ============ Struct Definitions ============\r\n\r\n/// @title Cache Control Structure\r\n/// @notice Defines WTTP cache control directives\r\n/// @dev Maps to standard WTTP cache-control header fields\r\nstruct CacheControl {\r\n /// @notice Indicates resource will never change\r\n bool immutableFlag;\r\n /// @notice Cache control preset for the client\r\n CachePreset preset;\r\n /// @notice Cache control directives for the client, stored as comma separated string eg. \"Max-Age=3600, No-Cache\"\r\n /// @dev preset should be NONE if custom is set or it may cause undesired behavior\r\n string custom;\r\n}\r\n/// @title CORS Policy Structure\r\n/// @notice Defines CORS policy for a resource\r\n/// @dev Used for resource header management\r\nstruct CORSPolicy {\r\n /// @notice Bitmask of allowed methods\r\n uint16 methods;\r\n /// @notice Array of access policies for the resource\r\n /// @dev Each policy is a role identifier use Method enum as index\r\n bytes32[] origins;\r\n /// @notice CORS policy preset for the resource\r\n CORSPreset preset;\r\n /// @notice String for client side CORS verification\r\n string custom;\r\n}\r\n/// @title Redirect Structure\r\n/// @notice Defines WTTP redirect information\r\n/// @dev Maps to standard WTTP redirect response\r\nstruct Redirect {\r\n /// @notice WTTP status code for redirect (3xx)\r\n uint16 code;\r\n /// @notice Target location for redirect in URL format\r\n string location; \r\n}\r\n\r\n/// @title Header Information Structure\r\n/// @notice Combines all WTTP header related information\r\n/// @dev Used for resource header management\r\nstruct HeaderInfo {\r\n /// @notice Cache control directives, using CachePreset enum with custom directives if needed\r\n CacheControl cache;\r\n /// @notice CORS policy for the resource\r\n CORSPolicy cors;\r\n /// @notice Redirect information if applicable\r\n Redirect redirect;\r\n}\r\n\r\nstruct ResourceProperties {\r\n /// @notice MIME type of the resource (2-byte identifier)\r\n bytes2 mimeType;\r\n /// @notice Character set of the resource (2-byte identifier)\r\n bytes2 charset;\r\n /// @notice Encoding of the resource (2-byte identifier)\r\n bytes2 encoding;\r\n /// @notice Language of the resource (2-byte identifier)\r\n bytes2 language;\r\n}\r\n\r\n/// @title Resource Metadata Structure\r\n/// @notice Stores metadata about web resources\r\n/// @dev Used to track resource properties and modifications\r\nstruct ResourceMetadata {\r\n /// @notice Resource properties\r\n ResourceProperties properties;\r\n /// @notice Size of the resource in bytes\r\n uint256 size;\r\n /// @notice Version number of the resource\r\n uint256 version;\r\n /// @notice Timestamp of last modification\r\n uint256 lastModified;\r\n /// @notice Header identifier determining which header the resource uses\r\n bytes32 header;\r\n}\r\n\r\n/// @title Data Registration Structure\r\n/// @notice Contains data for registering a resource chunk\r\n/// @dev Used for PUT and PATCH operations\r\nstruct DataRegistration {\r\n /// @notice The actual content data\r\n bytes data;\r\n /// @notice Index position in the resource's chunk array\r\n uint256 chunkIndex;\r\n /// @notice Address of the content publisher\r\n address publisher;\r\n}\r\n\r\n// ============ Helper Functions ============\r\n\r\n// Method Bitmask Converter\r\n// Converts array of methods to a bitmask representation\r\n// Used for efficient method permission storage (1 bit per method)\r\n// methods Array of WTTP methods to convert\r\n// uint16 Bitmask representing allowed methods\r\nfunction methodsToMask(Method[] memory methods) pure returns (uint16) {\r\n uint16 mask = 0;\r\n for (uint i = 0; i < methods.length; i++) {\r\n mask |= uint16(1 << uint8(methods[i]));\r\n }\r\n return mask;\r\n}\r\n\r\n// Header Address Calculator\r\n// Calculates a unique address for a header\r\n// Uses keccak256 hash of encoded header information\r\n// _header The header information \r\n// bytes32 The calculated header address\r\nfunction getHeaderAddress(HeaderInfo memory _header) pure returns (bytes32) {\r\n return keccak256(abi.encode(_header));\r\n}\r\n\r\n// ============ WTTP Site Contract ============\r\n\r\n/// @notice The URI and Query structs are intended for future use\r\n\r\n/// @title Query Structure\r\n/// @notice Represents a key-value pair in a URI query string\r\n/// @dev Used for parsing and processing query parameters\r\n// struct Query {\r\n// /// @notice The key part of the query parameter\r\n// string key;\r\n// /// @notice The value part of the query parameter\r\n// string value;\r\n// }\r\n// /// @title URI Structure\r\n// /// @notice Represents a Uniform Resource Identifier\r\n// /// @dev Used for parsing and processing URIs\r\n// struct URI {\r\n// /// @notice The path part of the URI\r\n// string path;\r\n// /// @notice The query parameters of the URI\r\n// Query[] query;\r\n// /// @notice The fragment part of the URI\r\n// string fragment;\r\n// }\r\n\r\n// OPTIONSRequest is just a path string\r\n\r\n/// @title OPTIONS Response Structure\r\n/// @notice Contains response data for OPTIONS requests\r\n/// @dev Includes bitmask of allowed methods\r\nstruct OPTIONSResponse {\r\n /// @notice Response status code\r\n uint16 status;\r\n /// @notice Bitmask of allowed methods\r\n uint16 allow;\r\n}\r\n\r\n/// @title HEAD Request Structure\r\n/// @notice Contains request data for HEAD requests\r\n/// @dev Includes conditional request headers\r\nstruct HEADRequest {\r\n /// @notice Resource path to request\r\n string path;\r\n /// @notice Conditional timestamp for If-Modified-Since header\r\n uint256 ifModifiedSince;\r\n /// @notice Conditional ETag for If-None-Match header\r\n bytes32 ifNoneMatch;\r\n}\r\n\r\n/// @title HEAD Response Structure\r\n/// @notice Contains metadata and header information for HEAD requests\r\n/// @dev Used as base response type for other methods\r\nstruct HEADResponse {\r\n /// @notice Response status code\r\n uint16 status;\r\n /// @notice Resource header information\r\n HeaderInfo headerInfo;\r\n /// @notice Resource metadata\r\n ResourceMetadata metadata;\r\n /// @notice Resource content hash for caching\r\n bytes32 etag;\r\n}\r\n\r\n/// @title LOCATE Response Structure\r\n/// @notice Extended response for LOCATE requests\r\n/// @param head The base HEAD response\r\n/// @param dataPoints The array of data point addresses for content chunks\r\n/// @param totalChunks The total number of chunks in the resource\r\n/// @dev Includes storage addresses and data point locations\r\nstruct LOCATEResponse {\r\n /// @notice Base HEAD response\r\n HEADResponse head;\r\n /// @notice Resource response\r\n ResourceResponse resource;\r\n}\r\n\r\n/// @title PUT Request Structure\r\n/// @notice Contains data for creating or replacing resources\r\n/// @dev Includes metadata and content chunks\r\nstruct PUTRequest {\r\n /// @notice Basic request information\r\n HEADRequest head;\r\n /// @notice Properties of the resource\r\n ResourceProperties properties;\r\n /// @notice Content chunks to store\r\n DataRegistration[] data;\r\n}\r\n\r\n// PUTResponse is the same as LOCATEResponse\r\n\r\n/// @title PATCH Request Structure\r\n/// @notice Contains data for updating parts of resources\r\n/// @dev Includes content chunks to update\r\nstruct PATCHRequest {\r\n /// @notice Basic request information\r\n HEADRequest head;\r\n /// @notice Content chunks to update\r\n DataRegistration[] data;\r\n}\r\n\r\n// PATCHResponse is the same as LOCATEResponse\r\n\r\n/// @title DEFINE Request Structure\r\n/// @notice Contains data for updating resource headers\r\n/// @dev Includes new header information\r\nstruct DEFINERequest {\r\n /// @notice Basic request information\r\n HEADRequest head;\r\n /// @notice New header information\r\n HeaderInfo data;\r\n}\r\n\r\n/// @title DEFINE Response Structure\r\n/// @notice Contains response data for DEFINE requests\r\n/// @dev Includes the new header address\r\nstruct DEFINEResponse {\r\n /// @notice Base HEAD response\r\n HEADResponse head;\r\n /// @notice New header address\r\n bytes32 headerAddress;\r\n}\r\n\r\n// ETag Calculator\r\n// Calculates a unique content identifier for caching\r\n// Hashes the combination of metadata and data point addresses\r\n// _metadata Resource metadata\r\n// _dataPoints Array of data point addresses\r\n// bytes32 The calculated ETag\r\nfunction calculateEtag(\r\n ResourceMetadata memory _metadata, \r\n bytes32[] memory _dataPoints\r\n) pure returns (bytes32) {\r\n return keccak256(abi.encode(_metadata, _dataPoints));\r\n}\r\n\r\n// ============ Gateway Contract ============\r\n/// @title Range Structure\r\n/// @notice Defines a range with start and end positions\r\n/// @dev Supports negative indices (counting from end)\r\nstruct Range {\r\n /// @notice Start position (negative means from end)\r\n int256 start;\r\n /// @notice End position (negative means from end, 0 means to end)\r\n int256 end;\r\n}\r\n\r\n/// @title LOCATE Request Structure\r\n/// @notice Extended request for LOCATE with chunk ranges\r\n/// @dev Allows requesting specific ranges of data point chunks\r\nstruct LOCATERequest {\r\n /// @notice Basic request information\r\n HEADRequest head;\r\n /// @notice Range of chunks to locate\r\n Range rangeChunks;\r\n}\r\n\r\nstruct DataPointSizes {\r\n uint256[] sizes;\r\n uint256 totalSize;\r\n}\r\n\r\nstruct ProcessedData {\r\n bytes data;\r\n DataPointSizes sizes;\r\n}\r\n\r\nstruct LOCATEResponseSecure {\r\n LOCATEResponse locate;\r\n DataPointSizes structure;\r\n}\r\n\r\n/// @title GET Request Structure\r\n/// @notice Extended request for GET with byte ranges\r\n/// @param locate The basic request information including path and conditional headers\r\n/// @param rangeBytes The range of bytes to retrieve\r\n/// @dev Allows requesting specific byte ranges of content\r\nstruct GETRequest {\r\n /// @notice Basic request information\r\n LOCATERequest locate;\r\n /// @notice Range of bytes to retrieve\r\n Range rangeBytes;\r\n}\r\n\r\n/// @title GET Response Structure\r\n/// @notice Contains response data for GET requests\r\n/// @dev Includes content data and metadata\r\nstruct GETResponse {\r\n /// @notice Base HEAD response\r\n HEADResponse head;\r\n /// @notice Content data\r\n ProcessedData body;\r\n}\r\n\r\n// ============ Constants ============\r\n\r\n// ============ Functions ============\r\nfunction maxMethods_() pure returns (uint16) {\r\n return uint16(type(Method).max) + 1;\r\n}\r\n\r\n/// @notice Normalizes an int256 range to be within the total length and positive\r\n/// automatically normalizes 0,0 to 0,totalLength\r\n/// @param range The range to normalize\r\n/// @param totalLength The total length of the resource\r\n/// @return The normalized range\r\nfunction normalizeRange_(\r\n Range memory range, \r\n uint256 totalLength\r\n) pure returns (Range memory) {\r\n int256 _length = int256(totalLength);\r\n\r\n // if range is -1, 0 treat as 0,0, since 0, 0 is treated as full range\r\n if (range.start == -1 && range.end == 0) {\r\n range.start = 0;\r\n range.end = 0;\r\n return range;\r\n }\r\n\r\n // if the range is 0,0, set the end to the last index for full range\r\n if (range.end == 0 && range.start == 0) {\r\n range.end = _length - 1;\r\n return range;\r\n }\r\n\r\n if (range.start < 0) {\r\n // start range is negative, reference from the end of the range\r\n range.start = _length - 1 + range.start;\r\n }\r\n // start should now be positive if the range wasn't out of bounds\r\n\r\n if (range.end < 0) {\r\n // end range is negative, reference from the end of the range\r\n range.end = _length - 1 + range.end;\r\n }\r\n // end should now be positive if the range wasn't out of bounds\r\n\r\n if (range.start > range.end + 1 || range.start < 0 || range.end > _length) {\r\n // +1 allows for a 0 length range: (5,4) would be valid but (6,4) is not\r\n revert _416(\"Out of Bounds\", range, _length);\r\n }\r\n\r\n return range;\r\n} \r\n\r\nfunction contentCode_(uint256 resourceSize, uint256 requestedSize) pure returns (uint16) {\r\n if (requestedSize == 0) {\r\n return 204;\r\n }\r\n if (requestedSize == resourceSize) {\r\n return 200;\r\n }\r\n return 206;\r\n}\r\n\r\n/// @notice Emitted when a DEFINE request is successful\r\n/// @param account The account or contract that made the request\r\n/// @param response The response data\r\nevent DEFINESuccess(address indexed account, DEFINEResponse response);\r\n\r\n/// @notice Emitted when a PUT request is successful\r\n/// @param account The account or contract that made the request\r\n/// @param response The response data\r\nevent PUTSuccess(address indexed account, LOCATEResponse response);\r\n\r\n/// @notice Emitted when a PATCH request is successful\r\n/// @param account The account or contract that made the request\r\n/// @param response The response data\r\nevent PATCHSuccess(address indexed account, LOCATEResponse response);\r\n\r\n/// @notice Emitted when a DELETE request is successful\r\n/// @param account The account or contract that made the request\r\n/// @param response The response data\r\nevent DELETESuccess(address indexed account, HEADResponse response);"},"contracts/BaseWTTPPermissions.sol":{"content":"/*\r\n * Web3 Transfer Protocol (WTTP) - BaseWTTPPermissions Contract\r\n * Copyright (C) 2025 TechnicallyWeb3\r\n * \r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License as published\r\n * by the Free Software Foundation, either version 3 of the License, or\r\n * (at your option) any later version.\r\n * \r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n * \r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see <https://www.gnu.org/licenses/>.\r\n */\r\n\r\n// SPDX-License-Identifier: AGPL-3.0\r\npragma solidity ^0.8.20;\r\n\r\nimport \"@openzeppelin/contracts/access/AccessControl.sol\";\r\nimport \"@wttp/core/contracts/types/WTTPTypes.sol\";\r\n\r\n/// @title WTTP Permissions Contract\r\n/// @author Web3 Tran