Skip to content

salazarsebas/datalog

 
 

Repository files navigation

Datalog

A decentralized knowledge base built on Arkiv.

Datalog lets you create documentation spaces, write pages in Markdown, and own your content through wallet-based ownership. All data lives on-chain as Arkiv entities -- no traditional database, no centralized storage.

Think GitBook or Notion, but every document is an on-chain entity with wallet-bound ownership and built-in expiration.

Built for the Arkiv Web3 Database Builders Challenge -- Knowledge Base vertical.

Live Demo


Features

Feature Description
Knowledge Spaces Group related documentation into named spaces with description and icon
Markdown Pages Full GFM Markdown support with live preview, code blocks with copy button, and auto-generated table of contents
Page Tree Nested pages via parentPageKey attribute, rendered as a collapsible GitBook-style sidebar
Version History Every edit snapshots the previous content as a Revision entity on Arkiv
Bookmarks Readers can save pages for quick reference
Expiration Management All entities expire -- visible badges with one-click extend
Public Read Access Anyone can browse spaces and read pages without a wallet
Wallet Ownership Authors own their content via Ethereum wallet; only the owner can edit or archive
Status Lifecycle Pages transition between draft, published, and archived states

Arkiv Integration

Datalog uses Arkiv as its sole data layer. There is no database, no file storage, no backend state outside of on-chain entities.

Entity Design

The application defines 4 entity types, each with distinct expiration durations reflecting their real-world lifecycle:

Space (365 days)
  |
  +-- Page (180 days)
  |     |
  |     +-- Page (nested, 180 days)
  |     |
  |     +-- Revision (30 days)
  |
  +-- Bookmark (90 days)
Entity Attributes Payload Expiration Rationale
Space type, name, slug, status JSON (name, description, icon) 365 days Spaces are long-lived containers; a year gives authors time to maintain them
Page type, spaceKey, parentPageKey, title, slug, status, order, version Markdown content 180 days Documentation pages need periodic review; 6 months balances longevity with freshness
Revision type, pageKey, version, summary, timestamp Markdown snapshot 30 days Edit history is useful short-term; old revisions can expire without data loss
Bookmark type, pageKey, spaceKey JSON (note) 90 days Bookmarks are personal references; 3 months is enough to revisit or let go

Query Patterns

All queries use the SDK's predicate-based query builder with eq() from @arkiv-network/sdk/query:

Operation Query
List active spaces eq("type", "space"), eq("status", "active")
Pages in a space eq("type", "page"), eq("spaceKey", key), eq("status", "published")
Draft pages eq("type", "page"), eq("spaceKey", key), eq("status", "draft")
Search by title eq("type", "page"), eq("title", query), eq("status", "published")
Page revisions eq("type", "revision"), eq("pageKey", key)
All bookmarks eq("type", "bookmark")

Every query chains .withAttributes(), .withPayload(), and .withMetadata() to fetch complete entity data.

Ownership Model

  • Writes use a server-side wallet client (private key in .env). The wallet owner is the author of all entities.
  • Reads use a public client -- no wallet required. Anyone can browse spaces, read pages, and search.
  • Entity ownership is enforced by Arkiv: only the wallet that created an entity can update or extend it.

Advanced Features

  • Status lifecycle transitions: draft -> published -> archived (pages), active -> archived (spaces)
  • Entity updates with revision tracking: editing a page creates a Revision entity with the previous content, then updates the page with new content and incremented version
  • Expiration extension: owners can extend any entity's expiration via the /api/extend endpoint
  • Bookmark as entity: bookmarks are themselves Arkiv entities with their own expiration, demonstrating that even user preferences live on-chain

Tech Stack

Layer Technology
Framework Next.js 15 (App Router, Server Components)
Language TypeScript (strict mode)
Styling Tailwind CSS v4 + @tailwindcss/typography
Data layer Arkiv via @arkiv-network/sdk v0.6.0+
Markdown react-markdown + remark-gfm
Package manager Bun
Testnet Arkiv Kaolin

Getting Started

Prerequisites

  • Bun v1.0+ (or Node.js 18+)
  • An Ethereum wallet with test ETH from the Kaolin faucet

Installation

git clone https://github.com/YOUR_USERNAME/datalog.git
cd datalog
bun install

Configuration

cp .env.example .env

Edit .env with your wallet credentials:

PRIVATE_KEY=0xYOUR_PRIVATE_KEY_HERE
ADDRESS=0xYOUR_ADDRESS_HERE

You can generate a new wallet using any Ethereum wallet tool. Then request test ETH from the Kaolin faucet.

Development

bun dev

Open http://localhost:3000.

Production Build

bun run build
bun start

Project Structure

datalog/
  src/
    app/                          # Next.js App Router
      page.tsx                    # Landing page (hero + featured spaces)
      spaces/
        page.tsx                  # Browse all spaces
        [spaceKey]/
          layout.tsx              # Space layout with sidebar
          page.tsx                # Space overview
          [pageKey]/
            page.tsx              # Page reader (Markdown + TOC)
      author/
        page.tsx                  # Author dashboard
        spaces/
          new/page.tsx            # Create space form
          [spaceKey]/
            page.tsx              # Manage space + pages
            pages/
              new/page.tsx        # Markdown editor (create)
              [pageKey]/edit/     # Markdown editor (edit)
      search/page.tsx             # Search results
      api/                        # REST API routes
        spaces/                   # POST create, GET list
        pages/                    # POST create, PUT update, DELETE archive
        bookmarks/                # POST create, DELETE remove
        search/                   # GET search by title
        extend/                   # POST extend expiration
    components/
      ExpirationBadge.tsx         # Color-coded expiration with extend button
      LoadingSkeleton.tsx         # Animated loading placeholders
      PageContent.tsx             # Markdown renderer with code copy
      PageEditor.tsx              # Write/preview editor with tabs
      PageTree.tsx                # Recursive nested page sidebar
      SearchBar.tsx               # Search input with navigation
      SpaceCard.tsx               # Space card + grid components
      TableOfContents.tsx         # Auto-generated from headings
      Toast.tsx                   # Success/error notifications
    lib/
      arkiv/                      # Arkiv SDK abstraction layer
        client.ts                 # Public + wallet client setup
        constants.ts              # Expiration durations (4 values)
        types.ts                  # TypeScript interfaces
        spaces.ts                 # Space CRUD operations
        pages.ts                  # Page CRUD + search + lifecycle
        revisions.ts              # Revision creation + queries
        bookmarks.ts              # Bookmark CRUD
        extend.ts                 # Entity expiration extension
        index.ts                  # Barrel exports
      utils.ts                    # Address truncation, date formatting
  challenge-context/              # Original challenge documentation

User Flows

Reader (no wallet required)

  1. Browse -- Visit the landing page or /spaces to see all active knowledge spaces
  2. Read -- Click into a space, navigate the page tree, read Markdown content
  3. Search -- Use the search bar to find pages by title
  4. Bookmark -- Save a page for later (creates a Bookmark entity)

Author (wallet required via .env)

  1. Create Space -- Go to Author > New Space, fill in name/description/icon
  2. Create Page -- Inside a space, create pages with the Markdown editor (write + preview)
  3. Nest Pages -- Set parentPageKey to create sub-pages (tree navigation)
  4. Edit Page -- Edit content; previous version is saved as a Revision entity
  5. Manage Lifecycle -- Publish drafts, archive old content, extend expirations
  6. Archive -- Archive spaces or pages (status transition, still on-chain)

API Reference

Method Endpoint Description
GET /api/spaces List all active spaces
POST /api/spaces Create a new space
GET /api/spaces/:key Get a single space
DELETE /api/spaces/:key Archive a space
POST /api/pages Create a new page
GET /api/pages/:key Get a single page
PUT /api/pages/:key Update page content (creates revision) or change status
DELETE /api/pages/:key Archive a page
GET /api/search?q=term Search pages by title
GET /api/bookmarks List all bookmarks
POST /api/bookmarks Create a bookmark
DELETE /api/bookmarks Remove a bookmark
POST /api/extend Extend an entity's expiration

Live Demo

https://datalog.vercel.app/

Deployed on Vercel. All reads happen server-side via Arkiv's public client; writes go through API routes using the server wallet.


License

MIT

About

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • TypeScript 90.3%
  • Shell 5.2%
  • CSS 3.3%
  • Python 1.1%
  • JavaScript 0.1%