| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
never marked for revocation by a second wake, lookups report outgoing sends and finish them, and pushes no longer run side by side
PullCap's night of 2026-10-24: every wake's diary stopped 8-12 s after its push (iOS stops the worker there, not at 30 s). Two wakes two seconds apart both drove one send; the second's InitiateLightningPayment was refused ("state: ln-spent") and the paid send went to 'revoking', where every later wake spent its whole budget on it, so no request was answered after midnight.
- manager: an initiate refused as ln-spent follows the payment ('initiated'); a send in 'revoking' asks the ASP first (paid: settle; in flight before expiry: back to waiting; not found: revoke)
- worker: 9 s budget on Apple endpoints (27 s elsewhere) for answers, earlier sends and renewals; every ASP step held to it
- lookup_invoice asks every copy of the connection and drives an outgoing send in flight, answering settled with the preimage
- a lease in the worker's IndexedDB store serialises pushes (the Web Lock didn't); diary notes a missing Web Locks API
- the reply and the mirror save run together; stuck sends are finished before a new payment only when they hold its coins
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QjVvE4YAcK3AGwV7kZXeN4
|
| |
|
|
|
|
|
| |
or pauses in place, a click on a playing clip pauses it (a paused one still opens the pager), and a tall clip is held to three quarters of a computer screen with its box narrowed to the clip's shape
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QjVvE4YAcK3AGwV7kZXeN4
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
instead of calling the invoice "already paid" with no preimage and locking its coin until the app opens
PullCap's night of 2026-10-23 (hourly 1-sat NWC requests to a closed iPhone
PWA): three of fifteen hours went wrong the same way. The push woke the
worker, it reserved the coin and wrote the ln-pay action to the mirror, and
the phone stopped it before the ASP was ever asked (no cosign in captaind's
log for those minutes). The client's retry ten minutes later hit the
manager's duplicate check, "this invoice was already paid or is being paid",
published as an INTERNAL error that the client read as paid — hours before
the money moved. And since the stuck action held the wallet's only coin,
the next hour's request (a different invoice) found nothing spendable and
fell to "Open Coinos to approve". Everything settled at once when the app
opened at 07:12 and resumed the actions.
- nwc-respond.js: pay_invoice first looks for a send already on the books
for this invoice — finishing one in flight and answering with its
preimage, repeating the preimage of one already done (nothing new on the
spend log) — and before paying a new invoice drives any other stuck send
to completion so its coin comes back. tendLnPays() does the same on every
wake, lookups included, and hands back "Payment sent" lines for what
settled. rec.pendingPays remembers which connection a send belongs to
(the action is the manager's); the app's mirror rewrite carries it.
- manager.js: the duplicate check says "already paid" only for a settled
send, "already in progress" for one on its way.
- features/nwc.js: the open app answers a repeated invoice from the local
action (preimage when settled, an honest "still in progress" otherwise)
before asking the ASP about a sibling device.
- sw-nwc.js: one push at a time over the shared mirror (Web Lock), so a
client's lookup + retry seconds apart can't double-drive one send. A
diary of what the worker did — each push, each ln-pay step as the mirror
saves it, every notification shown or refused, the fallback taken — is
appended line by line to IndexedDB (nwc-bg.js appendBgLog), so a worker
the phone stops mid-push leaves its last step behind. Settings →
Notifications → "Background activity log" copies it.
- tests: nwc-sw-test covers the four resumed-send cases; sw-push-quota
mocks the new seams and its "suspended app" case now expects the
stand-in-first order shipped in 91dbee4 (it had been failing since).
Co-Authored-By: Claude Fable 5.1 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
profile no longer keeps its released placeholder address
Jarryd (DM, 2026-10-24): on Android he could not sign in with Amber and had to paste his nsec, and his profile page showed the temporary name he had picked while the editor showed his real one.
Amber: Chrome lets a page open another app only on the heels of a tap. The Sign-in tap carried the get_public_key request, but the request the login fires once the key is back (decrypt the backup, sign the relay list…) had no tap behind it, so Chrome dropped the nostrsigner: navigation with a console warning the page never sees ("Navigation is blocked") and the card spun forever. Reproduced on Adam's Pixel 9 with Amber 6.6.9 (Amber 4.1.3 did not even parse the web request). Now a request without a user activation behind it waits for one: the card says the signer has another request and offers an "Open signer app" button that launches it from the tap; a launch that leaves the page in front (never hidden) is treated as blocked too and gets the same button. The clipboard is still read on return (that part worked).
Profile: the migration released the placeholder name and repointed lud16/nip05 to the new one, while the legacy-avatar import ran at the same moment, read the same old kind 0, and republished it nine seconds later with the placeholder address back ([email protected], dead on both coinos.io and v3). Kind-0 publishes now go one at a time, merge over the newest copy this session sent, and are stamped strictly later than it (relays keep the lower id of two with the same second). The profile page shows the claimed address instead of a same-domain name that is no longer ours, and once the domain confirms the old name is dead it repoints the kind 0 in the background (healStaleAddress), so zaps to the published lightning address reach the wallet again.
tools/profile-publish-race-test.js plays the migration's two publishes at once against an in-memory relay. tools/amber-login-test.js and identity-test pass; name-migration-test and avatar-profile-test fail the same way on the previous commit.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
|
| |
|
|
|
|
|
| |
tiles already showing, in their own date order; only a post newer than the top tile goes above it
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QjVvE4YAcK3AGwV7kZXeN4
|
| |
|
|
|
|
|
| |
edge to edge, the chat a plain full-width list under it
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QjVvE4YAcK3AGwV7kZXeN4
|
| |
|
|
|
|
|
| |
same money in the new unit, round-tripping exactly
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QjVvE4YAcK3AGwV7kZXeN4
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
"self": renewal stays automatic there, in the app and the worker
"Coinos holds my coins" was meant to exist only on servers that keep
cosigning a coin past its timelock (the presets carry honorsExpired), and
the custody card hid it elsewhere and showed "self". But the tier the
renewal pass and the worker mirror read came from the stored choice or the
custodial default regardless of server, so a wallet on Second or a custom
captaind (where an expired coin is gone) renewed nothing and warned of
nothing since 648a550 (2026-10-22): no backstop orders, no renewal in the
last hours, and the worker registering nothing while closed.
getCustody() now returns "self" in place of "custodial" whenever the active
server does not honor expired coins ("exit" stays "exit"); the mirror
carries the same, so the worker follows. The stored choice is left alone
for a later switch back to a coinos server, and choosing a tier always
writes it. tools/ark/custody-foreign-test.js: a custom server with no
honorsExpired, nothing stored or "custodial" stored, reads as "self", the
card offers only self/exit, and the renewal pass registers backstops and
renews the coin at its timelock.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QjVvE4YAcK3AGwV7kZXeN4
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
amount; a split that lands as several coins sends them all
An offboard moves whole coins, so a partial amount was first split off by
a payment to the wallet's own address, and the send then waited for ONE new
coin of exactly that size. A payment that needs more than one input arrives
as one coin per input, so for any balance held in two or more coins the
wait timed out ("The split is taking longer than expected") while the split
had gone through — every retry split again and nothing was ever sent
(Jarryd, 2026-10-23: three splits of 185,000 sats, each landing as
109,958 + 75,042).
Now the coins that leave are chosen as a set: a single coin of the exact
size, else the free coins that already add up to it (largest first, so the
halves an earlier split left behind go as they are, with no new split),
else the split's own output — every new coin on the receive key that adds
up to the amount. Change keeps its own key index and stays. Same carving
for the automatic withdrawal. tools/ark/offboard-split-test.js covers the
four cases against the real send form.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QjVvE4YAcK3AGwV7kZXeN4
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
counts as shown
PullCap's iPhone paid four times overnight with the "payments sent"
notifications on and never showed a "Payment sent" line. The worker hands
the handler the heads-up (covered by a test now); the handler flagged the
push as answered BEFORE calling showNotification, so a refusal left the
push with no line at all — on iOS a silent push, a strike towards losing
the subscription. Now the flag follows success, a refused notification is
retried with the plainest options, and the stand-in covers the rest. iOS
never replaces by tag, so renotify is left out there.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
server's depth cap strands them
A coin's exit depth grows by one per off-chain hop; the server refuses to
cosign a spend of a coin at max_vtxo_exit_depth (100), so a wallet paying
hourly from one change chain has an unspendable coin within days. Survey of
the ASP's 2,279 unspent coins: median depth 7, 154 coins past 40 holding
7.7k sats, five already stuck at the cap.
The server now waives the refresh base fee when every input is at its
deep_waiver_depth (60; ArkInfo.fees.refresh carries it). The client mirrors
that in refreshFee, never selects a capped coin as an input (the shortfall
message says why), and flattens deep coins whatever the custody tier: the
open app in a round of their own, the worker with a standing order two
blocks out per coin. The default tier's copy names the one exception.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
loop on open lands in safe mode; a closed-app payment is one history row
PullCap's night of 2026-10-22 on an iPhone: four hourly payments made while
closed, no notification for the fourth, then no more wake-ups until the app
was opened — WebKit's silent-push quota. APNs accepted every push (no 410);
the device had stopped listening. The stand-in line went up at the END of
the push handler, after a payment that can take most of the budget, and a
worker stopped before its last line showed nothing. On an Apple endpoint the
line now goes up first and the outcome ("Payment sent") replaces it.
The same phone then crashed on every open ("A problem repeatedly occurred").
An inline guard counts page starts before the app runs; the app clears the
count after eight seconds alive or a clean leave, and notes the boot phase
it reaches. A third start in a row opens in safe mode: no automatic Ark
connection, a notice naming the last phase, "Open normally" and "Copy
report".
Every payment the worker made showed twice once the app opened: the worker's
own ln-send row (merged from the mirror) and the "while closed" note the app
adds from its spend log. The note now stamps the existing row, and
lnFoldedIds hides a twin that still forms. The balance was never counted
twice — it comes from the coins.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
| |
gone, and a unilateral exit needs only that
Adam, 2026-10-23: the app must stay navigable and able to exit if Coinos disappears. The shell already was (the worker precaches every chunk; verified with every coinos host unresolvable: boot, wallet creation, Savings address, Send all work, and Electrum fails over to public servers). The Ark side was not: connectArk's init asked the server for its info and threw, so the Manage page's Exit stayed disabled and doArkExit waited on a connect that could never finish.
ArkManager takes infoHint (the btc-wallet-arkinfo cache the app keeps per server): when GetArkInfo fails and a hint exists, init proceeds on it with `offline` set; the server key, fee tables and lifetimes are in it, and an exit needs the chain (esplora, not Coinos) rather than the server. doArkExit uses the initialized manager and waits on init alone, not on the Nostr snapshot gate the full connect also waits for (its relays may be gone too). tools/ark-offline-init.test.js.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
| |
orphan HTLC coins are settled by the server's answer
Adam's wallet renewed a 1,000-sat coin past its expiry plus four bits of change for 301 sats — the expiry trigger had no floor, only the depth trigger did. Now every automatic renewal, under either renewing strategy, is skipped when the fee would exceed a tenth of the coins it renews; they stay spendable, the server honors them, and the strategy card says so.
Reconcile: five 22-sat HTLC-send coins sat 'pending' for days — their Lightning payments' actions had been pruned, and an unheld pending coin was only asked about when it was a plain pubkey coin. HTLC orphans are asked about now too: spent is spent; one the server still holds open stays pending (an HTLC coin is never this wallet's to spend). tools/ark-htlc-orphan.test.js.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
|
| |
|
|
|
|
| |
(which overflowed on a phone)
Co-Authored-By: Claude Fable 5.1 <[email protected]>
|
| |
|
|
| |
Co-Authored-By: Claude Fable 5.1 <[email protected]>
|
| |
|
|
|
|
|
|
| |
the ticked coins; a unilateral exit can be partial; the explainers moved to the confirmations
Adam, 2026-10-23: the three buttons belong right below the table so it is clear they act on the selection, "co-operative exit" is Withdraw and "unilateral exit" is Exit, Exit names the ticked total and takes just those coins, and the explainer cards were a wall — they now appear where the action is decided: the renewal text and fee schedule on the Renew confirmation, the withdraw note on the form it opens, the exit cost comparison on the Exit confirmation. The page is the coins, their three buttons, and the custody strategy. The buttons stay (disabled) while every coin is in a round.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
|
| |
|
|
|
|
|
|
| |
that describes only the chosen one
Adam, 2026-10-23: three descriptions at once were a wall of text. The card now sits between the coins table and Renewal, is a select of the three strategies with their prices, and shows one paragraph — the chosen strategy's. The intro is two sentences shorter.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
|
| |
|
|
|
|
|
|
| |
on-chain as exactly those coins
Adam, 2026-10-23: the checkboxes only fed Renew; the exit button always prefilled the whole balance. The manager's offboard always took a coin list, and the fee quote prices each coin by its own expiry, so the page now passes the selection through: the card says which coins will move and prices their total, the exit form shows "N selected coins · amount" instead of an amount field, the quote is for those coins, and no fresh coin is split off first. Nothing ticked (or everything) still means the whole balance, with the editable amount as before.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
|
| |
|
|
|
|
|
|
| |
cost", "Minimize exit cost"; no timelocks, rounds or "the old Coinos"
Adam, 2026-10-23. Coins "expire"; the exit is "yours until then"; what a renewal buys is said without naming the mechanism.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
|
| |
|
|
|
|
|
|
| |
default tier says the exit stays until a coin's timelock runs out
Adam, 2026-10-23: "Coinos holds my coins" read as if the holder never had a unilateral exit. They do, until the timelock runs out; only then does Coinos hold the coin. The option is now "Coinos holds my coins once they expire", its description says so, and the intro says what the timelock buys and what renewing keeps.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
| |
low-passed at 2.6 kHz
Adam auditioned twelve takes on the Jacob's ladder clip (freesound 536741) and chose this one: the first 0.45 s of the arc with its opening spike cut (0.10–0.45 s), pitched down 20%, the fizz above 2.6 kHz removed, a 130 ms fade. Same loudness as before (loudnorm −16 LUFS). The clip chunk shrinks from 12 KB to 4.7 KB of base64.
tools/zap-feedback-test.js pins the new length (0.3–0.5 s) and dispatches the held-screen's two clicks in the page: the sound toggle re-renders that screen, and puppeteer's own click found its node detached mid-morph (failed on HEAD with the old clip too).
Co-Authored-By: Claude Fable 5.1 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
| |
exit cheap" renews a coin once its history is four hops deep
Why: a unilateral exit publishes one on-chain transaction per off-chain hop, so depth — not age — is what makes an exit expensive, and a renewal a week before expiry flattens exactly the same history a renewal in the last hours does. The week-ahead "early" tier only guarded against the server being unreachable at the very end, which is not the case worth selling. (Adam, 2026-10-23.)
exit = self (last-hours renewal, free bracket + base, the same grid-snapped backstop) plus: any coin whose genesis chain is 4+ hops deep is renewed in the next round the app runs, paying the top bracket + base — but only when that fee is under a tenth of the coin (flattening a 21-sat coin for 300 sats helps nobody; its exit is uneconomic anyway). Deep coins ride along with an expiry renewal when one is due, or get a round of their own. The server-side backstop stays near-expiry only: depth changes only while the wallet transacts, i.e. while the app is open. A stored 'early' reads as 'exit'. Card copy says what the hop count means and what the two prices are for.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
renews on its own and no renewal fee is paid unless the user opts in
Why: renewal fees were "money passively draining" to people who thought they had a custodial wallet (Stacker News, 2026-10-22). Measured over Sep–Oct: 84% of what users paid came from the client's own consolidation round at 20 coins (0.2% + 300 on every fresh coin), the rest from 300-sat rounds that each cohort of Lightning-received coins (30-day pool lifetime) triggered on its own schedule. The ASP itself honors a coin past its timelock — rounds and offboards never checked expiry, and captaind's allow_expired_arkoor (now on at ark.coinos.io) lets arkoor spends through too — so expiry only ever meant "the exit is gone", which most people coming from v2 never had.
Settings → Spending gets a Custody card with three tiers:
- coinos holds my coins (default): no renewals, no fees; a coin past its timelock shows as "held by coinos", stays spendable and receivable, and is left out of a unilateral exit (there is nothing on-chain for it to take).
- Keep my own exit: renew in the last hours (free bracket + base), the server backstop registered 36 blocks out and snapped to a 48-block grid so every wallet's orders share one round.
- Renew a week early: 1008 blocks out on a 144-block grid (0.1% + base).
renewPolicy() in ark/manager.js is the one table; the app, the service worker (the mirror carries the tier) and the Manage page all read it. Only shown on servers that honor expired coins (presets carry honorsExpired); elsewhere renewal stays automatic.
Manager: honorsExpired makes a past-timelock coin ordinary money (balance, selection, receive validation via acceptExpired) while a server refusal (expiryRejected) still excludes it; such coins spend LAST so an older build on the receiving side almost never meets one. A once-per-wallet rescan re-reads the mailbox and adopts coins older builds refused as expired, un-forgets expired dust, and clears stale refusals. The refresh gate that retired a renewal of expired inputs is gone (the server accepts them; the Manage page's Renew of exactly those coins was failing silently). Automatic consolidation is gone; the send cap goes 24 → 48 coins; small change (<1,000 sats) folds into a renewal that happens anyway.
Server (cs:~/ark/captaind-main.toml, restarted): allow_expired_arkoor = true; pool vtxo_lifetime 4320 → 8640 so Lightning-received coins live as long as the rest.
Tests: tools/ark/custody-test.js (policies, honoring, ordering, grid snap, validator), tools/ark/custody-ui-test.js (the card, held coins, exit count, switching), nwc-sw-test updated for the tier the worker reads.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
load stays out
- Videos: one person's clips of one size to the byte are one clip. Beatbox
Serenade posted the same video as a note and as a video event, each
upload a fresh Blossom hash, so neither the file nor the words matched.
Only a size the post or the host states counts (a bitrate x duration
guess is marked sizeGuess and never matched).
- Images: a picture whose load failed was hidden by a class the next
repaint rewrote, so the broken-picture glyph came back (a deleted
nostr.media file in #artstr). Failed pictures are now remembered for the
session and left out of the grid.
- A tile fetching its own frame froze the whole tile against repaints, so
one built for the one-to-a-row layout never got its --ar in justified rows
(zero width). Only the player and its stand-ins are frozen now; the
render draws the cost badge itself. Tile pictures no longer size their
tile (a frame-grab <video>'s 320px stretched its row).
- Test fixtures that served one file under several names (or one imeta
size for every clip) now differ per clip.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01K5xtiFrkFVsrkWx6JDQjiT
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
there as a blank tile
A deleted file on Primal's blossom answers 404 without CORS headers, so the
probe saw only a quiet host (not a 404), the server had no still for it, and
the tile's fallback player failed with nothing listening: a blank box (Adam's
iPhone). The player's error now hides the tile and marks the clip gone for a
day, as a 404 the probe could read already did.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01K5xtiFrkFVsrkWx6JDQjiT
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
comes back
WebKit removes a subscription after three pushes that showed no
notification (743011c stops new strikes, but a wallet already struck out
stayed deaf): background stayed on, getSubscription() came back empty and
refreshRegistration gave up, so NWC requests stopped waking the closed app
until the switch was toggled (reported by PullCap). It now subscribes again
(also when the VAPID key changed) and re-registers with the notifier, on
start and whenever the app returns to the screen.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01K5xtiFrkFVsrkWx6JDQjiT
|
| |
|
|
|
|
| |
way round; the choice is stored only when it differs from the device's default). A clip's shape falls back to its still's proportions, so leaving All shapes finds the clips known. The grid's pager keeps a clip of unknown shape out until measured, as the grid does (d898efb let an unmeasured landscape clip into a phone's vertical pager).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
tile thumbnail is no longer a square crop: 360px tall, its middle cut to 1:2–2:1; vmedia pic.webp?s=row for hosts without CORS; tile cache v2)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
proportions, every row one height filling the width) instead of squares
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
tiles stay for a phone held upright showing tall clips only)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
16:9 poster whole, instead of portrait slivers three across
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
other way round (the pager now holds every clip, pagerFit keeping the wrong-shaped ones out of sight until asked)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
day instead of sitting there as a blank tile
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
file or Blossom hash, or the same words from the same person re-uploaded); on a big window a small clip in the pager is drawn at most 1.5x its pixels instead of blown up across the monitor
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
bar up, and it fades about 2 s after the mouse goes still (it stays while the pointer rests on the bar)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
wallet's push subscription
WebKit allows no silent pushes: a push that shows no notification is a
strike (even with the app open), and after three it removes the
subscription, so a closed wallet stopped waking for NWC requests until it
was opened again (reported by PullCap). On an Apple endpoint, the paths
that used to end quietly (lookups answered, another device took the
request, DMs/reactions we don't announce, an open window, unknown pushes)
now show a silent self-replacing "Coinos" line, closed at once when the
app is on screen. A backgrounded iOS app is suspended, so an NWC request
is no longer handed to it: the worker answers itself.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
missing
A reply under "Couldn't find that note on the relays" told nobody anything (Adam, 2026-10-20), so once every lookup comes back without its post it isn't shown in a feed's Conversations view (its thread, notifications and the replier's own Replies tab keep it; a lookup that later finds the post brings it back).
The lookups miss less:
- A NIP-22 comment (kind 1111) names its parent's author at e-tag [3], not NIP-10's [4], so every comment's parent lost its author and the author's outbox went unasked. fiatjaf's comment on Kieran's routstr post lives on relay.snort.social (its hint), Kieran's pyramid.fiatjaf.com and ditto: none of ours.
- A reply that names no author asks the outboxes of the people it's addressed to (its p tags, up to three).
- The relay the reference itself names is asked even when this device has marked it sick.
- A post read in Following (or the feed in use) is found in that feed's disk cache too, so a Conversations view opened right after a reload doesn't take its replies for orphans.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
|
| |
|
|
|
|
|
|
|
| |
carry the time
The "at this time" reply/like/zap buttons are gone, and with them the panel they made over the pager. A reply, like or zap made from a post's own buttons (the feed's, or the pager's ♥ ⚡ and post) while its clip has played is about that moment; the reply box says so and its × makes it about the whole post. What was said, reacted or zapped at a moment sits over the bar at that moment (a custom :emoji: as its picture, from the reaction's own tag; it was showing as :cb-rofl: text), a tap goes there and says who and what, and in the pager it floats up off the bar as the clip plays past. Your reaction no longer turns the count red, only the heart.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
|
| |
|
|
|
|
|
| |
A tap near the foot of the screen brings it up for a few seconds without pausing (longer while it's dragged), and a paused clip shows it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
|
| |
|
|
|
|
|
| |
preconnect for the grid's clip hosts: the first clip from a host took 1.8 s on Adam's phone, 0.65 s once connected), and the player starts loading when the finger comes down on the tile; the pager adopts that very element, so the load overlaps the tap and the pager's opening. A press with no tap after it lets its player go. (feed-media-views test: the Live chip, and the warm next/kept previous players.)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
|
| |
|
|
|
|
|
| |
unheard, waits a frame or two in at full volume, and plays with sound when swiped to.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
|
| |
|
|
|
|
|
| |
too (on Adam's phone it was the slow one: 0.66-0.78 s, built anew, against 0.04-0.08 s onto the warm next clip). The swipe clock records the player's readyState and how far it had buffered.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
|
| |
|
|
|
|
|
|
| |
- The pager's next clip gets a warm player: once its opening is in the cache it reads to its first frame (preload metadata: Chrome stops ~2-4 MB in at real link speeds) and waits paused, so landing on it is only play and sound. coinosPagerStarts() in the console times every landing (swipe to moving picture, warm or cold, host, size).
- A stream's "N watching" names who on hover, and a tap shows their faces: NIP-53 presence (kind 10312, as Shosho and zap.stream say it), fresh for half an hour. coinos says it too while a stream is open (every 5 min, with a key held here only, never for your own stream) and takes it back on leaving.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
|
| |
|
|
|
|
|
| |
bunker, passkey, Google) when there is one, else the wallet's key. They were always signed by the wallet's own key, so a signed-in person's zaps showed in stream chats and streamers' overlays under a stranger npub. Zap requests also carry created_at now (a real signer refused them without it).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
|
| |
|
|
|
|
|
| |
raw firehose of that relay alone (/feed/all?r=…). Trailing punctuation stays outside the link.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
|
| |
|
|
|
|
|
| |
Replies, shown once they've streamed), as the Live chip's grid of tiles.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
|
| | |
|
| |
|
|
|
|
|
|
|
| |
- **Delete recording:** your own ended stream's page has the button. The live server lets the recording go, and the stream is announced again without it, so other apps drop the link too. A deleted one leaves Past streams and says the streamer deleted it.
- **Admin:** the Take down button no longer shows on the admin's own streams.
- **Past streams** scroll on: 24 at a time as the grid's foot comes near, then older ones from the relays (before the oldest held), until a page brings nothing. They're no longer cut off at a month.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
|
| |
|
|
|
|
|
|
|
|
|
|
| |
SFU, which the live server brokers, and a viewer in the app watches from there: 0.1 s behind the broadcaster in go-live-test LATENCY=1, against 3.5 s on HLS.
- Switching to the screen and back swaps the track in place.
- A reconnect that makes a new stream publishes again, and its viewers follow.
- A viewer falls back to HLS if there's no WebRTC for the stream or no connection in 8 s.
HLS is still sent, for the recording and the other nostr apps.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
|