| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
| |
through. "Any way to stop classifying v3 notifications as spam? I've seen this a few times now" (Adam, 2026-11-03, phone: "Possible spam — Chrome detected possible spam from v3.coinos.io", Unsubscribe / Show notification): Chrome on Android scores every web notification's title and body with an on-device model before showing it, hides it behind that warning above 90 of 100, and — nine warnings in a week on a phone whose engagement with the site is under 50 — revokes the site's notification permission outright (Chromium kAutoRevokeSuspiciousNotification, enabled by default). The model is a text classifier trained on Gemini-made examples of scam notifications, and our lines were their very shape: "Payment received" 95, "Incoming payment / Someone is trying to send you money…" 99, "Payment request / An app is asking your wallet to pay…" 99, "alice is calling / Voice call. Tap to answer." 99, "New message / You have a new private message." 92, "alice / sent you a message." 95, "New reply to your post / <text>" 98, "alice reacted ❤️ / to your post…" 97. Desktop Chrome runs the same model (without the warning) and reports each score to chrome://histograms, so the lines were measured rather than guessed — ~200 candidates on Chrome 156's model: "sats" reads as money without reading as a payment scam, "payment" doesn't; a sender's name in the body of a message or reaction line tips it over, "New chat" / "<name>" doesn't; any "reply" title is 96–99; a reply's own text is out of our hands (an @name or a link in it scores 97+), so it no longer rides along; "Calling" / "<name>" is 11–29 where every "<name> is calling" is 80–99. src/notify-text.js holds every line, with the measurements; the worker, the background responder and the renewal warning draw from it. The new lines score 8–46 (the shortcode reaction 67). tools/notif-spam-score.js re-measures them in a throwaway Chrome (SystemNotifications off, so nothing reaches the desktop) and fails at 90 — run it before changing any of them. On the phone that already warned, "Show notification" then "Always allow" marks the site trusted and stops both the warning and the revocation count
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VMan6TFgisGKUDhdStLUvs
|
| |
|
|
|
|
|
| |
Lightning sent to its name arrives the moment it opens. A name whose wallet lives on Second (or a custom server) can only be paid over Lightning — the registrar's float can't arkoor to a server it isn't on — and only while the wallet is open to answer the registrar's offer request; its hourly retry with a six-second window rarely met a short phone session, and manna's 52 sats failed 449 times from 2026-10-18 to 11-03. Once the offer listener is up (nwc listen(), a beat after subscribing), the names feature POSTs /listening (NIP-98, coinosv3-server 14a6dd5) and the registrar sends whatever is queued for the name at once. Once per ten minutes, and never for a wallet on the coinos server: it is paid while asleep and spends no signature on this. tools/names-listening-test.js: nothing on coinos's server, one authed call on Second, no second within ten minutes, a registrar that is down is asked again next time
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VMan6TFgisGKUDhdStLUvs
|
| |
|
|
|
|
|
| |
is still sliding in. "I'm still not seeing the Post button right away when I open the feed. It should be there from the start" (Adam, 2026-11-02): measured on his phone over DevTools, the button was in the page 87 ms after the Feed tap — 4109 px down, below an 809 px screen — and in place at 562 ms. It is position: fixed, and it was rendered inside the page, whose entrance animation puts a transform on it; a transform makes fixed descendants position within the page, so the button rode at the foot of the feed card until the slide ended. The feed now hands the button and the new-posts pill to the shell (a pageFloaters hook, taken once per render), which paints them beside the page, outside anything that animates; the pill's CSS no longer depends on sitting inside the page, and its phone-width rule stays after the base one so it still rides above the button. tools/feed-fab-anim-test.js taps Feed from the wallet and samples the button every frame of the slide: on screen from the first. The direct-mount harnesses (feed-new-posts, feed-streaming, feed-bottom-nav) paint the floaters as the shell does
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VMan6TFgisGKUDhdStLUvs
|
| |
|
|
|
|
|
| |
server that holds the same blob. "No avatar for karnage?" (Adam, 2026-11-02): his kind 0 names a picture and a banner on media.21media.to, and that host answers "The requested blob was not found" for both — while blossom.primal.net, the server he publishes in his kind 10063, still has them, which is why other clients show his face. A picture named by its sha256 is a Blossom blob, served under the same name by any server holding the bytes: when the thumbnail maker finds the host without it (a 404, or a host that won't answer), the blob is looked for on the person's published servers and then the public ones we know, asked together, and the first that answers stands in — the thumbnail is made from it, the profile page's big face and banner paint from it, the feed's warm-up loads it — and the find is remembered on the device so the search runs once. tools/blob-alt-test.js serves a dead host and a published server holding the copies and checks the thumbnail, the profile page and the post rows
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VMan6TFgisGKUDhdStLUvs
|
| |
|
|
|
|
|
| |
so no faint grid shows across it. "When I zoom in on my image, I see very faint grid lines. Is that a compression artifact?" (Adam, 2026-11-02): no — Chrome keeps a will-change: transform layer rastered at 1× and scales that bitmap on the GPU, and the bitmap's tiles meet in faint seams, a regular grid over the sky. The hint stays on while a gesture moves the picture (no re-raster per frame) and is dropped once it comes to rest zoomed, so Chrome rasters the picture at the scale it is shown at: sharp, and seamless. At 1× the stylesheet's hint is back for the pager's swipe
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VMan6TFgisGKUDhdStLUvs
|
| |
|
|
|
|
|
| |
beside the heart say 1 if I have 2 heart reactions?" (Adam, 2026-11-02): a thread remembers its counts between visits so that a short relay answer can't erase them, and the bar showed the memory alone — while the tally in hand, which the who-panel reads, had the second heart, brought by the feed's own count fetch before the thread was opened again (the memory is only brought up to date while the thread is on screen). The bar now shows the larger of the remembered number and the live tally, hearts, boosts and sats alike. tools/thread-like-count-test.js opens a thread by its link with one heart on the relay, comes back through the feed when there are two, and checks the thread says 2
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VMan6TFgisGKUDhdStLUvs
|
| |
|
|
|
|
|
| |
words", straight to the phrase field. "Signing in on another device … it was hard to find how until I realised you click to make a new wallet, where then you get the option to use the seed phrase for an existing wallet" (user feedback, 2026-11-02): the import used to hide as a line under the freshly minted words behind "Create a new wallet". It sits below the sign-in buttons with the migrate door, and the step it opens is titled "Restore your wallet" rather than "Set up your wallet". tools/onboard-backup-test.js checks the door, that it opens on the phrase field with no minted words, and that a typed phrase opens the wallet
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VMan6TFgisGKUDhdStLUvs
|
| |
|
|
|
|
|
| |
relays first — the reference's own hints, ours, its author's — and from the wide net of public and archive relays only once those have come back empty, or after 1.2 s if they are slow about it. Asked all at once, as before, every quote and every reply's parent went out to a dozen relays, and in the Conversations view, where each row has a parent, half of all REQs in twenty seconds on the live app — three hundred, to 47 relays — were lookups of notes our own relays answered in the first beat. tools/relay-budget-test.js adds a far relay: the six quotes our relay holds are never asked of it, and the one only it holds is still found there
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VMan6TFgisGKUDhdStLUvs
|
| |
|
|
|
|
|
| |
posts NIP-22 comments (kind 1111) on a film's IMDb page: an I tag naming the address, no e or E tag. Adam's own ("Charming and wholesome", 2026-11-02, on relay.primal.net) showed on neither his profile's Replies tab — the profile page never asked for kind 1111 at all — nor in the Conversations view, whose warm-up pass asked for posts and reposts rather than the view's own kinds, and the refresh that asks properly is skipped for half a minute after it. The profile asks for comments now, the warm-up pass asks for what the view shows, and a comment with no post to show above it carries the page it is on where "Replying to" would go — "Comment on imdb.com/title/tt32565993", linked, or the comment's own alt tag when it has one ("Comment on Sheep Detectives (2025) in DaddyTube") — in place of the bare "reply" tag. Also, a report naming a post as 'other' with the author's bare p tag beside it counted as a report of the PERSON (an 'other' e tag didn't count as naming a post), and two such from follows folded everything the author wrote; every post named now counts. tools/web-comment-test.js plays all of it against a fake relay
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VMan6TFgisGKUDhdStLUvs
|
| |
|
|
|
|
|
| |
the laptop (2026-11-02, after the resume fix), an open of Following sent some 560 REQs in twenty seconds across 57 relays, over a hundred each to damus and primal, and damus answered the home IP "banned: too many rate-limit violations". Four sources, all cut: a quoted note's author (a face tapped, a reply's target) had their relay list asked for one REQ per author per relay — six quotes on screen sent eighteen — and those asks now wait 80 ms and go out as one REQ through the feed's batched fetch, which also remembers who has no list; the live subscriptions were closed and reopened at the end of every refresh pass (seventeen REQs over eight relays, twice per open) and now stay up while the relays and authors they cover are unchanged, the head they count fresh posts against read at each event; the follows' reports were fetched afresh at every reload (an in-memory clock) and now honour the clock the device saved, asking only for what came since; and every one-shot REQ was held open on our own relay until the slowest relay in the ask had answered — the library closes them all together — so the fast one carried each for up to five seconds. One-shot queries now go out per relay (queryOn, queryStreamOn, queryManyOn, the profile and inbox lookups), each closed on that relay's own EOSE, with no more than ten open on any relay at once: the rest wait their turn, and a turn that comes after the ask's own wait is skipped. tools/relay-budget-test.js runs the feed against a fast and a slow fake relay and checks each of these
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VMan6TFgisGKUDhdStLUvs
|
| |
|
|
|
|
|
| |
them anything: one tiny REQ to each; a socket that answers is kept, one that doesn't is closed and redialed at once, its subscriptions refired by the library with since set to the last event each saw, and only then do the DMs resubscribe and the feed refresh. "No new notes in Following since 11:35? It's 9 pm now … it loaded more posts, it just took a while" (Adam, 2026-11-01): after hours in the background a phone's tab is thawed with every socket reading OPEN and long dead on the network, so the catch-up sent on resume vanished, and the library found a dead socket out only after its 29 s ping and that ping's 20 s timeout, then waited 10 s to redial — a minute or more before the backlog arrived through the refired subscriptions. tools/resume-wake-test.js freezes a fake relay's sockets, posts while the app "sleeps", and has the post on screen 2.7 s after resume (never within 15 s before). Also: Primal's "too many concurrent REQs" notice no longer cools the relay off for 30 s at every boot — it serves every REQ past its twenty anyway (measured 60 at once: 60 EOSEs, 12 notices), so the cool-off only lost us its answers while the relay lists, profiles and the feed all asked at once; a CLOSED with that reason still counts
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VMan6TFgisGKUDhdStLUvs
|
| |
|
|
|
|
|
| |
with the file's link, instead of sitting as a dead player under "Tap to play". A post's video "won't play" (Adam, 2026-11-01): the mp4 had been deleted from Primal's blossom, which answers a 404 with no CORS headers, so the probe couldn't read the status and the box waited for a tap that loaded nothing — no client renders it (the reply under the post says as much) and no other blossom host has the hash. The player is the first to know: its original failing now tries the server's copy once (a file the browser can't decode fails the same way, and the copy plays that one), and the copy failing too marks the clip gone for a day — the line and the link in the box, its cover, play button and controls off, a short box; the next paint of the post says it at once with no request, the media warm-up and the in-view hook leave it alone, and the videos grid leaves it out as it did a 404 the probe could read. Outside the feed the box used to be hidden on an error before anything was said; it gets the line too. tools/video-gone-test.js serves the clips from a second origin without CORS, one of them a 404, and checks the line, the untouched live clip and the silent repaint
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VMan6TFgisGKUDhdStLUvs
|
| |
|
|
|
|
|
| |
frame: the Post button, the feed chips and the nav come with the page, not a beat after it. /feed is a public page, so it painted as a visitor's (no button, chips or nav) the moment the app ran, and the wallet's restore — synchronous work: the vault's scrypt on a cold start, the wallet's state, every feature's init, ~0.5 s on a laptop and more on a phone — re-painted it with the button only once it had run ("the post button takes a while to appear", Adam, 2026-10-31). Boot now tells before that work whether a wallet is about to open (a session list in the tab, a vault the last seal or unlock opened without a password — noted, since the vault alone can't say short of the scrypt being avoided — or watch-only accounts) and the feed, the nav and the chips paint for it; taps still go by the wallet actually being open, which it is by the time one lands. The wide-screen wallet column waits for the numbers. A visitor with no wallet on the device gets the visitor's page as before. tools/feed-boot-chrome-test.js boots the built app at /feed behind a session, a noted vault, an unnoted vault (the old order, and the unlock leaves the note) and as a visitor
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VMan6TFgisGKUDhdStLUvs
|
| |
|
|
|
|
|
| |
at v3.coinos.io/coinos.apk, the same file from the git.coinos.io mirror (with its hash), Zapstore, and the F-Droid review. Nothing on the site linked the APK before; people found it only by being told
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VMan6TFgisGKUDhdStLUvs
|
| |
|
|
|
|
| |
a long-time nostr user signed in with his key for the first time; our relays had never seen his kind 0 (it lived on ditto, snort and oxtr), the 3 s lookup came back empty, and the payment-address publish went out as {lud16, nip05} alone: name, picture and banner gone from every relay (nicstazzema, shown as npub1yk2lkr7). An empty quick lookup now widens to the same search the follow list got after its own overwrite (indexes, archives, the key's own write relays, Primal's signed copy) before anything is written, once per key per session so a brand-new key's first publish waits once. For anyone already hit, the profile editor offers "Look for older copies": a kind 0 from a history-keeping relay fills only the fields still empty in the editor, and Save publishes it. tools/kind0-overwrite-test.js plays the incident against a fake relay network where only an archive holds the profile
Co-Authored-By: Claude Fable 5.1 <[email protected]>
|
| |
|
|
|
|
| |
the fdroiddata maintainer asked after the on-device test (MR 49241, 2026-10-27): third-party media hosts, DNS-over-HTTPS resolvers and mempool.space on one side, the coinos Ark server, name registrar and relays on the other. Matches the MR branch
Co-Authored-By: Claude Fable 5.1 <[email protected]>
|
| |
|
|
|
|
|
| |
pays a Lightning invoice from the coins nearest expiry first, so fewer of them come up for a paid renewal (Stacker News request, 2026-10-29). Lightning sends only: the ASP takes those coins, whereas an Ark-to-Ark send would hand the recipient your short timelocks. The custodial default keeps the smallest coin that covers the payment (expiry costs nothing there), a coin past its timelock still goes last, and a pile of old crumbs that would breach the input cap falls back to largest-first. The closed-app NWC worker follows the mirrored tier the same way
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VMan6VLgQdujavxPsfU7A9
|
| |
|
|
|
|
|
| |
the background (a zap failing after you switched away) was hidden by its timer before it ever showed, because a hidden tab pauses requestAnimationFrame but not setTimeout; on return it showed and nothing took it down (Adam's phone, 2026-10-30). The hide timer now starts when the toast actually shows
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VMan6VLgQdujavxPsfU7A9
|
| |
|
|
|
|
|
| |
longer means a new connection: "Reconnect your signer" keeps trying the stored session (at once, every 10 s, and on every return to the tab) and closes itself when the signer answers. Before, the screen made one try, or none if a try had failed in the last 20 s (it nearly always had: that failure is what opened it), so the only way out was a fresh nostrconnect, while the stored session answered in 0.7 s whenever anyone asked (Adam's phone, 2026-10-29). A try made while the tab was hidden (frozen on a phone) no longer counts as a failure, a closed signer ("not open anymore") is treated as dead and replaced, and Cordn follows a replaced signer instead of signing with the closed one
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VMan6TUeqTyZB8eXLGymUY
|
| |
|
|
|
|
|
| |
who wears what (/hats/worn, a couple of dozen heads, kept per device and refreshed every two minutes), so a face seen for the first time on a message page gets its hat at once instead of after a 400 ms batch and a round trip
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VMan6TUeqTyZB8eXLGymUY
|
| |
|
|
|
|
|
| |
a signer app", Messages offers "Connect signer", and the login hint says it works with remote signer apps, since Amethyst and others can sign too
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VMan6TUeqTyZB8eXLGymUY
|
| |
|
|
|
|
|
| |
(INSUFFICIENT_BALANCE or PAYMENT_FAILED, with the reason) is left with the notifier at once and goes out unless someone answers within 5 s. Waiting the grace period out in the worker ran past iOS's ten seconds after a failed send, so the other app heard nothing (PullCap, 2026-10-29). A Lightning send no longer picks a coin at the server's depth cap, so such a coin fails here with a reason instead of at the ASP; a capped coin under 330 sats (a round won't take it) says to receive more instead of "waiting to be renewed", and the worker stops booking renewals the server would refuse as dust
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VMan6TUeqTyZB8eXLGymUY
|
| |
|
|
|
|
|
| |
ahead, on the quarter hour) and turns Post into Schedule. The note is signed now with that created_at, so a remote signer asks while you're there, and handed to the notifier, which publishes it at that time; nothing reaches a relay before then. What's waiting shows as "Scheduled (n)" under the composer and on your profile, each with Cancel (a kind 5 to the notifier, so it never goes out); one cancelled on another device leaves the list at the next status check
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VMan6TUeqTyZB8eXLGymUY
|
| |
|
|
|
|
|
| |
handing alice the coin: bark checks the anchor there, and esplora indexes a block ~5 s after it's mined, so alice dropped the coin as 'anchor not found'
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QjVvE4YAcK3AGwV7kZXeN4
|
| |
|
|
|
|
| |
signed over the gift's code (#f=…, beside the note), so the claim screen shows "From <name>" and claiming follows them. A signature that doesn't match the code names nobody, so a link can't be passed on as someone else's gift. "Show it's from me" is ticked by default when making a gift, and unticking it is remembered; the gift's record keeps the sender, so View and Copy link again keep it too
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
subscription ran out after 19 payments with the app closed, "key window exhausted"), derived once per account and memoized; 60 receive preimages (was 15). When the worker can't act on a request it still wakes the user, and now leaves a "wait, open the app" error with the notifier that goes out only if nobody answers within 20 s, so the other app hears something instead of silence and a sibling's real payment is never shouted over. A request older than its two-minute window (a push that waited at APNs) is ignored quietly instead of showing "Payment request"
Co-Authored-By: Claude Fable 5.1 <[email protected]>
|
| |
|
|
|
|
|
| |
there; the "[0:03] " prefix other clients read is left out of the words (and out of the marker's line on the bar)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QjVvE4YAcK3AGwV7kZXeN4
|
| |
|
|
|
|
|
| |
audio) instead of floating above it, and a reply made at a moment shows as its author's face, not ↩ (the pager's bar and the pop-up too)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QjVvE4YAcK3AGwV7kZXeN4
|
| |
|
|
|
|
|
| |
hardware keyboard's Enter still sends
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QjVvE4YAcK3AGwV7kZXeN4
|
| |
|
|
|
|
|
| |
error) in the toast, not just "check your connection", which hid hosts refusing the file and a signer that never answered
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QjVvE4YAcK3AGwV7kZXeN4
|
| |
|
|
|
|
| |
the "replying" flag, and the box stays up while a draft has text, so with anything typed it did nothing. Attachments the draft carried are dropped with it
Co-Authored-By: Claude Fable 5.1 <[email protected]>
|
| |
|
|
|
|
|
|
| |
on the Lightning line too, and Save in the profile editor repoints it in the kind 0 (a same-domain name that no longer answers); the background heal steps aside for an interactive signer (Amber) instead of waiting forever in the kind-0 queue
Jarryd's page still showed [email protected] over ⚡ [email protected]: the header only substituted the NIP-05 line, and his kind 0 was never republished — the heal of ce96364 needs a background signature, which an Amber sign-in can't give, and Save left a lud16 that wasn't the old address alone.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
|
| |
|
|
|
|
|
| |
(Magnitude Relay, built for gift-wrapped DMs) leads the DM and group-chat relays, with relay.coinos.io and primal still read and written. A wallet key's inbox list that only ever held our old defaults is updated to name it; feeds and zaps never ask it (it takes messages, not posts)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QjVvE4YAcK3AGwV7kZXeN4
|
| |
|
|
|
|
| |
(ellipsized when it must) and the "in progress" tag sits beside the time, not in the title row where it broke the name mid-word in the narrow wallet column
Co-Authored-By: Claude Fable 5.1 <[email protected]>
|
| |
|
|
|
|
|
| |
editable field beside @domain with Copy address and Release; typing a different name swaps those for the "old address stops working" line, Cancel and "Change to <name>"
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QjVvE4YAcK3AGwV7kZXeN4
|
| |
|
|
|
|
|
| |
fee)"); an on-chain gift still shows its network fee
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QjVvE4YAcK3AGwV7kZXeN4
|
| |
|
|
|
|
|
| |
the amount for whoever opens it. It rides the link after the # (#m=…), so no server sees it; the gift's record keeps it, so Copy link again and View include it; with a note the QR is byte mode
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QjVvE4YAcK3AGwV7kZXeN4
|
| |
|
|
|
|
|
| |
into) instead of leaving a "This post was deleted by its author" row; threads still keep the deleted post's place
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QjVvE4YAcK3AGwV7kZXeN4
|
| |
|
|
|
|
|
| |
the first-run steps: pick a username, then a picture and a cover ("Not now" lands in the account the gift arrived in). Also fixes Verify backup on the gift screen, which crashed (pickConfirm wasn't passed to the gifts feature)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QjVvE4YAcK3AGwV7kZXeN4
|
| |
|
|
|
|
|
| |
held in two coins (dust padding split the sender's 886 into 595 + 291) showed as two receives. Receives stamp their mailbox message and the history folds a message's coins together; older rows fold on the same delivery instant
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QjVvE4YAcK3AGwV7kZXeN4
|
| |
|
|
|
|
|
| |
player's own controls (its seek bar) stay off, the middle play/pause shows whenever it's paused (touch too), and the sound button stays to turn it down again
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QjVvE4YAcK3AGwV7kZXeN4
|
| |
|
|
|
|
|
| |
only when the post has timed reactions to mark (the player's own bar does the seeking)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QjVvE4YAcK3AGwV7kZXeN4
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
| |
|
|
|
|
|
| |
and a classic inline script cannot carry an export (standalone.html threw "Unexpected token 'export'" since b3cee21; nothing imported them)
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
|