The three-NIP Nostr Silent Payments stack (derivation standard PR #2355, receipts PR #2362, Silent Wallet Connect PR #2369) solves the on-chain privacy problem cleanly. A chain observer cannot link payments to the recipient’s identity. Each payment lands as a fresh unlinkable Taproot output.
But the wallet service – the always-on component that constructs and broadcasts Silent Payment transactions on behalf of Nostr clients – sees everything:
- Who is paying (sender’s Nostr identity)
- Who is being paid (recipient’s npub)
- How much
- When
Over time, a third-party wallet service operator builds a complete payment graph that correlates Nostr social identities with Bitcoin spending patterns. The on-chain privacy guarantee applies to chain observers. It does not extend to the wallet service operator.
This design note proposes a way to close that gap.
Alice wants to pay Bob privately. She opens her Nostr client, which sends an encrypted payment request to her connected wallet service. The wallet service derives Bob’s Silent Payment address from his npub, selects UTXOs, constructs the BIP-352 transaction, signs, and broadcasts.
The wallet service operator – even an honest one – now knows:
- Alice paid Bob
- The amount
- The time
If Alice pays 100 people over a year, the operator has a complete map of her Bitcoin social graph. If the operator is subpoenaed, breached, or simply untrustworthy, that graph is exposed.
The on-chain transaction is private. The wallet service is not.
No single wallet service component needs to know everything. The payment flow has two distinct operations that can be separated:
Operation 1 – Finding the output key
To construct the BIP-352 output, the wallet needs to compute:
shared = input_hash * a * Bscan
tk = H_tagged("BIP0352/SharedSecret", serP(shared) || ser32(k))
Pk = Bspend + tk * G
This requires knowledge of the recipient’s public scan key Bscan and the
sender’s input private keys. The result is an output key Pk – a public value.
Operation 2 – Signing the transaction
To authorize the spend, the wallet needs the sender’s private keys to produce a valid Schnorr signature over the transaction. This requires no knowledge of the recipient at all – just the unsigned PSBT.
These two operations can be assigned to two separate components, each knowing only what it needs.
Alice's Nostr Client
|
| encrypted kind 23352 request
| carrying: Bscan, Bspend, amount
| (NOT recipient_npub)
v
+-------------------------+
| Derivation Service |
| |
| - receives Bscan, |
| Bspend, amount |
| - selects UTXOs |
| - computes output key |
| Pk = Bspend + tk*G |
| - builds unsigned PSBT |
| - never learns npub |
| - never holds privkeys |
+-------------------------+
| unsigned PSBT only
v
+-------------------------+
| Signing Service |
| |
| - receives PSBT only |
| - signs with Alice's |
| private keys |
| - broadcasts tx |
| - never learns Bscan |
| - never learns npub |
| - never learns Bob |
+-------------------------+
|
v
Bitcoin network
What each component learns:
| Component | Knows sender? | Knows recipient? | Knows amount? |
|---|---|---|---|
| Derivation Service | No | Partial (Bscan/Bspend only) | Yes |
| Signing Service | Yes (holds privkeys) | No | Yes (from PSBT) |
| Either alone | Insufficient to reconstruct payment graph |
No single operator holds the full picture. A subpoena of one component yields an incomplete record. A breach of one component does not expose the full payment graph.
The split-service architecture reduces what each operator knows. Trusted Execution Environments (TEEs) go further – they prevent operators from seeing what their own service is processing.
A TEE is a hardware-enforced isolated execution environment. Code running inside a TEE cannot be observed or tampered with by the host operating system, the cloud provider, or the service operator. The TEE produces a cryptographic attestation proving to external parties that specific, unmodified code is running in the enclave.
Applied to the split-service architecture:
Derivation Service in a TEE:
- The operator deploys the derivation code into an enclave
- The enclave produces an attestation clients can verify before sending requests
- The operator cannot log, inspect, or extract
Bscan,Bspend, or amounts - Even if the operator is subpoenaed, they have nothing to hand over
Signing Service in a TEE:
- Alice’s private keys never leave the enclave in plaintext
- The operator cannot observe which UTXOs are being spent or who the output belongs to
- The enclave signs and broadcasts without the operator seeing the transaction contents
Combined:
Alice's Client
|
| verifies TEE attestation before sending
|
v
Derivation TEE ---> unsigned PSBT ---> Signing TEE ---> Bitcoin
| |
operator operator
sees nothing sees nothing
Two independent privacy guarantees. Neither dependent on the other. A compromise of one TEE does not expose the other component’s knowledge.
Protected:
- Wallet service operator cannot build a payment graph
- Neither component alone can link Alice to Bob
- Operator compliance with subpoenas yields incomplete records
- On-chain privacy (already guaranteed by BIP-352) is preserved
Not protected:
- Global passive adversary correlating blockchain timing with Nostr events
- Amount privacy on-chain – transaction amounts are public
- Alice’s identity from Bob – the kind 8352 receipt hint reveals a payment was made, though the ephemeral gift wrap key hides the sender’s Nostr identity
- TEE side-channel attacks – TEEs have known vulnerabilities (SGX has had multiple disclosures). The guarantee is probabilistic, not mathematical.
This design note proposes an optional advanced implementation tier on top of the Silent Wallet Connect NIP (PR #2369). The core protocol is unchanged:
- Kind
23352request format is unchanged - Kind
23353response format is unchanged - Kind
38352wallet connection info is unchanged
The only change is that the client sends Bscan and Bspend directly instead
of recipient_npub, and the wallet service is split into two TEE-attested
components instead of one. The BIP-352 math and the Nostr event structure are
identical.
This separation keeps the base NIP simple and implementable today with existing tools. The split-service TEE architecture is an upgrade path for operators who require stronger privacy guarantees – not a requirement for basic compliance.
The NSP derivation model (bscan = d_npub + t_scan mod n) means the scan
private key is root-equivalent to the Nostr private key. This is an algebraic
consequence of additive derivation on secp256k1, not a design choice. There is
no construction that simultaneously provides:
- Public derivability of the Silent Payment address from
npub - Independence of
bscanfromnsec - BIP-352 compatibility
The split-service TEE architecture accepts this constraint and addresses the wallet service surveillance problem at the infrastructure layer – which is where it belongs.
TEE platform selection. Intel SGX, AMD SEV, and Apple Secure Enclave have different security properties, attack surfaces, and availability constraints. A production implementation would need to specify which TEE platforms are acceptable and how clients verify attestations across platforms.
Attestation verification by clients. How does Alice’s Nostr client verify the TEE attestation before sending a request? This requires either a trusted attestation service or direct remote attestation – both have tradeoffs.
PSBT handoff between components. How does the unsigned PSBT move from the Derivation TEE to the Signing TEE without leaking information to either operator or an intermediary? End-to-end encryption between enclaves is possible but adds protocol complexity.
Minimum viable implementation. A split-service architecture without TEE attestation still reduces the surveillance surface compared to a single monolithic wallet service. Defining a minimum viable split-service profile that does not require TEE hardware may be a useful intermediate step.
silentius-satoshi
npub13vftmhzzxxyuvcq4d643agzwr4zvce3pc4gvxymgvuzlwpxa4z2sq4sjd9