Inspiration

The inspiration came from a simple observation that bothered us the more we thought about it: every privacy tool in the Bitcoin ecosystem is a post-mortem.Chain analysis firms, Chainalysis, Elliptic, OXT run their heuristics on confirmed, broadcast transactions. Academic research on Bitcoin privacy analyzes the public ledger after the fact. Even open tools like Blockchair's transaction graph operate on what is already permanent. The user is never in the room when the analysis happens. By the time anyone tells you your transaction was fingerprinted, it has been on-chain forever. The damage is irreversible.We kept asking: who actually benefits from post-broadcast privacy analysis? Not the user whose transaction is already public.

What it does

SiriScore is a pre-broadcast Bitcoin transaction privacy scorer. You paste a PSBT, raw transaction hex, or txid into SiriScore before you sign, and it tells you exactly how identifiable your transaction is to a chain analyst and what to fix before it becomes permanent.It accepts three input formats. A PSBT (BIP-174 or BIP-370) is the richest input, it contains full output scripts and values for all inputs, so SiriScore can run six of its eight heuristics entirely offline with no network calls at all. A raw transaction hex is also accepted with full validation. A txid is accepted for analysing existing transactions or for users who want to understand what was already broadcast.Against each input, SiriScore runs eight heuristics drawn directly from the chain analysis playbook:Script type mismatch — if your inputs are P2WPKH and your change output is P2PKH or P2TR, your change is trivially identifiable to any analyst. No clustering required.Round payment amount, an output of exactly 0.05 BTC announces itself as the payment. The irregular output is change. The distinction is immediate.Address reuse, if any input address has appeared on-chain before, it links your current transaction to your entire prior history at that address.UTXO age clustering, if all your inputs were created within a narrow block window, they fingerprint as a single-wallet consolidation even without address linking.High input consolidation ,spending many inputs at once creates a permanent common-ownership record. Every UTXO in that transaction is now linked forever.Dust input, spending a sub-546-sat output may be exactly what a dust attacker intended. SiriScore flags it and explains why.BIP-69 ordering, non-lexicographic input and output ordering is a wallet fingerprint that narrows down which software constructed the transaction.Tainted label,if a UTXO in your inputs was previously labelled as a KYC withdrawal, a doxxed address, or any user-defined tainted coin, SiriScore surfaces that label at analysis time even if the user forgot they tagged it.

How we built it

We built SiriScore in three layers that can operate independently or together.The core is a Python library, siriscore, structured so that each heuristic is a pure function. It takes a parsed transaction object and returns a finding or nothing. The engine calls all eight, collects the results, and computes the score. This design means each heuristic is independently testable, independently weighted, and independently replaceable. The library is the deliverable. Everything else wraps it.For input parsing we used python-bitcoinlib for raw transaction deserialisation and PSBT handling. Validation runs in two stages: client-side format checks before any processing, then full structural deserialisation in the library. A PSBT is validated against its magic bytes 0x70736274ff before any heuristic touches it. A txid is validated as exactly 64 hex characters before any network call is made.For heuristics that require external data, address reuse (H3) and UTXO age clustering (H4), we used the mempool.space public API. These are read-only GET requests against data that is already fully public. No PSBT content, no private keys, no amounts are transmitted. The six local heuristics run with zero network calls.The web interface is a simple html,css, file served by a FastAPI backend. The frontend is vanilla HTML, CSS, and JavaScript — no framework, no build step. It works by double-clicking the file offline using mock data, and connects to the FastAPI backend when the server is running. The label store is SQLite at ~/.siriscore/labels.db — local only, no sync, no server-side persistence.The design system is built around the name: orange from siri (Swahili for secret), green for a clean score, red for critical findings. Inter for body text, JetBrains Mono for transaction data. Every colour decision communicates information rather than decoration.

Challenges we ran into

The privacy paradox of the tool itself. SiriScore analyses pre-broadcast transactions. That means it handles the most sensitive data a Bitcoin user has, a PSBT contains input addresses, amounts, output scripts, and derivation paths. Building a privacy tool that itself violates privacy if deployed carelessly was the central architectural challenge. Our answer was to make the default behaviour require zero network calls, make external lookups explicit opt-ins, and design the tool so it runs locally by default. The hosted web interface is for demonstration. The library is the product. Validating inputs without a node. A PSBT is self-contained and can be fully validated offline. A raw transaction hex is also self-contained for most heuristics but requires previous output lookups for complete script type analysis. A txid requires fetching the full transaction. Building a validation path that is honest about what each input format can and cannot tell you, without failing silently or misleading the user, required careful handling of all three cases separately. Heuristics that are probabilistic, not deterministic. The round amount heuristic is not a certainty — it is a probability shift. The UTXO age heuristic is a signal, not a proof. Communicating this honestly in the UI without undermining the usefulness of the findings required writing finding descriptions carefully. We landed on severity levels (critical / warning / info) combined with plain-language explanations of confidence rather than false precision. Scope discipline. We had many ideas — Payjoin v2 detection, silent payments address checking, a Pyodide in-browser build, hardware wallet PSBT QR input. All of them are on the roadmap. None of them are in v0.1. A working scorer with eight well-implemented heuristics, a clean UI, and an importable library is a complete deliverable. Shipping a half-built version of ten features is not.

Accomplishments that we're proud of

The architecture held. The privacy-first design, local by default, opt-in for network calls, no server-side PSBT handling, was the hardest decision and the right one. It would have been faster to build a hosted service that processes PSBTs on our server. We chose not to, and the tool is more trustworthy for it. The heuristic engine is genuinely reusable. Any wallet developer can pip install siriscore, call score(psbt), and get a structured report in three lines of code. The design of the library — pure functions, one public API surface, typed return values — was deliberate and took discipline to maintain. The label system connecting SiriScore to Know Your Coin History is the feature we are most proud of conceptually. Coin history as decision-making context is a real idea, not a demo feature. A user who knows a UTXO came from a KYC exchange should be warned when they are about to spend it in a transaction that will link it to their other coins. SiriScore does that.

What we learned

Pre-broadcast is an underserved surface area. The entire privacy tooling ecosystem is oriented toward post-broadcast analysis — forensics, clustering, tracing. There is almost no tooling oriented toward helping users make better decisions before they broadcast. That gap is real and it is fixable with a library. PSBT is the right abstraction. BIP-174 and BIP-370 make it possible to run meaningful privacy analysis without a node, without a network call, and without access to the private keys. Hardware wallets, multisig coordinators, and modern wallet software all produce PSBTs. Targeting PSBT as the primary input format was the right call because it is where the analysis can be most complete and most private simultaneously. Privacy advice has to be timed correctly to change behaviour. Telling a user their transaction was fingerprinted after it is on-chain changes nothing. Telling them before they sign, with a specific fix and a rescore path, gives them the agency to act. Timing is the core product insight.

What's next for SiriScore

Silent payments recommendation (BIP-352). When H3 (address reuse) fires, SiriScore will detect whether the recipient supports silent payments and recommend switching to a silent payment address, eliminating address reuse permanently rather than just flagging it. Payjoin v2 detection (BIP-77). When a payment destination supports async Payjoin, SiriScore will surface it as a suggestion. Payjoin breaks the common-input-ownership heuristic entirely — it is the strongest available fix for H5. Pyodide in-browser build. Compile the Python scorer to WebAssembly so it runs entirely in the browser tab. The PSBT never leaves the user's machine at all, not even to a local server. The privacy caption becomes an engineering fact at every deployment. Hardware wallet PSBT flow. Direct support for Coldcard .psbt file uploads and SeedSigner QR-encoded PSBTs as input formats to the web UI. PyPI publication. pip install siriscore from anywhere, with full documentation, MIT license, and a CI pipeline enforcing heuristic test coverage on every commit.

Built With

Share this project:

Updates