Skip to content

Commit

Permalink
Admin order action (#64)
Browse files Browse the repository at this point in the history
* Admin order action

* Remove logic on flow::hold_invoice_canceled()

* Refactoring and update mostro-core
  • Loading branch information
grunch authored May 3, 2023
1 parent e8bd212 commit ef1914f
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 55 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ uuid = { version = "1.3.0", features = [
"serde",
] }
reqwest = { version = "0.11", features = ["json"] }
mostro-core = "0.2.4"
mostro-core = "0.2.6"
tokio-cron-scheduler = "*"
tracing = "0.1.37"
tracing-subscriber = "0.3.16"
24 changes: 16 additions & 8 deletions src/app.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod add_invoice;
pub mod admin_cancel;
pub mod cancel;
pub mod dispute;
pub mod fiat_sent;
Expand All @@ -9,6 +10,7 @@ pub mod take_buy;
pub mod take_sell;

use crate::app::add_invoice::add_invoice_action;
use crate::app::admin_cancel::admin_cancel_action;
use crate::app::cancel::cancel_action;
use crate::app::dispute::dispute_action;
use crate::app::fiat_sent::fiat_sent_action;
Expand Down Expand Up @@ -48,35 +50,35 @@ pub async fn run(
if msg.verify() {
match msg.action {
Action::Order => {
order_action(msg, &event, &my_keys, &client, &pool).await?
order_action(msg, &event, &my_keys, &client, &pool).await?;
}
Action::TakeSell => {
take_sell_action(msg, &event, &my_keys, &client, &pool)
.await?
.await?;
}
Action::TakeBuy => {
take_buy_action(msg, &event, &my_keys, &client, &pool)
.await?
.await?;
}
Action::FiatSent => {
fiat_sent_action(msg, &event, &my_keys, &client, &pool)
.await?
.await?;
}
Action::Release => {
release_action(
msg, &event, &my_keys, &client, &pool, ln_client,
)
.await?
.await?;
}
Action::Cancel => {
cancel_action(
msg, &event, &my_keys, &client, &pool, ln_client,
)
.await?
.await?;
}
Action::AddInvoice => {
add_invoice_action(msg, &event, &my_keys, &client, &pool)
.await?
.await?;
}
Action::PayInvoice => todo!(),
Action::RateUser => {
Expand All @@ -87,7 +89,13 @@ pub async fn run(
}
Action::Dispute => {
dispute_action(msg, &event, &my_keys, &client, &pool)
.await?
.await?;
}
Action::AdminCancel => {
admin_cancel_action(
msg, &event, &my_keys, &client, &pool, ln_client,
)
.await?;
}
_ => todo!(),
}
Expand Down
64 changes: 64 additions & 0 deletions src/app/admin_cancel.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use crate::lightning::LndConnector;
use crate::util::{send_dm, update_order_event};

use anyhow::Result;
use log::{error, info};
use mostro_core::order::Order;
use mostro_core::{Action, Message, Status};
use nostr_sdk::prelude::*;
use sqlx::{Pool, Sqlite};
use sqlx_crud::Crud;

pub async fn admin_cancel_action(
msg: Message,
event: &Event,
my_keys: &Keys,
client: &Client,
pool: &Pool<Sqlite>,
ln_client: &mut LndConnector,
) -> Result<()> {
let order_id = msg.order_id.unwrap();
let order = match Order::by_id(pool, order_id).await? {
Some(order) => order,
None => {
error!("AdminCancel: Order Id {order_id} not found!");
return Ok(());
}
};
let mostro_pubkey = my_keys.public_key().to_bech32()?;
// Check if the pubkey is Mostro
if event.pubkey.to_bech32()? != mostro_pubkey {
// We create a Message
let message = Message::new(0, Some(order.id), None, Action::CantDo, None);
let message = message.as_json()?;
send_dm(client, my_keys, &event.pubkey, message).await?;

return Ok(());
}

if order.hash.is_some() {
// We return funds to seller
let hash = order.hash.as_ref().unwrap();
ln_client.cancel_hold_invoice(hash).await?;
info!(
"AdminCancel: Order Id {}: Funds returned to seller",
&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
update_order_event(pool, client, my_keys, Status::CanceledByAdmin, &order, None).await?;
// We create a Message
let message = Message::new(0, Some(order.id), None, Action::CanceledByAdmin, None);
let message = message.as_json()?;
// Message to admin
send_dm(client, my_keys, &event.pubkey, message.clone()).await?;
let seller_pubkey = order.seller_pubkey.as_ref().unwrap();
let seller_pubkey = XOnlyPublicKey::from_bech32(seller_pubkey).unwrap();
send_dm(client, my_keys, &seller_pubkey, message.clone()).await?;
let buyer_pubkey = order.buyer_pubkey.as_ref().unwrap();
let buyer_pubkey = XOnlyPublicKey::from_bech32(buyer_pubkey).unwrap();
send_dm(client, my_keys, &buyer_pubkey, message.clone()).await?;

Ok(())
}
42 changes: 29 additions & 13 deletions src/app/cancel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,17 @@ pub async fn cancel_action(
let message = Message::new(0, Some(order.id), None, Action::CantDo, None);
let message = message.as_json()?;
send_dm(client, my_keys, &event.pubkey, message).await?;

return Ok(());
} else {
// We publish a new replaceable kind nostr event with the status updated
// and update on local database the status and new event id
update_order_event(pool, client, my_keys, Status::Canceled, &order, None).await?;
// We create a Message for cancel
let message = Message::new(0, Some(order.id), None, Action::Cancel, None);
let message = message.as_json()?;
send_dm(client, my_keys, &event.pubkey, message).await?;
}
// We publish a new replaceable kind nostr event with the status updated
// and update on local database the status and new event id
update_order_event(pool, client, my_keys, Status::Canceled, &order, None).await?;
// We create a Message for cancel
let message = Message::new(0, Some(order.id), None, Action::Cancel, None);
let message = message.as_json()?;
send_dm(client, my_keys, &event.pubkey, message).await?;

return Ok(());
}

if order.kind == "Sell" && order.status == "WaitingBuyerInvoice" {
Expand Down Expand Up @@ -89,11 +90,18 @@ pub async fn cancel_action(
);
}
init_cancel_order(pool, &order).await?;
order.status = "Canceled".to_string();
order.status = "CooperativelyCanceled".to_string();
// We publish a new replaceable kind nostr event with the status updated
// and update on local database the status and new event id
update_order_event(pool, client, my_keys, Status::Canceled, &order, None)
.await?;
update_order_event(
pool,
client,
my_keys,
Status::CooperativelyCanceled,
&order,
None,
)
.await?;
// We create a Message for an accepted cooperative cancel and send it to both parties
let message = Message::new(
0,
Expand Down Expand Up @@ -169,7 +177,15 @@ pub async fn cancel_add_invoice(
if &order.creator_pubkey == buyer_pubkey_bech32 {
// We publish a new replaceable kind nostr event with the status updated
// and update on local database the status and new event id
update_order_event(pool, client, my_keys, Status::Canceled, order, None).await?;
update_order_event(
pool,
client,
my_keys,
Status::CooperativelyCanceled,
order,
None,
)
.await?;
// We create a Message for cancel
let message = Message::new(0, Some(order.id), None, Action::Cancel, None);
let message = message.as_json()?;
Expand Down
33 changes: 3 additions & 30 deletions src/flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub async fn hold_invoice_paid(hash: &str) {
master_seller_pubkey,
);
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(
Expand Down Expand Up @@ -136,36 +136,9 @@ pub async fn hold_invoice_settlement(hash: &str) {

pub async fn hold_invoice_canceled(hash: &str) {
let pool = crate::db::connect().await.unwrap();
let client = crate::util::connect_nostr().await.unwrap();
let order = crate::db::find_order_by_hash(&pool, hash).await.unwrap();
let my_keys = crate::util::get_keys().unwrap();
let seller_pubkey = order.seller_pubkey.as_ref().unwrap();
let seller_pubkey = XOnlyPublicKey::from_bech32(seller_pubkey).unwrap();
let buyer_pubkey = order.buyer_pubkey.as_ref().unwrap();
let buyer_pubkey = XOnlyPublicKey::from_bech32(buyer_pubkey).unwrap();
// If this invoice was Canceled
info!(
"Order Id: {} - Invoice with hash: {hash} was canceled!",
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::Canceled, &order, None)
.await
.unwrap();
// We send "order canceled" messages to both parties
let message = Message::new(
0,
Some(order.id),
None,
Action::HoldInvoicePaymentCanceled,
None,
"Order Id: {} - Invoice with hash: {} was canceled!",
order.id, hash
);
let message = message.as_json().unwrap();
send_dm(&client, &my_keys, &seller_pubkey, message.clone())
.await
.unwrap();
send_dm(&client, &my_keys, &buyer_pubkey, message)
.await
.unwrap();
}
6 changes: 3 additions & 3 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,14 +290,14 @@ pub async fn show_hold_invoice(
// If this invoice was paid by the seller
if msg.state == InvoiceState::Accepted {
flow::hold_invoice_paid(&hash).await;
println!("Invoice with hash {hash} accepted!");
info!("Invoice with hash {hash} accepted!");
} else if msg.state == InvoiceState::Settled {
// If the payment was released by the seller
println!("Invoice with hash {hash} settled!");
info!("Invoice with hash {hash} settled!");
flow::hold_invoice_settlement(&hash).await;
} else if msg.state == InvoiceState::Canceled {
// If the payment was canceled
println!("Invoice with hash {hash} canceled!");
info!("Invoice with hash {hash} canceled!");
flow::hold_invoice_canceled(&hash).await;
} else {
info!("Invoice with hash: {hash} subscribed!");
Expand Down

0 comments on commit ef1914f

Please sign in to comment.