-
Notifications
You must be signed in to change notification settings - Fork 5.9k
BIP392: Silent Payment Output Script Descriptors #2047
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
craigraw
wants to merge
7
commits into
bitcoin:master
Choose a base branch
from
craigraw:spdescriptor
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
9557c1e
Add sp() output descriptor format for BIP352 Silent Payments
craigraw 6807d2f
Update headers and remove space after comma in descriptors
craigraw 62bb41f
Add label ranges with examples
craigraw cb9b1ac
Update with assigned number and adjust preamble for BIP3
craigraw 5ab38f6
BIP392: Add table entry to README
murchandamus b57b2e8
Add two argument key expression form and remove birthday and label ar…
craigraw 7a53822
Add BIP392 sp() descriptor to BIP380 script expressions table
craigraw File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,113 @@ | ||
| <pre> | ||
| BIP: 392 | ||
| Layer: Applications | ||
| Title: Silent Payment Output Script Descriptors | ||
| Authors: Craig Raw <craig@sparrowwallet.com> | ||
| Status: Draft | ||
| Type: Specification | ||
| Assigned: 2026-02-06 | ||
| License: BSD-2-Clause | ||
| Discussion: https://groups.google.com/g/bitcoindev/c/bP6ktUyCOJI | ||
| Requires: 341, 350, 352, 380 | ||
| </pre> | ||
|
|
||
| ==Abstract== | ||
|
|
||
| This document specifies <tt>sp()</tt> output script descriptors for silent payments. | ||
| <tt>sp()</tt> descriptors take silent payment key material and describe P2TR outputs when combined with sender input public keys as defined in BIP352. | ||
|
|
||
| ==Copyright== | ||
|
|
||
| This BIP is licensed under the BSD 2-clause license. | ||
|
|
||
| ==Motivation== | ||
|
|
||
| BIP352 defines silent payments, a protocol for static payment addresses without on-chain linkability. | ||
| This descriptor provides a standardized way to represent silent payment outputs within the output descriptor framework, enabling wallet interoperability and backup/recovery using existing descriptor-based infrastructure. | ||
|
|
||
| ==Specification== | ||
|
|
||
| A new top level script expression is defined: <tt>sp()</tt>. | ||
|
|
||
| ===Key Expressions=== | ||
|
|
||
| Two new key expression types are defined for use with <tt>sp()</tt> descriptors: | ||
|
|
||
| ====<tt>spscan</tt>==== | ||
|
|
||
| The <tt>spscan</tt> key expression encodes the scan private key and spend public key. | ||
| It is a [https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki Bech32m] encoding of: | ||
| * The human-readable part "spscan" for mainnet, "tspscan" for testnets | ||
| * The data-part values: | ||
| ** The character "q", to represent silent payments version 0 | ||
| ** The payload: <tt>ser<sub>256</sub>(b<sub>scan</sub>) || ser<sub>P</sub>(B<sub>spend</sub>)</tt> | ||
|
|
||
| ====<tt>spspend</tt>==== | ||
|
|
||
| The <tt>spspend</tt> key expression encodes both the scan and spend private keys. | ||
| It is a [https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki Bech32m] encoding of: | ||
| * The human-readable part "spspend" for mainnet, "tspspend" for testnets | ||
| * The data-part values: | ||
| ** The character "q", to represent silent payments version 0 | ||
| ** The payload: <tt>ser<sub>256</sub>(b<sub>scan</sub>) || ser<sub>256</sub>(b<sub>spend</sub>)</tt> | ||
|
|
||
| Note: The serialization of <tt>ser<sub>256</sub>(p)</tt> and <tt>ser<sub>P</sub>(P)</tt> follows the definition in BIP352. | ||
|
|
||
| ===<tt>sp()</tt>=== | ||
|
|
||
| The <tt>sp(KEY)</tt> or <tt>sp(KEY,KEY)</tt> expression can only be used as a top level descriptor. | ||
|
|
||
| <tt>sp(KEY)</tt> takes a single key expression as an argument, which must be either an <tt>spscan</tt> or <tt>spspend</tt> encoded key, optionally with key origin information. | ||
| If included, the key origin information specifies the fingerprint and derivation path to the depth from which the scan and spend keys are derived using the child paths recommended in BIP352 (<tt>1h/0</tt> for scan, <tt>0h/0</tt> for spend). | ||
|
|
||
| <tt>sp(KEY,KEY)</tt> takes two key expressions. | ||
| The first key expression represents the scan key and must be a single private key (e.g. a WIF compressed private key or <tt>xprv</tt> extended private key). | ||
| The second key expression represents the spend key and may be any key expression as defined in BIP380 or other key expression BIPs (e.g. <tt>musig()</tt> as defined in BIP390) that represents a single key, public or private. | ||
| Note however that uncompressed keys are not allowed under any <tt>sp()</tt> expression, as BIP352 only permits compressed public keys. | ||
|
|
||
| When combined with sender input public keys, the descriptor produces P2TR output scripts describing silent payments made to wallets represented by the key expression(s). | ||
|
|
||
| The output scripts produced are BIP341 taproot outputs as specified in BIP352. | ||
|
|
||
| ==Examples== | ||
|
|
||
| Valid descriptors: | ||
|
|
||
| * <tt>sp(spscan1q...)</tt> - Using spscan encoded key (watch-only) | ||
| * <tt>sp([deadbeef/352h/0h/0h]spscan1q...)</tt> - With key origin | ||
| * <tt>sp(spspend1q...)</tt> - Using spspend encoded key (full wallet) | ||
| * <tt>sp(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1,0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600)</tt> - WIF scan key with compressed public spend key (watch-only) | ||
| * <tt>sp([deadbeef/352h/0h/0h]xprv.../0h,xpub.../0h)</tt> - Extended private scan key with extended public spend key (watch-only) | ||
| * <tt>sp([deadbeef/352h/0h/0h]xprv.../0h,xprv.../0h)</tt> - Extended private keys for both scan and spend (full wallet) | ||
|
|
||
| Invalid descriptors: | ||
|
|
||
| * <tt>sp()</tt> requires at least one key expression | ||
| * <tt>sp(xpub...)</tt> single argument form requires spscan or spspend encoded key | ||
| * <tt>sp(xpub...,xpub...)</tt> two argument form requires private scan key (e.g. WIF or xprv) | ||
| * <tt>sp(spscan1q...,spscan1q...)</tt> two argument form requires single key expressions | ||
| * <tt>sp(5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss,0260b2003c386519fc9eadf2b5cf124dd8eea4c4e68d5e154050a9346ea98ce600)</tt> uncompressed private key | ||
| * <tt>sh(sp(spscan1q...))</tt> sp() is top level only | ||
| * <tt>wsh(sp(spscan1q...))</tt> sp() is top level only | ||
|
|
||
| ==Usage Notes== | ||
|
|
||
| For watch-only wallets, use <tt>spscan</tt> encoding or the two argument form with a public spend key. | ||
| For full wallets that can both scan and spend, use <tt>spspend</tt> encoding or the two argument form with a private spend key. | ||
|
|
||
| When using the two argument form, the scan key must be private (e.g. WIF or <tt>xprv</tt>) since scanning requires the private scan key. | ||
|
|
||
| ==Backwards Compatibility== | ||
|
|
||
| <tt>sp()</tt> descriptors use the format and general operation specified in BIP380. | ||
| As this is a wholly new descriptor, it is not compatible with any prior implementation. | ||
| The scripts produced are BIP341 taproot outputs, making them indistinguishable from other taproot outputs on-chain. | ||
|
|
||
| ==Reference Implementation== | ||
|
|
||
| TBD | ||
|
|
||
| ==Test Vectors== | ||
|
|
||
| TBD | ||
|
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.