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

430 lines
23 KiB
Markdown

# 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