# 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

```rust
/// 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

```bash
# 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

```yaml
# 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)

```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
