<feed xmlns='http://www.w3.org/2005/Atom'>
<title>coinos-server.git/index.ts, branch staging</title>
<subtitle>coinos server — legacy coinos.io backend (Lightning, on-chain, Liquid)</subtitle>
<id>https://git.coinos.io/coinos-server.git/atom?h=staging</id>
<link rel='self' href='https://git.coinos.io/coinos-server.git/atom?h=staging'/>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/'/>
<updated>2026-06-17T14:47:46Z</updated>
<entry>
<title>users: add authenticated self-delete endpoint</title>
<updated>2026-06-17T14:47:46Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-06-14T19:33:43Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=7332e55641c21e024e50f83176b302df9c488e9a'/>
<id>urn:sha1:7332e55641c21e024e50f83176b302df9c488e9a</id>
<content type='text'>
Port of master 2548f757, adapted from Express to this stack's Hono
handlers (c.get("user"), c.req.json(), setCookie, bail) and TigerBeetle
balances (getBalance/getPending instead of the Redis balance:/pending:
keys). POST /delete (auth) wipes every key tied to the calling user:
user records, payments/invoices, sub-accounts, NWC apps, nostr follow
graph + nip5. Gated by typing the username and refuses while
balance+pending &gt; 10k sats so funds can't be destroyed by accident.

Co-Authored-By: Claude Opus 4.8 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>payments: guard /replay double-credit race with SET NX idempotency</title>
<updated>2026-06-17T14:47:45Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-06-14T19:33:29Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=17a4461d8497f4f0f89871bb80604d449487a4c3'/>
<id>urn:sha1:17a4461d8497f4f0f89871bb80604d449487a4c3</id>
<content type='text'>
Port of master ca28c19f to the staging stack. The getPayment() pre-check
in the lightning listener/replay isn't atomic, so concurrent re-credits of
the same settlement each ran the credit path. Claim each lightning/bolt12
settlement with an atomic SET NX on credited:&lt;ref&gt; (ref = preimage) and
bail if already claimed. Guard sits before tbCredit and the pointer writes
so a duplicate bails cleanly. Also disable the /replay route that triggered
it.

Co-Authored-By: Claude Opus 4.8 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>ln/lightning: watchdog recycles zombie receive-listener socket</title>
<updated>2026-06-08T22:49:26Z</updated>
<author>
<name>Adam Soltys</name>
<email>asoltys@gmail.com</email>
</author>
<published>2026-06-08T22:49:26Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=7c34b4312c8aafc7643a5192d54daea14cfc1559'/>
<id>urn:sha1:7c34b4312c8aafc7643a5192d54daea14cfc1559</id>
<content type='text'>
Port of master bd1ece3 to staging. When cl restarts (e.g. autoheal after a
healthcheck timeout), the app's waitanyinvoice long-poll can hang on the now-dead
listen socket: listenerActive stays true forever, nothing restarts it, and
incoming lightning payments silently stop crediting until a manual app restart.
The per-call RPC timeout can't catch this — waitanyinvoice is meant to block.

ensureListenerAlive (run every 120s) now also detects a stalled listener — active
but blocked in waitanyinvoice for &gt;5min — probes cl via the main socket (getinfo),
and only if cl is actually alive treats the listen socket as a zombie: bumps a
listenerEpoch, calls lnListen.reset() (new: drops the proxy socket so the next
call reconnects), and re-arms. The epoch guard makes the wedged invocation bow out
when its waitanyinvoice finally rejects, so we never run two listeners or
double-credit.

Co-Authored-By: Claude Opus 4.8 (1M context) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>remove /gateway endpoint</title>
<updated>2026-05-18T06:42:28Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-05-18T06:42:28Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=ca4bdc84f1eac1859044639ffa16bac9aa8fce1b'/>
<id>urn:sha1:ca4bdc84f1eac1859044639ffa16bac9aa8fce1b</id>
<content type='text'>
Unauthenticated arbitrary db.set abuse vector. Exploited on the master
deployment to inflate user balances and override safety controls in real
time, leading to a hot-wallet drain. Route and handler both fully
removed; if a webhook-by-short-channel-id mapping is ever needed again
it must be rebuilt with auth + SCID format validation + webhook URL
validation + per-user ownership check.

Co-Authored-By: Claude Opus 4.7 (1M context) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>feat: blocked address protection, LNURL proxy, replay timestamps</title>
<updated>2026-03-28T06:58:56Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-03-28T06:58:51Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=a574e774318a37bfc1e5c638a3d83e3fb9c180d2'/>
<id>urn:sha1:a574e774318a37bfc1e5c638a3d83e3fb9c180d2</id>
<content type='text'>
- Add lib/changeid.ts for in-process account rekeying
- Block sends to addresses in redis blocked_addresses set, auto-rekey on attempt
- Add created param to credit() for accurate replay timestamps
- Add paid_at to replay() for correct payment dates
- Add /lnurl/proxy endpoint for server-side LNURL callback fetching

Co-Authored-By: Claude Opus 4.6 (1M context) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>update migrate script</title>
<updated>2026-03-16T23:37:03Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-03-16T23:35:11Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=8c1385eaf8e68ef0ad436ad9b74e5813e92bb378'/>
<id>urn:sha1:8c1385eaf8e68ef0ad436ad9b74e5813e92bb378</id>
<content type='text'>
</content>
</entry>
<entry>
<title>ark delegation</title>
<updated>2026-03-13T22:14:51Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-03-13T21:16:08Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=7a241cfb13395ba2218411cb56d2b0a73e758a06'/>
<id>urn:sha1:7a241cfb13395ba2218411cb56d2b0a73e758a06</id>
<content type='text'>
</content>
</entry>
<entry>
<title>remove bumpestimate</title>
<updated>2026-03-12T05:30:37Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-03-12T05:30:37Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=05119b32f331ee97130a5300feb5c02f791aac80'/>
<id>urn:sha1:05119b32f331ee97130a5300feb5c02f791aac80</id>
<content type='text'>
</content>
</entry>
<entry>
<title>add LNURL-withdraw endpoints for fund-based NFC payments</title>
<updated>2026-03-09T05:23:17Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-03-09T05:23:17Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=ac05ab09314eebd1d939d9b032ddcb16446e294c'/>
<id>urn:sha1:ac05ab09314eebd1d939d9b032ddcb16446e294c</id>
<content type='text'>
Co-Authored-By: Claude Opus 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>add group registry for MLS push notifications</title>
<updated>2026-03-07T07:22:12Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-03-07T07:22:12Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=4237e418f7332f9edfad30964d2d6a51aa6c1db2'/>
<id>urn:sha1:4237e418f7332f9edfad30964d2d6a51aa6c1db2</id>
<content type='text'>
Server now tracks MLS groups (synced from clients) and subscribes
to kind 445 events on group relays, sending push to all members
except the sender. Registry persisted to Redis across restarts.

Co-Authored-By: Claude Opus 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
</feed>
