synor/docs/ARCHITECTURE_HOSTING.md
Gulshan Yadav a70b2c765c feat(hosting): add Synor Hosting subdomain-based web hosting
Add synor-hosting crate for decentralized web hosting with:

- Name Registry: On-chain name→CID mapping with ownership, expiry,
  and custom domain linking
- Domain Verification: CNAME/TXT DNS verification for custom domains
- Hosting Router: Host-based routing with SPA support, redirects,
  and custom headers
- synor.json: Project configuration for build, routes, and error pages

Users can deploy to myapp.synor.cc and optionally link custom domains.

23 tests passing.
2026-01-10 12:34:07 +05:30

23 KiB

Synor Hosting Architecture

Decentralized web hosting powered by Synor Storage Layer.

Overview

Synor Hosting enables users to deploy web applications to permanent, censorship-resistant infrastructure with human-readable URLs. It combines:

  • Synor Storage L2: Decentralized content storage
  • Name Registry: On-chain name → CID mapping
  • Enhanced Gateway: Subdomain-based routing with SSL
  • Custom Domains: User-owned domain integration

User Journey

┌─────────────────────────────────────────────────────────────────────────┐
│                           Deployment Flow                                │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  1. BUILD                    2. UPLOAD                3. REGISTER        │
│  ─────────────               ─────────────            ─────────────      │
│  $ next build                $ synor upload           $ synor register   │
│  $ synor pack                  ./out                    myfirstapp       │
│                                    │                         │           │
│                                    ▼                         ▼           │
│                              CID: synor1abc...         TX confirmed      │
│                                                                          │
│  4. ACCESS                                                               │
│  ─────────────                                                           │
│  https://myfirstapp.synor.network  ──────────────────────▶  Your App!   │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

Architecture Components

1. Name Registry (On-Chain)

The name registry is a smart contract on Synor L1 that maps human-readable names to CIDs.

┌─────────────────────────────────────────────────────────────────┐
│                      Name Registry Contract                      │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  Names Table                                                     │
│  ┌────────────────┬──────────────────┬───────────────────────┐  │
│  │ Name           │ Owner            │ CID                   │  │
│  ├────────────────┼──────────────────┼───────────────────────┤  │
│  │ myfirstapp     │ synor1user123... │ synor1abc789xyz...    │  │
│  │ coolsite       │ synor1user456... │ synor1def012uvw...    │  │
│  │ myportfolio    │ synor1user789... │ synor1ghi345rst...    │  │
│  └────────────────┴──────────────────┴───────────────────────┘  │
│                                                                  │
│  Custom Domains Table                                            │
│  ┌────────────────────┬────────────────┬─────────────────────┐  │
│  │ Domain             │ Name           │ Verified            │  │
│  ├────────────────────┼────────────────┼─────────────────────┤  │
│  │ myfirstapp.com     │ myfirstapp     │ true                │  │
│  │ www.coolsite.io    │ coolsite       │ true                │  │
│  └────────────────────┴────────────────┴─────────────────────┘  │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

Contract Interface

/// Name Registry Contract
pub trait NameRegistry {
    /// Register a new name (must be unique, pay registration fee)
    fn register(name: String, cid: ContentId) -> Result<()>;

    /// Update CID for a name you own (deploy new version)
    fn update(name: String, new_cid: ContentId) -> Result<()>;

    /// Transfer ownership to another address
    fn transfer(name: String, new_owner: Address) -> Result<()>;

    /// Resolve name to CID
    fn resolve(name: String) -> Option<ContentId>;

    /// Add custom domain (requires verification)
    fn add_custom_domain(name: String, domain: String) -> Result<()>;

    /// Verify custom domain ownership
    fn verify_domain(name: String, domain: String, proof: DomainProof) -> Result<()>;

    /// Remove custom domain
    fn remove_custom_domain(name: String, domain: String) -> Result<()>;

    /// Resolve custom domain to name
    fn resolve_domain(domain: String) -> Option<String>;
}

Name Rules

Rule Description
Length 3-63 characters
Characters a-z, 0-9, hyphen (not at start/end)
Reserved synor, admin, api, gateway, www, etc.
Fee Registration fee + annual renewal
Grace Period 30 days after expiry before release

2. Enhanced Gateway

The gateway routes requests based on the Host header instead of just the path.

┌─────────────────────────────────────────────────────────────────────────┐
│                          Gateway Routing Flow                            │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  Incoming Request                                                        │
│  ─────────────────                                                       │
│  GET / HTTP/1.1                                                          │
│  Host: myfirstapp.synor.network                                          │
│                                                                          │
│         │                                                                │
│         ▼                                                                │
│  ┌─────────────────┐                                                     │
│  │ Extract Host    │                                                     │
│  │ header          │                                                     │
│  └────────┬────────┘                                                     │
│           │                                                              │
│           ▼                                                              │
│  ┌─────────────────┐     ┌─────────────────┐                            │
│  │ Is it           │ YES │ Parse subdomain │                            │
│  │ *.synor.network?├────▶│ "myfirstapp"    │                            │
│  └────────┬────────┘     └────────┬────────┘                            │
│           │ NO                    │                                      │
│           ▼                       ▼                                      │
│  ┌─────────────────┐     ┌─────────────────┐                            │
│  │ Check custom    │     │ Query Name      │                            │
│  │ domain table    │     │ Registry        │                            │
│  └────────┬────────┘     └────────┬────────┘                            │
│           │                       │                                      │
│           ▼                       ▼                                      │
│  ┌─────────────────────────────────────────┐                            │
│  │         Resolve to CID                   │                            │
│  │         synor1abc789xyz...               │                            │
│  └────────────────────┬────────────────────┘                            │
│                       │                                                  │
│                       ▼                                                  │
│  ┌─────────────────────────────────────────┐                            │
│  │         Fetch from Storage              │                            │
│  │         Serve with correct MIME type    │                            │
│  └─────────────────────────────────────────┘                            │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

SPA Routing

For Single Page Applications (React, Next.js, Vue, etc.), the gateway handles client-side routing:

Request: GET /dashboard/settings
Host: myfirstapp.synor.network

1. Try exact path: /dashboard/settings → Not found
2. Try with .html: /dashboard/settings.html → Not found
3. Check if SPA (has index.html): Yes
4. Serve index.html with 200 (not redirect)
5. Client-side router handles /dashboard/settings

3. SSL/TLS Management

┌─────────────────────────────────────────────────────────────────────────┐
│                         SSL Certificate Strategy                         │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  Synor Domains (*.synor.network)                                         │
│  ─────────────────────────────────                                       │
│  • Wildcard certificate: *.synor.network                                 │
│  • Single cert covers all subdomains                                     │
│  • Auto-renewed via Let's Encrypt                                        │
│                                                                          │
│  Custom Domains                                                          │
│  ─────────────────────────────────                                       │
│  • On-demand certificate generation                                      │
│  • Let's Encrypt HTTP-01 or DNS-01 challenge                            │
│  • Stored in distributed cache                                           │
│  • Auto-renewal 30 days before expiry                                    │
│                                                                          │
│  Certificate Storage                                                     │
│  ─────────────────────────────────                                       │
│  • Encrypted at rest                                                     │
│  • Replicated across gateway nodes                                       │
│  • Hot-reload without restart                                            │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

4. Custom Domain Verification

Users must prove domain ownership before linking to their Synor name.

┌─────────────────────────────────────────────────────────────────────────┐
│                      Domain Verification Flow                            │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  Step 1: Request Verification                                            │
│  ─────────────────────────────                                           │
│  $ synor domain add myfirstapp.com                                       │
│                                                                          │
│  Response:                                                               │
│  ┌─────────────────────────────────────────────────────────────────┐    │
│  │ To verify ownership of myfirstapp.com, add ONE of:              │    │
│  │                                                                  │    │
│  │ Option A: CNAME Record                                          │    │
│  │   myfirstapp.com  CNAME  myfirstapp.synor.network              │    │
│  │                                                                  │    │
│  │ Option B: TXT Record                                            │    │
│  │   _synor.myfirstapp.com  TXT  "synor-verify=abc123xyz789"      │    │
│  │                                                                  │    │
│  │ Then run: synor domain verify myfirstapp.com                    │    │
│  └─────────────────────────────────────────────────────────────────┘    │
│                                                                          │
│  Step 2: Add DNS Record (User action)                                    │
│  ─────────────────────────────────────                                   │
│  User adds record at their DNS provider (Cloudflare, Route53, etc.)      │
│                                                                          │
│  Step 3: Verify                                                          │
│  ─────────────                                                           │
│  $ synor domain verify myfirstapp.com                                    │
│                                                                          │
│  Gateway checks:                                                         │
│  1. DNS lookup for CNAME or TXT record                                   │
│  2. Verify record matches expected value                                 │
│  3. Submit verification proof to L1                                      │
│  4. Issue SSL certificate                                                │
│                                                                          │
│  ✓ Domain verified! myfirstapp.com → myfirstapp.synor.network           │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

URL Patterns

Pattern Example Description
CID Path gateway.synor.cc/synor1abc... Direct CID access
Subdomain myfirstapp.synor.network Registered name
Custom Domain myfirstapp.com User's own domain
Path in App myfirstapp.synor.network/dashboard SPA routing

CLI Commands

# Upload and get CID
synor upload ./dist
# Output: Uploaded! CID: synor1abc789xyz...

# Register a name
synor register myapp
# Output: Name "myapp" registered to synor1abc789xyz...

# Update deployment (new version)
synor upload ./dist --name myapp
# Output: Updated! myapp now points to synor1def012...

# Add custom domain
synor domain add myapp.com
# Output: Add CNAME record, then run: synor domain verify myapp.com

# Verify domain
synor domain verify myapp.com
# Output: ✓ Domain verified!

# Check status
synor status myapp
# Output:
#   Name: myapp
#   CID: synor1abc789xyz...
#   URL: https://myapp.synor.network
#   Custom Domains:
#     - myapp.com (verified)
#     - www.myapp.com (pending)

Pricing Model

Service Cost Notes
Name Registration 10 SYNOR One-time
Annual Renewal 5 SYNOR Per year
Storage Per deal pricing See storage tiers
Custom Domain Free Unlimited per name
SSL Certificate Free Auto-managed
Bandwidth Free* Fair use policy

*Heavy usage may require staking or premium tier.

DNS Configuration

Synor Infrastructure

# Wildcard for all subdomains
*.synor.network    A       <gateway-cluster-ip>
*.synor.network    AAAA    <gateway-cluster-ipv6>

# Gateway load balancer
gateway.synor.cc   A       <gateway-cluster-ip>
g.synor.cc         CNAME   gateway.synor.cc

User Custom Domain

# Option 1: CNAME (recommended)
myapp.com          CNAME   myapp.synor.network

# Option 2: A record (if CNAME not supported at apex)
myapp.com          A       <gateway-cluster-ip>

# For www subdomain
www.myapp.com      CNAME   myapp.synor.network

Deployment Types

Static Sites

# Supported frameworks
- Next.js (static export)
- React (CRA, Vite)
- Vue.js
- Svelte/SvelteKit
- Astro
- Hugo, Jekyll, 11ty
- Plain HTML/CSS/JS

Configuration File (synor.json)

{
  "name": "myapp",
  "build": {
    "command": "npm run build",
    "output": "dist"
  },
  "routes": {
    "/*": "/index.html"
  },
  "headers": {
    "/*": {
      "Cache-Control": "public, max-age=31536000, immutable"
    },
    "/index.html": {
      "Cache-Control": "no-cache"
    }
  },
  "redirects": [
    { "from": "/old-page", "to": "/new-page", "status": 301 }
  ]
}

Security Considerations

Name Squatting Prevention

  • Minimum registration fee discourages mass registration
  • Trademark dispute resolution process
  • Reserved names for common terms

Phishing Protection

  • Confusable name detection (l vs 1, O vs 0)
  • Warning for names similar to popular sites
  • Report mechanism for malicious content

Content Moderation

  • Gateway operators can block CIDs (not remove from storage)
  • Multiple gateways ensure censorship resistance
  • Hash-based blocking list shared among operators

Implementation Phases

Phase 1: Name Registry (2 weeks)

  • Name registry smart contract
  • CLI commands: register, update, transfer
  • Basic gateway subdomain routing

Phase 2: Enhanced Gateway (2 weeks)

  • Host-based routing
  • SPA support (fallback to index.html)
  • Custom headers and redirects
  • Caching layer

Phase 3: Custom Domains (2 weeks)

  • Domain verification (CNAME/TXT)
  • On-demand SSL certificates
  • Certificate storage and renewal

Phase 4: Developer Experience (1 week)

  • synor.json configuration
  • CI/CD integration examples
  • GitHub Actions deployment

Comparison

Feature Synor Hosting Vercel Netlify IPFS+ENS
Decentralized
Custom Domains
Auto SSL
Serverless Functions Future
Censorship Resistant
Pay Once, Host Forever
Native Blockchain

Future Enhancements

  1. Synor Functions: Serverless compute layer
  2. Database Integration: Decentralized database for dynamic apps
  3. Analytics: Privacy-preserving usage analytics
  4. Team Collaboration: Multi-user access to names
  5. Staging Environments: Preview deployments before going live