commit 68296b4a2e60c98c1dc76f3701e2d8d99482c2a0
parent 160e24603ea94affc98e788bbcf437c1254bece1
Author: triesap <137732411+triesap@users.noreply.github.com>
Date: Mon, 14 Apr 2025 17:59:39 +0000
Adds reference event parameters validation to job requests order handler and guards to ensure reference event can fulfill the job request.
Diffstat:
3 files changed, 64 insertions(+), 15 deletions(-)
diff --git a/src/events/job_request.rs b/src/events/job_request.rs
@@ -11,21 +11,21 @@ use crate::handlers::job_request_order::{JobRequestOrderError, handle_job_reques
use crate::handlers::job_request_preview::handle_job_request_preview;
use crate::handlers::job_request_quote::handle_job_request_quote;
use crate::utils::nostr::{
- NostrTagsResolveError, nostr_event_job_request_feedback, nostr_filter_kind,
- nostr_filter_new_events, nostr_tag_at_value, nostr_tag_first_value, nostr_tag_relays_parse,
- nostr_tag_slice, nostr_tags_resolve,
+ NostrTagsResolveError, nostr_event_job_feedback, nostr_filter_kind, nostr_filter_new_events,
+ nostr_tag_at_value, nostr_tag_first_value, nostr_tag_relays_parse, nostr_tag_slice,
+ nostr_tags_resolve,
};
use crate::utils::unit::MassUnitError;
#[derive(thiserror::Error, Debug)]
pub enum JobRequestError {
- #[error("Order request error: {0}")]
+ #[error("Order: {0}")]
JobRequestOrder(#[from] JobRequestOrderError),
- #[error("Mass unit error: {0}")]
+ #[error("{0}")]
MassUnit(#[from] MassUnitError),
- #[error("Mass unit error: {0}")]
+ #[error("{0}")]
NostrTagsResolve(#[from] NostrTagsResolveError),
#[error("Invalid job request input type: {0}")]
@@ -152,7 +152,7 @@ async fn handle_error(
warn!("job_request handle_error error {}", error);
warn!("job_request handle_error event {:?}", { event.clone() });
- let builder = nostr_event_job_request_feedback(&event, error, "error", None)?;
+ let builder = nostr_event_job_feedback(&event, error, "error", None)?;
let event_id = client.send_event_builder(builder).await?;
warn!("job_request handle_error sent feedback {:?}", {
diff --git a/src/handlers/job_request_order.rs b/src/handlers/job_request_order.rs
@@ -8,7 +8,7 @@ use tracing::info;
use crate::{
events::job_request::{JobRequest, JobRequestError, JobRequestInput},
models::event_classified::EventClassified,
- utils::nostr::nostr_fetch_event_by_id,
+ utils::nostr::{NostrEventError, nostr_event_job_result, nostr_fetch_event_by_id},
};
#[derive(Debug, Error)]
@@ -21,6 +21,15 @@ pub enum JobRequestOrderError {
#[error("Reference event not found {0}")]
ReferenceEventMissing(String),
+
+ #[error("Reference event does not satisfy requested {0}")]
+ ReferenceEventMissingRequested(String),
+
+ #[error("Failure building the job response")]
+ ResponseEventBuildFailure(#[from] NostrEventError),
+
+ #[error("Failure sending the job response")]
+ ResponseEventSendFailure(#[from] nostr_sdk::client::Error),
}
#[derive(Debug, Deserialize)]
@@ -58,7 +67,7 @@ pub struct JobRequestOrderData {
}
pub async fn handle_job_request_order(
- _event: Event,
+ event_job_request: Event,
_keys: Keys,
client: Client,
_job_req: JobRequest,
@@ -79,8 +88,6 @@ pub async fn handle_job_request_order(
order_data.event.id.clone(),
))?;
- info!("handle_job_request_order ref_event: {:?}", ref_event);
-
let ref_classified = EventClassified::from_event(ref_event)
.map_err(|_| JobRequestOrderError::ReferenceEventParse(order_data.event.id.clone()))?;
@@ -89,5 +96,28 @@ pub async fn handle_job_request_order(
ref_classified
);
+ if ref_classified.prices.is_empty() {
+ return Err(JobRequestError::JobRequestOrder(
+ JobRequestOrderError::ReferenceEventMissingRequested("price".to_string()),
+ ));
+ }
+
+ if ref_classified.quantities.is_empty() {
+ return Err(JobRequestError::JobRequestOrder(
+ JobRequestOrderError::ReferenceEventMissingRequested("quantity".to_string()),
+ ));
+ }
+
+ let payload = "your order was received!";
+ let event_result = nostr_event_job_result(&event_job_request.clone(), payload, 0, None, None)
+ .map_err(JobRequestOrderError::from)?;
+ let event_id = client
+ .send_event_builder(event_result)
+ .await
+ .map_err(JobRequestOrderError::from)?;
+
+ info!("handle_job_request_order sent result {:?}", {
+ event_id.clone()
+ });
Ok(())
}
diff --git a/src/utils/nostr.rs b/src/utils/nostr.rs
@@ -103,16 +103,35 @@ pub fn nostr_tag_match_summary(tag: &Tag) -> Option<String> {
}
}
-pub fn nostr_event_job_request_feedback(
- event: &Event,
+#[derive(Debug, thiserror::Error)]
+pub enum NostrEventError {
+ #[error("Failed to build job result event: {0}")]
+ BuildError(#[from] nostr::event::builder::Error),
+}
+
+pub fn nostr_event_job_result(
+ job_request: &Event,
+ payload: impl Into<String>,
+ millisats: u64,
+ bolt11: Option<String>,
+ tags: Option<Vec<Tag>>,
+) -> Result<EventBuilder, NostrEventError> {
+ let builder = EventBuilder::job_result(job_request.clone(), payload, millisats, bolt11)?
+ .tags(tags.unwrap_or_default());
+ Ok(builder)
+}
+
+pub fn nostr_event_job_feedback(
+ job_request: &Event,
error: JobRequestError,
status: &str,
tags: Option<Vec<Tag>>,
-) -> anyhow::Result<EventBuilder> {
+) -> Result<EventBuilder, NostrEventError> {
let status = status
.parse::<DataVendingMachineStatus>()
.unwrap_or(DataVendingMachineStatus::Error);
- let feedback_data = JobFeedbackData::new(&event, status).extra_info(error.to_string());
+ let feedback_data =
+ JobFeedbackData::new(&job_request.clone(), status).extra_info(error.to_string());
let builder = EventBuilder::job_feedback(feedback_data).tags(tags.unwrap_or_default());
Ok(builder)
}