Silent Amulet

BIP-352 · construct · sign · broadcast · v1.21

1 Mnemonic

Mainnet only. Mnemonic and passphrase are processed locally in this page — nothing is sent over the network. Your BIP-352 scan and spend keys are derived at m/352'/0'/{account}'/{1,0}'/0.

1 Your silent-payment address

Share this with senders. It never changes, and is never written on-chain.

sp1… address
Derive keys on the Setup tab first.
QR appears here after you derive
Click the QR to enlarge it for scanning — or copy the address text.

2 Labeled addresses (optional)

Label indices ≥ 1 produce distinct sp1… addresses that still resolve to the same spend key, so you can tag senders. Index 0 is reserved by spec for change.

3 Scan for received outputs (indexer)

Silent-payment receivers can't tell which taproot outputs are theirs without reading every transaction's inputs. A Blindbit-compatible indexer exposes per-block tweak data so a light client can do this work locally.

To keep scanning fast, Sync wallet checks only the last 50 blocks, which is enough to catch new incoming payments. To look further back (for example right after importing a wallet), use Advanced · scan a manual block range below and set your own range.
🔒 Local · no external exposure
Your keys never leave this page. The indexer only reads public chain data. Connecting to a remote indexer does expose your IP address and the block range you're asking about to that server's operator — that's the only leak, and it's unavoidable for any light-client scan.
Localhost CORS setup — required for Blindbit

Blindbit-oracle does not send Access-Control-Allow-Origin headers, so browsers block Silent Amulet from reading its responses. Put a tiny proxy in front:

Option A — Caddy (save as Caddyfile, run caddy run):

:8000 {
  reverse_proxy 127.0.0.1:7000
  header {
    Access-Control-Allow-Origin *
    Access-Control-Allow-Methods "GET, OPTIONS"
    Access-Control-Allow-Headers *
  }
  @options method OPTIONS
  respond @options 204
}

Option B — Python 3 (no dependencies, save as blindbit-cors.py, run python3 blindbit-cors.py):

from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.request import urlopen
from urllib.error import HTTPError, URLError
UPSTREAM = 'http://127.0.0.1:7000'
class H(BaseHTTPRequestHandler):
    def _c(self, s=200, b=b''):
        self.send_response(s)
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Access-Control-Allow-Methods', 'GET, OPTIONS')
        self.send_header('Access-Control-Allow-Headers', '*')
        self.send_header('Content-Type', 'application/json')
        self.end_headers()
        if b: self.wfile.write(b)
    def do_OPTIONS(self): self._c(204)
    def do_GET(self):
        try:
            with urlopen(UPSTREAM + self.path, timeout=30) as r: self._c(r.status, r.read())
        except HTTPError as e: self._c(e.code, e.read() if e.fp else b'')
        except URLError as e: self._c(502, str(e).encode())
HTTPServer(('127.0.0.1', 8000), H).serve_forever()

Both listen on 127.0.0.1:8000 (Silent Amulet's Localhost preset) and forward to Blindbit on :7000 (Blindbit's example default). If your Blindbit runs on 8000 directly, change UPSTREAM / reverse_proxy to a different port and keep the proxy on 8000.

Advanced · scan a manual block range

Use Sync wallet (above) for the normal flow. This pane is for rescanning a specific window, e.g. after importing a wallet with an older birthday.

Fast is right for almost everyone. Thorough matters only if a sender paid you multiple outputs in the same tx.
Crypto backend: loading…
Preparing… 0 matches

Send Bitcoin to a silent payment

The quick way: paste the address, type an amount, fetch your funds, send. The numbered cards below do the very same thing step by step if you want to watch every detail.

Broadcasting from this browser shows your IP address and the transaction to the indexer you connect to. For maximum privacy, use the numbered cards below and push the signed transaction through your own node or Tor.

1 Recipient

Live rates from mempool.space · fetching…
Add at least one UTXO to see the fee estimate.

2 Your UTXOs (inputs)

Add each UTXO you want to spend. For silent payments, only these types are eligible: P2TR-keypath (bc1p…), P2WPKH (bc1q…), P2SH-P2WPKH (3…), P2PKH (1…). Keys are used locally only.

Find other Bitcoin in this wallet to spend into a silent payment

This checks the wallet you set up on the Setup tab for ordinary Bitcoin funds that are not silent payments yet, so you can send them onward to a silent-payment address. It looks at the wallet's native SegWit, Taproot and wrapped-SegWit addresses. It uses the seed already loaded on the Setup tab, so nothing is re-entered and nothing leaves this page.

Privacy note: a public indexer sees every address of this wallet as one cluster. Point this at your own node for the best privacy. Also, spending UTXOs from several of these addresses in one payment links them together on-chain.

txidvoutamount (sats)scriptPubKey (hex)privkey (hex)elig.

3 Change address

BIP-352 reserves label index 0 on your own SP address for self-pay (change). When you pick the sp1… option, Silent Amulet will run a dual-recipient sender derivation — same inputs, same tweak, two distinct P2TR outputs. The bc1p… option uses x-only(B_spend) directly as a raw P2TR output, spendable by signing with your spend key.

4 Construct transaction

5 Sign transaction

Build a fully signed raw transaction in the browser using the private keys already loaded in your UTXO editor. Covers all four input types — P2TR (Schnorr, BIP-341), P2WPKH / P2SH-P2WPKH (ECDSA, BIP-143), and P2PKH (legacy ECDSA). Requires the fast-crypto backend (@noble/secp256k1) to be loaded — check the crypto pill on the Receive tab. If it's not loaded, use the PSBT above with an external signer.

6 Broadcast

Privacy note. Broadcasting from this browser to a public API reveals your IP address and the raw transaction bytes to the endpoint operator, who can link the two. For maximum privacy, copy the signed hex above and push it via Tor Browser, your own bitcoind, or any other trusted route. The quick buttons below are for convenience, not for privacy-sensitive sends.
Dev · BIP-352 self-test

Runs the official BIP-352 test vector (Simple send: two inputs) end-to-end: input-hash, shared-secret, output pubkey, and address encoding.

Silent payment address