<feed xmlns='http://www.w3.org/2005/Atom'>
<title>coinosv3-server.git/tools, branch master</title>
<subtitle>coinos v3 server — payment-name registrar, NWC push, Blossom sync storage, feed</subtitle>
<id>https://git.coinos.io/coinosv3-server.git/atom?h=master</id>
<link rel='self' href='https://git.coinos.io/coinosv3-server.git/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3-server.git/'/>
<updated>2026-10-19T18:15:11Z</updated>
<entry>
<title>live: a streamer can delete their own recording (POST /live/&lt;id&gt;/delete, NIP-98), ending the stream if it's on. Its files go, and stream.json stays as 'deleted' so the address answers 410 until the trim takes it. A stream someone reported is taken aside instead (.removed/, kept for reporting), so deleting can't destroy what was reported. Removed and deleted streams no longer count as live (toward MAX_STREAMS, or as exempt from the trim).</title>
<updated>2026-10-19T18:15:11Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-19T18:15:11Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3-server.git/commit/?id=5bbc130102de0a3c0eff6727241d0f8029ab6572'/>
<id>urn:sha1:5bbc130102de0a3c0eff6727241d0f8029ab6572</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
</content>
</entry>
<entry>
<title>live: WebRTC through Cloudflare's SFU (Realtime) for the app's viewers, a fraction of a second behind the broadcaster where HLS is 3.5 s. The server only brokers it, and the app's secret stays here ($LIVE_CONFIG sfuAppId/sfuSecret):</title>
<updated>2026-10-19T14:56:19Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-19T14:56:19Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3-server.git/commit/?id=926fe1f1958396deac929013d88847f6703665b6'/>
<id>urn:sha1:926fe1f1958396deac929013d88847f6703665b6</id>
<content type='text'>
- POST /live/&lt;id&gt;/rtc/publish (the sender, NIP-98) pushes its tracks.
- POST /live/&lt;id&gt;/rtc/watch hands a viewer an offer of them, and /rtc/answer takes its answer.
/stats says which publish is current (rtc), and ?watching=1 counts a WebRTC viewer, who never fetches the playlist. HLS carries on as before, for the recording and the other nostr apps.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
</content>
</entry>
<entry>
<title>live: 1 s HLS segments (keyframes every second), 10 in the live window — a player starts about three segments behind the edge, so most of a viewer's delay was the 2 s segments (8.6 s behind the broadcaster, measured; 4.5 s with these).</title>
<updated>2026-10-19T07:43:48Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-19T07:43:48Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3-server.git/commit/?id=debbfaa1f0173d5be08fe40c27b12764f18d41ad'/>
<id>urn:sha1:debbfaa1f0173d5be08fe40c27b12764f18d41ad</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
</content>
</entry>
<entry>
<title>live: a name streams a day after it's claimed (the registrar now records when; older records count from their last update), never if banned; GET /live/allowed says which and until when. Viewers can report a stream (POST /live/&lt;id&gt;/report, NIP-98): kept in .reports.jsonl and DM'd to the admins from the welcome key. An admin takes a stream down (POST /live/&lt;id&gt;/remove {ban}): it ends, its playlists and segments answer 410, its files move to .removed/ (kept for reporting, never trimmed), and a ban stops its sender streaming.</title>
<updated>2026-10-19T06:03:57Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-19T06:03:57Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3-server.git/commit/?id=07fb145efbc32cdfe2dc488c65d8708260f6f648'/>
<id>urn:sha1:07fb145efbc32cdfe2dc488c65d8708260f6f648</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
</content>
</entry>
<entry>
<title>nwcpush: calls push only to an app that says it rings for them (reasons.call), not to an older one whose worker would show a call as chat.</title>
<updated>2026-10-18T16:01:17Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-18T16:01:17Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3-server.git/commit/?id=56cad7ef0da868e7c7c2b3c902143acd611b4c48'/>
<id>urn:sha1:56cad7ef0da868e7c7c2b3c902143acd611b4c48</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
</content>
</entry>
<entry>
<title>nwcpush: calls wake a closed app. Kind 21059 wraps to a registered pubkey are watched; one big enough to be a call offer (an SDP) pushes 'call' at high urgency, a minute's TTL, naming the wrap, which the device fetches from GET /wrap/&lt;id&gt; (kept two minutes; a push can't carry it) and opens with its own key. ICE candidates and hang-ups are too small to wake anyone. A 'call' opt-out like the other reasons.</title>
<updated>2026-10-18T16:00:22Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-18T16:00:22Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3-server.git/commit/?id=2e897103836a6814a39dbb905d6a7ed1417344d7'/>
<id>urn:sha1:2e897103836a6814a39dbb905d6a7ed1417344d7</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
</content>
</entry>
<entry>
<title>live: /live/turn — ICE servers for the app's calls (Cloudflare TURN credentials good for 4 h, to a NIP-98-signed ask; 30 an hour per key, 60 per IP; STUN alone if TURN can't be had). The key comes from $STATE/live/config.json.</title>
<updated>2026-10-18T15:31:40Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-18T15:31:40Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3-server.git/commit/?id=265fc554840455c87b7e46a2f42bcb51e22318c1'/>
<id>urn:sha1:265fc554840455c87b7e46a2f42bcb51e22318c1</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
</content>
</entry>
<entry>
<title>live: live streams sent from the app — the browser's recording over a WebSocket (on 443, through Cloudflare: no ports to open), ffmpeg to 2 s HLS (H.264 720p, AAC), a live window and the whole stream (its recording), viewers counted, a dropped sender resuming the same stream, NIP-98 + coinos-name owners only, 3 at once, 4 h each, recordings kept a week.</title>
<updated>2026-10-18T15:14:20Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-18T15:14:20Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3-server.git/commit/?id=29688869753d7bc9f1d25db27b9fccc8f11266e1'/>
<id>urn:sha1:29688869753d7bc9f1d25db27b9fccc8f11266e1</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
</content>
</entry>
<entry>
<title>Make this the coinosv3-server repo: the services, with coinosv3 pinned</title>
<updated>2026-10-16T19:57:19Z</updated>
<author>
<name>Adam Soltys</name>
<email>asoltys@gmail.com</email>
</author>
<published>2026-10-16T19:57:19Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3-server.git/commit/?id=1dd70cc2c2b9b0a9f65a704ded9e322afabf736f'/>
<id>urn:sha1:1dd70cc2c2b9b0a9f65a704ded9e322afabf736f</id>
<content type='text'>
Carved out of coinosv3 (names, feed, nwcpush, blossom, vmedia, bridge and
their tests, with history). The shared wallet code they import (src/ark,
noffer, bolt12, popular-feed) now comes from a coinosv3 submodule pinned at
082fc2e, the commit the services have actually run on, so moving here changes
no behaviour; bumping it is its own commit. The two text helpers translation
uses arrived on the server later than that commit and are vendored under
names/vendor at the versions deployed, until the pin moves past them.

Root package.json pins the npm versions installed on the server. compose.yml
runs names, nwcpush and blossom from this checkout (read-only) with configs
and state under $STATE, outside the repo, and pins the Bun image.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Translation: into the phone's language, and DeepL with your own key. isolabellart saw the Translate button but nothing became Italian: the target was the app's language, coinos has no Italian UI (so it ran in English), and the language guess didn't know Italian. Posts now translate into the reader's choice (Settings → Nostr → Translation, any of 31 languages), else the phone's language when the app has no UI for it, else the app's; the guess knows Italian, Dutch and Polish. And, as Jumble offers: a DeepL API key of your own, kept on the device and sent per request as x-deepl-key — the registrar passes it to DeepL (api-free for ":fx" keys; DeepL refuses browsers) and never stores or logs it; a refused key or used-up quota says so once. names: translateDeepl (prose only, links/tags kept, detected source back, 401/402/422 statuses), CORS allows the header. Deployed to cs names. tools/translate-italian-test.js, tools/deepl-translate.test.js.</title>
<updated>2026-10-10T15:39:24Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-10T15:39:24Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3-server.git/commit/?id=b02290686a8bce9ae0884cec2faad7301aa02bf4'/>
<id>urn:sha1:b02290686a8bce9ae0884cec2faad7301aa02bf4</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01Vps2H27rhbG9ZqseGfMrc3
</content>
</entry>
</feed>
