Skip to content

Commit b95d194

Browse files
authored
Use node id, pubkey, secretkey and bill id (#557)
1 parent ae833ac commit b95d194

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+3679
-3423
lines changed

CHANGELOG.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
11
# 0.3.17
22

3-
* Use NodeId and BillId types internally instead of strings
4-
* Removed `NodeId` trait and replaced it with method
3+
* Use NodeId, PublicKey, SecretKey and BillId types internally instead of strings (fully breaking)
4+
* This breaks all existing databases, since the node ids and bill ids now have the format `prefix|network|pubkey`- example: `bitcrt03f9f94d1fdc2090d46f3524807e3f58618c36988e69577d70d5d4d1e9e9645a4f`
5+
* The `prefix` is `bitcr`
6+
* The `network` character is as follows:
7+
* m => Mainnet
8+
* t => Testnet
9+
* T => Testnet4
10+
* r => Regtest
11+
* The `pubkey` is a stringified secp256k1 public key
12+
* Existing apps need to a.) delete their IndexedDB and b.) their localhost (because the mint ID might be in there)
13+
* Removed `NodeId` trait and replaced it with a concrete method on the corresponding types (breaking API change)
14+
* Rename `BillId` TS type to `BillIdResponse` (breaking TS type)
515

616
# 0.3.16
717

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ futures = { version = "0.3", default-features = false }
4343
anyhow = { version = "1", default-features = false }
4444
thiserror = { version = "2", default-features = false }
4545
uuid = { version = "1", default-features = false, features = ["v4", "js"] }
46-
bitcoin = { version = "0.32", default-features = false }
46+
bitcoin = { version = "0.32", default-features = false, features = ["serde"] }
4747
bip39 = { version = "2.1", features = ["rand"] }
4848
ecies = { version = "0.2", default-features = false, features = ["pure"] }
4949
nostr = { version = "0.42" }

crates/bcr-ebill-api/src/data/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@ pub use bcr_ebill_core::company;
33
pub use bcr_ebill_core::contact;
44
pub use bcr_ebill_core::identity;
55
pub use bcr_ebill_core::mint;
6+
pub use bcr_ebill_core::nostr_contact;
67
pub use bcr_ebill_core::notification;
78

89
pub use bcr_ebill_core::File;
910
pub use bcr_ebill_core::GeneralSearchFilterItemType;
1011
pub use bcr_ebill_core::GeneralSearchResult;
12+
pub use bcr_ebill_core::NodeId;
1113
pub use bcr_ebill_core::OptionalPostalAddress;
1214
pub use bcr_ebill_core::PostalAddress;
15+
pub use bcr_ebill_core::PublicKey;
16+
pub use bcr_ebill_core::SecretKey;
1317
pub use bcr_ebill_core::UploadFileResult;

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

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
use crate::get_config;
22
use async_trait::async_trait;
3-
use bcr_ebill_core::{ServiceTraitBounds, util};
3+
use bcr_ebill_core::{PublicKey, ServiceTraitBounds, util};
44
use bitcoin::{Network, secp256k1::Scalar};
55
use log::debug;
66
use serde::Deserialize;
7-
use std::str::FromStr;
87
use thiserror::Error;
98

109
/// Generic result type
@@ -50,7 +49,11 @@ pub trait BitcoinClientApi: ServiceTraitBounds {
5049

5150
async fn check_if_paid(&self, address: &str, sum: u64) -> Result<(bool, u64)>;
5251

53-
fn get_address_to_pay(&self, bill_public_key: &str, holder_public_key: &str) -> Result<String>;
52+
fn get_address_to_pay(
53+
&self,
54+
bill_public_key: &PublicKey,
55+
holder_public_key: &PublicKey,
56+
) -> Result<String>;
5457

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

@@ -188,11 +191,13 @@ impl BitcoinClientApi for BitcoinClient {
188191
}
189192
}
190193

191-
fn get_address_to_pay(&self, bill_public_key: &str, holder_public_key: &str) -> Result<String> {
192-
let public_key_bill = bitcoin::CompressedPublicKey::from_str(bill_public_key)
193-
.map_err(|e| Error::PublicKey(e.to_string()))?;
194-
let public_key_bill_holder = bitcoin::CompressedPublicKey::from_str(holder_public_key)
195-
.map_err(|e| Error::PublicKey(e.to_string()))?;
194+
fn get_address_to_pay(
195+
&self,
196+
bill_public_key: &PublicKey,
197+
holder_public_key: &PublicKey,
198+
) -> Result<String> {
199+
let public_key_bill = bitcoin::CompressedPublicKey(*bill_public_key);
200+
let public_key_bill_holder = bitcoin::CompressedPublicKey(*holder_public_key);
196201

197202
let public_key_bill = public_key_bill
198203
.0

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

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::str::FromStr;
33
use crate::{constants::CURRENCY_CRSAT, util};
44
use async_trait::async_trait;
55
use bcr_ebill_core::{
6-
PostalAddress, ServiceTraitBounds,
6+
PostalAddress, SecretKey, ServiceTraitBounds,
77
bill::BitcreditBill,
88
contact::{BillAnonParticipant, BillIdentParticipant, BillParticipant, ContactType},
99
util::{BcrKeys, date::DateTimeUtc},
@@ -87,7 +87,7 @@ pub trait MintClientApi: ServiceTraitBounds {
8787
mint_url: &str,
8888
keyset: cdk02::KeySet,
8989
quote_id: &str,
90-
private_key: &str,
90+
private_key: &SecretKey,
9191
blinded_messages: Vec<cashu::BlindedMessage>,
9292
secrets: Vec<cashu::secret::Secret>,
9393
rs: Vec<cashu::SecretKey>,
@@ -196,14 +196,15 @@ impl MintClientApi for MintClient {
196196
mint_url: &str,
197197
keyset: cdk02::KeySet,
198198
quote_id: &str,
199-
private_key: &str,
199+
private_key: &SecretKey,
200200
blinded_messages: Vec<cashu::BlindedMessage>,
201201
secrets: Vec<cashu::secret::Secret>,
202202
rs: Vec<cashu::SecretKey>,
203203
) -> Result<String> {
204204
let token_mint_url =
205205
cashu::MintUrl::from_str(mint_url).map_err(|_| Error::InvalidMintUrl)?;
206-
let secret_key = cdk01::SecretKey::from_hex(private_key).map_err(|_| Error::PrivateKey)?;
206+
let secret_key = cdk01::SecretKey::from_hex(private_key.display_secret().to_string())
207+
.map_err(|_| Error::PrivateKey)?;
207208
let qid = uuid::Uuid::from_str(quote_id).map_err(|_| Error::InvalidMintRequestId)?;
208209

209210
// mint
@@ -262,7 +263,7 @@ impl MintClientApi for MintClient {
262263
files: &[Url],
263264
) -> Result<String> {
264265
let bill_info = BillInfo {
265-
id: bill.id.clone(),
266+
id: bill.id.clone().to_string(),
266267
drawee: map_bill_ident_participant(bill.drawee.to_owned()),
267268
drawer: map_bill_ident_participant(bill.drawer.to_owned()),
268269
payee: map_bill_participant(bill.payee.to_owned()),
@@ -453,7 +454,7 @@ fn map_bill_anon_participant(
453454
ident: BillAnonParticipant,
454455
) -> bcr_wdc_webapi::bill::BillAnonParticipant {
455456
bcr_wdc_webapi::bill::BillAnonParticipant {
456-
node_id: ident.node_id,
457+
node_id: ident.node_id.to_string(),
457458
email: ident.email,
458459
nostr_relays: ident.nostr_relays,
459460
}
@@ -464,7 +465,7 @@ fn map_bill_ident_participant(
464465
) -> bcr_wdc_webapi::bill::BillIdentParticipant {
465466
bcr_wdc_webapi::bill::BillIdentParticipant {
466467
t: map_contact_type(ident.t),
467-
node_id: ident.node_id,
468+
node_id: ident.node_id.to_string(),
468469
name: ident.name,
469470
postal_address: map_postal_address(ident.postal_address),
470471
email: ident.email,

crates/bcr-ebill-api/src/lib.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use anyhow::{Result, anyhow};
2+
use bcr_ebill_core::NodeId;
23
use bitcoin::Network;
34
use std::sync::OnceLock;
45

@@ -20,7 +21,7 @@ pub use persistence::db::SurrealDbConfig;
2021
pub use persistence::get_db_context;
2122
pub use persistence::notification::NotificationFilter;
2223

23-
#[derive(Debug, Clone, Default)]
24+
#[derive(Debug, Clone)]
2425
pub struct Config {
2526
pub bitcoin_network: String,
2627
pub esplora_base_url: String,
@@ -54,17 +55,16 @@ pub struct NostrConfig {
5455
}
5556

5657
/// Mint configuration
57-
#[derive(Debug, Clone, Default)]
58+
#[derive(Debug, Clone)]
5859
pub struct MintConfig {
5960
/// URL of the default mint
6061
pub default_mint_url: String,
6162
/// Node Id of the default mint
62-
pub default_mint_node_id: String,
63+
pub default_mint_node_id: NodeId,
6364
}
6465

6566
impl MintConfig {
66-
pub fn new(default_mint_url: String, default_mint_node_id: String) -> Result<Self> {
67-
util::crypto::validate_pub_key(&default_mint_node_id)?;
67+
pub fn new(default_mint_url: String, default_mint_node_id: NodeId) -> Result<Self> {
6868
reqwest::Url::parse(&default_mint_url)
6969
.map_err(|e| anyhow!("Invalid Default Mint URL: {e}"))?;
7070
Ok(Self {

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

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,18 +66,14 @@ impl BackupService {
6666
impl BackupServiceApi for BackupService {
6767
async fn backup(&self) -> Result<Vec<u8>> {
6868
self.validate_surreal_db_connection()?;
69-
let public_key = self.identity_store.get_key_pair().await?.get_public_key();
69+
let public_key = self.identity_store.get_key_pair().await?.pub_key();
7070
let bytes = self.store.backup().await?;
7171
let encrypted_bytes = util::crypto::encrypt_ecies(&bytes, &public_key)?;
7272
Ok(encrypted_bytes)
7373
}
7474

7575
async fn restore(&self, file_path: &Path) -> Result<()> {
76-
let private_key = self
77-
.identity_store
78-
.get_key_pair()
79-
.await?
80-
.get_private_key_string();
76+
let private_key = self.identity_store.get_key_pair().await?.get_private_key();
8177
let mut buffer = vec![];
8278
let mut file = File::open(file_path).await?;
8379
file.read_to_end(&mut buffer).await?;
@@ -187,7 +183,7 @@ OPTION IMPORT;
187183
DEFINE TABLE bill_chain TYPE ANY SCHEMALESS PERMISSIONS NONE;";
188184

189185
let encrypted_bytes =
190-
util::crypto::encrypt_ecies(backup_str.as_bytes(), &keys.get_public_key()).unwrap();
186+
util::crypto::encrypt_ecies(backup_str.as_bytes(), &keys.pub_key()).unwrap();
191187

192188
let temp_dir = env::temp_dir();
193189
let file_path = temp_dir.join("test.surql");

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

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use bcr_ebill_core::{
2-
Validate, ValidationError,
3-
bill::{BillKeys, BitcreditBill, RecourseReason},
2+
NodeId, Validate, ValidationError,
3+
bill::{BillId, BillKeys, BitcreditBill, RecourseReason},
44
blockchain::{
55
self, Blockchain,
66
bill::{
@@ -221,9 +221,10 @@ impl BillService {
221221
}
222222
// can be anon to offer to sell
223223
BillAction::OfferToSell(buyer, sum, currency) => {
224-
let address_to_pay = self
225-
.bitcoin_client
226-
.get_address_to_pay(&bill_keys.public_key, &signer_public_data.node_id())?;
224+
let address_to_pay = self.bitcoin_client.get_address_to_pay(
225+
&bill_keys.public_key,
226+
&signer_public_data.node_id().pub_key(),
227+
)?;
227228
let block_data = BillOfferToSellBlockData {
228229
seller: if holder_is_anon {
229230
// if holder is anon, we need to continue as anon
@@ -416,7 +417,7 @@ impl BillService {
416417

417418
pub(super) async fn validate_and_add_block(
418419
&self,
419-
bill_id: &str,
420+
bill_id: &BillId,
420421
blockchain: &mut BillBlockchain,
421422
new_block: BillBlock,
422423
) -> Result<()> {
@@ -432,7 +433,7 @@ impl BillService {
432433
pub(super) async fn add_identity_and_company_chain_blocks_for_signed_bill_action(
433434
&self,
434435
signer_public_data: &BillParticipant,
435-
bill_id: &str,
436+
bill_id: &BillId,
436437
block: &BillBlock,
437438
identity_keys: &BcrKeys,
438439
signer_keys: &BcrKeys,
@@ -457,8 +458,8 @@ impl BillService {
457458
block,
458459
identity_keys,
459460
&CompanyKeys {
460-
private_key: signer_keys.get_private_key_string(),
461-
public_key: signer_keys.get_public_key(),
461+
private_key: signer_keys.get_private_key(),
462+
public_key: signer_keys.pub_key(),
462463
},
463464
timestamp,
464465
)
@@ -491,7 +492,7 @@ impl BillService {
491492

492493
pub(super) async fn add_block_to_identity_chain_for_signed_bill_action(
493494
&self,
494-
bill_id: &str,
495+
bill_id: &BillId,
495496
block: &BillBlock,
496497
keys: &BcrKeys,
497498
timestamp: u64,
@@ -514,8 +515,8 @@ impl BillService {
514515

515516
pub(super) async fn add_block_to_identity_chain_for_signed_company_bill_action(
516517
&self,
517-
company_id: &str,
518-
bill_id: &str,
518+
company_id: &NodeId,
519+
bill_id: &BillId,
519520
block: &BillBlock,
520521
keys: &BcrKeys,
521522
timestamp: u64,
@@ -539,8 +540,8 @@ impl BillService {
539540

540541
pub(super) async fn add_block_to_company_chain_for_signed_bill_action(
541542
&self,
542-
company_id: &str,
543-
bill_id: &str,
543+
company_id: &NodeId,
544+
bill_id: &BillId,
544545
block: &BillBlock,
545546
signatory_keys: &BcrKeys,
546547
company_keys: &CompanyKeys,

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

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@ use crate::util;
22

33
use super::service::BillService;
44
use super::{Error, Result};
5-
use bcr_ebill_core::ValidationError;
65
use bcr_ebill_core::bill::BillMintStatus;
76
use bcr_ebill_core::bill::validation::get_expiration_deadline_base_for_req_to_pay;
87
use bcr_ebill_core::constants::RECOURSE_DEADLINE_SECONDS;
98
use bcr_ebill_core::contact::{BillParticipant, Contact};
109
use bcr_ebill_core::identity::IdentityType;
10+
use bcr_ebill_core::{NodeId, ValidationError};
1111
use bcr_ebill_core::{
1212
bill::{
13-
BillAcceptanceStatus, BillCurrentWaitingState, BillData, BillKeys, BillParticipants,
14-
BillPaymentStatus, BillRecourseStatus, BillSellStatus, BillStatus,
13+
BillAcceptanceStatus, BillCurrentWaitingState, BillData, BillId, BillKeys,
14+
BillParticipants, BillPaymentStatus, BillRecourseStatus, BillSellStatus, BillStatus,
1515
BillWaitingForPaymentState, BillWaitingForRecourseState, BillWaitingForSellState,
1616
BitcreditBill, BitcreditBillResult,
1717
},
@@ -43,7 +43,7 @@ impl BillService {
4343
chain: &BillBlockchain,
4444
bill_keys: &BillKeys,
4545
identity: &Identity,
46-
contacts: &HashMap<String, Contact>,
46+
contacts: &HashMap<NodeId, Contact>,
4747
) -> Result<BitcreditBill> {
4848
let bill_first_version = chain.get_first_version_bill(bill_keys)?;
4949
let bill_parties = chain.get_bill_parties(bill_keys, &bill_first_version)?;
@@ -137,7 +137,7 @@ impl BillService {
137137
chain: &BillBlockchain,
138138
bill_keys: &BillKeys,
139139
local_identity: &Identity,
140-
current_identity_node_id: &str,
140+
current_identity_node_id: &NodeId,
141141
current_timestamp: u64,
142142
) -> Result<BitcreditBillResult> {
143143
// fetch contacts to get current contact data for participants
@@ -193,7 +193,7 @@ impl BillService {
193193
// calculate, if the caller has received funds at any point in the bill
194194
let mut redeemed_funds_available =
195195
chain.is_beneficiary_from_a_block(bill_keys, current_identity_node_id);
196-
if holder.node_id() == current_identity_node_id && paid {
196+
if holder.node_id() == *current_identity_node_id && paid {
197197
redeemed_funds_available = true;
198198
}
199199

@@ -362,7 +362,7 @@ impl BillService {
362362
// we're waiting, collect data
363363
let address_to_pay = self
364364
.bitcoin_client
365-
.get_address_to_pay(&bill_keys.public_key, &holder.node_id())?;
365+
.get_address_to_pay(&bill_keys.public_key, &holder.node_id().pub_key())?;
366366

367367
let link_to_pay = self.bitcoin_client.generate_link_to_pay(
368368
&address_to_pay,
@@ -413,7 +413,7 @@ impl BillService {
413413

414414
let address_to_pay = self.bitcoin_client.get_address_to_pay(
415415
&bill_keys.public_key,
416-
&payment_info.recourser.node_id,
416+
&payment_info.recourser.node_id.pub_key(),
417417
)?;
418418

419419
let link_to_pay = self.bitcoin_client.generate_link_to_pay(
@@ -624,7 +624,7 @@ impl BillService {
624624
&self,
625625
bill: &mut BitcreditBillResult,
626626
identity: &Identity,
627-
contacts: &HashMap<String, Contact>,
627+
contacts: &HashMap<NodeId, Contact>,
628628
) {
629629
bill.participants.payee = self
630630
.extend_bill_chain_participant_data_from_contacts_or_identity(
@@ -711,9 +711,9 @@ impl BillService {
711711

712712
pub(super) async fn recalculate_and_cache_bill(
713713
&self,
714-
bill_id: &str,
714+
bill_id: &BillId,
715715
local_identity: &Identity,
716-
current_identity_node_id: &str,
716+
current_identity_node_id: &NodeId,
717717
current_timestamp: u64,
718718
) -> Result<BitcreditBillResult> {
719719
let chain = self.blockchain_store.get_chain(bill_id).await?;
@@ -739,9 +739,9 @@ impl BillService {
739739

740740
pub(super) async fn get_full_bill(
741741
&self,
742-
bill_id: &str,
742+
bill_id: &BillId,
743743
local_identity: &Identity,
744-
current_identity_node_id: &str,
744+
current_identity_node_id: &NodeId,
745745
current_timestamp: u64,
746746
) -> Result<BitcreditBillResult> {
747747
// if there is no such bill, we return an error

0 commit comments

Comments
 (0)