aboutsummaryrefslogtreecommitdiffstats
path: root/src/app.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-06-26 09:03:49 -0700
committerAdam Soltys <[email protected]>2026-06-26 09:03:49 -0700
commiteef3193729ccea2c3d712cda9381c24325fac260 (patch)
treedd22d714a3667773a73fc42e3b0a88b3171bdbae /src/app.js
parent190c849cf9ce1c09501fedea33020098c8026c1d (diff)
downloadcoinosv3-eef3193729ccea2c3d712cda9381c24325fac260.tar.gz
coinosv3-eef3193729ccea2c3d712cda9381c24325fac260.zip
Fold the coinos opt-out into a single Data source picker
Replace the Esplora|Electrum backend toggle plus the separate 'Instant notifications' on/off with one 'Data source' selector: • coinos (instant) — default; explorer data + coinos push • Block explorer — REST + polling, nothing sent to coinos (the opt-out) • Electrum server — one WS server for data + push (your node / public) Picking a non-coinos source IS the privacy opt-out, so the standalone toggle is gone. A single 'mode' setting drives getBackend()/getRealtimeEnabled(), so the wallet/wsUrl logic is unchanged; existing per-feature settings migrate in (realtime=off → explorer, backend=electrum → electrum). coinos⇄explorer just flips the watcher (no rescan); to/from electrum rebuilds the backend. Sets up cleanly for a future coinos Fulcrum: 'coinos' mode upgrades from REST+watcher to a full Electrum backend transparently. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Diffstat (limited to 'src/app.js')
-rw-r--r--src/app.js62
1 files changed, 27 insertions, 35 deletions
diff --git a/src/app.js b/src/app.js
index 6a994d8..8524528 100644
--- a/src/app.js
+++ b/src/app.js
@@ -8,7 +8,7 @@ import { Wallet, newMnemonic, isValidMnemonic, utxoId, previewGift, giftOutpoint
import { qrSvg } from './qr.js';
import { scanQr } from './scan.js';
import { getSyncConfig, setSyncConfig } from './nostr.js';
-import { getExplorerConfig, setExplorerConfig, EXPLORER_PRESETS, getRealtimeEnabled, setRealtimeEnabled, getBackend, setBackend, ELECTRUM_PRESETS, getElectrumServerConfig, setElectrumServerConfig } from './api.js';
+import { getExplorerConfig, setExplorerConfig, EXPLORER_PRESETS, getDataMode, setDataMode, ELECTRUM_PRESETS, getElectrumServerConfig, setElectrumServerConfig } from './api.js';
import { isSilentPaymentAddress } from './silentpay.js';
import { t, LANGS, getLang, setLang, isRTL, loadLocale } from './i18n.js';
import {
@@ -1298,36 +1298,34 @@ async function doRevoke(id) {
// Block explorer / server selection: a preset (mempool.space, blockstream.info)
// or a custom Esplora/electrs REST URL (e.g. your own node).
function explorerCard() {
- const backend = getBackend();
+ const mode = getDataMode();
const cfg = getExplorerConfig();
const ecfg = getElectrumServerConfig();
- const rt = getRealtimeEnabled();
- const setRealtime = (on) => {
- if (on === getRealtimeEnabled()) return;
- setRealtimeEnabled(on);
+ const setMode = (m) => {
+ const prev = getDataMode();
+ if (m === prev) return;
+ setDataMode(m);
render();
- if (!wallet.offline) wallet.startRealtime(); // reconnect or drop the watcher
- };
- const setBackendTo = (b) => {
- if (b === getBackend()) return;
- setBackend(b);
- render();
- if (!wallet.offline) wallet.reloadExplorer(); // rebuild api + reconnect
+ if (wallet.offline) return;
+ // coinos⇄explorer only flips the watcher (same REST data); to/from electrum
+ // swaps the whole backend, so rebuild + rescan there.
+ if ((m === 'electrum') !== (prev === 'electrum')) wallet.reloadExplorer();
+ else wallet.startRealtime();
};
return h(
'div',
{ class: 'card col' },
- h('h3', {}, t('explorer')),
- h('p', { class: 'small muted', style: 'margin:0' }, t('explorerDesc')),
- // Data source: Esplora REST, or a full Electrum-over-WS server (data + push).
- h('div', { class: 'row between', style: 'margin-top:2px' },
- h('span', { class: 'lab', style: 'margin:0' }, t('dataSource')),
- h('div', { class: 'seg' },
- h('button', { type: 'button', class: backend === 'esplora' ? 'active' : '', onClick: () => setBackendTo('esplora') }, t('backendEsplora')),
- h('button', { type: 'button', class: backend === 'electrum' ? 'active' : '', onClick: () => setBackendTo('electrum') }, t('backendElectrum'))
- )
+ h('h3', {}, t('dataSource')),
+ h('p', { class: 'small muted', style: 'margin:0' }, t('dataSourceDesc')),
+ h('select', { onChange: (e) => setMode(e.target.value) },
+ h('option', { value: 'coinos', selected: mode === 'coinos' }, t('modeCoinos')),
+ h('option', { value: 'explorer', selected: mode === 'explorer' }, t('modeExplorer')),
+ h('option', { value: 'electrum', selected: mode === 'electrum' }, t('modeElectrum'))
),
- backend === 'electrum'
+ mode === 'coinos'
+ ? h('div', { class: 'small faint' }, t('modeCoinosDesc'))
+ : null,
+ mode === 'electrum'
? h('div', { class: 'col', style: 'gap:8px' },
h('div', { class: 'small faint' }, t('backendElectrumDesc')),
h('select', {
@@ -1345,7 +1343,10 @@ function explorerCard() {
)
: null
)
- : h('div', { class: 'col', style: 'gap:8px' },
+ : null,
+ mode === 'explorer'
+ ? h('div', { class: 'col', style: 'gap:8px' },
+ h('div', { class: 'small faint' }, t('modeExplorerDesc')),
h('select', {
onChange: (e) => { setExplorerConfig({ server: e.target.value, url: cfg.url }); render(); if (e.target.value !== 'custom' || cfg.url) wallet.reloadExplorer(); },
}, EXPLORER_PRESETS.map((o) => h('option', { value: o.id, selected: o.id === cfg.server }, o.label))),
@@ -1359,18 +1360,9 @@ function explorerCard() {
}),
h('div', { class: 'small faint' }, t('explorerUrlHint'))
)
- : null,
- // Realtime via coinos — the one place addresses are shared off-device.
- // (Electrum already serves its own push, so this only applies to REST.)
- h('div', { class: 'row between', style: 'margin-top:8px' },
- h('span', { class: 'lab', style: 'margin:0' }, t('instantNotif')),
- h('div', { class: 'seg' },
- h('button', { type: 'button', class: rt ? 'active' : '', onClick: () => setRealtime(true) }, t('syncOn')),
- h('button', { type: 'button', class: !rt ? 'active' : '', onClick: () => setRealtime(false) }, t('syncOff'))
- )
- ),
- h('div', { class: 'small faint' }, t('instantNotifDesc'))
+ : null
)
+ : null
);
}