| Commit message (Collapse) | Author | Age | Files | Lines |
| ... | |
| |
|
|
|
|
|
|
| |
The float pays out in Ark while incoming Lightning accumulates on the
node, so it needs periodic refilling. It can now mint an invoice
against its own balance (token-guarded, since the endpoint is public).
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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]>
|