Skip to content

Commit 13c945c

Browse files
authored
Dev (#111)
* mainnet fixes (#109) * changelog * versions
1 parent a633534 commit 13c945c

14 files changed

Lines changed: 86 additions & 50 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Changelog
22

3+
## [0.0.8]
4+
5+
- Fixed many issues in the sdk crate regarding the Liquid mainnet network:
6+
- Changed `NetworkKind` to `Main` when `Liquid` is specified.
7+
- Changed the default descriptor derivation to `0` from `1`.
8+
- The change output populated by `Signer` is now confidential instead of being explicit.
9+
- The `xpub.parent_fingerprint` is now zeroed out before descriptor serialization to be compatible with the Blockstream app.
10+
311
## [0.0.7]
412

513
- Added support for SimplicityHL modules and multifile programs.

Cargo.lock

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ license = "MIT"
88
edition = "2024"
99

1010
[workspace.dependencies]
11-
smplx-macros = { path = "./crates/macros", version = "0.0.7" }
12-
smplx-build = { path = "./crates/build", version = "0.0.7" }
13-
smplx-test = { path = "./crates/test", version = "0.0.7" }
14-
smplx-regtest = { path = "./crates/regtest", version = "0.0.7" }
15-
smplx-sdk = { path = "./crates/sdk", version = "0.0.7" }
16-
smplx-std = { path = "./crates/simplex", version = "0.0.7" }
11+
smplx-macros = { path = "./crates/macros", version = "0.0.8" }
12+
smplx-build = { path = "./crates/build", version = "0.0.8" }
13+
smplx-test = { path = "./crates/test", version = "0.0.8" }
14+
smplx-regtest = { path = "./crates/regtest", version = "0.0.8" }
15+
smplx-sdk = { path = "./crates/sdk", version = "0.0.8" }
16+
smplx-std = { path = "./crates/simplex", version = "0.0.8" }
1717

1818
serde = { version = "1.0.228", features = ["derive"] }
1919
hex = { version = "0.4.3" }

crates/build/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "smplx-build"
3-
version = "0.0.7"
3+
version = "0.0.8"
44
description = "Simplex build command internal implementation"
55
license.workspace = true
66
edition.workspace = true

crates/cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "smplx-cli"
3-
version = "0.0.7"
3+
version = "0.0.8"
44
description = "Simplex cli with various utilities to manage a simplicity project"
55
license.workspace = true
66
edition.workspace = true

crates/macros/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "smplx-macros"
3-
version = "0.0.7"
3+
version = "0.0.8"
44
description = "Simplex macros re-export package"
55
license.workspace = true
66
edition.workspace = true

crates/regtest/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "smplx-regtest"
3-
version = "0.0.7"
3+
version = "0.0.8"
44
description = "Simplex regtest command internal implementation"
55
license.workspace = true
66
edition.workspace = true

crates/sdk/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "smplx-sdk"
3-
version = "0.0.7"
3+
version = "0.0.8"
44
description = "Simplex sdk to simplify the development with simplicity"
55
license.workspace = true
66
edition.workspace = true

crates/sdk/src/provider/network.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ use std::str::FromStr;
33
use simplicityhl::simplicity::elements;
44
use simplicityhl::simplicity::hashes::{Hash, sha256};
55

6+
use elements_miniscript::bitcoin::NetworkKind;
7+
68
use crate::constants::{LIQUID_DEFAULT_REGTEST_ASSET_STR, LIQUID_POLICY_ASSET_STR, LIQUID_TESTNET_POLICY_ASSET_STR};
79

810
/// The default Bitcoin `AssetId` used on Liquid testnet.
@@ -101,3 +103,19 @@ impl SimplicityNetwork {
101103
}
102104
}
103105
}
106+
107+
impl From<SimplicityNetwork> for NetworkKind {
108+
fn from(value: SimplicityNetwork) -> Self {
109+
(&value).into()
110+
}
111+
}
112+
113+
impl From<&SimplicityNetwork> for NetworkKind {
114+
fn from(value: &SimplicityNetwork) -> Self {
115+
if value.is_mainnet() {
116+
NetworkKind::Main
117+
} else {
118+
NetworkKind::Test
119+
}
120+
}
121+
}

crates/sdk/src/signer/core.rs

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use bip39::rand::thread_rng;
1717

1818
use elements_miniscript::{
1919
ConfidentialDescriptor, Descriptor, DescriptorPublicKey,
20-
bitcoin::{NetworkKind, PrivateKey, PublicKey, bip32::DerivationPath},
20+
bitcoin::{PrivateKey, PublicKey, bip32::DerivationPath},
2121
elements::{
2222
EcdsaSighashType,
2323
bitcoin::bip32::{Fingerprint, Xpriv, Xpub},
@@ -121,22 +121,23 @@ enum Estimate {
121121
Failure(u64),
122122
}
123123

124+
// TODO: refactor descriptors to be a standalone object to specify custom derivation paths.
124125
impl Signer {
125126
/// Creates a new `Signer` instance seeded from the provided mnemonic and paired with the specified provider.
126127
///
127128
/// # Panics
128129
/// Panics if the mnemonic fails to parse, or if deriving the master private key fails.
129130
#[must_use]
130131
pub fn new(mnemonic: &str, provider: Box<dyn ProviderTrait>) -> Self {
132+
let network = *provider.get_network();
131133
let secp = Secp256k1::new();
132134
let mnemonic: Mnemonic = mnemonic
133135
.parse()
134136
.map_err(|e: bip39::Error| SignerError::Mnemonic(e.to_string()))
135137
.unwrap();
136-
let seed = mnemonic.to_seed("");
137-
let xprv = Xpriv::new_master(NetworkKind::Test, &seed).unwrap();
138138

139-
let network = *provider.get_network();
139+
let seed = mnemonic.to_seed("");
140+
let xprv = Xpriv::new_master(network, &seed).unwrap();
140141

141142
Self {
142143
mnemonic,
@@ -278,7 +279,7 @@ impl Signer {
278279
descriptor.descriptor = descriptor.descriptor.into_single_descriptors().unwrap()[0].clone();
279280

280281
descriptor
281-
.at_derivation_index(1)
282+
.at_derivation_index(0)
282283
.unwrap()
283284
.address(&self.secp, self.network.address_params())
284285
.unwrap()
@@ -295,7 +296,7 @@ impl Signer {
295296
.unwrap();
296297

297298
descriptor.into_single_descriptors().unwrap()[0]
298-
.at_derivation_index(1)
299+
.at_derivation_index(0)
299300
.unwrap()
300301
.address(self.network.address_params())
301302
.unwrap()
@@ -390,19 +391,19 @@ impl Signer {
390391
let full_path = self.get_derivation_path().unwrap();
391392

392393
let derived = full_path.extend(
393-
DerivationPath::from_str("0/1")
394+
DerivationPath::from_str("0/0")
394395
.map_err(|e| SignerError::DerivationPath(e.to_string()))
395396
.unwrap(),
396397
);
397398

398399
let ext_derived = master_xprv.derive_priv(&self.secp, &derived).unwrap();
399400

400-
PrivateKey::new(ext_derived.private_key, NetworkKind::Test)
401+
PrivateKey::new(ext_derived.private_key, self.network)
401402
}
402403

403404
/// Generates the private key linked to confidential payload blinding.
404405
///
405-
/// The generated `PrivateKey` is associated with the `Test` (non-Bitcoin-mainnet) network kind.
406+
/// The generated `PrivateKey` is associated with the `Test` (non-Bitcoin/Liquid-mainnet) network kind.
406407
/// Retrieves the blinding private key derived from the master SLIP77 key and the script public key of the address.
407408
///
408409
/// # Panics
@@ -414,7 +415,7 @@ impl Signer {
414415
.unwrap()
415416
.blinding_private_key(&self.get_address().script_pubkey());
416417

417-
PrivateKey::new(blinding_key, NetworkKind::Test)
418+
PrivateKey::new(blinding_key, self.network)
418419
}
419420

420421
fn unblind(&self, utxos: Vec<UTXO>) -> Result<Vec<UTXO>, SignerError> {
@@ -440,12 +441,14 @@ impl Signer {
440441
) -> Result<Estimate, SignerError> {
441442
// estimate the tx fee with the change
442443
// use this wpkh address as a change script
443-
// TODO: this should be confidential
444-
fee_tx.add_output(PartialOutput::new(
445-
self.get_address().script_pubkey(),
446-
PLACEHOLDER_FEE,
447-
self.network.policy_asset(),
448-
));
444+
fee_tx.add_output(
445+
PartialOutput::new(
446+
self.get_address().script_pubkey(),
447+
PLACEHOLDER_FEE,
448+
self.network.policy_asset(),
449+
)
450+
.with_blinding_key(self.get_blinding_public_key()),
451+
);
449452

450453
fee_tx.add_output(PartialOutput::new(
451454
Script::new(),
@@ -469,6 +472,10 @@ impl Signer {
469472
}
470473

471474
// not enough funds, so we need to estimate without the change
475+
// TODO: if a UTXO being spent is confidential + there are no
476+
// confidential outputs + there is no change, this will fail
477+
// with `RPC error -26: bad-txns-in-ne-out, value in != value out`.
478+
// Fix this by adding a dummy change or throwing a clear error.
472479
fee_tx.remove_output(fee_tx.n_outputs() - 2);
473480

474481
let final_tx = self.sign_tx(&fee_tx)?;
@@ -624,7 +631,10 @@ impl Signer {
624631
fn get_wpkh_descriptor(&self) -> Result<String, SignerError> {
625632
let fingerprint = self.fingerprint()?;
626633
let path = self.get_derivation_path()?;
627-
let xpub = self.derive_xpub(&path)?;
634+
let mut xpub = self.derive_xpub(&path)?;
635+
636+
// TODO: Blockstream app does this. Is this a bug?
637+
xpub.parent_fingerprint = Fingerprint::default();
628638

629639
Ok(format!("elwpkh([{fingerprint}/{path}]{xpub}/<0;1>/*)"))
630640
}
@@ -646,7 +656,7 @@ mod tests {
646656

647657
fn create_signer() -> Signer {
648658
let url = "https://blockstream.info/liquidtestnet/api".to_string();
649-
let network = SimplicityNetwork::LiquidTestnet;
659+
let network = SimplicityNetwork::Liquid;
650660

651661
Signer::new(random_mnemonic().as_str(), Box::new(EsploraProvider::new(url, network)))
652662
}

0 commit comments

Comments
 (0)