Architecture

Simple Page is designed to give you control, without sacrificing user experience.


Home | User Guide | About


Overview

SimplePage operates as a three-tier decentralized system:

  1. Smart Contracts (Ethereum): Manage page subscriptions, indexing coordination, and ENS integration
  2. Frontend Application (Web): User interface for content creation, editing, and publishing
  3. DService node (Indexer + IPFS): Handle content storage, retrieval, and blockchain indexing

Data Flow

User writes content (in Frontend) → Content is uploaded (to DService) → ENS contenthash update (in Frontend) → Content available globally (your ENS name)

Smart Contracts

The platform is built on three core smart contracts deployed on Ethereum:

SimplePage

  • Purpose: Main contract managing pages and storage units
  • Functionality:
    • Mints an NFTs representing page
    • NFT contains number of Units with their expiry dates
    • The most recent patron of a page becomes the NFT owner

Currently the Simple Page system only utilizes a single unit for every page. In the future multiple units could be used to allow for larger storage quotas.

SimplePageManager

  • Purpose: Handles subscription purchases
  • Functionality:
    • Manages storage unit purchases and expiration
    • Handles subscription renewals
    • Handles price conversion (fees are priced in USD, but payed in ETH)

TokenRenderer

  • Purpose: Renders NFT metadata as SVG
  • Functionality:
    • Renders an SVG on-chain when the SimplePage NFT tokenURI is queried

DService (Decentralized Service)

A Node.js backend service that bridges smart contracts with IPFS storage:

Core Functionality

Indexer Service

  • Monitors SimplePage contract events for new page registrations
  • Tracks ENS contenthash updates for registered domains
  • Synchronizes blockchain state with IPFS storage
  • Retrieves page data from other nodes over IPFS

API Service

  • Provides REST endpoints for page operations
  • Handles page uploads with CAR (Content Addressable aRchive) files
  • Generates automatic OpenAPI documentation
  • Manages allow/block lists for domains

Key Endpoints

  • GET: /page?cid=<content-id> - Retrieve page content
  • POST: /page?domain=<ens-name> - Upload new page
  • GET: /info - Service information
  • GET: /docs - Interactive API documentation

DService ENS Record

In order to mitigate the centralization vector of hard coding the API into the SimplePage frontend, an ENS text record is used. Briefly, an array of indexer URLs (currently only simplepg.org) are stored in the dservice ENS TEXT record. When the frontend is loaded it fetches these endpoints using the Ethereum RPC API. This DService endpoint is currently stored on the new.simplepage.eth domain.

Frontend

A React-based web application with modern UI/UX:

Core Features

  • Markdown Editor: Live preview with syntax highlighting
  • Web3 Integration: Wallet connection via Wagmi and Viem
  • Page Management: Create, edit, and organize multiple pages
  • Subscription Dashboard: Manage storage units and payments
  • Fork System: Remix any existing SimplePage site
  • Static HTML: Your website will render even if your users have javascript disabled

Data Structure

SimplePage uses a hierarchical file system structure stored on IPFS, with each page represented by both markdown and HTML files:

Root Directory Structure:
├── index.md              # Home page markdown
├── index.html            # Home page HTML
├── about/
│   ├── index.md          # About page markdown
│   └── index.html        # About page HTML
├── blog/
│   ├── index.md          # Blog index markdown
│   ├── index.html        # Blog index HTML
│   └── post/
│       ├── index.md      # Blog post markdown
│       └── index.html    # Blog post HTML
├── _template.html        # HTML template for all pages
├── _redirects            # URL redirects configuration
├── manifest.webmanifest  # Web app manifest
└── _prev/
    └── 0/               # Previous version
        ├── index.md
        ├── index.html
        └── about/
            ├── index.md
            └── index.html

Page Storage Pattern

Dual File Format
Every page is stored in two formats:

  • index.md: Raw markdown content with frontmatter metadata, this is the content which the user edits
  • index.html: Rendered HTML with populated template

Path Structure

  • Pages use URL-style paths (e.g., /, /about/, /blog/post/)
  • Each path corresponds to a directory containing index.md and index.html
  • The root page is stored directly in the root directory
  • Nested pages create nested directory structures

Template System

  • _template.html: Master HTML template used for all pages
  • Template is populated with page content, metadata, and navigation
  • Each page's HTML is generated by combining template + markdown content
  • New version of the _template.html and other files get published on new.simplepage.eth, during the publishing process the user is prompted to upgrade their site if a new Simple Page version is available

Version History System

_prev Directory Structure
The _prev directory maintains a recursive version history of the repository:

Current Repository Root:
├── index.md              # Current version
├── index.html
├── about/
│   ├── index.md
│   └── index.html
└── _prev/
    └── 0/               # Previous version
        ├── index.md
        ├── index.html
        ├── about/
        │   ├── index.md
        │   └── index.html
        └── _prev/
            └── 0/       # Even older version (recursive structure)
                ├── index.md
                └── index.html

Version Management Process

  1. Current State: The active repository root contains the latest version
  2. Commit Process: When changes are committed:
    • Current root is copied to _prev/0/
    • Previous versions remain in their existing _prev/0/ structure
    • New content becomes the new root
  3. Recursive History: Each version contains its own _prev/0/ pointing to the previous version
  4. Rollback Capability: Any previous version can be accessed by following the _prev/0/ chain

Version Naming Convention

  • _prev/0/: Always points to the previous version
  • Currently only /0/ is supported, but numbered for future expansion
  • Future versions may support multiple previous versions (e.g., /1/, /2/) for scenarios like:
    • Fork and merge workflows
    • Multiple parallel development branches
    • Conflict resolution with multiple parent versions

Recursive Structure Benefits

  • Complete History: Every version maintains its own history chain
  • Efficient Access: Direct access to any previous version
  • Branch Support: Future support for multiple previous versions
  • Immutable History: Previous versions cannot be modified

Content Addressing

IPFS Integration

  • All content is stored using IPFS Content Identifiers (CIDs)
  • Each file and directory has a unique cryptographic hash
  • Content is immutable - changes create new CIDs
  • Directory structures are represented as IPFS DAGs

CAR File Format

  • Content is distributed as CAR (Content Addressable aRchive) files
  • CAR files contain all blocks needed to reconstruct the file system
  • Efficient for uploading/downloading entire repositories
  • Includes only necessary blocks, excluding previous versions

Metadata and Configuration

Page Metadata

  • Stored in markdown frontmatter (YAML format)
  • Includes title, description, and possible future extensions
  • Automatically parsed and used in HTML generation

Site Configuration

  • manifest.webmanifest: Web app configuration
  • _redirects: URL redirection rules
  • _template.html: Master template for all pages

Special Directories

  • _prev/: Version history
  • _assets/: Various assets needed by the application
  • _css/: Default styling for SimplePage
  • _js/: Application javascript code

Developer CLI Tool

A command-line interface for advanced users and developers:

Features

  • Static Webapp Support: Host any static web application on ENS domains
  • Direct Publishing: Deploy content directly from local directories
  • CAR File Generation: Creates efficient IPFS uploads
  • Subscription Management: Check and manage domain subscriptions

Usage Example

# Publish a static website
npx @simplepg/cli publish myapp.eth ./dist

# Check subscription status
npx @simplepg/cli info myapp.eth