| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
| |
First mempool pass over a >200-tx mempool would fire thousands of getrawtransaction
calls at the node in a burst. Mark the existing backlog seen and scan only new
arrivals instead; small (regtest) mempools still scan fully.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
silentpay.js: silentPaymentCandidate() (our P_0 for a tweak) + buildBloom/bloomHas
(double-hashed sha256, ~0.8% FP). Validated: candidate == P_0 on all no-label
vectors.
Indexer /scan now returns, per block, the tweaks + a Bloom over that block's
taproot output keys (no outputs), with an optional dustLimit. The wallet derives
a candidate per tweak, tests the filter, and only fetches /block on a hit — so a
big historical scan costs candidate math + a handful of fetches instead of
downloading and scanning every block. Live WS pushes still carry full items.
SP_DUST_LIMIT defaults to 0 (receive everything; the indexer honors any value).
Verified end-to-end on regtest: the filter flow finds the output.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
| |
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Indexer: scan the mempool (getrawmempool + getrawtransaction; prevouts fetched
explicitly since verbosity-2 omits them for mempool txs), track SP-eligible
unconfirmed txs, serve /mempool, and push {type:'mempool'} on change. Switched
Core RPC to node:http (no keep-alive) + serialized calls — Bun's fetch was
dropping sockets under the added mempool load.
Wallet: handle the mempool push and /mempool catch-up (_scanSpMempool) — pending
SP receipts rebuild on each update (also drops RBF'd/vanished ones); block pushes
promote a pending entry to confirmed. So a silent payment shows the instant it's
broadcast, like a normal receive, with no mining.
Verified on regtest: an unconfirmed SP is detected and served; clean logs.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
- Persist blocks/items to SQLite (SP_DB; defaults to in-memory) so the indexer
resumes instead of re-walking the chain on restart — verified resume-from the
stored height.
- Subscribe to Core's hashblock ZMQ (SP_ZMQ) via a tiny pure-JS ZMTP/3.0 SUB
client (no native dep, bundle stays self-contained) to trigger a sync the
instant a block lands — measured ~200ms end-to-end vs the poll interval. Poll
remains a backstop.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
The indexer now serves a /ws endpoint and publishes each newly-indexed block's
SP items to subscribers. The wallet subscribes (_spConnect) and scans pushed
items on arrival (_scanSpItems) — folding receipts into the balance instantly —
catching up via /scan on connect/reconnect. Polling for SP is now only a fallback
for when the socket isn't live.
Verified on regtest: connect, mine a block, wallet receives the push.
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]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
tools/sp-indexer.js: a minimal BIP-352 oracle (Bun) that walks Core and serves,
per block, one entry per eligible tx — the tweak (input_hash*A) plus that tx's
taproot outputs — for the wallet to scan on-device. Shares src/silentpay.js so
the tweak math is the vector-validated code. Added to the regtest compose as the
'sp' service (oven/bun, pointed at bc:18443).
inputPubKey now accepts a witness as either serialized hex (vectors) or an array
of stack items (Core getblock RPC). Verified end-to-end on regtest: a real SP
payment is indexed and the scan recovers the output, value, and spend tweak.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
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]>
|
| |
|
|
|
|
|
|
|
|
| |
The watcher's block (rawblock) push now carries confirmed=true + the block time,
and _applyTxNotification flips the matching history row and coins from pending to
confirmed directly — for incoming and outgoing txs (flag-only, so no overcount).
Confirmations no longer wait on a mempool.space reconcile; the 30s backstop poll
just fills in block height / fee afterward.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The watcher push now carries the tx data (matched outputs + confirmed flag), so
the app credits an incoming payment the moment the push arrives — no mempool.space
round-trip. This removes the rate-limited REST reconcile from the path a user
actually waits on, and lets us back the frontier poll way off when the socket is
live (30s backstop vs the old 3s receive-tab hammer), cutting the 429s to a
trickle.
- watcher: notification includes { txid, confirmed, outputs:[{vout,value}] }.
- wallet: _applyTxNotification credits the receive coin + a pending history row
optimistically (receives only; change reconciles in the background), advances
the frontier, updates the balance, and schedules a background reconcile for
full accuracy off the critical path.
- poll intervals relaxed now that the WS does the real work instantly.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
|
|
Replace the unreliable public WebSocket push (mempool/blockchain.info address
subscriptions never reliably fire) with a private notification service:
- tools/zmq-watcher.js: a standalone Bun service (reusing coinos lib/zmq.ts's
ZMTP subscriber) that reads Bitcoin Core's ZMQ rawtx/rawblock, computes the
scripthash of each output, and pushes a blockchain.scripthash.subscribe
notification to subscribed clients. No historical index (~24MB RAM) — just the
live tx stream. Runs on the coinos box reading its Core's ZMQ.
- wallet.js: realtime client now speaks the Electrum protocol (server.version,
scripthash.subscribe, server.ping) over the WS; any scripthash notification
triggers the existing refreshLive() (REST stays the source of truth).
- api.js: wsUrl -> wss://coinos.io/electrum.
Verified end-to-end: live mempool txs to subscribed addresses notify instantly.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|