Skip to content

1001-digital/observations

Repository files navigation

-------------------------------------
|                                   |
|     ·  ·  ·  ·  ·  ·  ●  ·  ·     |
|     ·  ·  ·  ·  ·  ·  ·  ·  ·     |
|     ·  ●  ·  ·  ·  ·  ·  ·  ·     |
|     ·  ·  ·  ·  ●  ·  ·  ·  ·     |
|     ·  ·  ·  ·  ·  ·  ·  ·  ●     |
|     ·  ·  ●  ·  ·  ·  ·  ·  ·     |
|     ·  ·  ·  ·  ·  ·  ·  ●  ·     |
|     ·  ●  ·  ·  ·  ●  ·  ·  ·     |
|     ·  ·  ·  ●  ·  ·  ·  ·  ·     |
|                                   |
-------------------------------------

Observations

Leave observations on any ERC-721 or ERC-1155 artifact.

Observations is a minimal, permissionless protocol for annotating NFTs. Anyone can leave a text observation on any token — optionally pinned to specific coordinates on the artifact itself. All observations are emitted as events, making them free to write and easy to index.

Inspired by Sam Spratt's The Monument Game.

Contract

The core of the protocol is a single Solidity contract: Observations.sol.

observe

Leave a text observation on a token.

function observe(
    address collection,
    uint256 tokenId,
    uint64 parent,
    bool update,
    string calldata note,
    uint8 viewType,
    uint32 time
) external payable

observeAt

Leave an observation pinned to a specific location on the artifact.

function observeAt(
    address collection,
    uint256 tokenId,
    uint64 parent,
    bool update,
    string calldata note,
    int32 x,
    int32 y,
    uint8 viewType,
    uint32 time
) external payable

Events

Every observation emits a single event:

event Observation(
    address indexed collection,
    uint256 indexed tokenId,
    address indexed observer,
    uint64 id,
    uint64 parent,
    bool update,
    string note,
    bool located,
    int32 x,
    int32 y,
    uint8 viewType,
    uint32 time,
    uint256 tip
)

The collection and tokenId are indexed, so you can efficiently filter observations for a specific artifact. The observer is also indexed, so you can query all observations left by a given address. Each observation gets a sequential id scoped to the artifact.

Edits and Deletions

Observations can be edited or deleted by their original author by submitting a new observation with parent set to the target observation's id and update=true.

  • Edit: observe(collection, tokenId, parent=targetId, update=true, "new note", ...) — replaces the content of the target observation.
  • Delete: observe(collection, tokenId, parent=targetId, update=true, "", ...) — an empty note signals deletion.

Only the original observer of the target observation may edit or delete it. The update event is always recorded as its own observation (preserving full event history), but indexers should apply the update to the parent and exclude the update record from display. parent=0 with update=false is a regular top-level observation.

State

The contract tracks a lightweight Artifact record per token:

struct Artifact {
    uint64 count;       // total number of observations
    uint128 firstBlock; // block of the first observation
}

Readable via:

mapping(address => mapping(uint256 => Artifact)) public artifacts;

This is the only on-chain state. Observation content lives in event logs.

Packages

This is a monorepo managed with pnpm workspaces.

Package Description Status
packages/contract Solidity contract, tests, and deployment Ready
packages/indexer Ponder-based indexer for all observations In progress
packages/ui UI components for creating and viewing observations In progress

Contract

Built with Hardhat 3 and viem.

cd packages/contract
npx hardhat test

Indexer

A Ponder indexer that watches for Observation events and stores them in a queryable database with a GraphQL API.

UI

A Nuxt app providing embeddable components for hosting observation interfaces — create observations, browse observations on a given artifact, and view observation locations on token media.

Setup

pnpm install

License

MIT

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published