diff --git a/clippy.toml b/clippy.toml index 84e14003..5e1396aa 100644 --- a/clippy.toml +++ b/clippy.toml @@ -1 +1 @@ -too-many-arguments-threshold=14 +too-many-arguments-threshold=200 diff --git a/crates/bcr-ebill-api/src/service/bill_service/mod.rs b/crates/bcr-ebill-api/src/service/bill_service/mod.rs index 74b863e1..f30be081 100644 --- a/crates/bcr-ebill-api/src/service/bill_service/mod.rs +++ b/crates/bcr-ebill-api/src/service/bill_service/mod.rs @@ -5617,7 +5617,7 @@ pub mod tests { ctx.bill_blockchain_store .expect_get_chain() .returning(move |_| { - let now = util::date::now().timestamp() as u64; + let now = util::date::now().timestamp() as u64 - 10; // to avoid race with called code let mut chain = get_genesis_chain(Some(bill.clone())); let req_to_recourse = BillBlock::create_block_for_request_recourse( bill_id_test(), diff --git a/crates/bcr-ebill-api/src/service/bill_service/service.rs b/crates/bcr-ebill-api/src/service/bill_service/service.rs index 058b90c3..410fe5ff 100644 --- a/crates/bcr-ebill-api/src/service/bill_service/service.rs +++ b/crates/bcr-ebill-api/src/service/bill_service/service.rs @@ -54,6 +54,7 @@ use bcr_ebill_core::notification::ActionType; use bcr_ebill_core::util::currency; use bcr_ebill_core::{File, ServiceTraitBounds, Validate, ValidationError}; use bcr_ebill_persistence::mint::MintStoreApi; +use bcr_ebill_persistence::nostr::NostrContactStoreApi; use log::{debug, error, info, warn}; use std::collections::{HashMap, HashSet}; use std::sync::Arc; @@ -76,6 +77,7 @@ pub struct BillService { pub mint_store: Arc, pub mint_client: Arc, pub court_client: Arc, + pub nostr_contact_store: Arc, } impl ServiceTraitBounds for BillService {} @@ -95,6 +97,7 @@ impl BillService { mint_store: Arc, mint_client: Arc, court_client: Arc, + nostr_contact_store: Arc, ) -> Self { Self { store, @@ -111,6 +114,7 @@ impl BillService { mint_store, mint_client, court_client, + nostr_contact_store, } } @@ -212,6 +216,10 @@ impl BillService { } else { (None, vec![]) } + } else if let Ok(Some(nostr_contact)) = + self.nostr_contact_store.by_node_id(node_id).await + { + (None, nostr_contact.relays) } else { (None, vec![]) } diff --git a/crates/bcr-ebill-api/src/service/bill_service/test_utils.rs b/crates/bcr-ebill-api/src/service/bill_service/test_utils.rs index d2113106..28691f81 100644 --- a/crates/bcr-ebill-api/src/service/bill_service/test_utils.rs +++ b/crates/bcr-ebill-api/src/service/bill_service/test_utils.rs @@ -11,10 +11,10 @@ use crate::{ MockBillChainStoreApiMock, MockBillStoreApiMock, MockCompanyChainStoreApiMock, MockCompanyStoreApiMock, MockContactStoreApiMock, MockFileUploadStoreApiMock, MockIdentityChainStoreApiMock, MockIdentityStoreApiMock, MockMintStore, - VALID_PAYMENT_ADDRESS_TESTNET, bill_id_test, bill_identified_participant_only_node_id, - bill_participant_only_node_id, empty_address, empty_bill_identified_participant, - empty_bitcredit_bill, empty_identity, init_test_cfg, node_id_test, node_id_test_other, - node_id_test_other2, private_key_test, + MockNostrContactStore, VALID_PAYMENT_ADDRESS_TESTNET, bill_id_test, + bill_identified_participant_only_node_id, bill_participant_only_node_id, empty_address, + empty_bill_identified_participant, empty_bitcredit_bill, empty_identity, init_test_cfg, + node_id_test, node_id_test_other, node_id_test_other2, private_key_test, }, util, }; @@ -58,6 +58,7 @@ pub struct MockBillContext { pub mint_store: MockMintStore, pub mint_client: MockMintClientApi, pub court_client: MockCourtClientApi, + pub nostr_contact_store: MockNostrContactStore, } pub fn get_baseline_identity() -> IdentityWithAll { @@ -206,6 +207,9 @@ pub fn get_service(mut ctx: MockBillContext) -> BillService { ) }); bitcoin_client.expect_generate_link_to_pay().returning(|_,_,_| String::from("bitcoin:1Jfn2nZcJ4T7bhE8FdMRz8T3P3YV4LsWn2?amount=0.01&message=Payment in relation to bill some bill")); + ctx.nostr_contact_store + .expect_by_node_id() + .returning(|_| Ok(None)); ctx.contact_store.expect_get().returning(|node_id| { let mut contact = get_baseline_contact(); contact.node_id = node_id.to_owned(); @@ -300,6 +304,7 @@ pub fn get_service(mut ctx: MockBillContext) -> BillService { Arc::new(ctx.mint_store), Arc::new(ctx.mint_client), Arc::new(ctx.court_client), + Arc::new(ctx.nostr_contact_store), ) } @@ -318,6 +323,7 @@ pub fn get_ctx() -> MockBillContext { mint_store: MockMintStore::new(), mint_client: MockMintClientApi::new(), court_client: MockCourtClientApi::new(), + nostr_contact_store: MockNostrContactStore::new(), } } diff --git a/crates/bcr-ebill-core/src/bill/mod.rs b/crates/bcr-ebill-core/src/bill/mod.rs index 13decbb7..ada40054 100644 --- a/crates/bcr-ebill-core/src/bill/mod.rs +++ b/crates/bcr-ebill-core/src/bill/mod.rs @@ -422,7 +422,7 @@ pub enum BillsFilterRole { #[derive(Clone, Debug)] pub struct PastEndorsee { - pub pay_to_the_order_of: LightBillIdentParticipant, + pub pay_to_the_order_of: BillIdentParticipant, pub signed: LightSignedBy, pub signing_timestamp: u64, pub signing_address: Option, diff --git a/crates/bcr-ebill-wasm/src/api/bill.rs b/crates/bcr-ebill-wasm/src/api/bill.rs index 30c5027f..1984ba38 100644 --- a/crates/bcr-ebill-wasm/src/api/bill.rs +++ b/crates/bcr-ebill-wasm/src/api/bill.rs @@ -922,26 +922,38 @@ async fn request_recourse( let timestamp = external::time::TimeApi::get_atomic_time().await.timestamp; let (signer_public_data, signer_keys) = get_signer_public_data_and_keys().await?; - let public_data_recoursee = match get_ctx() + // we fetch the nostr contact first to know where we have to send + let nostr_contact = match get_ctx() .contact_service - .get_identity_by_node_id(recoursee_node_id) + .get_nostr_contact_by_node_id(recoursee_node_id) .await { - Ok(Some(BillParticipant::Ident(recoursee))) => recoursee, - Ok(Some(BillParticipant::Anon(_))) => { - // recoursee has to be identified - return Err( - BillServiceError::Validation(ValidationError::ContactIsAnonymous( - recoursee_node_id.to_string(), - )) - .into(), - ); - } + Ok(Some(nc)) => nc, Ok(None) | Err(_) => { return Err(BillServiceError::RecourseeNotInContacts.into()); } }; + // fetch past endorsees to validate the recoursee is in there and to get their data + let past_endorsees = get_ctx() + .bill_service + .get_past_endorsees(bill_id, &get_current_identity_node_id().await?) + .await?; + + // create public recourse data from past endorsees and our nostr contacts + let mut public_data_recoursee = match past_endorsees + .iter() + .find(|pe| &pe.pay_to_the_order_of.node_id == recoursee_node_id) + { + Some(found_pe) => found_pe.pay_to_the_order_of.clone(), + None => { + return Err( + BillServiceError::Validation(ValidationError::RecourseeNotPastHolder).into(), + ); + } + }; + public_data_recoursee.nostr_relays = nostr_contact.relays; + get_ctx() .bill_service .execute_bill_action( diff --git a/crates/bcr-ebill-wasm/src/context.rs b/crates/bcr-ebill-wasm/src/context.rs index c428b45a..6ef74f53 100644 --- a/crates/bcr-ebill-wasm/src/context.rs +++ b/crates/bcr-ebill-wasm/src/context.rs @@ -86,6 +86,7 @@ impl Context { db.mint_store.clone(), mint_client, court_client, + db.nostr_contact_store.clone(), )); let identity_service = IdentityService::new( diff --git a/crates/bcr-ebill-wasm/src/data/bill.rs b/crates/bcr-ebill-wasm/src/data/bill.rs index f54b3a90..d33b0071 100644 --- a/crates/bcr-ebill-wasm/src/data/bill.rs +++ b/crates/bcr-ebill-wasm/src/data/bill.rs @@ -894,6 +894,16 @@ impl From for LightBillIdentParticipantWeb { } } +impl From for LightBillIdentParticipantWeb { + fn from(val: BillIdentParticipant) -> Self { + LightBillIdentParticipantWeb { + t: val.t.into(), + name: val.name, + node_id: val.node_id, + } + } +} + #[derive(Tsify, Debug, Clone, Deserialize)] #[tsify(from_wasm_abi)] pub struct ShareBillWithCourtPayload {