diff options
| author | Adam Soltys <[email protected]> | 2026-07-04 08:55:45 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-07-04 08:55:45 -0700 |
| commit | 11a14600da683769c74d49e3d973183aa1a2fe5e (patch) | |
| tree | 004ac05ad9a6f6e109acb2d0efdf82b19747d48a /src/features/sp.js | |
| parent | 65ad54a060a8035d8cf1e1ca2004f7c3bc5ff296 (diff) | |
| download | coinosv3-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.js | 57 |
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()]; }, + }; +} |
