Skip to content

Commit

Permalink
Add Action::AddInvoice branch on main (#43)
Browse files Browse the repository at this point in the history
* Add Action::AddInvoice branch on main

Code refactoring

* Updated sqlx data
  • Loading branch information
grunch authored Apr 16, 2023
1 parent 635cc12 commit 39418a2
Show file tree
Hide file tree
Showing 5 changed files with 205 additions and 33 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ uuid = { version = "1.3.0", features = [
"serde",
] }
reqwest = { version = "0.11", features = ["json"] }
mostro-core = "0.1.6"
mostro-core = "0.1.7"
tokio-cron-scheduler = "*"
tracing = "0.1.37"
tracing-subscriber = "0.3.16"
10 changes: 10 additions & 0 deletions sqlx-data.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,15 @@
}
},
"query": "\n UPDATE orders\n SET\n buyer_invoice = ?1\n WHERE id = ?2\n "
},
"97414183485e04346f420960beed77912ebe76089f58d30f0f526e232ce4be25": {
"describe": {
"columns": [],
"nullable": [],
"parameters": {
"Right": 8
}
},
"query": "\n UPDATE orders\n SET\n status = ?1,\n amount = ?2,\n fee = ?3,\n hash = ?4,\n preimage = ?5,\n taken_at = ?6,\n invoice_held_at = ?7\n WHERE id = ?8\n "
}
}
3 changes: 1 addition & 2 deletions src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ pub async fn add_order(
}
let kind = order.kind.to_string();
let status = order.status.to_string();
let empty = String::new();
let buyer_invoice = order.buyer_invoice.as_ref().unwrap_or(&empty);
let buyer_invoice = order.buyer_invoice.as_ref();
let price_from_api = order.amount == 0;

let order = sqlx::query_as::<_, Order>(
Expand Down
82 changes: 53 additions & 29 deletions src/flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,42 +16,66 @@ pub async fn hold_invoice_paid(hash: &str) {
order.id
);

// We publish a new replaceable kind nostr event with the status updated
// and update on local database the status and new event id
crate::util::update_order_event(&pool, &client, &my_keys, Status::Active, &order, None)
.await
.unwrap();
// We send this data related to the order to the parties
let order_data = SmallOrder::new(
order.id,
order.amount,
order.fiat_code,
order.fiat_code.clone(),
order.fiat_amount,
order.payment_method,
order.payment_method.clone(),
order.premium,
order.buyer_pubkey,
order.seller_pubkey,
);
// We send a confirmation message to seller
let message = Message::new(
0,
Some(order.id),
Action::BuyerTookOrder,
Some(Content::SmallOrder(order_data.clone())),
);
let message = message.as_json().unwrap();
send_dm(&client, &my_keys, &seller_pubkey, message)
.await
.unwrap();
// We send a message to buyer saying seller paid
let message = Message::new(
0,
Some(order.id),
Action::HoldInvoicePaymentAccepted,
Some(Content::SmallOrder(order_data)),
order.buyer_pubkey.as_ref().cloned(),
order.seller_pubkey.as_ref().cloned(),
);
let message = message.as_json().unwrap();
send_dm(&client, &my_keys, &buyer_pubkey, message)
let status;
println!("buyer_invoice {:#?}", order.buyer_invoice);
if order.buyer_invoice.is_some() {
// We send a confirmation message to seller
let message = Message::new(
0,
Some(order.id),
Action::BuyerTookOrder,
Some(Content::SmallOrder(order_data.clone())),
);
let message = message.as_json().unwrap();
send_dm(&client, &my_keys, &seller_pubkey, message)
.await
.unwrap();
// We send a message to buyer saying seller paid
let message = Message::new(
0,
Some(order.id),
Action::HoldInvoicePaymentAccepted,
Some(Content::SmallOrder(order_data)),
);
let message = message.as_json().unwrap();
send_dm(&client, &my_keys, &buyer_pubkey, message)
.await
.unwrap();
status = Status::Active;
} else {
// We ask to buyer for a new invoice
let message = Message::new(
0,
Some(order.id),
Action::AddInvoice,
Some(Content::SmallOrder(order_data.clone())),
);
let message = message.as_json().unwrap();
send_dm(&client, &my_keys, &buyer_pubkey, message)
.await
.unwrap();
// We send a message to seller we are waiting for buyer invoice
let message = Message::new(0, Some(order.id), Action::WaitingBuyerInvoice, None);
let message = message.as_json().unwrap();
send_dm(&client, &my_keys, &seller_pubkey, message)
.await
.unwrap();
status = Status::WaitingBuyerInvoice;
}
// We publish a new replaceable kind nostr event with the status updated
// and update on local database the status and new event id
crate::util::update_order_event(&pool, &client, &my_keys, status, &order, None)
.await
.unwrap();
}
Expand Down
141 changes: 140 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use log::{error, info};
use nostr_sdk::prelude::*;

use mostro_core::order::Order;
use mostro_core::{Action, Content, Message, Peer, Status};
use mostro_core::{order::SmallOrder, Action, Content, Message, Peer, Status};
use scheduler::start_scheduler;
use sqlx_crud::Crud;
use std::str::FromStr;
Expand Down Expand Up @@ -558,6 +558,145 @@ async fn main() -> anyhow::Result<()> {
unimplemented!()
}
}
Action::AddInvoice => {
// Safe unwrap as we verified the message
let order_id = msg.order_id.unwrap();
let order = match Order::by_id(&pool, order_id).await? {
Some(order) => order,
None => {
error!(
"AddInvoice: Order Id {order_id} not found!"
);
break;
}
};
if order.kind != "Buy" {
error!("AddInvoice: Order Id {order_id} wrong kind");
break;
}
let buyer_pubkey = event.pubkey;
let pr: String;
// If a buyer sent me a lightning invoice we look on db an order with
// that order id and save the buyer pubkey and invoice fields
if let Some(payment_request) = msg.get_payment_request() {
// Verify if invoice is valid
match is_valid_invoice(
&payment_request,
Some(order.amount as u64),
) {
Ok(_) => {}
Err(e) => match e {
MostroError::ParsingInvoiceError
| MostroError::InvoiceExpiredError
| MostroError::MinExpirationTimeError
| MostroError::WrongAmountError
| MostroError::MinAmountError => {
// We create a Message
let message = Message::new(
0,
Some(order.id),
Action::CantDo,
Some(Content::TextMessage(
e.to_string(),
)),
);
let message = message.as_json()?;
send_dm(
&client,
&my_keys,
&buyer_pubkey,
message,
)
.await?;
error!("{e}");
break;
}
_ => {}
},
}
pr = payment_request;
} else {
error!("AddInvoice: Order Id {order_id} wrong get_payment_request");
break;
}

let order_status = match Status::from_str(&order.status) {
Ok(s) => s,
Err(e) => {
error!("AddInvoice: Order Id {order_id} wrong status: {e:?}");
break;
}
};
// Buyer can take pending orders only
match order_status {
Status::WaitingBuyerInvoice => {}
_ => {
// We create a Message
let message = Message::new(
0,
Some(order.id),
Action::CantDo,
Some(Content::TextMessage(format!(
"Order Id {order_id} status must be WaitingBuyerInvoice!"
))),
);
let message = message.as_json()?;
send_dm(&client, &my_keys, &buyer_pubkey, message)
.await?;
break;
}
}
// We send this data related to the order to the parties
let order_data = SmallOrder::new(
order.id,
order.amount,
order.fiat_code.clone(),
order.fiat_amount,
pr,
order.premium,
order.buyer_pubkey.as_ref().cloned(),
order.seller_pubkey.as_ref().cloned(),
);
// We send a confirmation message to seller
let message = Message::new(
0,
Some(order.id),
Action::BuyerTookOrder,
Some(Content::SmallOrder(order_data.clone())),
);
let message = message.as_json().unwrap();
let seller_pubkey =
order.seller_pubkey.as_ref().cloned().unwrap();
let seller_pubkey =
XOnlyPublicKey::from_str(&seller_pubkey).unwrap();
send_dm(&client, &my_keys, &seller_pubkey, message)
.await
.unwrap();
// We send a message to buyer saying seller paid
let message = Message::new(
0,
Some(order.id),
Action::HoldInvoicePaymentAccepted,
Some(Content::SmallOrder(order_data)),
);
let message = message.as_json().unwrap();
send_dm(&client, &my_keys, &buyer_pubkey, message)
.await
.unwrap();

// We publish a new replaceable kind nostr event with the status updated
// and update on local database the status and new event id
crate::util::update_order_event(
&pool,
&client,
&my_keys,
Status::Active,
&order,
None,
)
.await
.unwrap();
}
Action::PayInvoice => todo!(),
_ => todo!(),
}
Expand Down

0 comments on commit 39418a2

Please sign in to comment.