Skip to content

Commit

Permalink
derive: add initial set of derivation methods
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-orlovsky committed Jul 29, 2023
1 parent b01390a commit ca37a23
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 8 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.

57 changes: 51 additions & 6 deletions src/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use bc::ScriptPubkey;
use secp256k1::XOnlyPublicKey;
use bc::{InternalPk, ScriptPubkey};

use crate::{ComprPubkey, NormalIndex};
use crate::{Address, AddressNetwork, ComprPubkey, Idx, NormalIndex};

pub trait Derive {
type Derived;
Expand All @@ -33,13 +32,59 @@ pub trait Derive {
change: impl Into<NormalIndex>,
index: impl Into<NormalIndex>,
) -> Self::Derived;

fn derive_batch(
&self,
change: impl Into<NormalIndex>,
from: impl Into<NormalIndex>,
max_count: u8,
) -> Vec<Self::Derived> {
let change = change.into();
let mut index = from.into();
let mut count = 0u8;
let mut batch = Vec::with_capacity(max_count as usize);
loop {
batch.push(self.derive(change, index));
count += 1;
if index.checked_inc_assign().is_none() || count >= max_count {
return batch;
}
}
}
}

pub trait DeriveCompr: Derive<Derived = ComprPubkey> {}
impl<T: Derive<Derived = ComprPubkey>> DeriveCompr for T {}

pub trait DeriveXOnly: Derive<Derived = XOnlyPublicKey> {}
impl<T: Derive<Derived = XOnlyPublicKey>> DeriveXOnly for T {}
pub trait DeriveXOnly: Derive<Derived = InternalPk> {}
impl<T: Derive<Derived = InternalPk>> DeriveXOnly for T {}

pub trait DeriveSpk: Derive<Derived = ScriptPubkey> {
fn derive_address(
&self,
network: AddressNetwork,
change: impl Into<NormalIndex>,
index: impl Into<NormalIndex>,
) -> Address {
let spk = self.derive(change, index);
Address::with(&spk, network)
.expect("invalid derive implementation constructing broken scriptPubkey")
}

pub trait DeriveSpk: Derive<Derived = ScriptPubkey> {}
fn derive_address_batch(
&self,
network: AddressNetwork,
change: impl Into<NormalIndex>,
from: impl Into<NormalIndex>,
max_count: u8,
) -> Vec<Address> {
self.derive_batch(change, from, max_count)
.into_iter()
.map(|spk| {
Address::with(&spk, network)
.expect("invalid derive implementation constructing broken scriptPubkey")
})
.collect()
}
}
impl<T: Derive<Derived = ScriptPubkey>> DeriveSpk for T {}
17 changes: 16 additions & 1 deletion src/descriptors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,25 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::DeriveXOnly;
use bc::ScriptPubkey;

use crate::{Derive, DeriveXOnly, NormalIndex};

pub struct TrKey<K: DeriveXOnly>(K);

impl<K: DeriveXOnly> Derive for TrKey<K> {
type Derived = ScriptPubkey;

fn derive(
&self,
change: impl Into<NormalIndex>,
index: impl Into<NormalIndex>,
) -> Self::Derived {
let internal_key = self.0.derive(change, index);
ScriptPubkey::p2tr_key_only(internal_key)
}
}

/*
pub struct TrScript<K: DeriveXOnly> {
internal_key: K,
Expand Down

0 comments on commit ca37a23

Please sign in to comment.