Skip to content
This repository was archived by the owner on Jun 29, 2025. It is now read-only.
/ anchorPDS Public archive

A specialized ATProto server for check-in records, providing location-based social features for the Anchor ecosystem.

Notifications You must be signed in to change notification settings

dropanchorapp/anchorPDS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

5 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Note: I'm archiving this experiment and consider the ideas herein outdated after some solid feedback on Bluesky, an alternative approach based on the community feedback is in the works. Feel free to poke at what's here i will leave it up as a failed research experiment but it is no longer going to be maintained.

Anchor Personal Data Server (PDS)

Tests

A specialized ATProto server for check-in records, providing location-based social features for the Anchor ecosystem.

This PDS powers the backend infrastructure for Drop Anchor - an experimental location-based social network built on the AT Protocol. While Drop Anchor provides the user interface and client experience, this PDS handles the storage, federation, and API endpoints for check-in records.

πŸš€ Live Service

Production URL: https://anchorpds.val.run/

πŸ“‹ Current Features (Phase 1)

Core Functionality

  • Check-in Records: Create and store location-based check-ins using ATProto standard
  • Authentication: Token validation via home PDS integration
  • Federation: Full AT Protocol compliance for external client support
  • Global Feed: View recent check-ins from all users (max 100 records)
  • User Feed: View your own check-in history with pagination

ATProto Endpoints

  • POST /xrpc/com.atproto.repo.createRecord - Create check-in records
  • GET /xrpc/com.atproto.sync.getRecord - Retrieve individual records

Anchor-Specific Endpoints

  • GET /xrpc/app.dropanchor.listCheckins - List user's check-ins (authenticated)
  • GET /xrpc/app.dropanchor.getGlobalFeed - Global feed of recent check-ins
  • GET /health - Service health check

πŸ—„οΈ Data Model

Check-in Records (v3 Schema)

Each check-in follows the AT Protocol lexicon standard with structured location data:

{
  "$type": "app.dropanchor.checkin",
  "text": "Great coffee and climbing session!",
  "createdAt": "2025-06-27T10:30:00Z",
  "locations": [
    {
      "$type": "community.lexicon.location.geo",
      "latitude": "40.7128",
      "longitude": "-74.0060"
    },
    {
      "$type": "community.lexicon.location.address",
      "name": "Brooklyn Boulders",
      "street": "123 Main St",
      "locality": "New York",
      "region": "NY",
      "country": "US",
      "postalCode": "10001"
    }
  ],
  "category": "climbing",
  "categoryGroup": "Sports & Fitness",
  "categoryIcon": "πŸ§—β€β™‚οΈ"
}

Core Fields

  • text: Message or venue name (required)
  • createdAt: ISO timestamp (required)
  • locations: Array of community.lexicon.location.* objects (optional)

Location Objects

  • geo: GPS coordinates with latitude/longitude as strings
  • address: Structured address with name, street, locality, region, country, postalCode

Categorization (Optional)

  • category: OpenStreetMap category value
  • categoryGroup: Human-readable group name
  • categoryIcon: Unicode emoji representing the category

Place Categorization

The PDS supports rich categorization based on OpenStreetMap standards with 11 custom category groups:

Anchor Category Groups

  1. 🍽️ Food & Drink - Restaurants, cafes, bars, food courts
  2. 🎭 Entertainment - Cinemas, theaters, nightlife, gaming
  3. πŸƒβ€β™‚οΈ Sports & Fitness - Gyms, climbing, swimming, sports venues
  4. πŸ›οΈ Shopping - Retail stores, markets, malls, specialty shops
  5. 🏨 Accommodation - Hotels, hostels, guesthouses, camping
  6. 🚌 Transportation - Stations, airports, public transport
  7. πŸ›οΈ Services - Banks, government, professional services
  8. 🌳 Nature & Parks - Parks, gardens, nature reserves, outdoor recreation
  9. 🎨 Culture - Museums, galleries, historic sites, libraries
  10. πŸ₯ Health - Hospitals, clinics, pharmacies, healthcare
  11. πŸ“š Education - Schools, universities, educational facilities

OpenStreetMap Integration

Categories map to OSM tags and values from these primary keys:

  • amenity - Community facilities (66+ categories)
  • leisure - Recreation and sports (40+ categories)
  • shop - Retail and commercial (88+ categories)
  • tourism - Tourist attractions and services (27+ categories)

For detailed category mappings, see OSM Map Features.

Storage

  • SQLite database with proper indexing for performance
  • Optimized for queries by author, timestamp, location, and categories
  • User settings for feed preferences

πŸ” Authentication

Uses ATProto token validation:

  • Accepts Bearer tokens from any compatible PDS
  • Validates tokens against home PDS (bsky.social, staging.bsky.dev)
  • In-memory caching for performance (1-hour TTL)

πŸ› οΈ Technology Stack

  • Runtime: Deno on Val Town platform
  • Framework: Hono web framework
  • Database: Val Town hosted SQLite
  • Protocol: AT Protocol (ATProto) compliant
  • Language: TypeScript with full type safety

πŸ“¦ API Usage

Create a Check-in

curl -X POST https://anchorpds.val.run/xrpc/com.atproto.repo.createRecord \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "collection": "app.dropanchor.checkin",
    "record": {
      "text": "Great coffee at the local cafΓ©!",
      "createdAt": "2024-01-15T10:30:00Z",
      "locations": [
        {
          "$type": "community.lexicon.location.geo",
          "latitude": "40.7128",
          "longitude": "-74.0060"
        },
        {
          "$type": "community.lexicon.location.address",
          "name": "Central Perk CafΓ©",
          "street": "199 Lafayette St",
          "locality": "New York",
          "region": "NY",
          "country": "US"
        }
      ],
      "category": "cafe",
      "categoryGroup": "Food & Drink",
      "categoryIcon": "β˜•"
    }
  }'

Get Global Feed

curl https://anchorpds.val.run/xrpc/app.dropanchor.getGlobalFeed?limit=10

Get Your Check-ins

curl https://anchorpds.val.run/xrpc/app.dropanchor.listCheckins \
  -H "Authorization: Bearer YOUR_TOKEN"

πŸ”„ Pagination

All feed endpoints support cursor-based pagination:

  • limit: Number of records to return (default: 50, max: 100)
  • cursor: Timestamp for pagination (optional)

πŸ§ͺ Testing

Comprehensive test suite covering validation, database operations, and integration:

deno test test/

Tests include validation of the v3 schema with categories, community lexicon location formats, and API endpoint functionality.

πŸ—οΈ Development

Requirements

  • Deno runtime
  • Val Town CLI (vt)
  • TypeScript knowledge

Local Development

# Type checking
deno check --allow-import backend/index.ts

# Linting
deno lint

# Testing
deno test tests/

# Formatting
deno fmt

Deployment

Uses Val Town platform for hosting:

vt push

🚧 Roadmap

Phase 2: Enhanced Features

  • Geospatial "nearby" queries with radius search
  • Optional feed cross-posting to home PDS
  • Advanced location filtering

Phase 3: Social Interactions

  • Likes support via Bluesky API proxy
  • Direct check-in comments
  • Social interaction feeds

πŸ“„ License

MIT License - See LICENSE file for details

🀝 Contributing

This is a specialized PDS implementation. For contributions:

  1. Follow Val Town development guidelines
  2. Maintain ATProto compliance
  3. Include comprehensive tests
  4. Use TypeScript with proper types

πŸ“ž Support

For issues or questions about the Anchor PDS implementation, please file an issue in the repository.

About

A specialized ATProto server for check-in records, providing location-based social features for the Anchor ecosystem.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published