Skip to content

Commit

Permalink
Finalization of PSBT DBC-related API
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-orlovsky committed Jul 2, 2022
1 parent 293a054 commit e989537
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 9 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion psbt/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "psbt"
version = "0.8.1"
version = "0.8.4"
license = "Apache-2.0"
authors = ["Dr. Maxim Orlovsky <[email protected]>"]
description = "Partially signed bitcoin transaction v0-2 library (bip174, bip370, bip371)"
Expand Down
19 changes: 19 additions & 0 deletions psbt/src/commit/lnpbp4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
// If not, see <https://opensource.org/licenses/Apache-2.0>.

use amplify::Slice32;
use bitcoin::hashes::Hash;
use commit_verify::lnpbp4;
use commit_verify::lnpbp4::{Message, ProtocolId};
use strict_encoding::{StrictDecode, StrictEncode};

Expand Down Expand Up @@ -160,6 +162,23 @@ impl Psbt {
/// Extension trait for [`Output`] for working with proprietary LNPBP4
/// keys.
impl Output {
/// Returns [`lnpbp4::MessageMap`] constructed from the proprietary key
/// data.
pub fn lnpbp4_message_map(&self) -> Result<lnpbp4::MessageMap, Lnpbp4KeyError> {
self.proprietary
.iter()
.filter(|(key, _)| {
key.prefix == PSBT_LNPBP4_PREFIX && key.subtype == PSBT_OUT_LNPBP4_MESSAGE
})
.map(|(key, val)| {
Ok((
ProtocolId::from_slice(&key.key).ok_or(Lnpbp4KeyError::InvalidKeyValue)?,
Message::from_slice(val).map_err(|_| Lnpbp4KeyError::InvalidKeyValue)?,
))
})
.collect()
}

/// Returns a valid LNPBP-4 [`Message`] associated with the given
/// [`ProtocolId`], if any.
///
Expand Down
2 changes: 2 additions & 0 deletions psbt/src/commit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
// along with this software.
// If not, see <https://opensource.org/licenses/Apache-2.0>.

// TODO: Relocate to BP DBC library

//! Managing commitment-related proprietary keys inside PSBT.
//!
//! Supports Tapret, Opret, P2C and S2C commitments and LNPBP4 structures used
Expand Down
31 changes: 24 additions & 7 deletions psbt/src/commit/tapret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
//! commitments.

use amplify::Slice32;
use bitcoin::util::taproot::TaprootMerkleBranch;
use bitcoin_scripts::taproot::DfsPath;
use strict_encoding::{StrictDecode, StrictEncode};

Expand Down Expand Up @@ -93,7 +92,7 @@ impl ProprietaryKeyTapret for ProprietaryKey {}

/// Errors processing tapret-related proprietary PSBT keys and their values.
#[derive(
Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display, Error
Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display, Error, From
)]
#[display(doc_comments)]
pub enum TapretKeyError {
Expand All @@ -104,6 +103,10 @@ pub enum TapretKeyError {
/// the output is not marked to host tapret commitments. Please first set
/// PSBT_OUT_TAPRET_HOST flag.
TapretProhibited,

/// The key contains invalid value
#[from(strict_encoding::Error)]
InvalidKeyValue,
}

/// Error decoding [`DfsPath`] inside PSBT data
Expand Down Expand Up @@ -189,8 +192,8 @@ impl Output {
}

/// Assigns value of the tapreturn commitment to this PSBT output, by
/// adding [`PSBT_OUT_TAPRET_COMMITMENT`] proprietary key containing the
/// 32-byte commitment as its value.
/// adding [`PSBT_OUT_TAPRET_COMMITMENT`] and [`PSBT_OUT_TAPRET_PROOF`]
/// proprietary keys containing the 32-byte commitment as its proof.
///
/// # Errors
///
Expand All @@ -201,6 +204,7 @@ impl Output {
pub fn set_tapret_commitment(
&mut self,
commitment: impl Into<[u8; 32]>,
proof: &impl StrictEncode,
) -> Result<(), TapretKeyError> {
if !self.is_tapret_host() {
return Err(TapretKeyError::TapretProhibited);
Expand All @@ -215,6 +219,9 @@ impl Output {
commitment.into().to_vec(),
);

self.proprietary
.insert(ProprietaryKey::tapret_proof(), proof.strict_serialize()?);

Ok(())
}

Expand All @@ -238,8 +245,18 @@ impl Output {
/// commitments (having non-32 bytes) will be filtered at the moment of PSBT
/// deserialization and this function will return `None` only in situations
/// when the commitment is absent.
pub fn tapret_proof(&self) -> Option<TaprootMerkleBranch> {
let proof = self.proprietary.get(&ProprietaryKey::tapret_proof())?;
TaprootMerkleBranch::from_slice(proof).ok()
///
/// Function returns generic type since the real type will create dependency
/// on `bp-dpc` crate, which will result in circular dependency with the
/// current crate.
pub fn tapret_proof<T>(&self) -> Result<Option<T>, TapretKeyError>
where
T: StrictDecode,
{
self.proprietary
.get(&ProprietaryKey::tapret_proof())
.map(T::strict_deserialize)
.transpose()
.map_err(TapretKeyError::from)
}
}

0 comments on commit e989537

Please sign in to comment.