diff --git a/README.md b/README.md index 335e2d60..a9e26095 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ The complete on-chain price catalogue is exposed via `FilecoinWarmStorageService ## Service metadata -FilecoinWarmStorageService implements `IFilecoinServiceMetadata`, exposing a `name()` and `description()` for `eth_call`. Other FOC services are encouraged to use this interface so explorers and clients can identify service operator contracts without hard-coded address maps. Consumers should note that this output should be treated as untrusted data and should only ever be presented to users in carefully escaped form. +FilecoinWarmStorageService implements `IFilecoinServiceMetadata`, exposing `name()`, `description()`, and `homepage()` for `eth_call`. Other FOC services are encouraged to use this interface so explorers and clients can identify service operator contracts without hard-coded address maps. `description()` is capped at 256 bytes and should be treated as untrusted display-only text. `homepage()` is an optional URL, capped at 256 bytes, and returns an empty string when not provided. Consumers should validate metadata from unverified contracts and carefully escape all displayed values. ## 🚀 Quick Start @@ -148,4 +148,3 @@ See [service_contracts/CONTRIBUTING.md](./service_contracts/CONTRIBUTING.md) for ## 📄 License Dual-licensed under [MIT](https://github.com/FilOzone/filecoin-services/blob/main/LICENSE.md) + [Apache 2.0](https://github.com/FilOzone/filecoin-services/blob/main/LICENSE.md) - diff --git a/service_contracts/README.md b/service_contracts/README.md index a9886673..fbfa2d2e 100644 --- a/service_contracts/README.md +++ b/service_contracts/README.md @@ -7,7 +7,7 @@ This directory contains the smart contracts for different Filecoin services usin - `src/` - Contract source files - `FilecoinWarmStorageService.sol` - A service contract with [PDP](https://github.com/FilOzone/pdp) (Proof of Data Possession) and payment integration - `FilecoinWarmStorageServiceStateView.sol` - View contract for reading `FilecoinWarmStorageService` with `eth_call`. - - `IFilecoinServiceMetadata.sol` - Minimal service identity interface (`name`, `description`) + - `IFilecoinServiceMetadata.sol` - Minimal service identity interface (`name`, `description`, `homepage`) - `src/lib` - Library source files - `FilecoinWarmStorageServiceLayout.sol` - Constants conveying the storage layout of `FilecoinWarmStorageService` - `FilecoinWarmStorageServiceStateInternalLibrary.sol` - `internal` library for embedding logic to read `FilecoinWarmStorageService` diff --git a/service_contracts/abi/FilecoinWarmStorageService.abi.json b/service_contracts/abi/FilecoinWarmStorageService.abi.json index 34f26e07..987d6677 100644 --- a/service_contracts/abi/FilecoinWarmStorageService.abi.json +++ b/service_contracts/abi/FilecoinWarmStorageService.abi.json @@ -367,6 +367,19 @@ ], "stateMutability": "view" }, + { + "type": "function", + "name": "homepage", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string", + "internalType": "string" + } + ], + "stateMutability": "pure" + }, { "type": "function", "name": "initialize", diff --git a/service_contracts/abi/IFilecoinServiceMetadata.abi.json b/service_contracts/abi/IFilecoinServiceMetadata.abi.json index 6e02a462..87ba388e 100644 --- a/service_contracts/abi/IFilecoinServiceMetadata.abi.json +++ b/service_contracts/abi/IFilecoinServiceMetadata.abi.json @@ -12,6 +12,19 @@ ], "stateMutability": "view" }, + { + "type": "function", + "name": "homepage", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string", + "internalType": "string" + } + ], + "stateMutability": "view" + }, { "type": "function", "name": "name", diff --git a/service_contracts/src/FilecoinWarmStorageService.sol b/service_contracts/src/FilecoinWarmStorageService.sol index c44624e6..00b67caa 100644 --- a/service_contracts/src/FilecoinWarmStorageService.sol +++ b/service_contracts/src/FilecoinWarmStorageService.sol @@ -84,6 +84,7 @@ contract FilecoinWarmStorageService is string private constant SERVICE_NAME = "Filecoin Warm Storage Service"; string private constant SERVICE_DESCRIPTION = "Warm storage service for the Filecoin Onchain Cloud. Manages PDP-backed datasets, Filecoin Pay storage rails, lifecycle fees, and optional CDN payment rails."; + string private constant SERVICE_HOMEPAGE = "https://github.com/FilOzone/filecoin-services"; using Rails for FilecoinPayV1; @@ -404,6 +405,10 @@ contract FilecoinWarmStorageService is return SERVICE_DESCRIPTION; } + function homepage() external pure override returns (string memory) { + return SERVICE_HOMEPAGE; + } + function announcePlannedUpgrade(PlannedUpgrade calldata plannedUpgrade) external onlyOwner { require(plannedUpgrade.nextImplementation.code.length > 3000); require(plannedUpgrade.afterEpoch > block.number); diff --git a/service_contracts/src/IFilecoinServiceMetadata.sol b/service_contracts/src/IFilecoinServiceMetadata.sol index 958cb23e..eda72b74 100644 --- a/service_contracts/src/IFilecoinServiceMetadata.sol +++ b/service_contracts/src/IFilecoinServiceMetadata.sol @@ -4,9 +4,16 @@ pragma solidity ^0.8.20; /// @title IFilecoinServiceMetadata /// @notice Minimal service identity interface for Filecoin Onchain Cloud service contracts. interface IFilecoinServiceMetadata { - /// @notice Human-readable service name. + /// @notice Short, human-readable service name. function name() external view returns (string memory); - /// @notice Human-readable service description. + /// @notice Concise, human-readable service description. + /// @dev Implementations must limit the UTF-8 encoded value to 256 bytes. + /// Consumers should treat the value as untrusted display-only text. function description() external view returns (string memory); + + /// @notice Optional URL for service documentation, specifications, or source code. + /// @dev Implementations must limit the UTF-8 encoded value to 256 bytes and + /// return an empty string when no homepage is provided. + function homepage() external view returns (string memory); } diff --git a/service_contracts/test/FilecoinWarmStorageService.t.sol b/service_contracts/test/FilecoinWarmStorageService.t.sol index 2a91e9f4..28620cb7 100644 --- a/service_contracts/test/FilecoinWarmStorageService.t.sol +++ b/service_contracts/test/FilecoinWarmStorageService.t.sol @@ -337,6 +337,7 @@ contract FilecoinWarmStorageServiceTest is MockFVMTest { IFilecoinServiceMetadata metadata = IFilecoinServiceMetadata(address(pdpServiceWithPayments)); string memory serviceName = metadata.name(); string memory serviceDescription = metadata.description(); + string memory serviceHomepage = metadata.homepage(); assertEq(serviceName, "Filecoin Warm Storage Service", "Service name should match"); assertEq( @@ -344,6 +345,9 @@ contract FilecoinWarmStorageServiceTest is MockFVMTest { "Warm storage service for the Filecoin Onchain Cloud. Manages PDP-backed datasets, Filecoin Pay storage rails, lifecycle fees, and optional CDN payment rails.", "Service description should match" ); + assertEq(serviceHomepage, "https://github.com/FilOzone/filecoin-services", "Service homepage should match"); + assertLe(bytes(serviceDescription).length, 256, "Service description should not exceed 256 bytes"); + assertLe(bytes(serviceHomepage).length, 256, "Service homepage should not exceed 256 bytes"); } function testUpgrade() public {