| Commit message (Collapse) | Author | Age | Files | Lines |
| ... | |
| |
|
|
|
| |
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_014tE4U5nEjGTQy8PwYqamfv
|
| |
|
|
|
|
|
| |
forever — the deadline survives refreshes and relocks on time; the skip button says what it does; the header padlock hangs open in green while you're in
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_014tE4U5nEjGTQy8PwYqamfv
|
| |
|
|
|
|
|
| |
Move money is gone — and pasting an on-chain address in a Spending wallet just exits ark to it
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_014tE4U5nEjGTQy8PwYqamfv
|
| |
|
|
|
|
|
| |
switcher, named for its purpose, renamable apart — and a new wallet can carry its own seed or live at the next BIP84 account of one you already back up
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_014tE4U5nEjGTQy8PwYqamfv
|
| |
|
|
|
|
|
| |
avatar goes straight to your profile — the popup menu retires
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_014tE4U5nEjGTQy8PwYqamfv
|
| |
|
|
|
|
|
| |
of a post to the profile it came from, and a refresh mid-thread reopens the thread
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_014tE4U5nEjGTQy8PwYqamfv
|
| |
|
|
|
|
|
| |
survives reload and is re-applied on boot — profiles, tabs, settings pages all hold their ground
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_014tE4U5nEjGTQy8PwYqamfv
|
| |
|
|
|
|
|
| |
zaps your saved amount in one tap (asking once if you haven't picked one), and tapping a note opens its thread
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_014tE4U5nEjGTQy8PwYqamfv
|
| |
|
|
|
|
|
| |
hover, focus, selection and scroll simply persist — with a smoke test that walks the app and proves node identity survives
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_014tE4U5nEjGTQy8PwYqamfv
|
| |
|
|
|
|
|
| |
resting cursor keeps its hover through a boot burst
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_014tE4U5nEjGTQy8PwYqamfv
|
| |
|
|
|
|
|
| |
honours server-side — and the status bar gets a real coinos badge instead of a black blob
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_014tE4U5nEjGTQy8PwYqamfv
|
| |
|
|
|
|
|
| |
stop rebuilding the focused input mid-keypress; the profile npub is itself the copy button
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_014tE4U5nEjGTQy8PwYqamfv
|
| |
|
|
|
|
| |
and Move money appear once it's set up (or money's already there), and the tour is gone
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
| |
the tour stops flickering under a busy first scan and finds the balance card it lost
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
| |
optional 13th word, not a login or encryption
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
| |
in Savings — naming yourself waits until after the tour, as an offer to set up Spending
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
| |
activate, so no one inherits another wallet's chats or steals its inbox
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01DbA53PJA8fgSvMcEzfuw22
|
| |
|
|
|
|
|
| |
and uploads just change it
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01DbA53PJA8fgSvMcEzfuw22
|
| |
|
|
|
|
| |
search answers from memory before the network
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
| |
address to land on becomes a gift only their key can open
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
| |
keeps its pending line to itself
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01M5kFodm9azZJVTQxnkDdKe
|
| |
|
|
|
|
|
| |
anywhere
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01M5kFodm9azZJVTQxnkDdKe
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The warning: when the Spending balance minus round fee is under the
330-sat round minimum AND a vtxo enters the renewal window, auto-refresh
can't save the coins — a wallet-screen notice (and a daily local
notification, when permitted) says to receive any amount or spend
before the deadline. New walletNotices feature hook renders under the
balance card.
The amnesty: sub-dust vtxos have no unilateral exit to protect, and
regtest proves captaind keeps cosigning their spends past expiryHeight —
even after the watchman claims the backing on-chain
(tools/ark/expired-dust-test.js). Only hal's own receive validation
stood in the way; it now exempts sub-330 vtxos from the expiry check.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015QwAtBSpKvECqp1rHLHjJk
|
| |
|
|
|
|
|
|
|
| |
Not a pane of its own: a regular Bitcoin address means receiving to
Savings, so the entry switches the account selector over and lets the
savings receive view show its fresh address.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015QwAtBSpKvECqp1rHLHjJk
|
| |
|
|
|
|
|
|
|
| |
Finishing the avatar step published name = the payment-address name and
the default punk under the user's real nostr identity — renaming (and
re-facing) profiles that already existed. Wizard-suggested fields are
fill-only now: they land only where the profile has nothing.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
| |
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
| |
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
| |
Publishing the profile on the avatar step is best-effort now — a signer
that can't sign (a sleeping phone bunker) skips it with a toast instead
of erroring the Continue button forever. And once a wallet exists, the
logo leads home even out of a resumed wizard.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
| |
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
| |
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
| |
The pencil opens a dedicated screen — no balances, no tabs — wired into
the history stack like the other sub-pages.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
| |
Signing in mid-wizard with a key whose wallet was restored left you on
the sign-in step: the back-button hold matched the restored account and
blocked the auto-advance. A login now clears the hold explicitly — and a
restored wallet skips the rest of onboarding entirely; it was already
onboarded wherever it came from.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
| |
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
| |
Back from username (and sign-in) holds the auto-advance for the wallet
you backed away from, so welcome doesn't bounce you straight forward;
Get started then continues with the already-minted wallet instead of
minting another.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
The recipient candidate list was hiding under the on-screen keyboard:
scroll the field to the top on focus and when fresh candidates land,
give the list scroll room to get there, and let the keyboard resize the
viewport (interactive-widget) so the scroll has somewhere to go.
The wizard now shows whenever the device has no wallet — the one-time
onboarded flag is gone; deleting every wallet brings the wizard back.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
| |
The wizard mints the wallet on its first step, so 'an account exists'
stopped meaning 'wizard done' — reloading dropped you into the half-set-up
wallet. Persist the current step until the wizard finishes.
Also trims the balance coach-mark copy.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
| |
A background repaint rebuilt the strip at scrollLeft 0 mid-swipe; render()
now carries scroll positions across the swap the same way it carries focus.
The onboarding column also sized itself to the strip's intrinsic width
(auto margins defeat flex stretch), overflowing phones below ~450px.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
| |
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Paste, on the import and load-seed screens, was a bordered box floating
beside a small label — heavier than the label, detached from the field it
fills. It now sits inside the textarea, and only while that textarea is
empty: the only time it's wanted, and the only time it can't cover what
you typed. It's toggled on the node rather than through render(), since
re-rendering a textarea per keystroke rebuilds it under the caret. Beside
a one-line input (Send) the old placement was right and is untouched.
The footer measured 100dvh, which on a phone can resolve to the tall
viewport at first paint and leave the language picker just below the
fold. svh is the one that fits with the address bar showing. Short
screens also tighten their padding, which buys back the ~50px the
create/import screen was overflowing at 375x553.
And the wizard no longer asks every new user whether they have an old
coinos.io account before letting them have a name. Claiming the name is
the step; the people who do have an old account know it, and say so with
a link. That screen is a statement now, not a question they just
answered. The npub-shaped default address is no longer offered as a
button — a plain skip goes past without showing anyone that.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
|
| |
|
|
|
|
|
|
|
| |
Same construction as the sign-in button on the unlock screen — .btn-block
forces display:block, so the flex centering lives on an inner wrapper
rather than the button.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The sign-in screen stacked 'Connect a signer app' directly above a
bunker/nsec field, which reads as two steps rather than two ways in.
A divider says which it is.
The wizard's second step asked whether you have a nostr account, then
sent you to a screen that asks the same thing. Step one now offers both
paths directly — Get started, or sign in with Nostr — and the middle
step is gone, along with its strings. The welcome blurb goes too: the
screen is one decision, and prose above it is something to read before
you can make it.
The footer sinks to the bottom of the window rather than trailing the
content up the page. #app is a full-height column now; the chat card
sizes itself against the viewport, so the layout test covers it at
three sizes.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Locking with no password locks nothing — the wallets sit on the device
under an empty one and reopen with a tap. So the first deliberate lock
now asks whether to set one, explaining plainly what happens if you
don't. 'Not now' is a real answer, recorded, and never asked again: a
wallet that nags is a wallet people stop reading.
The offer rides the deliberate lock only. lock() is also where the idle
timer, the last-wallet-removed path and boot-after-expiry land, and a
password form appearing because you went to lunch is a different app
than the one you left.
Two subtleties worth naming: the offer is set after lock()'s ui reset
block, which clears ui.pw and had been swallowing it; and taking the
offer re-enters lock(), which now finds a password and lands on the
unlock screen instead of the wallet list.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
'Logout' promises a return to a fresh app with nothing of yours left on
it. This closes the open wallet and keeps everything saved, which is why
it read as interchangeable with 'Clear all' — the one that really does
send you back to the beginning.
Renamed via a new key rather than rewording the old one: nineteen locale
tables carry their own word for 'Logout' and t() prefers the locale's
value, so reusing the key would have kept the wrong meaning in every
language but English. The dead key is dropped from those files; they
fall back to English until translated.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Wallets save themselves to this device as soon as you open one, encrypted
under an empty password unless you choose one. Logging out still sent
you to 'Unlock saved wallets — enter your password', which asks for
something that doesn't exist and makes logout look like it did something
drastic. It didn't: logout only drops the keys from memory, and 'Clear
all' is the one that deletes.
With no password, logout now returns to the wallet list — honest, since
nothing is protecting those wallets and a blank prompt protects nothing.
With a password set it prompts exactly as before.
Fixed underneath: mergeVaultList derived the comparison xpub with
accountXpubFor's mainnet default, so on any other network it never
matched the stored one and every unlock re-added the same wallet as a
fresh entry — visible as the same wallet listed twice, once watch-only.
The seed-mismatch checks in 'load recovery phrase' had the same default
and would have rejected the correct seed on testnet.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The header carries a message button again, left of the wallet selector,
with a red dot when a conversation is waiting. Unread is a per-thread
watermark on the newest message from someone else, kept in the rumor's
own created_at so it means the same thing on every device it syncs to.
Rooms subscribe at startup now, or the dot could not speak for a
community nobody was listening to.
Communities no longer buzz a phone by default: push registration only
carries the stream keys of communities you have opted in, per community,
from a bell in the room header. DMs and payments are unchanged.
Presence and typing ride the channel stream as 21059 wraps, so who is
around stays inside the community's encryption rather than becoming a
public status. Measured against relay.coinos.io and nos.lol, neither
actually drops NIP-01 ephemeral kinds, so beats carry a NIP-40
expiration and relay.coinos.io sweeps kind 21059 hourly — and presence
is dated by the beat, never by arrival, or a replayed beat would light
up the whole member list.
The member list follows Telegram: online, then last seen in minutes and
hours, then a vague 'recently' rather than advertising how long someone
has been gone.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The service worker can't watch a relay, so it doesn't try: the app
resolves the destination to something concrete (ark address, LNURL
endpoint, or on-chain script) and mirrors it beside the keys the
background NWC payer already uses. On a push wake-up — which is exactly
when money has just landed — the worker re-checks the same gate and
sends, writing the outcome back into the mirror for the app to absorb on
next open. A partial on-chain forward still waits for the app, since
carving an exact vtxo needs more round trips than a worker is promised.
writeBgMirror now carries forward the NWC connections and offer when
another caller refreshes the mirror, instead of blanking them.
And onboarding's legacy step loses its Back: the wallet exists by then,
so returning to the nostr question just bounced straight forward again
and the link looked broken. Its copy no longer promises a rename either.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
A seed that only lives in this tab is one refresh from gone, and that
surprise costs people money — so a wallet now saves itself to the device
when it's opened or committed, no button required. No password is set
(Settings still offers one), and a locked existing vault is left to the
manual Save button since writing it needs their password.
The recovery card gains a middle step: the first click opens the grid
with the words masked — the warning and the shape of what's coming are
on screen before anything readable is — and a second click shows them.
Copy only appears once they're visible.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
|
| |
|
|
|
|
|
|
|
|
| |
"Instant · free to send" and "On-chain · mining fees apply" were one
line that swapped with the account; the card is just the balance now.
Strings, styles and stale translations removed with it, and the face's
reserved height comes down to match.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
|
| |
|
|
|
|
|
|
|
|
|
| |
The dots were an indicator pressed into service as a control — fine
under a thumb that can just swipe, too small for a mouse. They're
replaced by a pill in the header row naming the account it takes you to
(⇄ Savings / ⇄ Spending), which is both a proper click target and a
clearer answer to "what's the other one?". Swiping the card still works.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
|
| |
|
|
|
|
|
|
|
|
| |
The step needed this wallet's payment address for the migrate link, and
the background claim often hasn't landed yet when the step appears — so
it flashed a spinner first. The page renders complete now; if someone
taps before the address exists, the wait happens on the button instead.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
|