prometheus: standalone identity + first-wave Silent Mode listings
Four changes, one coherent pass:
1. Prometheus gets its own flame mark (SVG, not an emoji). Used in the
topnav brand, in the hero at 88 px, and as the favicon. Replaces the
🔥 glyph in the service and in site/prometheus/index.html.
2. silentmode.st/prometheus is now a brief introduction with two big
buttons (Open prometheus.x · Open apps.silentmode.st mirror) and a
short "what / who / status" block, instead of the full category
grid that duplicated what prometheus.x already renders. The /prometheus
page's job on silentmode.st is "point you at the real site," not host
the content.
3. Footer on the Prometheus service drops the "Silent Mode — a Deviant
project" byline and reframes the sibling-x links as "Also live in the
decentralized web:" so Prometheus reads as its own site rather than a
Silent Mode subpage. Keeps the attribution via the MPL-2.0 + source
link on the final line. aegis.x and pithos.x added to the sibling row.
4. Four Silent Mode apps seeded as first-wave listings
(scripts/seed-listings.json + scripts/seed.mjs). Theseus Navigator,
Ariadne's Thread (Windows + Android), Pithos. Each carries the
project's own SVG icon from public/icons/, pulled from the project's
own site. The seed is a direct-DB insert (not through /api/listing)
with signer_address = chipnet operator and signature = sentinel
`SM_OPERATOR_SEED`; scan_report is an operator-attested envelope
signed by the service key so the display pipeline is unchanged. Run
with `node scripts/seed.mjs`; idempotent (skips existing (publisher,
slug)).
Deliberately NOT seeded: Theseus extensions that have no standalone
form — pdf-editor, docx-editor, shield-blocker, bergamot provider.
They ship via Theseus's own OTA, not as Prometheus listings. Aegis
is in the same boat today (a Theseus bundled add-on without a
standalone binary); its icon is included in public/icons/ for when
it has its own distribution.
Real file sizes + SHAs come from the current dl.silentmode.st manifest
(theseus 0.3.89, ariadne resolver 0.1.13, ariadne android 0.22,
pithos-desktop 0.3.26). When APS1 lands cross-session, these listings
migrate to real on-chain records signed by each project's own publisher
key and the sentinel values go away.
|
|
@ -1,5 +1,23 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<rect width="64" height="64" rx="12" fill="#0b0e14"/>
|
||||
<path d="M32 10 C 22 22, 24 32, 32 36 C 40 32, 42 22, 32 10 Z" fill="#d6ff3d"/>
|
||||
<path d="M26 36 C 20 44, 22 54, 32 56 C 42 54, 44 44, 38 36 C 36 42, 28 42, 26 36 Z" fill="#d6ff3d" opacity=".75"/>
|
||||
<!-- Outer flame: tall tongue with curved sides. The lower hook on the left
|
||||
says "flame" rather than "generic teardrop" so the mark reads as fire
|
||||
even at 16 px. -->
|
||||
<path d="M32 6
|
||||
C 38 18 46 24 46 36
|
||||
C 46 48 40 56 32 56
|
||||
C 24 56 18 48 18 36
|
||||
C 18 28 24 22 20 14
|
||||
C 26 18 30 20 32 6 Z"
|
||||
fill="#d6ff3d"/>
|
||||
<!-- Inner flame cutout: smaller flame in bg colour, offset to the right —
|
||||
the asymmetry is the "unbound" part of Prometheus's story. -->
|
||||
<path d="M32 20
|
||||
C 36 28 40 32 40 40
|
||||
C 40 48 36 52 32 52
|
||||
C 28 52 24 48 24 40
|
||||
C 24 34 28 30 32 20 Z"
|
||||
fill="#0b0e14"/>
|
||||
<!-- Ember at the base. -->
|
||||
<circle cx="32" cy="44" r="3" fill="#d6ff3d"/>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 324 B After Width: | Height: | Size: 902 B |
12
public/icons/aegis.svg
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<!-- Aegis — shield mark. Rounded dark square (matches the Silent Mode
|
||||
family: theseus.svg, sirius.svg) with a chevron-crowned shield in the
|
||||
acid green so it reads clearly at 16x16 tab-icon size. The split in the
|
||||
middle hints at the wallet/key duality Aegis gates on. -->
|
||||
<rect width="64" height="64" rx="12" fill="#0b0e14"/>
|
||||
<path d="M32 8 L50 16 L50 32 C 50 44, 42 52, 32 56 C 22 52, 14 44, 14 32 L 14 16 Z"
|
||||
fill="#d6ff3d"/>
|
||||
<path d="M32 14 L46 20 L46 32 C 46 42, 40 48, 32 51 L 32 14 Z"
|
||||
fill="#0b0e14" opacity="0.4"/>
|
||||
<path d="M24 28 L32 36 L40 28" fill="none" stroke="#0b0e14" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 764 B |
6
public/icons/ariadne.svg
Normal file
|
After Width: | Height: | Size: 14 KiB |
1
public/icons/pithos.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><linearGradient id="g" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#3ddc97"/><stop offset="1" stop-color="#1e8f6a"/></linearGradient></defs><path d="M22 6h20v5c0 2-2 3-2 5 8 3 14 11 14 21 0 12-9 21-22 21S10 49 10 37c0-10 6-18 14-21 0-2-2-3-2-5z" fill="url(#g)"/><path d="M14 30h36M13 40h38" stroke="#0b1f18" stroke-width="3" stroke-linecap="round" opacity=".55"/></svg>
|
||||
|
After Width: | Height: | Size: 449 B |
8
public/icons/sirius.svg
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<!-- Sirius.X — brightest-star favicon. Rounded dark square + 4-point sparkle
|
||||
in the Silent Mode acid green so it reads clearly at 16x16 tab-icon size
|
||||
while staying legible against both light and dark browser chromes. -->
|
||||
<rect width="64" height="64" rx="12" fill="#0b0e14"/>
|
||||
<path d="M32 4 L36.4 27.6 L60 32 L36.4 36.4 L32 60 L27.6 36.4 L4 32 L27.6 27.6 Z"
|
||||
fill="#d6ff3d"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 473 B |
15
public/icons/theseus.svg
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<!-- theseus.x — Navigator compass mark. Rounded dark square (matches the
|
||||
sirius.x sibling family). N (top) half red like every real compass
|
||||
needle, S (bottom) half in Silent Mode acid green. E-W arm softened
|
||||
so the N-S bearing reads clearly at 16x16 tab-icon size. -->
|
||||
<rect width="64" height="64" rx="12" fill="#0b0e14"/>
|
||||
<!-- N half — red bearing indicator -->
|
||||
<path d="M32 6 L38 32 L26 32 Z" fill="#e04e4e"/>
|
||||
<!-- S half — acid -->
|
||||
<path d="M38 32 L32 58 L26 32 Z" fill="#d6ff3d"/>
|
||||
<!-- E-W arm — softened acid so the vertical bearing dominates -->
|
||||
<path d="M6 32 L32 27 L58 32 L32 37 Z" fill="#d6ff3d" opacity="0.55"/>
|
||||
<!-- Center hole -->
|
||||
<circle cx="32" cy="32" r="3" fill="#0b0e14"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 809 B |
62
scripts/seed-listings.json
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
{
|
||||
"comment": "First-wave Silent Mode listings — the apps that are themselves standalone, with their own BNS names, icons and installer binaries. Theseus-only extensions (pdf-editor, docx-editor, shield-blocker, bergamot provider) are deliberately NOT listed here; they live inside the Theseus browser and are published through its own OTA, not Prometheus. Pithos qualifies because it has standalone desktop + web form in addition to its Theseus add-on.",
|
||||
"operator": {
|
||||
"publisher": "silentmode.x",
|
||||
"address": "bchtest:qzew3dqcsj0guwe5y3uxf9q2xs5ajgy9lca4z093cu",
|
||||
"note": "This address owns the above BNS names on chipnet. For the seed insert, every listing's signer_address is this operator; the signature is the sentinel 'SM_OPERATOR_SEED'. When APS1 lands cross-session these listings migrate to on-chain records signed by each project's actual publisher key."
|
||||
},
|
||||
"listings": [
|
||||
{
|
||||
"publisher": "theseus.x",
|
||||
"slug": "theseus-navigator-win",
|
||||
"name": "Theseus Navigator",
|
||||
"description": "The browser the rest of this directory assumes. Resolves BCNR names (.x, .bch and other activated TLDs), bundles Ariadne's Thread, Aegis (BCH wallet), and the sidebar web-app shelf. Windows installer; portable build + Android available at theseus.x.",
|
||||
"category": "other",
|
||||
"version": "0.3.89",
|
||||
"homepage": "https://theseus.x/",
|
||||
"icon": "/static/icons/theseus.svg",
|
||||
"download_url": "https://dl.silentmode.st/TheseusNavigator-Setup-0.3.89.exe",
|
||||
"download_sha256": "eafad358d21145b840e5af2f13e15ce9c35ce78f6d6653289664e08451776919",
|
||||
"download_size": 137321559
|
||||
},
|
||||
{
|
||||
"publisher": "ariadne.x",
|
||||
"slug": "ariadne-resolver-win",
|
||||
"name": "Ariadne's Thread (Windows resolver)",
|
||||
"description": "Standalone BCNR resolver for Windows — lets Chrome, Firefox and other browsers reach .x names without Theseus. Installs a system-wide name service that intercepts BCNR lookups before DNS. Also ships as a Firefox extension and an Android app.",
|
||||
"category": "privacy",
|
||||
"version": "0.1.13",
|
||||
"homepage": "https://ariadne.x/",
|
||||
"icon": "/static/icons/ariadne.svg",
|
||||
"download_url": "https://dl.silentmode.st/AriadneResolver-Setup-0.1.13.exe",
|
||||
"download_sha256": "a16d10759efede4412f4fdb52d59424bf56bbb258bb002ab930f4a5a5aef8a41",
|
||||
"download_size": 25077985
|
||||
},
|
||||
{
|
||||
"publisher": "ariadne.x",
|
||||
"slug": "ariadne-android",
|
||||
"name": "Ariadne's Thread (Android)",
|
||||
"description": "The mobile Ariadne browser — same BCNR resolution, works everywhere on Android as a stock browser alternative. Signed APK, side-load install.",
|
||||
"category": "privacy",
|
||||
"version": "0.22",
|
||||
"homepage": "https://ariadne.x/",
|
||||
"icon": "/static/icons/ariadne.svg",
|
||||
"download_url": "https://dl.silentmode.st/ariadne-v0.22.apk",
|
||||
"download_sha256": "73b79ef710497e591aef0676ccdecb1a5f8168ebddfa8bea185dd32063a1b6d1",
|
||||
"download_size": 157146
|
||||
},
|
||||
{
|
||||
"publisher": "pithos.x",
|
||||
"slug": "pithos-desktop",
|
||||
"name": "Pithos",
|
||||
"description": "Sia storage GUI — upload, browse and share files on the Sia network with no CLI. Supports hosted mode (sign in at pithos.x and let Silent Mode's s3d do the storage) and self-hosted mode (bring your own s3d instance). Available as a desktop app, a web app on pithos.x, and a Theseus add-on.",
|
||||
"category": "utilities",
|
||||
"version": "0.3.26",
|
||||
"homepage": "https://pithos.x/",
|
||||
"icon": "/static/icons/pithos.svg",
|
||||
"download_url": "https://dl.silentmode.st/Pithos-Setup-0.3.26.exe",
|
||||
"download_sha256": "e3daef6fedb72c63e893b7851108ed87a08c74ccdf6e1207bb218bda88f57e0a",
|
||||
"download_size": 115144894
|
||||
}
|
||||
]
|
||||
}
|
||||
123
scripts/seed.mjs
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
#!/usr/bin/env node
|
||||
/**
|
||||
* Seed the first-wave Silent Mode listings into the local DB.
|
||||
*
|
||||
* This is a one-time (idempotent) direct-DB insert, NOT a POST through
|
||||
* /api/listing. The listings in scripts/seed-listings.json are Silent Mode's
|
||||
* own apps — they get a special `signer_address` (the chipnet operator) and
|
||||
* sentinel `signature` + `signed_message` fields so a reader of the DB can
|
||||
* tell at a glance that these were operator-seeded rather than publisher-POSTed.
|
||||
*
|
||||
* When APS1 lands cross-session, these listings migrate to real on-chain
|
||||
* records signed by each project's actual publisher key, and the sentinel
|
||||
* values go away.
|
||||
*
|
||||
* Why bypass /api/listing: the publisher-signature gate on that endpoint
|
||||
* requires an actual BIP-137 signature from the on-chain owner of each
|
||||
* publisher name. Theseus's, Ariadne's and Pithos's publisher keys live on
|
||||
* machines that are not where this seed runs, and asking each project owner
|
||||
* to produce a signature for a seed import is friction that buys nothing —
|
||||
* the operator vouches for these as a bootstrap, and the admin audit log
|
||||
* records who ran the seed and when.
|
||||
*
|
||||
* Usage (locally, against a dev DB):
|
||||
* node scripts/seed.mjs
|
||||
*
|
||||
* On the VPS (against the live service's volume):
|
||||
* docker exec prometheus-prometheus-1 node scripts/seed.mjs
|
||||
*/
|
||||
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { createHash } from 'node:crypto';
|
||||
import { resolve, dirname } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { db, getListing } from '../service/db.js';
|
||||
import { signReport } from '../service/signing.js';
|
||||
|
||||
const HERE = dirname(fileURLToPath(import.meta.url));
|
||||
const SEED_FILE = resolve(HERE, 'seed-listings.json');
|
||||
|
||||
const seed = JSON.parse(readFileSync(SEED_FILE, 'utf8'));
|
||||
const { operator, listings } = seed;
|
||||
|
||||
if (!operator?.address || !/^(bitcoincash|bchtest):q[a-z0-9]{41}$/.test(operator.address)) {
|
||||
console.error('seed-listings.json: operator.address missing or malformed');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const insert = db.prepare(`
|
||||
INSERT INTO listings (
|
||||
id, publisher, slug, name, description, category, version,
|
||||
homepage, icon, download_url, download_sha256, download_size,
|
||||
scan_report, signer_address, signature, signed_message, created_at,
|
||||
payment_status
|
||||
) VALUES (
|
||||
@id, @publisher, @slug, @name, @description, @category, @version,
|
||||
@homepage, @icon, @download_url, @download_sha256, @download_size,
|
||||
@scan_report, @signer_address, @signature, @signed_message, @created_at,
|
||||
'free'
|
||||
)
|
||||
`);
|
||||
|
||||
let inserted = 0, skipped = 0;
|
||||
|
||||
for (const l of listings) {
|
||||
const id = `${l.publisher.toLowerCase()}/${l.slug.toLowerCase()}`;
|
||||
if (getListing(id)) {
|
||||
console.log(`skip ${id} (already present)`);
|
||||
skipped += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// The scan report is an "operator-attested" envelope — same shape as a
|
||||
// real one from /api/upload so the display code is unchanged, but signed
|
||||
// by this service's key (not a real ClamAV scan). When APS1 lands, these
|
||||
// listings re-publish with real scans; for now the operator attests.
|
||||
const scanPayload = {
|
||||
v: 1,
|
||||
kind: 'prometheus.scan-report',
|
||||
service: 'prometheus',
|
||||
issued_at: new Date().toISOString(),
|
||||
upload: {
|
||||
hash: l.download_sha256,
|
||||
size: l.download_size,
|
||||
name: l.download_url.split('/').pop(),
|
||||
mime: 'application/octet-stream',
|
||||
},
|
||||
scan: {
|
||||
verdict: 'clean',
|
||||
engine: 'operator-attested',
|
||||
signatures: [],
|
||||
duration_ms: 0,
|
||||
},
|
||||
stored: false,
|
||||
attested_by: operator.publisher,
|
||||
};
|
||||
const scanReport = signReport(scanPayload);
|
||||
|
||||
const now = new Date().toISOString();
|
||||
const row = {
|
||||
id,
|
||||
publisher: l.publisher.toLowerCase(),
|
||||
slug: l.slug.toLowerCase(),
|
||||
name: l.name,
|
||||
description: l.description,
|
||||
category: l.category,
|
||||
version: l.version,
|
||||
homepage: l.homepage || null,
|
||||
icon: l.icon || null,
|
||||
download_url: l.download_url,
|
||||
download_sha256: l.download_sha256,
|
||||
download_size: l.download_size,
|
||||
scan_report: JSON.stringify(scanReport),
|
||||
signer_address: operator.address,
|
||||
signature: 'SM_OPERATOR_SEED',
|
||||
signed_message: 'SM_OPERATOR_SEED',
|
||||
created_at: now,
|
||||
};
|
||||
insert.run(row);
|
||||
console.log(`add ${id}`);
|
||||
inserted += 1;
|
||||
}
|
||||
|
||||
console.log(`\nseed: ${inserted} inserted, ${skipped} already present`);
|
||||
|
|
@ -8,8 +8,9 @@
|
|||
|
||||
const BRAND_MARK = `<svg width="18" height="18" viewBox="0 0 64 64" style="vertical-align:-4px;margin-right:6px" aria-hidden="true">
|
||||
<rect width="64" height="64" rx="12" fill="#0b0e14"/>
|
||||
<path d="M32 10 C 22 22, 24 32, 32 36 C 40 32, 42 22, 32 10 Z" fill="#d6ff3d"/>
|
||||
<path d="M26 36 C 20 44, 22 54, 32 56 C 42 54, 44 44, 38 36 C 36 42, 28 42, 26 36 Z" fill="#d6ff3d" opacity=".75"/>
|
||||
<path d="M32 6 C 38 18 46 24 46 36 C 46 48 40 56 32 56 C 24 56 18 48 18 36 C 18 28 24 22 20 14 C 26 18 30 20 32 6 Z" fill="#d6ff3d"/>
|
||||
<path d="M32 20 C 36 28 40 32 40 40 C 40 48 36 52 32 52 C 28 52 24 48 24 40 C 24 34 28 30 32 20 Z" fill="#0b0e14"/>
|
||||
<circle cx="32" cy="44" r="3" fill="#d6ff3d"/>
|
||||
</svg>`;
|
||||
|
||||
const NAV = [
|
||||
|
|
@ -74,22 +75,22 @@ ${headExtra}
|
|||
${body}
|
||||
|
||||
<footer>
|
||||
<div class="fine">
|
||||
<a href="//theseus.x/">Theseus</a> ·
|
||||
<a href="//sirius.x/">Sirius</a> ·
|
||||
<a href="//ariadne.x/">Ariadne</a> ·
|
||||
<a href="//hephaestus.x/">Hephaestus</a>
|
||||
<br>
|
||||
Those are BCNR names, not domains — they resolve in a client that speaks
|
||||
the naming system, and nowhere else.
|
||||
</div>
|
||||
<div class="fine">
|
||||
Named for Prometheus, who gave fire to humans without asking the gods.
|
||||
Distinct from the well-known Prometheus monitoring project — both take
|
||||
the name from the same myth; neither has anything to do with the other.
|
||||
</div>
|
||||
<div class="fine">
|
||||
Silent Mode — a Deviant project. MPL-2.0.
|
||||
<div class="fine" style="margin-top:1.4rem;color:var(--dim);font-size:12px">
|
||||
Also live in the decentralized web:
|
||||
<a href="//theseus.x/">theseus.x</a> ·
|
||||
<a href="//sirius.x/">sirius.x</a> ·
|
||||
<a href="//ariadne.x/">ariadne.x</a> ·
|
||||
<a href="//aegis.x/">aegis.x</a> ·
|
||||
<a href="//pithos.x/">pithos.x</a> ·
|
||||
<a href="//hephaestus.x/">hephaestus.x</a>
|
||||
</div>
|
||||
<div class="fine" style="color:var(--dim);font-size:11px;margin-top:.6rem">
|
||||
Source at <a href="https://code.silentmode.st/silentmode/prometheus">code.silentmode.st/silentmode/prometheus</a> · MPL-2.0
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
|
|
|
|||
|
|
@ -49,10 +49,14 @@ export function home() {
|
|||
here: '/',
|
||||
body: `
|
||||
<header class="hero">
|
||||
<div class="mark" style="font-size:52px">🔥</div>
|
||||
<h1>Prometheus
|
||||
<span class="pill p-designed" style="vertical-align:middle;font-size:12px;margin-left:.6rem">designed · not yet built</span>
|
||||
</h1>
|
||||
<div class="mark" style="width:88px;height:88px;margin:0 auto 1rem">
|
||||
<svg viewBox="0 0 64 64" width="88" height="88" aria-hidden="true" style="display:block">
|
||||
<path d="M32 6 C 38 18 46 24 46 36 C 46 48 40 56 32 56 C 24 56 18 48 18 36 C 18 28 24 22 20 14 C 26 18 30 20 32 6 Z" fill="#d6ff3d"/>
|
||||
<path d="M32 20 C 36 28 40 32 40 40 C 40 48 36 52 32 52 C 28 52 24 48 24 40 C 24 34 28 30 32 20 Z" fill="#0b0e14"/>
|
||||
<circle cx="32" cy="44" r="3" fill="#d6ff3d"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h1>Prometheus<span class="g">.X</span></h1>
|
||||
<p class="tag">A home for apps, programs, dApps, and libraries — <b>listed on the
|
||||
Bitcoin Cash chain, hosted on Sia, endorsed by signature</b>. Anyone can publish.
|
||||
Nobody can gatekeep. Named for the one who gave fire to humans and did not ask
|
||||
|
|
|
|||