prometheus: SEO polish and the apps.silentmode.st mirror vhost
layout gained three optional fields: ogType, ogImage, headExtra. The
listing detail page uses all three — ogType=article, ogImage=the icon
URL (fallback to the Prometheus favicon), and headExtra for schema.org
SoftwareApplication JSON-LD. Google renders this as a rich card for
app results; the SEO uplift is real and the data is straightforward.
JSON-LD payload composed in service/seo.js:
@type SoftwareApplication, name, description, softwareVersion,
applicationCategory (mapped from Prometheus's slug to schema's name),
url, downloadUrl, fileSize, offers (free), author (BNS name as org),
image (icon when present), contentRating ("ClamAV clean" on a clean
scan).
OG defaults for every page: og:type (website unless overridden),
og:image (favicon unless overridden). The canonical URL stays
prometheus.x on both the live service and the apps.silentmode.st
mirror — crawlers that land on the mirror attribute the content to
the real address, matching the pattern [[silentmode-site-url-scheme]]
describes.
deploy/apps-silentmode-st.conf is the angie vhost for the mirror:
reverse-proxies to 127.0.0.1:3700, declines /admin (operator always
goes direct), 2 GiB client_max_body_size for POST /api/upload,
proxy_request_buffering off so a slow upload does not spool to disk.
Reuses the main silentmode.st certificate (SAN *.silentmode.st; if
that's not set up yet, request one and reload before enabling).
2026-10-08 21:45:59 +02:00
|
|
|
# apps.silentmode.st — SEO-friendly read-only mirror of prometheus.x.
|
|
|
|
|
#
|
|
|
|
|
# Prometheus's real home is the BCNR name `prometheus.x`, served from this
|
|
|
|
|
# VPS via the name's `ip`+`tls` records. Search engines can't resolve `.x`,
|
|
|
|
|
# so this subdomain exists specifically to be crawled: it reverse-proxies to
|
|
|
|
|
# the same service and the response's `rel=canonical` already names
|
|
|
|
|
# `prometheus.x` as the authoritative URL — Googlebot indexes the content
|
|
|
|
|
# but attributes it to the real address.
|
|
|
|
|
#
|
|
|
|
|
# This is the same practice theseus.x and ariadne.x use via their
|
|
|
|
|
# conventional-DNS mirrors; see [[silentmode-site-url-scheme]] for the
|
|
|
|
|
# family's URL convention.
|
|
|
|
|
#
|
|
|
|
|
# POST endpoints (publish, admin, login) are proxied too — operator admin
|
|
|
|
|
# over https works via this hostname as a backup. For the typical sign-in
|
|
|
|
|
# flow we still prefer prometheus.x directly from Theseus.
|
|
|
|
|
|
|
|
|
|
server {
|
|
|
|
|
listen 443 ssl;
|
|
|
|
|
listen [::]:443 ssl;
|
|
|
|
|
http2 on;
|
|
|
|
|
server_name apps.silentmode.st;
|
|
|
|
|
|
|
|
|
|
# Reuse the main silentmode.st certificate (it covers *.silentmode.st when
|
|
|
|
|
# that SAN is set up). If it isn't, request one and reload angie.
|
|
|
|
|
ssl_certificate /etc/letsencrypt/live/silentmode.st/fullchain.pem;
|
|
|
|
|
ssl_certificate_key /etc/letsencrypt/live/silentmode.st/privkey.pem;
|
|
|
|
|
|
|
|
|
|
# No agent, no cookies lost in transit — we want the proxy to be a thin
|
|
|
|
|
# pipe so what the live service sends is what the crawler reads.
|
|
|
|
|
location / {
|
|
|
|
|
proxy_pass http://127.0.0.1:3700;
|
|
|
|
|
proxy_http_version 1.1;
|
|
|
|
|
proxy_set_header Host $host;
|
|
|
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
|
|
|
proxy_set_header X-Forwarded-Proto https;
|
|
|
|
|
proxy_set_header X-Forwarded-Host apps.silentmode.st;
|
|
|
|
|
|
prometheus: size-tiered pricing, 2 GiB cap, new hero copy, SEO LD
Three threads, one commit:
1. Size-tiered listing fee instead of a flat $1
priceUsdForSize(bytes) in service/payments.js:
0 - 100 MiB → free
100.001 - 200 MiB → $1
200.001 - 300 MiB → $2
...
1900.001 - 2000 MiB → $19
2000.001 - 2048 MiB → $20 (ceiling at 2 GiB)
listingNeedsPayment(bytes) replaces paymentsRequired() — a free-tier
upload always publishes immediately even when PAYMENT_REQUIRED=1; the
operator switch only governs the paid tiers. createInvoice derives the
fee from the listing's own size at invoice time.
2. Upload cap back to 2 GiB
The 200-MiB cap from the previous commit (which fixed the Caddy-413
HTML bug) is reverted. The paywall is now the real size gate; Caddy
is just the ceiling. p2pexchange Caddyfile already updated + reloaded.
3. Hero + SEO
Hero leads with the plain-English product category:
The decentralized app store.
A home for apps, programs, dApps, and libraries — listed and settled
on the Bitcoin Cash chain, hosted on the decentralized web, endorsed
by signature. Anyone can publish. Nobody can gatekeep.
Named for the one who gave fire to humans and did not ask the gods first.
"hosted on Sia" → "hosted on the decentralized web". Sia is the
mechanism, not the pitch — general readers aren't tripped on the
acronym on the hero.
Meta description rewritten to lead with "decentralized app store" and
name the long-tail terms the audience searches for ("web3 browsers",
"BCH wallets", "mobile and desktop apps").
Two JSON-LD blocks (WebSite + Organization) inlined on home via
layout's headExtra channel — knowledge panel + WebSite result card.
4. Submit wizard
Step 1 result shows the computed listing fee under the scan verdict,
so publishers see the price BEFORE filling out the manifest.
Step 4 publish branches on the server's payment_required flag. On a
paid listing it POSTs /api/invoice right after the listing POST and
renders a payment card with the exact sat amount, the operator receive
address, a `bitcoincash:` URI the wallet opens, and the invoice status
URL for polling.
2026-10-22 23:31:43 +03:00
|
|
|
# Matches the service's 2 GiB upload cap. The paywall (free below
|
|
|
|
|
# 100 MiB, $1/USD per 100 MiB above) is the real size gate.
|
|
|
|
|
client_max_body_size 2g;
|
prometheus: SEO polish and the apps.silentmode.st mirror vhost
layout gained three optional fields: ogType, ogImage, headExtra. The
listing detail page uses all three — ogType=article, ogImage=the icon
URL (fallback to the Prometheus favicon), and headExtra for schema.org
SoftwareApplication JSON-LD. Google renders this as a rich card for
app results; the SEO uplift is real and the data is straightforward.
JSON-LD payload composed in service/seo.js:
@type SoftwareApplication, name, description, softwareVersion,
applicationCategory (mapped from Prometheus's slug to schema's name),
url, downloadUrl, fileSize, offers (free), author (BNS name as org),
image (icon when present), contentRating ("ClamAV clean" on a clean
scan).
OG defaults for every page: og:type (website unless overridden),
og:image (favicon unless overridden). The canonical URL stays
prometheus.x on both the live service and the apps.silentmode.st
mirror — crawlers that land on the mirror attribute the content to
the real address, matching the pattern [[silentmode-site-url-scheme]]
describes.
deploy/apps-silentmode-st.conf is the angie vhost for the mirror:
reverse-proxies to 127.0.0.1:3700, declines /admin (operator always
goes direct), 2 GiB client_max_body_size for POST /api/upload,
proxy_request_buffering off so a slow upload does not spool to disk.
Reuses the main silentmode.st certificate (SAN *.silentmode.st; if
that's not set up yet, request one and reload before enabling).
2026-10-08 21:45:59 +02:00
|
|
|
proxy_request_buffering off;
|
|
|
|
|
|
|
|
|
|
# The service's own long-cache headers decide for static assets; this
|
|
|
|
|
# proxy does not add any additional caching layer.
|
|
|
|
|
proxy_buffering off;
|
|
|
|
|
proxy_read_timeout 120s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Deny the admin via the mirror — the operator always goes direct to
|
|
|
|
|
# prometheus.x. Removes one scanner's worth of noise against /admin.
|
|
|
|
|
location ^~ /admin {
|
|
|
|
|
return 404;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
server {
|
|
|
|
|
listen 80;
|
|
|
|
|
listen [::]:80;
|
|
|
|
|
server_name apps.silentmode.st;
|
|
|
|
|
return 301 https://$host$request_uri;
|
|
|
|
|
}
|