Skip to content

Commit d29be2f

Browse files
change private key in request to pay
A private key can be interpreted into different recipient types: p2pkh, p2wpkh, p2tr, etc... In order for the client to import the private key and recover the UTXO, we need to specify the descriptor type. In this commit we change get_combined_private_key into a get_combined_private_descriptor, where the return type is a proper bitcoin descriptor with a WIF-formatted private key
1 parent 4eb1a0f commit d29be2f

File tree

7 files changed

+39
-24
lines changed

7 files changed

+39
-24
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,4 @@ async-broadcast = "0.7.2"
4545
rstest = "0.25.0"
4646
secp256k1 = { version = "0.29" }
4747
reqwest = { version = "0.12", default-features = false }
48+
miniscript = {version = "12.3"}

crates/bcr-ebill-api/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ anyhow.workspace = true
2020
thiserror.workspace = true
2121
uuid.workspace = true
2222
bitcoin.workspace = true
23+
miniscript.workspace = true
2324
nostr-sdk.workspace = true
2425
nostr.workspace = true
2526
futures.workspace = true
@@ -29,6 +30,7 @@ bcr-ebill-persistence = { path = "../bcr-ebill-persistence" }
2930
bcr-ebill-transport = { path = "../bcr-ebill-transport" }
3031
tokio.workspace = true
3132
tokio_with_wasm.workspace = true
33+
secp256k1.workspace = true
3234

3335
[target.'cfg(target_arch = "wasm32")'.dependencies]
3436
reqwest = { workspace = true, features = ["json"] }

crates/bcr-ebill-api/src/external/bitcoin.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ pub trait BitcoinClientApi: ServiceTraitBounds {
5454

5555
fn generate_link_to_pay(&self, address: &str, sum: u64, message: &str) -> String;
5656

57-
fn get_combined_private_key(
57+
fn get_combined_private_descriptor(
5858
&self,
5959
pkey: &bitcoin::PrivateKey,
6060
pkey_to_combine: &bitcoin::PrivateKey,
@@ -197,7 +197,7 @@ impl BitcoinClientApi for BitcoinClient {
197197
link
198198
}
199199

200-
fn get_combined_private_key(
200+
fn get_combined_private_descriptor(
201201
&self,
202202
pkey: &bitcoin::PrivateKey,
203203
pkey_to_combine: &bitcoin::PrivateKey,
@@ -206,7 +206,19 @@ impl BitcoinClientApi for BitcoinClient {
206206
.inner
207207
.add_tweak(&Scalar::from(pkey_to_combine.inner))
208208
.map_err(|e| Error::PrivateKey(e.to_string()))?;
209-
Ok(bitcoin::PrivateKey::new(private_key_bill, get_config().bitcoin_network()).to_string())
209+
let priv_key = bitcoin::PrivateKey::new(private_key_bill, get_config().bitcoin_network());
210+
let single = miniscript::descriptor::SinglePriv {
211+
key: priv_key,
212+
origin: None,
213+
};
214+
let desc_seckey = miniscript::descriptor::DescriptorSecretKey::Single(single);
215+
let desc_pubkey = desc_seckey.to_public(secp256k1::global::SECP256K1).unwrap();
216+
let kmap = miniscript::descriptor::KeyMap::from_iter(std::iter::once((
217+
desc_pubkey.clone(),
218+
desc_seckey,
219+
)));
220+
let desc = miniscript::Descriptor::new_pkh(desc_pubkey).unwrap();
221+
Ok(desc.to_string_with_secret(&kmap))
210222
}
211223

212224
fn get_mempool_link_for_address(&self, address: &str) -> String {

crates/bcr-ebill-api/src/service/bill_service/service.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -471,12 +471,12 @@ impl BillServiceApi for BillService {
471471
}
472472

473473
// The first key is always the bill key
474-
let private_key = self.bitcoin_client.get_combined_private_key(
474+
let private_descriptor = self.bitcoin_client.get_combined_private_descriptor(
475475
&BcrKeys::from_private_key(&bill_keys.private_key)?
476476
.get_bitcoin_private_key(get_config().bitcoin_network()),
477477
&caller_keys.get_bitcoin_private_key(get_config().bitcoin_network()),
478478
)?;
479-
return Ok(BillCombinedBitcoinKey { private_key });
479+
return Ok(BillCombinedBitcoinKey { private_descriptor });
480480
}
481481

482482
async fn get_detail(
@@ -827,7 +827,7 @@ impl BillServiceApi for BillService {
827827
Some(ref endorsee) => endorsee,
828828
};
829829

830-
let private_key_to_spend = self.bitcoin_client.get_combined_private_key(
830+
let descriptor_to_spend = self.bitcoin_client.get_combined_private_descriptor(
831831
&BcrKeys::from_private_key(&bill_keys.private_key)?
832832
.get_bitcoin_private_key(get_config().bitcoin_network()),
833833
&caller_keys.get_bitcoin_private_key(get_config().bitcoin_network()),
@@ -872,7 +872,7 @@ impl BillServiceApi for BillService {
872872
sum: currency::sum_to_string(bill.sum),
873873
link_to_pay,
874874
address_to_pay,
875-
private_key_to_spend: private_key_to_spend.clone(),
875+
private_descriptor_to_spend: descriptor_to_spend.clone(),
876876
mempool_link_for_address_to_pay,
877877
status: if is_paid {
878878
PastPaymentStatus::Paid(req_to_pay.timestamp)
@@ -918,7 +918,7 @@ impl BillServiceApi for BillService {
918918
sum: currency::sum_to_string(past_sell_payment.0.sum),
919919
link_to_pay,
920920
address_to_pay,
921-
private_key_to_spend: private_key_to_spend.clone(),
921+
private_descriptor_to_spend: descriptor_to_spend.clone(),
922922
mempool_link_for_address_to_pay,
923923
status: past_sell_payment.1,
924924
}));
@@ -952,7 +952,7 @@ impl BillServiceApi for BillService {
952952
sum: currency::sum_to_string(past_sell_payment.0.sum),
953953
link_to_pay,
954954
address_to_pay,
955-
private_key_to_spend: private_key_to_spend.clone(),
955+
private_descriptor_to_spend: descriptor_to_spend.clone(),
956956
mempool_link_for_address_to_pay,
957957
status: past_sell_payment.1,
958958
}));

crates/bcr-ebill-api/src/service/bill_service/test_utils.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,11 +168,11 @@ pub fn get_service(mut ctx: MockBillContext) -> BillService {
168168
.expect_check_if_paid()
169169
.returning(|_, _| Ok((true, 100)));
170170
bitcoin_client
171-
.expect_get_combined_private_key()
172-
.returning(|_, _| Ok(String::from("123412341234")));
171+
.expect_get_combined_private_descriptor()
172+
.returning(|_, _| Ok(String::from("wpkh(cNjLH9K88VEhLeinPJkgPCZJZ9vNdi2L2UiTBuEfy4gSbTsMvvJg)")));
173173
bitcoin_client
174174
.expect_get_address_to_pay()
175-
.returning(|_, _| Ok(String::from("tb1qteyk7pfvvql2r2zrsu4h4xpvju0nz7ykvguyk0")));
175+
.returning(|_, _| Ok(String::from("tb1qssh7nk78mm35h75dg4th77zqz4qk3eay68krf9")));
176176
bitcoin_client
177177
.expect_get_mempool_link_for_address()
178178
.returning(|_| {

crates/bcr-ebill-core/src/bill/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ pub enum BillRole {
402402

403403
#[derive(Debug)]
404404
pub struct BillCombinedBitcoinKey {
405-
pub private_key: String,
405+
pub private_descriptor: String,
406406
}
407407

408408
#[derive(Debug)]
@@ -458,7 +458,7 @@ pub struct PastPaymentDataSell {
458458
pub sum: String,
459459
pub link_to_pay: String,
460460
pub address_to_pay: String,
461-
pub private_key_to_spend: String,
461+
pub private_descriptor_to_spend: String,
462462
pub mempool_link_for_address_to_pay: String,
463463
pub status: PastPaymentStatus,
464464
}
@@ -472,7 +472,7 @@ pub struct PastPaymentDataPayment {
472472
pub sum: String,
473473
pub link_to_pay: String,
474474
pub address_to_pay: String,
475-
pub private_key_to_spend: String,
475+
pub private_descriptor_to_spend: String,
476476
pub mempool_link_for_address_to_pay: String,
477477
pub status: PastPaymentStatus,
478478
}
@@ -486,7 +486,7 @@ pub struct PastPaymentDataRecourse {
486486
pub sum: String,
487487
pub link_to_pay: String,
488488
pub address_to_pay: String,
489-
pub private_key_to_spend: String,
489+
pub private_descriptor_to_spend: String,
490490
pub mempool_link_for_address_to_pay: String,
491491
pub status: PastPaymentStatus,
492492
}

crates/bcr-ebill-wasm/src/data/bill.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -125,13 +125,13 @@ pub struct RejectActionBillPayload {
125125
#[derive(Tsify, Debug, Clone, Serialize)]
126126
#[tsify(into_wasm_abi)]
127127
pub struct BillCombinedBitcoinKeyWeb {
128-
pub private_key: String,
128+
pub private_descriptor: String,
129129
}
130130

131131
impl From<BillCombinedBitcoinKey> for BillCombinedBitcoinKeyWeb {
132132
fn from(val: BillCombinedBitcoinKey) -> Self {
133133
BillCombinedBitcoinKeyWeb {
134-
private_key: val.private_key,
134+
private_descriptor: val.private_descriptor,
135135
}
136136
}
137137
}
@@ -310,7 +310,7 @@ pub struct PastPaymentDataSellWeb {
310310
pub sum: String,
311311
pub link_to_pay: String,
312312
pub address_to_pay: String,
313-
pub private_key_to_spend: String,
313+
pub private_descriptor_to_spend: String,
314314
pub mempool_link_for_address_to_pay: String,
315315
pub status: PastPaymentStatusWeb,
316316
}
@@ -325,7 +325,7 @@ impl From<PastPaymentDataSell> for PastPaymentDataSellWeb {
325325
sum: val.sum,
326326
link_to_pay: val.link_to_pay,
327327
address_to_pay: val.address_to_pay,
328-
private_key_to_spend: val.private_key_to_spend,
328+
private_descriptor_to_spend: val.private_descriptor_to_spend,
329329
mempool_link_for_address_to_pay: val.mempool_link_for_address_to_pay,
330330
status: val.status.into(),
331331
}
@@ -342,7 +342,7 @@ pub struct PastPaymentDataPaymentWeb {
342342
pub sum: String,
343343
pub link_to_pay: String,
344344
pub address_to_pay: String,
345-
pub private_key_to_spend: String,
345+
pub private_descriptor_to_spend: String,
346346
pub mempool_link_for_address_to_pay: String,
347347
pub status: PastPaymentStatusWeb,
348348
}
@@ -356,7 +356,7 @@ impl From<PastPaymentDataPayment> for PastPaymentDataPaymentWeb {
356356
sum: val.sum,
357357
link_to_pay: val.link_to_pay,
358358
address_to_pay: val.address_to_pay,
359-
private_key_to_spend: val.private_key_to_spend,
359+
private_descriptor_to_spend: val.private_descriptor_to_spend,
360360
mempool_link_for_address_to_pay: val.mempool_link_for_address_to_pay,
361361
status: val.status.into(),
362362
}
@@ -373,7 +373,7 @@ pub struct PastPaymentDataRecourseWeb {
373373
pub sum: String,
374374
pub link_to_pay: String,
375375
pub address_to_pay: String,
376-
pub private_key_to_spend: String,
376+
pub private_descriptor_to_spend: String,
377377
pub mempool_link_for_address_to_pay: String,
378378
pub status: PastPaymentStatusWeb,
379379
}
@@ -388,7 +388,7 @@ impl From<PastPaymentDataRecourse> for PastPaymentDataRecourseWeb {
388388
sum: val.sum,
389389
link_to_pay: val.link_to_pay,
390390
address_to_pay: val.address_to_pay,
391-
private_key_to_spend: val.private_key_to_spend,
391+
private_descriptor_to_spend: val.private_descriptor_to_spend,
392392
mempool_link_for_address_to_pay: val.mempool_link_for_address_to_pay,
393393
status: val.status.into(),
394394
}

0 commit comments

Comments
 (0)