| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
| |
floored to the cent (so it never parses back above the maximum), not a BTC figure under a CAD label. One ctx.amountField helper for the ark send/LN Max, the gift Max and fixed-amount zap/BOLT 12 fills
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
|
| |
|
|
|
|
| |
names its inputs, and ArkManager._free / freeCoins exclude coins an in-flight remote renewal holds from balance (counted pending), send/LN/offboard/exit selection, auto-renew, the backstop and the coins page (greyed with the round). Freed the moment that renewal reads finished, failed or lapsed
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
renewals as display-only slivers (step, amounts, fee, round txid; no signing material), merged into remoteRenewals furthest-step-wins, never as actions; the coins page lists another device's renewal in progress with its round transaction until it finishes there or a 'Renewed' row syncs (two-day cap)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
schedule and re-prices instead of resubmitting the same underpaying set on every sync; if the new fee leaves under 330 sats (or the price didn't change) it fails and frees the coins. Backstop registration re-reads the schedule on the same refusal
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
forever: once its done action is pruned, a re-read round breadcrumb adopted it again as a rescue at step 'issued', whose spent inputs had lost their bytes, so every sync threw. A round counts as claimed when its 'Renewed' movement or its fresh coins are already in the wallet; the breadcrumb and rescueParticipation skip it, and a stuck issued action retires without a row
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
| |
OfflineAudioContext and makes its real AudioContext on the first tap (one made at load ran at once in the installed app, re-opening the phone's audio output on every open/refocus), suspended again after the sound and when the app is hidden
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01PCGjEEMD23CweKrefbTDJp
|
| |
|
|
|
|
| |
button and size (no seek bar or sound button until playing); hovering the cover no longer paints it over with the app's button grey; upright phone clips (stored sideways with a quarter-turn matrix) paint upright, v1 size caches dropped; a clip the probe found HEVC switches to the copy before fetching the original
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
clip this browser can't picture (an iPhone's HEVC on Chrome for Linux played sound over black) — vmedia container on cs (bun + ffmpeg, /vmedia/), switch on zero-width metadata or an HEVC header from the probe, a line saying why if the copy fails too
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
blocked the recipient field — only a field you're typing in is protected now (test opens Send with a real click)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
never off another field, never on phones); the amount field still takes it once a recipient resolves
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
the send-by menu (White Noise is one app that speaks it); a zap on something no relay has says it may be a private message instead of claiming the post vanished
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
(self-hosted, Unsplash) cycled with arrows or a swipe, or upload your own; untouched, each pubkey gets its own default, published as the kind-0 banner beside the punk
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
| |
/nprofile1… and /<name> with the kind 0, latest posts, follow counts and mentioned faces inlined (stale-while-refresh cache, 2 s budget), the app seeds its caches from it, and the big avatar never flashes punk art while a lookup runs
A cold visit to a profile link showed a punk, '–' counts and no posts for 9 s.
Server-side relay answers settle once events stop arriving (idle 400 ms)
instead of waiting out a relay that never sends EOSE: a cold build is ~1.9 s.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
a pending Sent row with the recipient's face, and gives way to its completed row
One-tap zaps now record who they went to, so their rows carry a face too.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
arrives — the default punk flashed in front of a new account's chosen picture
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
A suite run let ~90 throwaway test wallets subscribe and publish on public
relays from one home address, and nos.lol and relay.damus.io banned it.
tools/puppeteer.js wraps puppeteer-core: every socket to a non-local host
gets an in-page stand-in relay (EVENT -> OK, REQ -> EOSE). Tests that read
real content launch with { relays: 'read' } (real reads, publishes answered
in place); feed-live, chat-layout and cordn-ui launch with { relays: 'live' }.
LIVE_RELAYS=read|1|host,... overrides per run.
profile-key-qr: measure the QR again if a repaint swapped it out.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
never off another field, never on phones)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
tap); Enter on Send picks the top suggestion, and Enter walks amount → review → confirm
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
ark ui-test: wait for the selected balance card to stick before opening
Receive (the carousel lands on a card's history, and a glide could settle
back on Savings), wait for the first mailbox read before paying, paste
addresses whole (typed a key at a time, a re-render mid-typing broke the
checksum), and poll for alice's balance and the history rows. 8/8 runs.
comments-test: the article and comments it fetched are handed to the app
on every relay socket that asks, so it no longer depends on the app
reaching the same public relays.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |\ |
|
| | |
| |
| |
| |
| |
| |
| |
| |
| | |
receive
Run right after tests that mine, cln-ark could trail by a block or two and
the receive failed with final_incorrect_cltv_expiry.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The old test spawned ~/halwallet's dev server and drove its long-gone UI
(receive-mode select, Settings 'Refresh / consolidate'). It now builds this
repo's app bundle and drives it against the regtest stack: set up Spending,
receive over Ark from alice, send back from the Send form, fund Savings
on-chain and move it into Spending (board), reload. Only the page and the
local backends are reachable. aliceReady uses 'bark maintain' so actions a
killed run left half-done get resumed instead of holding coins locked.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| | |
It needs vtxo_lifetime <= 60 so it can mine past expiry; against the normal
4320-block server it would age the whole shared chain. Also import the
manager relative to the repo instead of the main checkout's absolute path.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| | |
scheduled-refresh-test mines a whole vtxo lifetime, which expires alice's
coins; every test run after it funded nothing (spendableSat 0) or was handed
an expired coin (receive-test). The helper refreshes expired coins and boards
more when alice runs low, and the funding tests call it before paying.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
- mine/fund through the bc container (the standalone :18543 node was retired
in the July consolidation)
- board-test hands the server the funding tx (require_board_funding_tx) and
waits for esplora to see the board confirmed: bark silently drops a received
vtxo whose board tx it can't find yet
- refresh-test rounds the ppm fee up like the server (and the manager) do
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
68fd614 removed the VtxoPolicy::Htlc encoding from send.js/proto.js (upstream
took type 0x08) and the bridge was retired from the app on 2026-08-02, so
htlcLock can no longer build its output (policyTaproot throws on the missing
userPubkey). bridge-e2e-test also drove bridge/server.js, which sits on the
same dead primitives.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| | |
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
scratchpad
The default fixture paths pointed into an old session's scratchpad, so the
test died reading them (exit 1, no output). Fresh pair from the regtest stack:
offer from clc, invoice fetched by cln-ark. Network and expiry checks no longer
assume mainnet or a recent wall clock.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| | |
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |\ \ |
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
prepend and editor
- feed-list, markdown-note: open the Feed tab, on Following; feed-list opens
the editor from the feed's ⋯ menu
- feed-stability: the warm-up query asks kinds 1+1068 (polls); a live post with
the header on screen goes in above the first post, held still (it no longer
waits); the per-frame drift check uses a second post once the header is away
- relays-settings: a new identity puts out its DM inbox list at boot, and the
page has other Save buttons; the no-change save clears the log and clicks
the card's own Save
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
The feed left the chat home for a bottom-nav tab, and a wallet with no
feed remembered opens on Popular, so these tests click the Feed tab and
seed Following as the wallet's last feed. Also brought up to date:
- feed-live: the pill lands on the oldest new post; arrivals at the top go
in above the first post (held still), not behind the pill; scroll up a
screen at a time (one jump lands before the windowed rows are back)
- feed-custom: only the feeds' chips are counted (not All/Images/…); the
follows box is not the first checkbox any more; the last feed is
remembered across a reload; the pack shows in the feed's editor (the chat
home no longer lists the feed)
- feed-follow: Feed tab + Following chip instead of the messages-home row;
the feed opens at ten posts (tall ones, so a page doesn't fill the screen)
- moderation: nos.lol is a local stand-in (a relay that won't connect held
the mute list back past the checks)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |/
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
defs and the tint that fades on sight
- feed-media-views: the mode switch has an Articles button now
- feed-media-cache: the live watch's since-only subscription isn't part of the crawl
- feed-switch-seed: seeded feeds carry their edit time (the feeds sync merge drops one without)
- feed-editor-relays: nos.lol is a local stand-in relay, so the test doesn't depend on reaching it
- feed-streaming: the stub wallet opens on Following (no remembered feed = Popular); the held picture
answers repeat fetches once released; the new-post tint is recorded as it paints (it fades on sight)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |\ \ |
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
the amount
A tap pays the default amount at once (21 sats unless set), so the test
holds the button to open the amount screen instead of tapping an empty
wallet into a failed payment.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
- unread-dot: the front door's way to import is Create a new wallet → Have an
existing seed; the dot is the Messages bottom-nav button's
- sw-reload: the split build loads app-<token>.js, so a restamped build asks
for app-deadbeef….js; serve the real entry for it
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
When our own community list came back with a channel key the local copy
lacked (every community we create: its list entry carries the keys), the
room was torn down to be rebuilt with them, but the wraps it had already
opened stayed in seenWraps. The rebuilt room's subscription then skipped
the relay replay, so its Control fold held only editions newer than the
rebuild: a second channel showed up as the only one (no picker; general
gone from the fold), and the guestbook lost its joins.
Each room now remembers the wrap ids it opened and hands them back when it
is rebuilt. chat-layout-test reaches Messages through the bottom nav.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
- padlock-flow: the padlock lives behind the balance card's gear (wallet
settings), declining lands back there; another wallet is added from the
profile's 'Sign into another account' (import tab) and counted in the
identity switcher, since the Accounts list is no longer reached from the
wallet
- onboard-backup: the welcome card lost its blurb (42c8d4e); the way in now
says what the wallet is by putting the twelve words on screen at once
- amber-login: the starter follows wait on the deep contact-list lookup
(follows-overwrite fix), so their signature can come after the wallet
opens; keep answering sign requests until things go quiet
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |/
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Following, follow today's onboarding
- avatar-profile, profile-open: a new wallet opens the feed on Popular, so seed
this wallet's last feed as Following; profile-open opens Feed from the nav
- profile-feed: a mainnet import offers a username first (Not now), Messages
is a bottom-nav button
- profile-draft, profile-recovery: the import button reads 'Have an existing
seed or entropy to import?'; profile batches stream through queryStreamOn,
so the recovery test answers that too
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- feed tests reach the Feed from the bottom nav (the chat-home row is
gone) and seed this wallet's last feed as Following (new wallets open on
Popular, c89050e) plus the author's profile (readiness gate)
- post-actions: its picture is made locally (it read another session's
scratchpad), the post's own ⋯ (not the feed header's), a real tap on the
DM picture (a tap beside a fitted picture is a tap on the post)
- composer-media / video-compress: intercept every public media host
(ditto is first now; the tests were uploading for real)
- compose-preview: Preview is one toggle button (aria-pressed)
- thread-reply: harness has a wallet (else visitor: Reply asks to sign in),
registers <coinos-text>, holds the root's id-only query; atomic send tap
- video-unmute: stubs what videoNode reaches outside its slice; preload
none means the in-view clip is told to load
- zap-deep-profile: zap button scrolled to mid-screen (the bottom nav
covered it)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
localStorage is ~5M characters per site whatever the device, and a phone
had filled it. Profiles, faceless list, reports, follow packs, profile
pages, relay lists, the moderation baseline, community directory, link
previews, video sizes/probes and search profiles (~3M on that phone) now
live in IndexedDB, which shares the site's disk allowance (GBs).
cacheStorage keeps localStorage's string API: reads from memory,
coalesced write-behind, flushed on hide. Copies migrate on open and are
removed once written. Boot waits for it (max 3s) beside the Ark store;
caches read at construction re-merge on ready; an early write can't
replace the stored copy. A copy an older build writes to localStorage
later moves in on first ask. Wallet wipes reach it; private mode stays on
localStorage. Read markers, drafts, follows, note threads and sync
outboxes stay in localStorage on purpose (cross-tab consistency, early
server-rendered seeding). Also asks navigator.storage.persist().
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
row on the chat home)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
An invitation adds all of a person's fresh KeyPackages (one per slot, at
most ten) instead of one, and where our account is an admin a device that
finds a sibling's KeyPackage not yet in a group adds it, so the Welcome
reaches the other device through our own inbox. These are the same-account
rules Marmot's multi-device direction marks as valid today; the device
group and pairing it plans are not here. Verified against MDK (wn): a group
with two coinos leaves of one npub plus a wn member, all three reading and
writing (tools/marmot-multidevice-test.js). marmotClient takes an
injectable store for tests.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01YRC6aKhwAud231ot9FPmhi
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
interop)
src/contextvm.js speaks ContextVM (kind 25910 inside ephemeral gift wraps)
to a coordinator; src/cordn.js is the protocol (KeyPackages with hex-text
identities, the 0xC04D metadata extension, exporter-keyed ChaCha20 sealing,
unsigned nostr-shaped envelopes with the sender as MLS AAD, cordn1 group
refs, a record engine like marmot.js); src/cordn-client.js mirrors
marmot-client.js with the same interface, so the Messages group screens
drive both — New group gains a White Noise / Cordn toggle.
Verified against @cordn/cli (ts-mls) on the public coordinator both ways,
from the engine (tools/cordn-interop-test.js) and from the real app
(tools/cordn-ui-test.js). mls.js: the OpenMLS required_capabilities rule for
GroupContextExtensions now applies only to groups that carry one.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01YRC6aKhwAud231ot9FPmhi
|
| |
|
|
|
|
|
| |
still accepted); silent-payment leftovers removed
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01YRC6aKhwAud231ot9FPmhi
|
| |
|
|
|
|
|
|
|
|
|
|
| |
A reconcile pass that began before the first zap took its coin handed
it back as spendable (the server still said so) while the zap was in
flight; the second zap picked it and the server refused: 'vtxo …
already spent'. Coins whose state changed during the pass are left
alone. And a payment refused for an already-spent coin now reconciles
and pays once more instead of failing with the raw error.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_011bvzKaZosXGHkigcGcSzAR
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- The coins page's Renew button opens a confirmation instead of renewing
at once: how many coins, their amount, the fee, and what is left to
spend meanwhile — with a red notice when that is nothing (the button
selects every coin by default, which is how a user locked their whole
balance for an hour on 2026-10-03). It says the coins can't be spent
until the round's transaction confirms and that a renewal can't be
cancelled; the wallet renews for free near expiry anyway. The inline
notice from 328f2db moves into it.
- A renewal keeps its round's transaction id as soon as the round has
run (before it confirms): the in-progress card on the coins page links
to it, and the finished renewal's history row carries it, so its
detail shows the id with View/Copy like any on-chain movement.
Renewals finished before this change have no id recorded.
tools/ark/renew-confirm-ui-test.js, tools/ark/renew-txid-test.js
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01ULQZS9MQa6iAsXnrJUD9Du
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
A user renewed all ten of their coins (55,611 sats) from the coins page,
tried to pay a 55,300-sat invoice three minutes later, and was told only
'Payment failed'. Nothing had failed: the renewal's round ran at once,
but its coins stay unspendable until the round's transaction confirms
on-chain, and that block took 64 minutes. The quote found no spendable
coin and gave up with the generic message; nothing reached the server.
- The quote now tells apart (lnShortfall): money held by another payment
(wait, as before — now by sum, not one coin covering it all), money a
renewal holds ('Nothing was sent. N sats are being renewed…'), and a
real shortfall ('needs X sats with its fee, Y available'). Coins leaving
in an offboard or exit are never waited for.
- The manager's 'insufficient ark balance' names a renewal too.
- The coins page says before the tap that renewed coins can't be spent
until the round confirms, and that renewing every coin leaves nothing
to pay with meanwhile.
tools/ark/ln-shortfall-test.js
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01ULQZS9MQa6iAsXnrJUD9Du
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Regression from 6488806: pager clips were loaded crossorigin so their
frame could be kept, and on a phone the large clip's slide went black.
Some hosts (Primal's R2 bucket) send CORS headers only to a request with
an Origin and don't Vary on it, so a copy the browser cached from a plain
player load answers a later CORS load without them, and it fails. The
same thing made the size probe fail for any clip that had played in the
feed.
- Pager clips load plainly again; the still under a tap-to-play cover is
restored on every return.
- The probe (and its HEAD) go past the browser cache (no-store).
- A clip's frame is now made from bytes: the opening of the file (index
plus about 1 MB, no-store) decoded from a blob and kept as a JPEG —
for tiles and as the pager's poster. No CORS player anywhere. Files
whose index trails, or hosts whose bytes can't be read, keep the plain
player still (shown, not kept).
- Kept frames are 480 px wide (were 270) and capped at 600.
- Probe failures are stored as failedAt, so earlier failures are asked
again at once.
- Test: an R2-style host, its clip cached by a plain load first, is
still measured and its frame kept (failed before this change).
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01ULQZS9MQa6iAsXnrJUD9Du
|