mirror of
https://github.com/bitcoin/bips.git
synced 2026-03-09 15:53:54 +00:00
* Add sp() output descriptor format for BIP352 Silent Payments * Update headers and remove space after comma in descriptors * Add label ranges with examples * Update with assigned number and adjust preamble for BIP3 * BIP392: Add table entry to README * Add two argument key expression form and remove birthday and label arguments * Add BIP392 sp() descriptor to BIP380 script expressions table * Add sp() descriptor to BIP390 allowed expressions and add musig() example to BIP392 * Add changelog and version header to BIP390
115 lines
5.8 KiB
Plaintext
115 lines
5.8 KiB
Plaintext
<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)
|
|
* <tt>sp(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1,musig(03dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659,023590a94e768f8e1815c2f24b4d80a8e3149316c3518ce7b7ad338368d038ca66))</tt> - WIF scan key with MuSig2 aggregate spend key (watch-only)
|
|
|
|
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
|
|
|