mirror of
https://github.com/creating2morrow/neveko.git
synced 2025-01-18 16:54:38 +00:00
start testing nasr implementation
This commit is contained in:
parent
2b5cb6ef1f
commit
1e65a87127
6 changed files with 153 additions and 64 deletions
|
@ -8,9 +8,9 @@ use lmdb::{
|
||||||
Environment,
|
Environment,
|
||||||
};
|
};
|
||||||
use log::{
|
use log::{
|
||||||
info,
|
|
||||||
debug,
|
debug,
|
||||||
error,
|
error,
|
||||||
|
info,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::utils;
|
use crate::utils;
|
||||||
|
|
|
@ -429,7 +429,12 @@ pub async fn sign(data: String) -> reqres::XmrRpcSignResponse {
|
||||||
|
|
||||||
/// Performs the xmr rpc 'verify' method
|
/// Performs the xmr rpc 'verify' method
|
||||||
pub async fn verify(address: String, data: String, signature: String) -> bool {
|
pub async fn verify(address: String, data: String, signature: String) -> bool {
|
||||||
info!("executing {} for sig: {} on {}", RpcFields::Verify.value(), &signature, &data);
|
info!(
|
||||||
|
"executing {} for sig: {} on {}",
|
||||||
|
RpcFields::Verify.value(),
|
||||||
|
&signature,
|
||||||
|
&data
|
||||||
|
);
|
||||||
let client = reqwest::Client::new();
|
let client = reqwest::Client::new();
|
||||||
let host = get_rpc_host();
|
let host = get_rpc_host();
|
||||||
let params = reqres::XmrRpcVerifyParams {
|
let params = reqres::XmrRpcVerifyParams {
|
||||||
|
|
|
@ -4,6 +4,7 @@ use crate::{
|
||||||
contact,
|
contact,
|
||||||
db,
|
db,
|
||||||
gpg,
|
gpg,
|
||||||
|
i2p,
|
||||||
message,
|
message,
|
||||||
models::*,
|
models::*,
|
||||||
monero,
|
monero,
|
||||||
|
@ -287,10 +288,42 @@ pub async fn validate_order_for_ship(orid: &String) -> reqres::FinalizeOrderResp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// NASR (neveko auto-ship request)
|
||||||
|
pub async fn trigger_nasr(
|
||||||
|
contact: &String,
|
||||||
|
jwp: &String,
|
||||||
|
orid: &String,
|
||||||
|
) -> Result<Order, Box<dyn Error>> {
|
||||||
|
info!("executing trigger_nasr");
|
||||||
|
let host = utils::get_i2p_http_proxy();
|
||||||
|
let proxy = reqwest::Proxy::http(&host)?;
|
||||||
|
let client = reqwest::Client::builder().proxy(proxy).build();
|
||||||
|
match client?
|
||||||
|
.get(format!("http://{}/ship/{}/{}", contact, orid, contact))
|
||||||
|
.header("proof", jwp)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(response) => {
|
||||||
|
let res = response.json::<Order>().await;
|
||||||
|
debug!("order retrieve response: {:?}", res);
|
||||||
|
match res {
|
||||||
|
Ok(r) => Ok(r),
|
||||||
|
_ => Ok(Default::default()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("failed to trigger due to: {:?}", e);
|
||||||
|
Ok(Default::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Write encrypted delivery info to lmdb. Once the customer releases the signed
|
/// Write encrypted delivery info to lmdb. Once the customer releases the signed
|
||||||
/// txset
|
/// txset
|
||||||
///
|
///
|
||||||
/// This will also attempt to notify the customer to trigger the NASR (neveko auto-ship request).
|
/// This will also attempt to notify the customer to trigger the NASR (neveko
|
||||||
|
/// auto-ship request).
|
||||||
///
|
///
|
||||||
/// they will have access to this information (tracking number, locker code,
|
/// they will have access to this information (tracking number, locker code,
|
||||||
/// etc.)
|
/// etc.)
|
||||||
|
@ -300,7 +333,8 @@ pub async fn upload_delivery_info(
|
||||||
) -> reqres::FinalizeOrderResponse {
|
) -> reqres::FinalizeOrderResponse {
|
||||||
info!("uploading delivery info");
|
info!("uploading delivery info");
|
||||||
let lookup: Order = order::find(orid);
|
let lookup: Order = order::find(orid);
|
||||||
let e_delivery_info: Vec<u8> = gpg::encrypt(lookup.cid, &delivery_info).unwrap_or(Vec::new());
|
let e_delivery_info: Vec<u8> =
|
||||||
|
gpg::encrypt(String::from(&lookup.cid), &delivery_info).unwrap_or(Vec::new());
|
||||||
if e_delivery_info.is_empty() {
|
if e_delivery_info.is_empty() {
|
||||||
error!("unable to encrypt delivery info");
|
error!("unable to encrypt delivery info");
|
||||||
}
|
}
|
||||||
|
@ -313,11 +347,23 @@ pub async fn upload_delivery_info(
|
||||||
m_order.ship_date = chrono::offset::Utc::now().timestamp();
|
m_order.ship_date = chrono::offset::Utc::now().timestamp();
|
||||||
m_order.hash = String::from(&sweep.result.tx_hash_list.remove(0));
|
m_order.hash = String::from(&sweep.result.tx_hash_list.remove(0));
|
||||||
m_order.vend_msig_txset = sweep.result.multisig_txset;
|
m_order.vend_msig_txset = sweep.result.multisig_txset;
|
||||||
// delivery info will be stored encrypted and separate from the rest of the order
|
// delivery info will be stored encrypted and separate from the rest of the
|
||||||
|
// order
|
||||||
let s = db::Interface::async_open().await;
|
let s = db::Interface::async_open().await;
|
||||||
let k = String::from(crate::DELIVERY_INFO_DB_KEY);
|
let k = String::from(crate::DELIVERY_INFO_DB_KEY);
|
||||||
db::Interface::async_write(&s.env, &s.handle, &k, &hex::encode(&delivery_info)).await;
|
db::Interface::async_write(&s.env, &s.handle, &k, &hex::encode(&delivery_info)).await;
|
||||||
modify(Json(m_order));
|
modify(Json(m_order));
|
||||||
|
// trigger nasr, this will cause the customer's neveko instance to request the
|
||||||
|
// txset
|
||||||
|
let i2p_address = i2p::get_destination(None);
|
||||||
|
let s = db::Interface::open();
|
||||||
|
// get jwp from db
|
||||||
|
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, &lookup.cid);
|
||||||
|
let jwp = db::Interface::read(&s.env, &s.handle, &k);
|
||||||
|
let nasr_order = trigger_nasr(&i2p_address, &jwp, orid).await;
|
||||||
|
if nasr_order.is_err() {
|
||||||
|
return Default::default();
|
||||||
|
}
|
||||||
FinalizeOrderResponse {
|
FinalizeOrderResponse {
|
||||||
delivery_info: delivery_info.to_vec(),
|
delivery_info: delivery_info.to_vec(),
|
||||||
orid: String::from(orid),
|
orid: String::from(orid),
|
||||||
|
@ -471,11 +517,7 @@ pub async fn transmit_sor_request(
|
||||||
/// A decomposition trigger for the shipping request so that the logic
|
/// A decomposition trigger for the shipping request so that the logic
|
||||||
///
|
///
|
||||||
/// can be executed from the gui.
|
/// can be executed from the gui.
|
||||||
pub async fn trigger_ship_request(
|
pub async fn trigger_ship_request(contact: &String, jwp: &String, orid: &String) -> Order {
|
||||||
contact: &String,
|
|
||||||
jwp: &String,
|
|
||||||
orid: &String,
|
|
||||||
) -> Order {
|
|
||||||
info!("executing trigger_ship_request");
|
info!("executing trigger_ship_request");
|
||||||
let data = String::from(orid);
|
let data = String::from(orid);
|
||||||
let wallet_password =
|
let wallet_password =
|
||||||
|
@ -495,16 +537,17 @@ pub async fn trigger_ship_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decomposition trigger for the shipping request
|
/// Decomposition trigger for the shipping request
|
||||||
pub async fn d_trigger_ship_request(
|
pub async fn d_trigger_ship_request(contact: &String, orid: &String) -> Order {
|
||||||
contact: &String,
|
// ugh, sorry seems we need to get jwp for vendor from fts cache
|
||||||
jwp: &String,
|
// get jwp from db
|
||||||
orid: &String,
|
let s = db::Interface::async_open().await;
|
||||||
) -> Order {
|
let k = format!("{}-{}", crate::FTS_JWP_DB_KEY, &contact);
|
||||||
|
let jwp = db::Interface::async_read(&s.env, &s.handle, &k).await;
|
||||||
info!("executing d_trigger_ship_request");
|
info!("executing d_trigger_ship_request");
|
||||||
// request shipment if the order status is MultisigComplete
|
// request shipment if the order status is MultisigComplete
|
||||||
let trigger = trigger_ship_request(contact, jwp, orid).await;
|
let trigger = trigger_ship_request(contact, &jwp, orid).await;
|
||||||
if trigger.status == order::StatusType::MulitsigComplete.value() {
|
if trigger.status == order::StatusType::MulitsigComplete.value() {
|
||||||
let ship_res = transmit_ship_request(contact, jwp, orid).await;
|
let ship_res = transmit_ship_request(contact, &jwp, orid).await;
|
||||||
if ship_res.is_err() {
|
if ship_res.is_err() {
|
||||||
error!("failure to decompose trigger_ship_request");
|
error!("failure to decompose trigger_ship_request");
|
||||||
return Default::default();
|
return Default::default();
|
||||||
|
|
|
@ -109,8 +109,8 @@ pub struct MarketApp {
|
||||||
_refresh_on_delete_product_rx: Receiver<bool>,
|
_refresh_on_delete_product_rx: Receiver<bool>,
|
||||||
submit_order_tx: Sender<models::Order>,
|
submit_order_tx: Sender<models::Order>,
|
||||||
submit_order_rx: Receiver<models::Order>,
|
submit_order_rx: Receiver<models::Order>,
|
||||||
ship_request_tx: Sender<models::Order>,
|
// ship_request_tx: Sender<models::Order>,
|
||||||
ship_request_rx: Receiver<models::Order>,
|
// ship_request_rx: Receiver<models::Order>,
|
||||||
s_contact: models::Contact,
|
s_contact: models::Contact,
|
||||||
s_order: models::Order,
|
s_order: models::Order,
|
||||||
vendor_status: utils::ContactStatus,
|
vendor_status: utils::ContactStatus,
|
||||||
|
@ -132,7 +132,7 @@ impl Default for MarketApp {
|
||||||
let (get_vendor_products_tx, get_vendor_products_rx) = std::sync::mpsc::channel();
|
let (get_vendor_products_tx, get_vendor_products_rx) = std::sync::mpsc::channel();
|
||||||
let (get_vendor_product_tx, get_vendor_product_rx) = std::sync::mpsc::channel();
|
let (get_vendor_product_tx, get_vendor_product_rx) = std::sync::mpsc::channel();
|
||||||
let (submit_order_tx, submit_order_rx) = std::sync::mpsc::channel();
|
let (submit_order_tx, submit_order_rx) = std::sync::mpsc::channel();
|
||||||
let (ship_request_tx, ship_request_rx) = std::sync::mpsc::channel();
|
// let (ship_request_tx, ship_request_rx) = std::sync::mpsc::channel();
|
||||||
let (our_prepare_info_tx, our_prepare_info_rx) = std::sync::mpsc::channel();
|
let (our_prepare_info_tx, our_prepare_info_rx) = std::sync::mpsc::channel();
|
||||||
let (our_make_info_tx, our_make_info_rx) = std::sync::mpsc::channel();
|
let (our_make_info_tx, our_make_info_rx) = std::sync::mpsc::channel();
|
||||||
let (order_xmr_address_tx, order_xmr_address_rx) = std::sync::mpsc::channel();
|
let (order_xmr_address_tx, order_xmr_address_rx) = std::sync::mpsc::channel();
|
||||||
|
@ -201,8 +201,8 @@ impl Default for MarketApp {
|
||||||
_refresh_on_delete_product_rx,
|
_refresh_on_delete_product_rx,
|
||||||
s_contact: Default::default(),
|
s_contact: Default::default(),
|
||||||
s_order: Default::default(),
|
s_order: Default::default(),
|
||||||
ship_request_rx,
|
// ship_request_rx,
|
||||||
ship_request_tx,
|
// ship_request_tx,
|
||||||
submit_order_rx,
|
submit_order_rx,
|
||||||
submit_order_tx,
|
submit_order_tx,
|
||||||
vendor_status: Default::default(),
|
vendor_status: Default::default(),
|
||||||
|
@ -301,12 +301,12 @@ impl eframe::App for MarketApp {
|
||||||
self.is_loading = false;
|
self.is_loading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(shipped) = self.ship_request_rx.try_recv() {
|
// if let Ok(shipped) = self.ship_request_rx.try_recv() {
|
||||||
if shipped.status != order::StatusType::Shipped.value() {
|
// if shipped.status != order::StatusType::Shipped.value() {
|
||||||
log::error!("failure to obtain shipment please contact vendor")
|
// log::error!("failure to obtain shipment please contact vendor")
|
||||||
}
|
// }
|
||||||
self.is_loading = false;
|
// self.is_loading = false;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Vendor status window
|
// Vendor status window
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
|
@ -625,32 +625,49 @@ impl eframe::App for MarketApp {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if self.msig.completed_export && !self.msig.completed_shipping_request {
|
if self.msig.completed_export && !self.msig.completed_shipping_request {
|
||||||
|
// idk if manual shipping request will be necessary with the new nasr logic,
|
||||||
|
// let's see
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.label("Request Shipping: \t");
|
ui.label(
|
||||||
if ui.button("Send").clicked() {
|
RichText::new("Delivery Pending")
|
||||||
let vendor_prefix = String::from(crate::GUI_OVL_DB_KEY);
|
.small()
|
||||||
let vendor = utils::search_gui_db(vendor_prefix, self.m_order.orid.clone());
|
.color(ui.visuals().code_bg_color),
|
||||||
self.is_loading = true;
|
)
|
||||||
let jwp = utils::search_gui_db(
|
.on_hover_text("Please wait for the vendor to upload delivery info.");
|
||||||
String::from(crate::GUI_JWP_DB_KEY),
|
|
||||||
String::from(&vendor),
|
|
||||||
);
|
|
||||||
shipping_req(
|
|
||||||
self.ship_request_tx.clone(),
|
|
||||||
ctx.clone(),
|
|
||||||
&self.m_order.orid,
|
|
||||||
&vendor,
|
|
||||||
&jwp,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if ui.button("Check").clicked() {
|
if ui.button("Check").clicked() {
|
||||||
let order = order::find(&self.m_order.orid);
|
let order = order::find(&self.m_order.orid.clone());
|
||||||
if order.status == order::StatusType::Shipped.value() {
|
if order.status == order::StatusType::Shipped.value() {
|
||||||
self.msig.completed_shipping_request = true;
|
self.msig.completed_shipping_request = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// ui.horizontal(|ui| {
|
||||||
|
// ui.label("Request Shipping: \t");
|
||||||
|
// if ui.button("Send").clicked() {
|
||||||
|
// let vendor_prefix = String::from(crate::GUI_OVL_DB_KEY);
|
||||||
|
// let vendor = utils::search_gui_db(vendor_prefix,
|
||||||
|
// self.m_order.orid.clone()); self.is_loading = true;
|
||||||
|
// let jwp = utils::search_gui_db(
|
||||||
|
// String::from(crate::GUI_JWP_DB_KEY),
|
||||||
|
// String::from(&vendor),
|
||||||
|
// );
|
||||||
|
// shipping_req(
|
||||||
|
// self.ship_request_tx.clone(),
|
||||||
|
// ctx.clone(),
|
||||||
|
// &self.m_order.orid,
|
||||||
|
// &vendor,
|
||||||
|
// &jwp,
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// if ui.button("Check").clicked() {
|
||||||
|
// let order = order::find(&self.m_order.orid);
|
||||||
|
// if order.status == order::StatusType::Shipped.value() {
|
||||||
|
// self.msig.completed_shipping_request = true;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
if self.msig.completed_shipping_request && !self.msig.completed_payment_release {
|
if self.msig.completed_shipping_request && !self.msig.completed_payment_release {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.label("Release Payment: \t");
|
ui.label("Release Payment: \t");
|
||||||
|
@ -2141,23 +2158,23 @@ fn send_import_info_req(tx: Sender<String>, ctx: egui::Context, orid: &String, v
|
||||||
ctx.request_repaint();
|
ctx.request_repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shipping_req(
|
// fn shipping_req(
|
||||||
tx: Sender<models::Order>,
|
// tx: Sender<models::Order>,
|
||||||
ctx: egui::Context,
|
// ctx: egui::Context,
|
||||||
orid: &String,
|
// orid: &String,
|
||||||
contact: &String,
|
// contact: &String,
|
||||||
jwp: &String,
|
// jwp: &String,
|
||||||
) {
|
// ) {
|
||||||
let ship_orid = String::from(orid);
|
// let ship_orid = String::from(orid);
|
||||||
let vendor_i2p = String::from(contact);
|
// let vendor_i2p = String::from(contact);
|
||||||
let v_jwp = String::from(jwp);
|
// let v_jwp = String::from(jwp);
|
||||||
tokio::spawn(async move {
|
// tokio::spawn(async move {
|
||||||
log::info!("shipping order req: {}", ship_orid);
|
// log::info!("shipping order req: {}", ship_orid);
|
||||||
let order = order::d_trigger_ship_request(&vendor_i2p, &v_jwp, &ship_orid).await;
|
// let order = order::d_trigger_ship_request(&vendor_i2p, &v_jwp, &ship_orid).await;
|
||||||
let _ = tx.send(order);
|
// let _ = tx.send(order);
|
||||||
ctx.request_repaint();
|
// ctx.request_repaint();
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
// End Async fn requests
|
// End Async fn requests
|
||||||
|
|
||||||
fn validate_msig_step(
|
fn validate_msig_step(
|
||||||
|
|
|
@ -102,6 +102,8 @@ pub async fn sign_and_submit_multisig(
|
||||||
|
|
||||||
/// API for uploading delivery info in vendor mode
|
/// API for uploading delivery info in vendor mode
|
||||||
///
|
///
|
||||||
|
/// Attempts to trigger NASR so that and automate txset draft from vendor.
|
||||||
|
///
|
||||||
/// Protected: true
|
/// Protected: true
|
||||||
#[post("/<orid>", data = "<r_data>")]
|
#[post("/<orid>", data = "<r_data>")]
|
||||||
pub async fn upload_delivery_info(
|
pub async fn upload_delivery_info(
|
||||||
|
|
|
@ -197,6 +197,28 @@ pub async fn request_shipment(
|
||||||
Custom(Status::Ok, Json(finalize))
|
Custom(Status::Ok, Json(finalize))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The vendor should trigger nasr once they have uploaded delivery info.
|
||||||
|
///
|
||||||
|
/// This will automate txset release from the customer
|
||||||
|
///
|
||||||
|
/// orid - `order id of the nasr`
|
||||||
|
///
|
||||||
|
/// vedor - `vendor's .b32.i2p`
|
||||||
|
///
|
||||||
|
/// Protected: true
|
||||||
|
#[post("/ship/<vendor>/<orid>")]
|
||||||
|
pub async fn trigger_nasr(
|
||||||
|
orid: String,
|
||||||
|
vendor: String,
|
||||||
|
_jwp: proof::PaymentProof,
|
||||||
|
) -> Custom<Json<models::Order>> {
|
||||||
|
let order: models::Order = order::d_trigger_ship_request(&orid, &vendor).await;
|
||||||
|
if order.orid == utils::empty_string() {
|
||||||
|
return Custom(Status::BadRequest, Json(Default::default()));
|
||||||
|
}
|
||||||
|
Custom(Status::Ok, Json(order))
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a dispute (customer)
|
/// Create a dispute (customer)
|
||||||
#[post("/create", data = "<dispute>")]
|
#[post("/create", data = "<dispute>")]
|
||||||
pub async fn create_dispute(
|
pub async fn create_dispute(
|
||||||
|
|
Loading…
Reference in a new issue