<feed xmlns='http://www.w3.org/2005/Atom'>
<title>coinosv3.git/src/silentpay.js, branch master</title>
<subtitle>coinos v3 — bitcoin, Ark, Lightning and nostr wallet (web + Android)</subtitle>
<id>https://git.coinos.io/coinosv3.git/atom?h=master</id>
<link rel='self' href='https://git.coinos.io/coinosv3.git/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/'/>
<updated>2026-10-06T05:35:56Z</updated>
<entry>
<title>README rewritten for today's coinos v3; build switches are COINOS_* (HAL_* still accepted); silent-payment leftovers removed</title>
<updated>2026-10-06T05:35:56Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-06T05:35:56Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=f571e46937d423d9ba44154a92aeb4136466daaa'/>
<id>urn:sha1:f571e46937d423d9ba44154a92aeb4136466daaa</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01YRC6aKhwAud231ot9FPmhi
</content>
</entry>
<entry>
<title>Spend SP coins like any coin — confirmed-only, and able to fund SP payments</title>
<updated>2026-06-28T11:14:07Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-06-28T11:14:07Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=76daca707a7b9cb9aafab1ceb8999ec3c708a63d'/>
<id>urn:sha1:76daca707a7b9cb9aafab1ceb8999ec3c708a63d</id>
<content type='text'>
Two things:
- Only confirmed SP coins enter the spend pool. Unconfirmed ones are excluded
  (the sender's tx could be replaced, invalidating our spend) — matching the
  spendable headline, which already counted confirmed-only.
- SP→SP sending: our own silent-payment coins can now fund a payment TO an sp1
  address (previously excluded). _applySilentPayments includes SP inputs with
  their key d = spend_priv + t_k, and silentPaymentScripts negates a taproot
  input's key when it gives odd Y, per BIP-352 (so the sender's A = a·G matches
  what the indexer reconstructs). signing was already SP-aware.

Validated: BIP-352 sending vectors pass for all clean key-path-taproot-input
cases (the remaining vector failures are NUMS script-path / labels / uncompressed
keys — input types the wallet never spends). End-to-end on regtest: an SP coin
funds a payment to another sp address, testmempoolaccept passes, and the recipient
scans and finds it.

Note: silentPaymentScripts derives input_hash from the eligible inputs it's given,
which is correct because the wallet only ever spends all-eligible coins (P2WPKH +
key-path SP); it isn't a general-purpose sender for txs with ineligible inputs.

Co-Authored-By: Claude Opus 4.8 (1M context) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Catch-up scaling: dust filter + per-block Bloom filters</title>
<updated>2026-06-28T00:17:58Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-06-28T00:17:58Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=56a2736be51d2f35d68ca88b477a948efe3398ce'/>
<id>urn:sha1:56a2736be51d2f35d68ca88b477a948efe3398ce</id>
<content type='text'>
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) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Add regtest SP tweak indexer; accept Core's array-witness in inputPubKey</title>
<updated>2026-06-27T21:42:11Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-06-27T21:42:11Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=1beae75ebd34142cc63342fbf7c8a798af45bb5a'/>
<id>urn:sha1:1beae75ebd34142cc63342fbf7c8a798af45bb5a</id>
<content type='text'>
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) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Add BIP-352 receiving crypto (scan, tweak, keys, address)</title>
<updated>2026-06-27T21:34:59Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-06-27T21:34:59Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=6c817756c5cca849864119405be9fa3f9e968057'/>
<id>urn:sha1:6c817756c5cca849864119405be9fa3f9e968057</id>
<content type='text'>
silentpay.js gains the receiving half of silent payments, validated against all
official BIP-352 vectors (29/29 receiving sub-cases):
- inputPubKey(): recover the eligible input pubkey from P2PKH/P2WPKH/P2SH-P2WPKH/
  P2TR inputs (skips uncompressed keys, excludes NUMS script-path, hash160-matches
  malleated P2PKH scriptSigs)
- silentPaymentTweak(): the oracle tweak input_hash*A (sum over eligible inputs,
  input hash over all outpoints, point-at-infinity guarded) — used by the indexer
- silentPaymentScan(): ecdh = scan_priv*tweak, derive P_k = B_spend + t_k*G, match
  the tx's taproot outputs, return per-output spend tweaks
- silentPaymentOutputPrivKey(), deriveSilentPaymentKeys() (m/352' paths),
  encodeSilentPaymentAddress()

Labels not yet implemented (wallet uses a single no-label address).

Co-Authored-By: Claude Opus 4.8 (1M context) &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Add Silent Payments (BIP-352) sending</title>
<updated>2026-06-26T03:41:20Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-06-26T03:41:20Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=aa044138337c947b26eea910db57f2d5b743b5b8'/>
<id>urn:sha1:aa044138337c947b26eea910db57f2d5b743b5b8</id>
<content type='text'>
Pay sp1… addresses: the wallet derives the one-time taproot output from the
recipient's address + the transaction's own input keys (ECDH), so payments are
unlinkable on-chain with no interaction. New src/silentpay.js implements the
sender derivation + bech32m address decode, validated against the official
BIP-352 test vectors (all P2WPKH-input / single-recipient cases pass; the rest
exercise input types Hal never spends).

buildTx detects sp1… recipients, selects coins against a same-size placeholder
taproot output, then swaps in the script derived from the final input set
(updateOutput). Works for normal sends, multi-recipient, and send-max. The
review screen shows the sp1… address with a 'Silent payment' label (the on-chain
output is a derived one-time taproot address). End-to-end signing verified.

Co-Authored-By: Claude Opus 4.8 (1M context) &lt;noreply@anthropic.com&gt;
</content>
</entry>
</feed>
