<feed xmlns='http://www.w3.org/2005/Atom'>
<title>coinos-server.git/lib/nwc.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:49Z</updated>
<entry>
<title>nwc: fix pay_invoice reply reliability, rate-limit drops, always reply</title>
<updated>2026-06-17T14:47:49Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-06-14T19:42:59Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=b83d5dfc6dc27b7af1fbc723b61e017fd9caf7d7'/>
<id>urn:sha1:b83d5dfc6dc27b7af1fbc723b61e017fd9caf7d7</id>
<content type='text'>
Port of master 8cb18821 (refs #80), adapted to staging's nwc event loop.

(a) pay_invoice: sendLightning runs xpay to completion and finalize() sets
p.ref = preimage, so return that directly instead of polling listpays and
racing a 20s timeout that returned a misleading "Payment timed out" even
when the payment settled. Keep a longer listpays loop as a fallback; on
still-in-flight return an explicit "check with lookup_invoice".

(b) rate limiting: raised per-pubkey cap 5 -&gt; 60/min, and over-limit
requests now get a NIP-47 RATE_LIMITED reply instead of a silent drop that
looked like a lost reply. Every request path now always sends a 23195
reply (success, error, or handler-returned-nothing) so a client never
hangs. Pulled the reply/encrypt logic into a reply() helper.

The notify default-on part of 8cb18821 is intentionally NOT ported: master
10284aa1 reverted it to opt-in, which is already staging's behavior
(notify = String(notify) === "true").

Co-Authored-By: Claude Opus 4.8 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>nwc: publish 13194 info event only when missing, recheck hourly</title>
<updated>2026-06-17T14:47:49Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-06-14T19:40:33Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=ceb003afb154560bb68b4252759fedc1fee75a0f'/>
<id>urn:sha1:ceb003afb154560bb68b4252759fedc1fee75a0f</id>
<content type='text'>
Port of master 6372d918, adapted to staging's nwc relay loop (no
heartbeat here). NWC clients fetch the kind 13194 info event before they
talk to the wallet; without it they show "no info event" and an unknown
balance. 13194 is replaceable and meant to persist, so instead of blindly
republishing on every connect, query the relay (ensureInfo) and publish
only the server pubkeys whose event is actually missing. Re-check hourly
so a relay restart that leaves our socket intact self-heals; interval is
cleared on close/reconnect. Verified nostr@0.2.8 Relay exposes ws/
readyState, on("eose") and unsubscribe.

Co-Authored-By: Claude Opus 4.8 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>nwc: pay_invoice honors request amount for amountless bolt11</title>
<updated>2026-06-17T14:47:49Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-06-14T19:38:29Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=0987582546363935c5a388a9accb9b245c11a7c7'/>
<id>urn:sha1:0987582546363935c5a388a9accb9b245c11a7c7</id>
<content type='text'>
Port of master ce9616f6. pay_invoice derived the amount solely from the
decoded invoice, so an amountless bolt11 yielded amount = round(undefined/
1000) = NaN and sendLightning rejected it with "Invalid amount". NIP-47
lets the client specify the amount (msat) in the request; fall back to it
when the invoice carries none, with a clear error if still missing.
Fixes #83.

Co-Authored-By: Claude Opus 4.8 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>nwc: fix make_invoice timestamps (ms -&gt; seconds) breaking NWC clients</title>
<updated>2026-06-17T14:47:48Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-06-14T19:38:29Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=af8e395dd9ed010fce0e3b92593d5ea6d39dc65a'/>
<id>urn:sha1:af8e395dd9ed010fce0e3b92593d5ea6d39dc65a</id>
<content type='text'>
Port of master 0154bb06. generate() stores `created` in milliseconds, but
NWC make_invoice returned it directly as created_at and computed
expires_at = created_at + expiry. NWC timestamps are Unix SECONDS
(NIP-47), so clients parsed a ~1.78e12 expires_at that overflowed their
date types (ptcpay's .NET DateTimeOffset, issue #84). Convert created to
seconds. Fixes #84.

Co-Authored-By: Claude Opus 4.8 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>nwc: handle stale user record and skip reverted-duplicate records</title>
<updated>2026-05-18T06:49:55Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-05-18T06:49:55Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=0d40e407f4c1a14a7da9466e38ade97adbdeeaee'/>
<id>urn:sha1:0d40e407f4c1a14a7da9466e38ade97adbdeeaee</id>
<content type='text'>
- fail loudly when an NWC request references an app whose user record no
  longer exists (migrated/deleted account); previously crashed inside
  handle() on `user.id`
- filter `revertedDuplicate` payments out of list_transactions so
  clients never see the doubled records that were later reverted

Co-Authored-By: Claude Opus 4.7 (1M context) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>stop republishing external events and add NWC rate limiting</title>
<updated>2026-03-18T18:39:05Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-03-18T18:39:05Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=a8977f8c5c84b0c37c4fb36f0a0be5bf6f492f3d'/>
<id>urn:sha1:a8977f8c5c84b0c37c4fb36f0a0be5bf6f492f3d</id>
<content type='text'>
Co-Authored-By: Claude Opus 4.6 (1M context) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>fix typescript issues</title>
<updated>2026-02-28T23:16:20Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-02-28T23:16:20Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=32f01e3e328db0006a55c6324625b49d60244b66'/>
<id>urn:sha1:32f01e3e328db0006a55c6324625b49d60244b66</id>
<content type='text'>
</content>
</entry>
<entry>
<title>formatting</title>
<updated>2026-02-24T21:18:42Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-02-24T21:18:42Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=ad7b09b43323d0ffc0a8ddabb43e4838a184c697'/>
<id>urn:sha1:ad7b09b43323d0ffc0a8ddabb43e4838a184c697</id>
<content type='text'>
</content>
</entry>
<entry>
<title>upgrade dependencies</title>
<updated>2026-02-06T17:00:22Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-02-06T03:00:39Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=310568dea00de03edd27b702a881e66fd7b5b837'/>
<id>urn:sha1:310568dea00de03edd27b702a881e66fd7b5b837</id>
<content type='text'>
- Fastify 4→5 with all plugins
- @noble/hashes 1→2, @scure/base 1→2, @scure/bip32 1→2
- redis 4→5, pino 8→10, got 13→14, uuid 8→13, ws 7→8
- nostr-tools 2.16→2.23 (fix getPublicKey to pass Uint8Array)
- Remove unused deps: date-fns, buffer-crc32, readable-stream-clone
- Fix @noble/hashes import paths for v2 (.js extensions)
- Fix Fastify maxParamLength deprecation (use routerOptions)
- Convert sharp require() to ES import

Co-Authored-By: Claude Opus 4.6 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>tigerbeetle</title>
<updated>2026-02-06T17:00:09Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-02-05T07:13:33Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinos-server.git/commit/?id=1ebc40afc14a75d7fe157b2c6c20ffea9dedb5eb'/>
<id>urn:sha1:1ebc40afc14a75d7fe157b2c6c20ffea9dedb5eb</id>
<content type='text'>
</content>
</entry>
</feed>
