| Commit message (Collapse) | Author | Age | Files | Lines |
| ... | |
| |
|
|
| |
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
| |
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
The avatar img was recreated on every render — boot's render bursts made
it flash; there is exactly one header avatar, so the node is reused until
the profile actually changes.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
| |
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
| |
Anyone still on the npub-shaped default sees their address here, not in
the collapsed corner of Settings where the claim form lived.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
| |
The registrar now lets a migrated coinos user's nostr identity (re)take
its own name — migration could land the claim in whatever wallet ran it,
stranding the name there. The claim form signs with the (re)attached
login identity when there is one; the wallet key alone could never prove
the takeover.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
| |
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
| |
Opening it hides the payment address and its QR — two payment codes on
one screen is a good way to have someone scan the wrong one. "Hide"
becomes "Back", which is what it now does.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Between "do you have a nostr account" and claiming a username, new users
are asked whether they already have an account on the original coinos.
Yes hands off to coinos.io/migrate with their fresh v3 payment address
and a return URL — they're already signed in there, so no password or
key ever travels. That page sweeps the balance over Lightning and
renames the old account, releasing the username.
Coming back, coinos.io returns ?migrated=<username>; v3 claims that name
on the registrar (retrying for a minute, since the registrar's
"is this a legacy user?" guard caches), and their lightning address now
resolves to the v3 wallet.
The legacy page ships in coinos-ui and is NOT deployed yet.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Mining pools (Ocean) and payroll pay to a reusable offer rather than a
lightning address, and the memo is how the payer labels it. A
disclosure under the payment address mints one: the registrar's new
NIP-98'd /offer endpoint asks the ASP's CLN for an `amount: any` offer
carrying the memo, keyed to the caller's name (issuer = their address,
so two users' identical memos can't collapse onto one CLN offer). Up to
ten each, identical memos reuse the existing offer, and GET lists them.
Settled offer payments already had a home: the registrar's settle loop
now resolves a custom offer id to its owner and hands it to the same
forwarder the default offer uses — an instant, free arkoor send into
the user's Spending balance.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Fresh devices land in a full-screen flow instead of the unlock screen:
welcome → "do you have a nostr account?" (sign in brings wallet, name,
and profile along; No mints a wallet on the spot) → claim a username
(the background npub-default only surfaces a Keep button; a custom
claim — or a restored login's recovered name — advances by itself) →
pick a punk or upload a photo (nostr.build), published as the kind-0
name+picture → confetti. "Enter coinos" drops into a three-stop tour:
the avatar menu, the Spending/Savings toggle, and the tabs with the
swipe tip — each highlighted by a measured gold ring over a dimmed
page. One time only (localStorage flag), with an "I already have a
wallet" escape to the classic screen.
New seams: names.namesClaimForm, messages.publishProfile.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
|
| |
|
|
|
|
|
|
|
| |
The registrar's auto-claimed username and every npub-fallback display
name use the npub's first 12 characters, shown whole (no truncation
dots), and the profile page's npub gets a copy button.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Tapping any avatar or author name (chat rooms, DM threads, the chat
home) opens a profile page: avatar, name, nip05, lightning address,
about, npub, with Message and Pay actions (Pay runs the npub payment
cascade). Your own profile — reachable from your avatar on the chat
home — gets an editor for name, about, picture, and lightning address
(prefilled with your coinos address); saving merges over the newest
published kind 0 so fields we don't understand survive the round trip.
Zaps now remember who they went to: the ark feature keys the recipient
by what the movement already records (destination address or invoice)
and history rows wear a clickable avatar chip that opens the profile.
The messages feature exposes showProfile/profileChip seams so any
feature can do the same.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
A payment to an address settled on our node and then sat in a retry
queue because the float wallet that forwards it was empty — the money
was safe but invisible to the recipient. Delivery now has a second
route: ask the recipient's wallet for an invoice (CLINK) and pay it
over Lightning, which needs no float at all. The float path stays first
because it works while they're offline; the queue is now the last
resort rather than the only one.
Existing addresses never carried the wallet's offer key, so that route
was unavailable to them. The wallet now records what it published and
re-registers whenever the registrar is missing the current key.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
An address only worked for wallets that speak DNS payment instructions
or BOLT 12; everything else looks for /.well-known/lnurlp/<name>. The
registrar now serves LUD-06/16 (with NIP-57 zap support), preferring
the path that touches no funds: if the recipient's wallet published a
CLINK offer key, we ask IT for the invoice over nostr and hand the
result straight back — the payment never passes through us. Only when
nobody answers does our node mint the invoice, and the existing settle
forwarder pushes the money on to their address, signing a zap receipt
when the payment was a zap.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
A bulk replacement removed lookupMine() and the flag along
with the block it was rewriting, so names setup threw at runtime — the
kind of break every existing test happily passed over because nothing
ever constructed a feature and started it.
tools/features-smoke-test.js does exactly that: builds every feature
against a stubbed wallet with the network cut, runs init/render/stop,
and fails on undefined identifiers. It caught the second missing helper
immediately.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The passive setup path asked the browser extension to sign the claim,
so it sat behind a permission popup — 20s per attempt, retried, hence
the minute-long spinner ending in the manual form. The wallet's own key
now makes that claim: no signer, no prompt, no wait. Tying the address
to the user's real npub happens at login instead, where the signer is
already live, and nominates the wallet key to manage the record after.
Failures are visible now rather than hidden: the pane shows why setup
failed, the watchdog is 12s instead of 60s, internal timeouts are
tighter, and the registrar logs every refusal with its reason.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
NIP-98 puts the claim under an Authorization header, but the registrar
only allowed content-type in access-control-allow-headers, so browsers
blocked every claim before sending it. The failure arrived as a generic
network error, which the retry logic treated as transient — hence the
endless 'setting up your payment address' spinner. Bun tests never saw
it because they don't preflight.
Registrar now allows the header. Client-side, nothing may hang: signing,
the registrar call and the ark lookup all have timeouts, retries are
capped, and a one-minute watchdog always resolves the spinner into
either an address or the manual form.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
After a reload the extension signer is gone, so claiming the user's
real npub name was signed by the wallet key — which the anti-squatting
rule rightly refuses, and the retry loop then span forever. An
installed extension is now silently re-attached when possible (keeping
the address tied to the real identity across reloads), refusals are
treated as permanent rather than retried, and anything unresumable
falls back to the wallet's own npub so an address always appears.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
| |
The auto-claim ran once at feature init — before Ark finishes
connecting — saw an unavailable wallet and gave up for good, so users
got a claim box instead of their npub address. It now retries while Ark
comes up (and after a failed claim), and shows a setting-up state
rather than the claim form while it works.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Consistency fix with teeth: logging in with a pasted key derived one
wallet while an extension login for the SAME identity found no backup
and generated a different one. Now every signer kind runs one flow —
look for the published association first (that's where the money is),
then derive (key in hand) or generate (signer only) — and a derived
seed is published too. That costs nothing, since the derivation is
public and anyone holding the key could compute it anyway, and it makes
the identity open the same wallet however you log in.
Registrar auth is now NIP-98 (HTTP Auth, kind 27235) instead of a
homemade envelope: the signature binds the URL, method and body hash,
so a captured header can't be replayed elsewhere. NIP-78 already
covered the encrypted association; NIP-26 delegation is deprecated, so
owner→manager nomination lives in the registrar's own model: an
npub-shaped name may only be claimed by that identity, which nominates
the wallet key to keep the record updated afterwards (the wallet key is
the only one always available — offline, in the worker).
Payment addresses therefore default to the user's REAL npub in all
three login methods, falling back to the wallet's own identity when no
Nostr account is linked.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Every wallet silently claims the first 20 characters of its npub as its
payment address the first time it opens: unique, free, and nothing to
decide. The pick-a-username gate is gone (the generic onboardingView
hook stays as an extension point). A custom name is an optional change
tucked into the payment-address card — and swapping to one releases the
old name so the registrar and DNS stay tidy. Custom names may become
paid later to deter squatting; the default tier keeps working
regardless.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
New wallets must pick a username before entering the wallet: the
onboarding gate renders a claim screen until a name exists. Imported
seeds skip it — the registrar's new /pubkey lookup recovers the name
owned by the wallet's key, so nothing is retyped. If claiming errors
(registrar or ark unreachable) a do-it-later escape appears rather than
locking anyone away from funds; the prompt returns next open.
The Receive tab now defaults to the payment address — name QR + copy —
with the on-chain address and other modes behind it, and the claim form
inline for wallets that skipped onboarding.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The wallet is the next version of coinos, deployed at v3.coinos.io
(same build as halwallet.app) ahead of an eventual migration of
coinos.io itself. App name, manifest, notifications, and the NWC alias
all say Coinos; the Hal Finney tribute stays.
The registrar is multi-domain (per-domain Cloudflare zones; existing
halwallet.app names keep working) and new claims default to @coinos.io.
Names belonging to existing coinos users are reserved for them — the
registrar checks the live coinos API before granting a claim — until
the migration gives those users a way to claim their own.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
CLINK offers (noffer): every wallet gets a static offer keypair (synced
across devices, first-minted wins) answering kind-21001 invoice
requests — from open tabs and from the service worker while closed,
which mints against the mirrored state (the record now carries chain-4
and chain-5 key windows) and raises an open-to-receive notification.
Zap requests ride along and their kind-9735 receipts publish once the
payment is claimed. The code is shown in the payment-address card for
pasting into a Nostr profile; the notifier watches and relays kind
21001 alongside NWC.
Payment names also gain a Lightning offer: the registrar creates a
BOLT 12 offer per name on the node and appends lno= to the DNS record;
a settle-forwarder pushes each received payment on to the name's ark
destination from a small float wallet (custody window: seconds between
Lightning settle and the ark send).
Name resolution now runs full client-side DNSSEC validation
(src/dnssec.js): binary DoH, root-anchor chain walk, RSA + ECDSA via
WebCrypto — the resolver is untrusted transport, verified against live
signed zones including the canonical BIP-353 test name.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
|
|
Receiving: a Settings card claims a username, signed with the wallet's
nostr key; the new names registrar (names/server.js, deployed at
names.halwallet.app) enforces first-come ownership by that key and
mirrors the claim into a DNSSEC-signed TXT record at
<name>.user._bitcoin-payment.halwallet.app whose BIP-21 URI carries the
wallet's reusable ark address. The record re-registers itself if the
ark address ever changes, and a collapsible hint shows the single CNAME
a user adds to serve the same name from their own domain (BIP-353
supports delegation when both zones are DNSSEC-signed).
Sending: a pasted name@domain resolves over DNS first — two independent
DoH resolvers must agree and both report the DNSSEC AD flag (full
client-side chain validation is the stated follow-up) — an ark=
instruction pays natively, an on-chain path fills the send form, and a
name with no DNS record falls back to the Lightning-address zap flow.
Co-Authored-By: Claude Fable 5 <[email protected]>
|