aboutsummaryrefslogtreecommitdiffstats
path: root/src/features/sp.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-07-04 08:55:45 -0700
committerAdam Soltys <[email protected]>2026-07-04 08:55:45 -0700
commit11a14600da683769c74d49e3d973183aa1a2fe5e (patch)
tree004ac05ad9a6f6e109acb2d0efdf82b19747d48a /src/features/sp.js
parent65ad54a060a8035d8cf1e1ca2004f7c3bc5ff296 (diff)
downloadcoinosv3-11a14600da683769c74d49e3d973183aa1a2fe5e.tar.gz
coinosv3-11a14600da683769c74d49e3d973183aa1a2fe5e.zip
Features: extract swaps, Ark, and SP behind a plugin seam
First step toward optional build profiles. app.js gains a small feature registry (ctx + FEATURES + hook helpers); swaps/Ark/silent-payments UI moves wholesale to src/features/{swaps,ark,sp}.js, each exporting a factory returning integration hooks: init/stop/networkChanged wallet lifecycle receiveModes/receiveTakeover receive tab isSendDest/matchSendText/ interceptReview/sendView/ hideSendControls/sendFormNote send flow historyEntries/historyDetail/ txDetailSection history balanceLines/settingsCards balance card + settings No behavior change: ark + gift browser e2e suites pass, and a probe confirms LN receive, all receive modes, and the three settings cards render as before. Gifts extraction and build flags come next. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
Diffstat (limited to 'src/features/sp.js')
-rw-r--r--src/features/sp.js57
1 files changed, 57 insertions, 0 deletions
diff --git a/src/features/sp.js b/src/features/sp.js
new file mode 100644
index 0000000..0960cdf
--- /dev/null
+++ b/src/features/sp.js
@@ -0,0 +1,57 @@
+// Silent payments (BIP-352) feature — the reusable sp1… receive address and
+// the tweak-indexer settings. (The SP scanning/spending machinery itself lives
+// in wallet.js/silentpay.js and ships with the core wallet for now.)
+
+import { isSilentPaymentAddress } from '../silentpay.js';
+import { getNetwork, getSpIndexerConfig, setSpIndexerConfig, spIndexerPresets } from '../api.js';
+import { t } from '../i18n.js';
+import { qrSvg } from '../qr.js';
+
+export function spFeature(ctx) {
+ const { h, ui, render, wallet, copyBtn } = ctx;
+
+ function spIndexerCard() {
+ if (!wallet.silentPaymentKeys || !wallet.silentPaymentKeys()) return null;
+ const net = getNetwork();
+ const cfg = getSpIndexerConfig(net);
+ return h(
+ 'div',
+ { class: 'card col' },
+ h('h3', {}, t('spIndexerTitle')),
+ h('p', { class: 'small muted', style: 'margin:0' }, t('spIndexerDesc')),
+ h('select', { onChange: (e) => { setSpIndexerConfig({ server: e.target.value, url: cfg.url }, net); render(); } },
+ spIndexerPresets(net).map((o) => h('option', { value: o.id, selected: o.id === cfg.server }, o.id === 'custom' ? o.label : o.url.replace(/^\w+:\/\//, '')))),
+ cfg.server === 'custom'
+ ? h('label', { class: 'field' },
+ h('span', { class: 'lab' }, t('spIndexerUrl')),
+ h('input', {
+ type: 'text', class: 'mono-input', placeholder: 'https://your-indexer:8888',
+ autocapitalize: 'none', autocomplete: 'off', spellcheck: 'false', value: cfg.url,
+ onChange: (e) => { setSpIndexerConfig({ server: 'custom', url: e.target.value.trim() }, net); render(); },
+ }),
+ h('div', { class: 'small faint' }, t('spIndexerHint')))
+ : null
+ );
+ }
+
+ return {
+ id: 'sp',
+ receiveModes() {
+ const spAddr = wallet.silentPaymentsAvailable && wallet.silentPaymentsAvailable() ? wallet.silentPaymentAddress() : null;
+ if (!spAddr) return [];
+ return [{
+ id: 'sp', label: t('receiveSpTab'),
+ render: (seg) => h(
+ 'div',
+ { class: 'card col', style: 'align-items:center;gap:14px' },
+ seg,
+ h('div', { html: qrSvg(spAddr) }),
+ h('div', { class: 'addr-box break', style: 'width:100%;font-size:12px' }, spAddr),
+ copyBtn(spAddr, t('copyAddress'))
+ ),
+ }];
+ },
+ isSendDest(a) { return isSilentPaymentAddress(a); },
+ settingsCards() { return [spIndexerCard()]; },
+ };
+}