| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
| |
Opening a wallet no longer contacts the ASP unless it already holds
vtxos / history / unfinished operations. Fresh wallets connect on first
use instead: selecting Ark on the Receive tab, confirming an Ark send,
or the Connect button on the Settings card. connectArk() is idempotent
and generation-guarded against wallet switches mid-dial.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
|
| |
|
|
|
|
|
|
| |
History is the home for Ark movements now; the Settings card keeps
balance, coin count, board, refresh, and in-progress operations.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
|
| |
|
|
|
|
|
|
|
| |
Receives, sends, and boards interleave with on-chain transactions in one
time-sorted, paginated timeline, each tagged 'Ark'. Refreshes are
internal churn and stay in the Settings activity list only.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
|
| |
|
|
|
|
|
|
|
| |
Same card and tap-to-acknowledge flow as on-chain receives; the ack
persists in the ark state (shows exactly once) and a 2h recency guard
keeps old payments from celebrating when a wallet is opened later.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- Settings: Ark server card (off by default, per-network presets incl.
Second mainnet + local regtest, custom URLs) with balance, coin count,
board form (on-chain -> Ark; funding output pinned to vout 0 via the
new buildTx noSort option), refresh/consolidate, and recent activity.
- Receive: Ark option in the address-type dropdown (QR + copy).
- Send: t?ark1 addresses are recognized in the normal send form and
route to an Ark confirmation (no mining fee) with a success view.
- Balance card: Ark balance line under the on-chain figure.
- ArkManager lifecycle: per-wallet instance created on account
activation, background sync every 5s (regtest) / 30s, state persisted
under the wallet cache key.
Verified end-to-end in a real browser (tools/ark/ui-test.js, puppeteer
against the regtest stack): receive, send, board, and refresh all green.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
|
| |
|
|
|
|
|
|
|
|
|
|
| |
A reverse-swap claim is an on-chain receive, so instead of a separate LN
'Received!' card (which stacked with the generic celebration and needed
suppression), credit the claimed coin to the wallet the instant we broadcast the
claim — new wallet.creditReceive() mirrors the instant-payment watcher path
(adds the utxo + pending row, advances the receive index, emits). The generic
'Payment received!' then fires immediately with the right amount, one screen, one
tap. Dropped the LN success card + the suppression logic.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
| |
A reverse-swap claim is also an on-chain receive, so after the LN 'Received!' card
the generic 'Payment received' celebration would fire too — making the first Done
tap appear to do nothing (it just revealed the second screen). Suppress the
generic celebration while the LN claim card is shown, and have its Done ack the
generic one as well, so a single tap dismisses both.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- Send: show only the destination input ('Address or Lightning invoice') until a
valid on-chain/SP address is entered, then reveal amount + fee rate + coin
selection + Review. A pasted bolt11 still auto-advances to its own confirmation,
so those controls never appear for it. New wallet.isOnchainAddress() validator +
a destReady() gate; recipient onInput/paste re-render only when validity flips.
- History: stop listing swaps at the top. Instead, a send/receive that was part of
a swap shows its Lightning context (invoice, swap fee, status, refund) on the tx
detail screen via swaps.findByTxid(). Removed the dead swapListView.
- Lightning receive: drop the '50000' amount placeholder — a bare number looked
like a value was already entered; the min/max hint below covers it.
Verified in-browser: controls hidden until a valid address, then revealed; LN
receive placeholder empty; no errors.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
| |
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
| |
The 'Receive over' label was redundant above a self-explanatory dropdown; remove
it (and the now-unused i18n key). Rename the first option to 'Bitcoin address' so
it's clear alongside Lightning and Silent payment.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
| |
The fee label and status copy shouldn't hardcode the provider, since the swap
backend is configurable. 'Boltz fee' → 'Swap fee', and the pay/settle messages no
longer name Boltz. (The settings card still says 'Boltz-compatible provider',
which is an accurate description of the API standard.)
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- Receive: replace the 3-button segmented control (too wide on mobile) with a
compact 'Receive over' dropdown that scales to more address types.
- Remove the standalone Swap tab. Paying an invoice now lives in Send; the
in-flight/recent swap list folds into the top of History. Deleted the dead
swapTab + doSubmarine.
- Send: as soon as a valid bolt11 is pasted/typed/scanned into the recipient
field, jump straight to the Lightning confirmation (submarine-swap quote with
itemized cost) — the invoice's baked-in amount is used, so the amount field is
skipped entirely. Wired into the recipient onInput, the paste button, and QR scan.
Verified in-browser: Swap tab gone, dropdown renders, and a pasted 60k invoice
auto-progresses to 'Pay over Lightning' with the Boltz fee shown, no Review tap.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Paste a bolt11 into the normal Send recipient field and Review now detects it and
routes through a Boltz submarine swap — no 'swap' concept surfaced. Split
startSubmarine into quoteSubmarine (POST + build-but-don't-broadcast the funding
tx) and fundQuotedSubmarine, so the review shows an itemized cost before
committing: Amount + Boltz fee + on-chain network fee = Total. Pay funds the
lockup; Boltz pays the invoice once it confirms.
Verified on regtest: a 60,000-sat invoice quotes to Amount 60,000 / Boltz 362 /
network 442 / Total 60,804, with a Pay button.
Lightning-address (LNURL) input + removing the standalone Swap tab are the
remaining pieces.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Receive now has a segmented [Address | Lightning | Silent payment] toggle.
'Lightning' takes an amount and creates a Boltz reverse-swap bolt11 to share;
when it's paid, Boltz locks up on-chain and the SwapManager claims it into this
wallet automatically (shown live, then 'Received!'). Gated to non-watch-only
wallets (a reverse swap needs our keys). Removed the duplicate 'Receive over
Lightning' card from the Swap tab. Verified in-browser on regtest: real limits
(Min 50,000) load via the proxy and an invoice is created.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
expected')
A watch-only wallet has no private key, so swapNode().privateKey is null and
startReverse's sha256(node.privateKey) threw 'uint8array expected'. The receive
card wasn't gated by watchOnly (the pay card already was). Hide both for watch-only
and show a prompt to re-enter the recovery phrase, since swaps need the key to
derive the preimage and claim on-chain.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
hardcoded 50k
doReverse rejected anything under a hardcoded 50,000 sats — which happens to be
the regtest provider's minimum, but mainnet boltz's real minimum is 25,000 (and
providers/networks differ), so valid 25k-50k mainnet swaps were refused and the
max was unchecked client-side.
Add SwapManager.reverseLimits() (GET /v2/swap/reverse, cached per API) and use it
in the swap UI: show the real min/max range under the amount field and validate
against it. Reset the cached limits when the network or provider changes.
Verified: regtest min/max 50,000/40,294,967; mainnet 25,000/25,000,000.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |\
| |
| |
| |
| |
| | |
# Conflicts:
# src/api.js
# src/app.js
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The create pane shows the existing draftMnemonic's backup if one is set, only
falling back to the Generate-seed step when it's empty. Nothing cleared the draft
after a wallet was created, and Add wallet jumped to the create tab without
resetting it — so Add wallet presented the already-active wallet's seed, and
'creating' it just re-opened the same account (no new wallet).
Clear draftMnemonic (+ createStep, confirm) when Add wallet starts a fresh
creation, and clear it in openWallet once a seed has been used to create/enter a
wallet, so each new creation generates a fresh seed.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Opening a gift link when you already have wallet(s) now shows a 'Choose where to
receive it' screen — each known wallet (full accounts this session plus the
durable directory, deduped by xpub) plus 'Receive into a new wallet'. A
first-timer with no wallets goes straight to a fresh wallet as before.
Claiming into an existing wallet activates it non-provisionally and sweeps the
gift to its receive address (watch-only is fine — re-enter the seed to spend),
skipping the new-seed backup step. Both bearer and locked (NIP-17) gifts route
through the same claimGift() entry. Verified in-browser: selection lists the
wallet + new option + amount; claim-into-address mechanic proven on regtest.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Persist a per-account gift record (shareable link/code + amount, plus a locked
gift's claim code) when a gift is created, so:
- Unclaimed gifts in History get a 'Gift link' button that re-opens the QR + link
(and the claim code for locked gifts), to re-share without recreating the gift.
- Once a gift's coin is spent and we didn't revoke it, it shows in History as
'claimed' instead of vanishing. Revoking marks the record so a reclaim isn't
mislabelled as claimed.
Verified on regtest: create → outstanding=1, link stored; after the recipient
claims → outstanding=0, claimed=1 with the right amount.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| | |
| |
| |
| |
| |
| | |
card
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
- Settings gains a 'Consolidate coins' card (shown when you hold >1 spendable
coin): wallet.consolidate() does a max self-send merging them into one, so
future sends/gifts use a single input — cheaper and a smaller gift QR.
- At gift creation, detect when the gift would bundle several coins
(giftCoinSummary returns the input count) and trigger the split/consolidate
offer when count ≥ 3 (not just when it frees change). The offer now explains it
plainly ('would bundle N coins, costly to claim') and recommends splitting into
one coin first, with 'Use N coins anyway' as the explicit opt-out.
Verified on regtest: 6 small coins → a 1000-sat gift needs 3 inputs and triggers
the offer; consolidate merges them to 1 coin, after which the same gift is a clean
single input.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
- A many-input gift produces a URL too long for a QR, and qrSvg threw — uncaught,
inside render() — so the click did nothing and showed no error. Wrap the gift QR
in try/catch: render the QR when it fits, otherwise fall back to a 'too large for
a QR — use the link' note. The link itself still works.
- The split-offer card has its own Back; hide the gift sub-view's outer Back while
the split offer is showing, so there aren't two stacked Back buttons.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The gift payload is now encrypted two ways in the link: under the one-time code
(the DM / manual path) AND to the recipient's nostr pubkey via an ephemeral key.
When a NIP-07 browser extension (window.nostr) is present, the claim view offers
'Claim with nostr extension' — it checks the extension's pubkey matches the gift,
decrypts ctKey via window.nostr.nip44.decrypt, and claims into a fresh wallet with
no code. The pasted-code path remains as the fallback for everyone else.
Verified: both decrypt paths recover the payload from the blob; a different
extension account is rejected.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
A gift can now be locked to a recipient's nostr npub. The shareable link
(/lg/<blob>) carries the amount + recipient in the clear (anyone can see what it
is and who it's for), but the claim payload is encrypted under a one-time code.
That code is delivered as an encrypted nostr DM (NIP-04) to the recipient — so
only they can read it. They paste the code to decrypt, then claim into a fresh
wallet exactly like a normal bearer gift.
- nostr.js: parseNostrPubkey/npubOf, encryptWithCode/decryptWithCode (random
32-byte code), fetchNostrProfile, NostrSync.sendDM (broad relays).
- wallet.js: lockGift → { blob, claimCode }, previewLockedGift, nostr identity +
sendNostrDM.
- app.js: gift form gains an optional 'Lock to npub' field that shows the
recipient's avatar + name (nostr kind-0 profile); create encrypts + DMs the
code (with sent/failed status + a copyable fallback); /lg/ links open a claim
view showing the gift + recipient where you paste the code; account settings
shows your own npub to share.
Verified: code lock/unlock round-trip, a real nostr DM published and read back
from relay.damus.io, and the UI loads + renders with no errors.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| | |
Drop the human-readable name and the scheme prefix in the data-source and
SP-indexer dropdowns, e.g. 'electrum.coinos.io', 'mempool.space/api',
'tweaks.coinos.io'. 'Custom' stays bare.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
- Data-source and SP-indexer dropdowns now show the endpoint URL alongside the
name (e.g. 'coinos — wss://electrum.coinos.io'), so it's clear where data comes
from; 'Custom' stays bare.
- The tweak indexer is now served at https://tweaks.coinos.io (was halwallet.app/
sp): a cloudflared route on the bitcoin tunnel → the indexer at :8888, with a
DNS CNAME. Verified from a browser: /height, /mempool (1064 items), and /ws all
work (the coinos.io Bot Fight Mode challenges non-browser clients only).
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
- Combined the separate Electrum and Explorer settings into a single data-source
list. Each preset knows its type (electrum vs esplora); a custom source's type
is detected from its URL scheme (ws/wss → Electrum, http/https → Esplora). The
settings UI is now one dropdown + a URL field for Custom, with a one-line note
showing the detected/selected type. getBackend/electrumCandidates/resolveHosts
derive from the selected source. Old split settings migrate automatically.
- coinos now points at wss://electrum.coinos.io (was wss://halwallet.app/electrum).
Set up as a cloudflared route on the bitcoin tunnel → the Fulcrum WS (:50003),
with a DNS CNAME. Verified the endpoint serves Electrum from a browser (Fulcrum
2.1.1 replies; cloudflare Bot Fight Mode only challenges non-browser clients).
Verified: combined list + auto-detection (unit + browser), old-settings migration,
regtest data flow unchanged, and the app loads over electrum.coinos.io with no
errors.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Two causes, both fixed:
- _scanSpMempool emitted on every WS push even when our pending set was unchanged.
The mainnet mempool churns constantly, so this re-rendered the whole app every
few seconds, stealing focus mid-type. Now it only emits when our pending SP set
actually changes.
- render() rebuilds the DOM (replaceChildren), which inherently drops focus. Added
focus + caret preservation: capture the focused field's index-path and selection
before the rebuild, restore them after. So any render source (poll, payment
push, scan) is now invisible to someone typing.
Verified via CDP: typing 'bc1q…' in the Send address, caret at 6, then forcing a
re-render — focus, value, and caret all retained.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
A freshly-generated wallet can't have received SP before it existed, so set its
scan watermark to the current tip on first connect (skipping the whole historical
catch-up) instead of scanning from 0. Threaded a 'generated' flag through the
create flow (openWallet → enterWallet → activateAccount → load spFresh); imported
wallets still scan from the indexer start since they may have prior receipts.
Verified on regtest: a fresh wallet skips the block-5780 receipt (watermark=tip,
balance 0); the same seed imported finds it.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The screen-changing back buttons (tx detail, gift sub-view, all-gifts, bump,
account settings, accounts) now call goBack(), which does history.back() when
there's an entry to pop — so they no longer push a duplicate entry. Falls back to
an explicit parent-screen navigation when there's no in-app history (e.g. reloaded
straight into a sub-screen). Modal-dismiss buttons (revoke, rename, password,
draft) are unchanged — they don't touch nav state.
Verified via CDP: detail (i=2) → in-app back → i=1 (popped) → Forward restores
the detail.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Mirror the app's screen position (screen, tab, txDetail, bump, giftsAll, giftMode,
claimStep) into the browser history, so Back/Forward (and Android system back)
move between screens actually viewed. render() snapshots just these nav fields and
pushState()s on change — incidental re-renders (typing, polling) don't add
entries. popstate restores the snapshot and re-renders. History-API calls are
guarded so they can never break a render.
Verified via CDP: tab nav and tx-detail push entries; Back/Forward (incl. A→B→A)
restore the right screen and the DOM follows.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
- One Receive card with an Address ⇄ Silent payment toggle (no separate card, no
BIP-352 badge, no scan-status line or Rescan button — discovery is automatic).
- SP receipts appear in History like normal payments: wallet.history merges BIP84
txs with per-tx SP receive rows (spTxRows), newest first; the detail view and
pagination use it. SP outputs carry a firstSeen timestamp.
- Receive description simplified to 'A reusable address that can't be tracked.'
- Removed the '· Silent payment' tag from the Send recipient line.
Verified on regtest: a received SP shows in history and balance with no manual
scan.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
scanSilentPayments() now recomputes the balance so received SP value shows in the
wallet total (not just the Receive card), and gains a silent mode. It's triggered
automatically after each full scan and on the poll loop (incremental, cheap), so
payments appear without tapping anything. The Receive card now shows a status
line ('Watching for payments' / found amount) with a small manual Rescan instead
of a primary Scan button.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
wallet.js: scanSilentPayments() pulls the indexer's /scan range, matches outputs
on-device, and verifies each is unspent via the chain backend; spUtxos + balance
are tracked in their own bucket (one-time taproot keys), persisted in the cache.
silentPaymentsAvailable()/spBalance() expose state.
app.js: the Receive tab shows the reusable sp address (QR + copy), a 'Scan for
silent payments' button, and the found amount; Settings gains a per-network SP
indexer picker (under Data source) with custom/self-host support.
sp-indexer.js: added /scan/{from} so a client fetches a whole range in one
request instead of one fetch per block.
Receiving verified end-to-end on regtest (scan finds the output, 49,999,800 sat
confirmed). Spending SP outputs is the remaining piece.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |\| |
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
On a fresh open, receiveSeenIndex was baselined to the pre-scan frontier (line
691), so the moment the socket's reconcile credited a deposit that predated the
open, nextReceiveIndex advanced past it and the celebration flashed for ~2s until
the post-scan baseline caught up. Leave receiveSeenIndex null until that final
baseline for fresh opens (matching the documented intent); the != null guard then
suppresses the flash. Same-session refreshes still use the persisted ack.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
|
| |\| |
|
| | |
| |
| |
| |
| |
| |
| | |
The mempool parenthetical is jargon for non-technical users; the status line now
reuses the plain `pending` string. Drop the now-unused pendingInMempool key.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
|
| |\|
| |
| |
| |
| | |
# Conflicts:
# src/app.js
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The recovery-phrase section of the per-wallet settings page now shows an Import
seed action for watch-only wallets, with the load-seed card inline. The load-seed
flow takes an account id (defaulting to the active wallet), so it can upgrade a
specific watch-only wallet — validating the entered seed against that wallet's
xpub before making it spendable.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| | |
| |
| |
| | |
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| | |
| |
| |
| | |
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The global Settings tab no longer shows the recovery phrase / public key — those
live only on each wallet's settings page now (the watch-only 'load seed' upgrade
stays in the global tab since it targets the active wallet). On the per-wallet
page, recovery phrase moves to the top and auto-logout to the bottom. Removes the
now-dead pubkeyCard/autoLockCard. Lowercases 'THIS' in the auto-logout copy.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The accounts list now shows a settings cog (instead of a rename pencil) that
opens a per-wallet settings page: edit name, set auto-logout (moved here from the
global settings tab), reveal the recovery phrase, and show the public key (zpub)
— all read from the account itself, so it works for any wallet, not just the
active one. Room for more per-wallet settings later.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The network card is now just the network picker. Each network's endpoints
(Electrum server + block explorer) live solely in the Data source card, whose
options change per network and are stored per network (so switching networks
remembers each one's choice). Removes the duplicate regtest Esplora/WS fields.
Adds mutinynet (signet — testnet address format, explorer at mutinynet.com).
Per-network defaults: mainnet → coinos Electrum, testnet/mutinynet → explorer,
regtest → local Fulcrum. Fixes tx-explorer links to use each network's web base
(no double /testnet).
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| | |
The data-source picker is now just Electrum vs Block explorer; coinos is the
first/default entry in the Electrum server list (our own Fulcrum), with public
servers as failover. Drops the standalone 'coinos' mode and the retired watcher
shim. Old 'coinos' selections migrate to electrum.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |\|
| |
| |
| |
| | |
# Conflicts:
# src/app.js
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
On regtest there's no realtime push (coinos watcher is mainnet-only), so the UI
only updated on the 5–10s poll — a funded tx took a while to appear and a
just-mined block stayed "pending" until the next reconcile. electrs speaks the
Electrum protocol the watcher already understands, but only over TCP; route it
through a small WS<->TCP bridge (see coinos-server/electrum-ws) so the wallet
subscribes scripthashes and reconciles instantly on each notification. Data
still comes from esplora; this only adds the push channel. Configurable in
Settings (default ws://localhost:50003); falls back to polling if unreachable.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Replaces the single hardcoded Boltz endpoint with a provider selector.
Presets are independent Boltz-compatible instances from SwapMarket's list
(Boltz Exchange, Middle Way, ZEUS Swaps, Eldamar) plus Local (regtest) and a
Custom option; default is Local on regtest, Boltz Exchange otherwise. The
swap-status WebSocket is derived from the API URL (http->ws + /v2/ws) unless
overridden. Swaps remain non-custodial regardless of provider — a provider can
fail a swap but never take funds (hal claims/refunds on-chain).
Co-Authored-By: Claude Opus 4.8 <[email protected]>
|