--- eip: 8278 title: Service Objects description: An ERC-721 extension for service manifests, operators, and payment routes. author: MeltedMindz (@MeltedMindz) discussions-to: https://ethereum-magicians.org/t/erc-8278-service-objects/28659 status: Draft type: Standards Track category: ERC created: 2026-05-28 requires: 165, 721 --- ## Abstract This ERC defines an [ERC-721](./eip-721.md) extension for service objects. A service object exposes a service manifest, a service operator, and a payment route consisting of a revenue recipient, payment manifest URI, payment manifest hash, and route nonce. This ERC does not define service discovery, reputation, validation, payment settlement, endpoint execution, smart account behavior, or any particular offchain service protocol. ## Motivation A transferable token can represent control over an offchain service, but existing token interfaces do not expose the operational and payment-route state that clients need before interacting with that service. This ERC standardizes a small read interface and event set so indexers, service clients, and payment middleware can resolve current service metadata without relying on a centralized registry. ## Specification The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119. A compliant contract MUST implement [ERC-721](./eip-721.md) and [ERC-165](./eip-165.md). The [ERC-165](./eip-165.md) interface ID for the following interface is `0xf94c99e5`. ```solidity interface IERCServiceObject is IERC165 { event ServiceManifestUpdated( uint256 indexed serviceId, string uri, bytes32 indexed manifestHash ); event ServiceOperatorUpdated( uint256 indexed serviceId, address indexed operator, uint64 expiresAt ); event ServicePaymentRouteUpdated( uint256 indexed serviceId, address indexed revenueRecipient, string paymentURI, bytes32 indexed paymentManifestHash, uint64 routeNonce ); function serviceManifest(uint256 serviceId) external view returns (string memory uri, bytes32 manifestHash); function serviceOperator(uint256 serviceId) external view returns (address operator, uint64 expiresAt); function servicePaymentRoute(uint256 serviceId) external view returns ( address revenueRecipient, string memory paymentURI, bytes32 paymentManifestHash, uint64 routeNonce ); } ``` `serviceId` is the [ERC-721](./eip-721.md) `tokenId`. `ownerOf(serviceId)` is the service owner. `serviceManifest(serviceId)` returns a URI and `keccak256` hash of the exact bytes of the current service manifest. `serviceOperator(serviceId)` returns the current service operator and expiry. A zero operator means no operator is specified. A zero expiry means no expiry is specified. `servicePaymentRoute(serviceId)` returns the current revenue recipient, payment manifest URI, payment manifest hash, and route nonce. The route nonce MUST change when the revenue recipient or payment manifest hash changes. The payment manifest MAY describe x402 payment routes, but x402 is not required by this ERC. The service manifest MAY describe MCP endpoints or capability documents, but MCP is not required by this ERC. ## Rationale [ERC-721](./eip-721.md) is used for ownership because wallets, marketplaces, and indexers already understand [ERC-721](./eip-721.md) transfers and metadata. The payment route groups revenue recipient, payment manifest, and route nonce so clients can read the state needed to validate an offchain payment offer with one call. The service operator is separate from [ERC-721](./eip-721.md) approvals because marketplace approvals are transfer permissions, not service operation permissions. URI/hash commitments are used instead of onchain endpoint arrays because service metadata can be large and mutable. ## Backwards Compatibility This ERC is opt-in and does not change [ERC-721](./eip-721.md) behavior. Contracts that do not implement this interface remain ordinary [ERC-721](./eip-721.md) contracts. Existing service assets can expose this interface directly or through a wrapper that also exposes the required [ERC-721](./eip-721.md) ownership semantics. A later profile may define how the same service semantics are exposed by an [ERC-7656](./eip-7656.md)-linked service contract. ## Test Cases Test cases are included in the reference implementation. ## Reference Implementation A reference implementation is available at `https://github.com/MeltedMindz/erc-service-object/tree/v0.1.0`. ## Security Considerations This ERC does not prove service quality, availability, endpoint honesty, payment finality, or legal rights. It only exposes current route and manifest commitments. Clients MUST treat manifest URI contents as untrusted until the fetched bytes match the onchain hash. Payment clients SHOULD verify that offchain payment offers match the current payment route before authorizing payment. Marketplaces SHOULD include service manifest hash, payment manifest hash, revenue recipient, service operator, and route nonce in sale-order review or warnings. ## Copyright Copyright and related rights waived via [CC0](../LICENSE.md).