Paid episodes: - server/services/cashu.ts: self-custodied Cashu wallet against a configured mint (NUT-04 mint quote -> bolt11 invoice -> mint/store proofs -> LNURL-pay payout on withdraw). Buyers pay a plain Lightning invoice, no Cashu wallet needed on their end. - routes/marketplace.ts: purchase/confirm flow, download-url paywall gate, reseller certification/revocation, earnings ledger + withdraw. - services/marketplace.ts: producer + certified-reseller source resolution, with a naive per-seller sales-count reputation signal. Discovery: - services/rss.ts: <podsteadr:source> RSS tag on priced episodes (producer + resellers, price, sales count, url) so pricing/sources are discoverable straight from the feed, not just a separate API call. Locked episodes point their <enclosure> at an info page instead of the raw file. - routes/feeds.ts: /catalog.opml lists every podcast this instance hosts, for peer podsteadr servers or any OPML-aware crawler to discover without a central directory. Frontend: episode wizard price/reseller controls, sources display, earnings dashboard. Also fixes CORS and a container-image reference: - app.ts: register @fastify/cors, open on the catalog/feed/sources endpoints (already deliberately public/crawlable) and on purchase/confirm (already accept stateless NIP-98 header auth for exactly this case). Credentials stay off, so the session cookie never crosses origins — cookie-authed admin routes stay same-origin-only. Needed so external clients like podsteadr-player can browse/buy/play from a different origin. - docker-compose.yml: fully qualify the mediamtx image reference (docker.io/bluenviron/mediamtx:1.19.2) — some Podman hosts have no unqualified-search registry configured and fail to resolve short names. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
34 lines
800 B
JSON
34 lines
800 B
JSON
{
|
|
"name": "podsteadr-server",
|
|
"version": "0.1.0",
|
|
"private": true,
|
|
"type": "module",
|
|
"scripts": {
|
|
"dev": "tsx watch src/index.ts",
|
|
"build": "tsc -p tsconfig.json",
|
|
"start": "node dist/index.js",
|
|
"test": "vitest run",
|
|
"typecheck": "tsc --noEmit"
|
|
},
|
|
"dependencies": {
|
|
"@cashu/cashu-ts": "^4.7.2",
|
|
"@fastify/cookie": "^11.0.2",
|
|
"@fastify/cors": "^11.3.0",
|
|
"@fastify/static": "^8.1.1",
|
|
"better-sqlite3": "^12.2.0",
|
|
"fastify": "^5.4.0",
|
|
"fastify-plugin": "^5.1.0",
|
|
"nostr-tools": "^2.15.0",
|
|
"ws": "^8.18.0",
|
|
"zod": "^3.25.0"
|
|
},
|
|
"devDependencies": {
|
|
"@types/better-sqlite3": "^7.6.13",
|
|
"@types/node": "^22.15.0",
|
|
"@types/ws": "^8.18.0",
|
|
"tsx": "^4.20.0",
|
|
"typescript": "^5.9.0",
|
|
"vitest": "^3.2.0"
|
|
}
|
|
}
|