Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 126 additions & 0 deletions ERCS/erc-8278.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
---
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).
Loading