<feed xmlns='http://www.w3.org/2005/Atom'>
<title>coinosv3-server.git/names, 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-22T05:19:07Z</updated>
<entry>
<title>names: custom offers carry their owner's key; ones that can't reach a wallet are retired</title>
<updated>2026-10-22T05:19:07Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-22T05:19:07Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3-server.git/commit/?id=6b59316493a9a02f735a19e9747d2f3982d27ce2'/>
<id>urn:sha1:6b59316493a9a02f735a19e9747d2f3982d27ce2</id>
<content type='text'>
Releasing a name disabled its own offer but left its custom offers live
(27 orphans on 2026-10-22, rick@ had 4): a payment to one found no name
and no key, and would have sat in the forward queue for good. Custom
offers now record the owner's pubkey (backfilled at start from the name,
or for an orphaned npub1xxxxxxx@ name from the one current key with that
npub prefix — 4 recovered), and the settle loop forwards by it, so a
released name's offer pays the same key's name now, as the name's own
offer already did. Orphans with no owner to follow are disabled on the
node and dropped (23), as are a released staging name's.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>names: mint nothing payable for a wallet on another network, and retire what was minted</title>
<updated>2026-10-22T05:16:57Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-22T05:16:57Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3-server.git/commit/?id=5c007a2540d5a033c0934844eff68688af68817c'/>
<id>urn:sha1:5c007a2540d5a033c0934844eff68688af68817c</id>
<content type='text'>
A staging name is a mutinynet wallet, but every claim got a mainnet BOLT12
offer on our node published in its record, and custom offers and POS sales
were minted there too: real sats paid that way had no route onward (2,092
sat parked on 2026-10-22). otherNetwork() — the record's ark address decides,
a staging name without one is mutinynet — now gates the claim's stand-in
offer, custom offers and POS invoices (LNURL already refused staging).

At start, retireOtherNetworkOffers() disables the offers already out there
(83 staging names, 13 custom offers), takes their lno= out of the published
DNS record and drops them from state; idempotent, so a failure retries next
start. npub1x7acf8s@staging.coinos.io keeps its offers: its wallet is mainnet.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>names: a queued payment the float can cover goes now, backoff or not</title>
<updated>2026-10-22T05:03:55Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-22T05:03:55Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3-server.git/commit/?id=8229ea08caeb6d03efa56205b9526e2751217162'/>
<id>urn:sha1:8229ea08caeb6d03efa56205b9526e2751217162</id>
<content type='text'>
Float top-ups that missed their 60 s settle window landed later (+300k on
2026-10-22 once the ASP's vtxo pool refilled), but only a top-up seen to
settle resets the queue's backoff, so jarryd's 248k sat in a 1-hour wait
with 477k in the float.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>names: a wallet on another ark server gets its own Lightning invoice, one on another network is parked</title>
<updated>2026-10-22T04:43:05Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-22T04:43:05Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3-server.git/commit/?id=481e1f827d94f9ac3b54ad2a5c087fc5d8ce9a88'/>
<id>urn:sha1:481e1f827d94f9ac3b54ad2a5c087fc5d8ce9a88</id>
<content type='text'>
The float step threw 'address belongs to a different ark server' before the
Lightning step ever ran, so manna and rogerv3 (wallets on Second) were retried
100 times since 10-18 without once asking their wallets for an invoice. The
destination's ark id now decides: the float only on our own server, otherwise
straight to the wallet's CLINK invoice — those wait for the wallet without
paging (waitingOnWallet in /health).

A staging name's tark address paid real sats through its mainnet offer has no
route at all: such a forward is parked (state.parked, with its reason) instead
of retried forever, and /health counts it for the desk monitor. Ten such
payments (2,092 sat, Sep–Oct test payments to @staging.coinos.io names) had
been retried ~900 times each.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>names: deliver to coinos wallets over a circular route, shrink failing float top-ups, report stuck money in /health</title>
<updated>2026-10-22T04:39:11Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-22T04:39:11Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3-server.git/commit/?id=4c5cd496c321083501dee75da97f702953cb44f5'/>
<id>urn:sha1:4c5cd496c321083501dee75da97f702953cb44f5</id>
<content type='text'>
The ASP's vtxo pool sat empty for 35 hours (2026-10-20/22: 614k in the
rounds wallet against 1.12M needed to refill), and two forwards of ~124k
for jarryd sat in the queue the whole time:

- viaClink paid the wallet's own invoice with a plain pay, but a coinos
  wallet's invoice is minted by our ASP on this very node: a self-payment
  the hold plugin never sees ('Destination said it doesn't know invoice').
  It now goes out and back in over a channel pair (payCircular, shared with
  the float top-up) and waits for the wallet to claim, so a payment is
  delivered whenever the wallet is open, float or no float.
- a float top-up that doesn't settle halves the next ask (down to 20k),
  back to full size after one lands: 79 tries of 200k failed where the
  pool's 100k coins could have funded half of it.
- the retry tick can't overlap itself any more (a circular delivery waits
  up to 4 min; an overlapping tick would forward the same payment twice).
- /health reports pendingSat, oldestPendingAt, the top-up failure streak
  and last error, and payments for wallets on another ark server apart
  (undeliverable): the desk float monitor pages on these.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</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>coinosv3 → 73bffd9: the services run the wallet's current Ark code; names/vendor/ goes.</title>
<updated>2026-10-16T23:33:53Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-16T23:33:53Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3-server.git/commit/?id=13da0eda3b972eafb3962960165f73181497b7e5'/>
<id>urn:sha1:13da0eda3b972eafb3962960165f73181497b7e5</id>
<content type='text'>
The pin had stayed at 082fc2e (Sep 14) while the app's Ark manager moved on —
renewals priced at a 300-sat base fee and re-priced on "insufficient refresh
fee", expiry-aware coin selection, standing (scheduled) renewals merged by
unlock hash, policy-aware freeing of in-flight coins — so the registrar's
forwarder float was a month behind the wallets it forwards to. The manager's
constructor, the methods the services call (balance, sync, refresh, send,
address, createLnInvoice, driveLn, startBoard, pendingActions, htlcClaim,
htlcCosignRefund, _key) and the storage contract (load → state or null, save
← state) are unchanged between the two commits, and nothing new is imported
from a package the server lacks.

names/translate.js imports translate-split.js from the submodule now, as
feed/cache.js already did lang-guess.js: the vendored copies were byte-equal
to what the pin now carries. The README's note about them goes with them.

Resolve-checked every service entry (bun build --target=bun); the moved tests
(registry-ownership, public-feed-cache) and the bun-test files
(deepl-translate, names/store) pass.

Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01J1Kon8bxJoHRpJdSzshCkp
</content>
</entry>
<entry>
<title>README, example config and the deploy hook</title>
<updated>2026-10-16T19:58:17Z</updated>
<author>
<name>Adam Soltys</name>
<email>asoltys@gmail.com</email>
</author>
<published>2026-10-16T19:58:17Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3-server.git/commit/?id=2fe542686dde91f424ecb019c2886e467e9aebd8'/>
<id>urn:sha1:2fe542686dde91f424ecb019c2886e467e9aebd8</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>names: keep state in SQLite</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=a3d2dc2e05a4f7c5ab0d6e7689498da9ca63de7b'/>
<id>urn:sha1:a3d2dc2e05a4f7c5ab0d6e7689498da9ca63de7b</id>
<content type='text'>
persist() rewrote the whole state file, close to 10 MB, on every settled
payment and every queue tick, so one crash during a write could take every
name with it. State now lives in SQLite (bun:sqlite, WAL,
synchronous=FULL): one row per name, offer, invoice and so on, with the
forwarder wallet's state kept as a single row. Each persist() is one
transaction that writes only the rows that changed, so a crash leaves the
previous state or the new one, never a torn file.

The in-memory state object and every persist() call stay as they were. On
the first start the JSON state file is imported, and a corrupt one stops
startup. The file is left in place, so a rollback to the JSON build still
finds its data. store.snapshot() makes a consistent copy while the service
runs, for backups.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</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>
</feed>
