mirror of
https://github.com/creating2morrow/neveko.git
synced 2024-12-22 19:49:24 +00:00
add prepare mulitsig info orchestration
This commit is contained in:
parent
06cab5460e
commit
e97f3394bc
10 changed files with 308 additions and 125 deletions
|
@ -75,8 +75,9 @@ NEVidebla-MESago (invisible message)
|
|||
* nevmes-auth - `internal` auth server
|
||||
* nevmes-contact - `internal` add contacts server
|
||||
* nevmes-gui - primary user interface
|
||||
* nevmes-market - `internal` marketplace admin server
|
||||
* nevmes-message - `internal` message tx/read etc. server
|
||||
* nevmes - `external` primary server for contact share, payment, message rx etc.
|
||||
* nevmes - `external` primary server for contact share, payment, market, message rx etc.
|
||||
* [monerod](https://www.getmonero.org/downloads/#cli) - (not included) monero-wallet-rpc needs this
|
||||
* can be overriden with remote node
|
||||
* use the `--remote-node` flag
|
||||
|
|
|
@ -6,7 +6,7 @@ use crate::{
|
|||
i2p,
|
||||
models::*,
|
||||
reqres,
|
||||
utils,
|
||||
utils, monero,
|
||||
};
|
||||
use log::{
|
||||
debug,
|
||||
|
@ -17,9 +17,25 @@ use reqwest::StatusCode;
|
|||
use rocket::serde::json::Json;
|
||||
use std::error::Error;
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub enum MessageType {
|
||||
Normal,
|
||||
Multisig,
|
||||
}
|
||||
|
||||
struct MultisigMessageData {
|
||||
info: String,
|
||||
sub_type: String,
|
||||
orid: String,
|
||||
}
|
||||
|
||||
/// Create a new message
|
||||
pub async fn create(m: Json<Message>, jwp: String) -> Message {
|
||||
let f_mid: String = format!("m{}", utils::generate_rnd());
|
||||
pub async fn create(m: Json<Message>, jwp: String, m_type: MessageType) -> Message {
|
||||
let rnd = utils::generate_rnd();
|
||||
let mut f_mid: String = format!("m{}", &rnd);
|
||||
if m_type == MessageType::Multisig {
|
||||
f_mid = format!("msig{}", &rnd);
|
||||
}
|
||||
info!("creating message: {}", &f_mid);
|
||||
let created = chrono::offset::Utc::now().timestamp();
|
||||
// get contact public gpg key and encrypt the message
|
||||
|
@ -47,7 +63,7 @@ pub async fn create(m: Json<Message>, jwp: String) -> Message {
|
|||
debug!("writing message index {} for id: {}", msg_list, list_key);
|
||||
db::Interface::write(&s.env, &s.handle, &String::from(list_key), &msg_list);
|
||||
info!("attempting to send message");
|
||||
let send = send_message(&new_message, &jwp).await;
|
||||
let send = send_message(&new_message, &jwp, m_type).await;
|
||||
send.unwrap();
|
||||
new_message
|
||||
}
|
||||
|
@ -88,6 +104,68 @@ pub async fn rx(m: Json<Message>) {
|
|||
db::Interface::write(&s.env, &s.handle, &String::from(list_key), &msg_list);
|
||||
}
|
||||
|
||||
/// Parse the multisig message type and info
|
||||
fn parse_multisig_message(mid: String) -> MultisigMessageData {
|
||||
let d: reqres::DecryptedMessageBody = decrypt_body(mid);
|
||||
let mut bytes = hex::decode(d.body.into_bytes()).unwrap_or(Vec::new());
|
||||
let decoded = String::from_utf8(bytes).unwrap_or(utils::empty_string());
|
||||
let values = decoded.split(":");
|
||||
let mut v: Vec<String> = values.map(|s| String::from(s)).collect();
|
||||
let sub_type: String = v.remove(0);
|
||||
let orid: String = v.remove(0);
|
||||
let info: String = v.remove(0);
|
||||
bytes = Vec::new();
|
||||
debug!("zero decryption bytes: {:?}", bytes);
|
||||
MultisigMessageData { info, sub_type, orid }
|
||||
}
|
||||
|
||||
/// Rx multisig message
|
||||
///
|
||||
/// Upon multisig message receipt the message is automatically
|
||||
///
|
||||
/// decrypted for convenience sake. The client must determine which
|
||||
///
|
||||
/// .b32.i2p address belongs to the vendor / mediator.
|
||||
///
|
||||
/// ### Example
|
||||
///
|
||||
/// ```rust
|
||||
/// // lookup prepare info for vendor
|
||||
/// let s = db::Interface::open();
|
||||
/// let key = "prepare-o123-test.b32.i2p";
|
||||
/// db::Interface::read(&s.env, &s.handle, &key);
|
||||
/// ```
|
||||
pub async fn rx_multisig(m: Json<Message>) {
|
||||
// make sure the message isn't something strange
|
||||
let is_valid = validate_message(&m);
|
||||
if !is_valid {
|
||||
return;
|
||||
}
|
||||
// don't allow messages from outside the contact list
|
||||
let is_in_contact_list = contact::exists(&m.from);
|
||||
if !is_in_contact_list {
|
||||
return;
|
||||
}
|
||||
let f_mid: String = format!("m{}", utils::generate_rnd());
|
||||
let new_message = Message {
|
||||
mid: String::from(&f_mid),
|
||||
uid: String::from("rx"),
|
||||
from: String::from(&m.from),
|
||||
body: m.body.iter().cloned().collect(),
|
||||
created: chrono::offset::Utc::now().timestamp(),
|
||||
to: String::from(&m.to),
|
||||
};
|
||||
debug!("insert multisig message: {:?}", &new_message);
|
||||
let s = db::Interface::open();
|
||||
let k = &new_message.mid;
|
||||
db::Interface::async_write(&s.env, &s.handle, k, &Message::to_db(&new_message)).await;
|
||||
let data: MultisigMessageData = parse_multisig_message(new_message.mid);
|
||||
debug!("writing multisig message type {} for order {}", &data.sub_type, &data.orid);
|
||||
// lookup msig message data by {type}-{order id}-{contact .b32.i2p address}
|
||||
let msig_key = format!("{}-{}-{}", &data.sub_type, &data.orid, &m.from);
|
||||
db::Interface::write(&s.env, &s.handle, &msig_key, &data.info);
|
||||
}
|
||||
|
||||
/// Message lookup
|
||||
pub fn find(mid: &String) -> Message {
|
||||
let s = db::Interface::open();
|
||||
|
@ -134,18 +212,21 @@ pub fn find_all() -> Vec<Message> {
|
|||
}
|
||||
|
||||
/// Tx message
|
||||
async fn send_message(out: &Message, jwp: &str) -> Result<(), Box<dyn Error>> {
|
||||
async fn send_message(out: &Message, jwp: &str, m_type: MessageType) -> Result<(), Box<dyn Error>> {
|
||||
let host = utils::get_i2p_http_proxy();
|
||||
let proxy = reqwest::Proxy::http(&host)?;
|
||||
let client = reqwest::Client::builder().proxy(proxy).build();
|
||||
|
||||
let mut url = format!("http://{}/message/rx", out.to);
|
||||
if m_type == MessageType::Multisig {
|
||||
url = format!("http://{}/message/rx/multisig", out.to)
|
||||
}
|
||||
// check if the contact is online
|
||||
let is_online: bool = is_contact_online(&out.to, String::from(jwp))
|
||||
.await
|
||||
.unwrap_or(false);
|
||||
if is_online {
|
||||
return match client?
|
||||
.post(format!("http://{}/message/rx", out.to))
|
||||
.post(url)
|
||||
.header("proof", jwp)
|
||||
.json(&out)
|
||||
.send()
|
||||
|
@ -314,7 +395,12 @@ pub async fn retry_fts() {
|
|||
let k = format!("{}-{}", "fts-jwp", &message.to);
|
||||
let jwp = db::Interface::read(&s.env, &s.handle, &k);
|
||||
if jwp != utils::empty_string() {
|
||||
send_message(&message, &jwp).await.unwrap();
|
||||
let m_type = if message.mid.contains("misg") {
|
||||
MessageType::Multisig
|
||||
} else {
|
||||
MessageType::Normal
|
||||
};
|
||||
send_message(&message, &jwp, m_type).await.unwrap();
|
||||
} else {
|
||||
error!("not jwp found for fts id: {}", &message.mid);
|
||||
}
|
||||
|
@ -339,6 +425,24 @@ fn is_fts_clear(r: String) -> bool {
|
|||
v.len() >= 2 && v[v.len() - 1] == utils::empty_string() && v[0] == utils::empty_string()
|
||||
}
|
||||
|
||||
pub async fn send_prepare_info(orid:String, contact:String) {
|
||||
let s = db::Interface::open();
|
||||
let prepare_info = monero::prepare_wallet().await;
|
||||
let k = format!("{}-{}", "fts-jwp", &contact);
|
||||
let jwp = db::Interface::read(&s.env, &s.handle, &k);
|
||||
let body_str = format!("prepare:{}:{}", &orid, &prepare_info.result.multisig_info);
|
||||
let message: Message = Message {
|
||||
mid: utils::empty_string(),
|
||||
uid: utils::empty_string(),
|
||||
body: body_str.into_bytes(),
|
||||
created: chrono::Utc::now().timestamp(),
|
||||
from: utils::empty_string(),
|
||||
to: String::from(&contact),
|
||||
};
|
||||
let j_message: Json<Message> = utils::message_to_json(&message);
|
||||
create(j_message, jwp, MessageType::Multisig).await;
|
||||
}
|
||||
|
||||
// Tests
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
|
@ -366,7 +470,7 @@ mod tests {
|
|||
let j_message = utils::message_to_json(&message);
|
||||
let jwp = String::from("test-jwp");
|
||||
tokio::spawn(async move {
|
||||
let test_message = create(j_message, jwp).await;
|
||||
let test_message = create(j_message, jwp, MessageType::Normal).await;
|
||||
let expected: Message = Default::default();
|
||||
assert_eq!(test_message.body, expected.body);
|
||||
cleanup(&test_message.mid).await;
|
||||
|
|
|
@ -315,17 +315,20 @@ pub struct Order {
|
|||
pub cust_msig_txset: String,
|
||||
pub date: i64,
|
||||
pub deliver_date: i64,
|
||||
/// Transaction hash from vendor or customer signed txset
|
||||
pub hash: String,
|
||||
pub mediator_kex_1: String,
|
||||
pub mediator_kex_2: String,
|
||||
pub mediator_kex_3: String,
|
||||
pub mediator_msig_make: String,
|
||||
pub mediator_msig_prepare: String,
|
||||
/// Address gpg key encrypted bytes
|
||||
pub ship_address: Vec<u8>,
|
||||
pub ship_date: i64,
|
||||
/// This is the final destination for the payment
|
||||
pub subaddress: String,
|
||||
pub status: String,
|
||||
pub quantity: i64,
|
||||
pub quantity: u64,
|
||||
pub vend_kex_1: String,
|
||||
pub vend_kex_2: String,
|
||||
pub vend_kex_3: String,
|
||||
|
@ -350,13 +353,14 @@ impl Default for Order {
|
|||
cust_msig_txset: utils::empty_string(),
|
||||
date: 0,
|
||||
deliver_date: 0,
|
||||
ship_date: 0,
|
||||
hash: utils::empty_string(),
|
||||
mediator_kex_1: utils::empty_string(),
|
||||
mediator_kex_2: utils::empty_string(),
|
||||
mediator_kex_3: utils::empty_string(),
|
||||
mediator_msig_make: utils::empty_string(),
|
||||
mediator_msig_prepare: utils::empty_string(),
|
||||
ship_address: Vec::new(),
|
||||
ship_date: 0,
|
||||
subaddress: utils::empty_string(),
|
||||
status: utils::empty_string(),
|
||||
quantity: 0,
|
||||
|
@ -372,8 +376,9 @@ impl Default for Order {
|
|||
|
||||
impl Order {
|
||||
pub fn to_db(o: &Order) -> String {
|
||||
let ship_address = hex::encode(&o.ship_address);
|
||||
format!(
|
||||
"{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}",
|
||||
"{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}",
|
||||
o.cid,
|
||||
o.pid,
|
||||
o.cust_kex_1,
|
||||
|
@ -390,6 +395,7 @@ impl Order {
|
|||
o.mediator_kex_1,
|
||||
o.mediator_kex_2,
|
||||
o.mediator_kex_3,
|
||||
ship_address,
|
||||
o.ship_date,
|
||||
o.subaddress,
|
||||
o.status,
|
||||
|
@ -429,13 +435,14 @@ impl Order {
|
|||
let mediator_kex_1 = v.remove(0);
|
||||
let mediator_kex_2 = v.remove(0);
|
||||
let mediator_kex_3 = v.remove(0);
|
||||
let ship_address = hex::decode(v.remove(0)).unwrap_or(Vec::new());
|
||||
let ship_date = match v.remove(0).parse::<i64>() {
|
||||
Ok(d) => d,
|
||||
Err(_) => 0,
|
||||
};
|
||||
let subaddress = v.remove(0);
|
||||
let status = v.remove(0);
|
||||
let quantity = match v.remove(0).parse::<i64>() {
|
||||
let quantity = match v.remove(0).parse::<u64>() {
|
||||
Ok(d) => d,
|
||||
Err(_) => 0,
|
||||
};
|
||||
|
@ -464,6 +471,7 @@ impl Order {
|
|||
mediator_kex_3,
|
||||
mediator_msig_make,
|
||||
mediator_msig_prepare,
|
||||
ship_address,
|
||||
ship_date,
|
||||
subaddress,
|
||||
status,
|
||||
|
@ -496,6 +504,7 @@ impl Order {
|
|||
mediator_kex_3: String::from(&o.mediator_kex_3),
|
||||
mediator_msig_make: String::from(&o.mediator_msig_make),
|
||||
mediator_msig_prepare: String::from(&o.mediator_msig_prepare),
|
||||
ship_address: o.ship_address.iter().cloned().collect(),
|
||||
ship_date: o.ship_date,
|
||||
subaddress: String::from(&o.subaddress),
|
||||
status: String::from(&o.status),
|
||||
|
|
|
@ -1080,3 +1080,24 @@ impl Default for ErrorResponse {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle intial information for request
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
pub struct OrderRequest {
|
||||
pub cid: String,
|
||||
pub pid: String,
|
||||
pub ship_address: Vec<u8>,
|
||||
pub quantity: u64,
|
||||
}
|
||||
|
||||
impl Default for OrderRequest {
|
||||
fn default() -> Self {
|
||||
OrderRequest {
|
||||
cid: utils::empty_string(),
|
||||
pid: utils::empty_string(),
|
||||
ship_address: Vec::new(),
|
||||
quantity: 0,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -778,7 +778,8 @@ fn send_message_req(tx: Sender<bool>, ctx: egui::Context, body: String, to: Stri
|
|||
};
|
||||
let j_message = utils::message_to_json(&m);
|
||||
tokio::spawn(async move {
|
||||
let result = message::create(j_message, jwp).await;
|
||||
let m_type = message::MessageType::Normal;
|
||||
let result = message::create(j_message, jwp, m_type).await;
|
||||
if result.mid != utils::empty_string() {
|
||||
log::info!("sent message: {}", result.mid);
|
||||
let _ = tx.send(true);
|
||||
|
|
|
@ -13,7 +13,7 @@ async fn rocket() -> _ {
|
|||
..rocket::Config::debug_default()
|
||||
};
|
||||
env_logger::init();
|
||||
log::info!("nevmes-auth is online");
|
||||
log::info!("nevmes-market is online");
|
||||
rocket::custom(&config)
|
||||
.mount(
|
||||
"/dispute",
|
||||
|
|
|
@ -1,109 +1,94 @@
|
|||
// use nevmes_core::*;
|
||||
// use log::{debug, error, info};
|
||||
// use rocket::serde::json::Json;
|
||||
// use crate::product;
|
||||
use nevmes_core::*;
|
||||
use log::{debug, error, info};
|
||||
use rocket::serde::json::Json;
|
||||
|
||||
// enum StatusType {
|
||||
// Delivered,
|
||||
// MultisigMissing,
|
||||
// MulitsigComplete,
|
||||
// Shipped,
|
||||
// }
|
||||
enum StatusType {
|
||||
_Delivered,
|
||||
MultisigMissing,
|
||||
_MulitsigComplete,
|
||||
_Shipped,
|
||||
}
|
||||
|
||||
// impl StatusType {
|
||||
// pub fn value(&self) -> String {
|
||||
// match *self {
|
||||
// StatusType::Delivered => String::from("Delivered"),
|
||||
// StatusType::MultisigMissing => String::from("MultisigMissing"),
|
||||
// StatusType::MulitsigComplete => String::from("MulitsigComplete"),
|
||||
// StatusType::Shipped => String::from("Shipped"),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
impl StatusType {
|
||||
pub fn value(&self) -> String {
|
||||
match *self {
|
||||
StatusType::_Delivered => String::from("Delivered"),
|
||||
StatusType::MultisigMissing => String::from("MultisigMissing"),
|
||||
StatusType::_MulitsigComplete => String::from("MulitsigComplete"),
|
||||
StatusType::_Shipped => String::from("Shipped"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// /// Create a skeleton for order
|
||||
// pub fn create(cid: String, pid: String) -> models::Order {
|
||||
// let ts = chrono::offset::Utc::now().timestamp();
|
||||
// let orid: String = format!("O{}", utils::generate_rnd());
|
||||
// let m_product: models::Product = product::find(&pid);
|
||||
// let new_order = models::Order {
|
||||
// orid,
|
||||
// cid: String::from(&cid),
|
||||
// pid: String::from(&pid),
|
||||
// cust_kex_1: utils::empty_string(),
|
||||
// cust_kex_2: utils::empty_string(),
|
||||
// cust_kex_3: utils::empty_string(),
|
||||
// cust_msig_make: utils::empty_string(),
|
||||
// cust_msig_prepare: utils::empty_string(),
|
||||
// cust_msig_txset: utils::empty_string(),
|
||||
// date: 0,
|
||||
// deliver_date: 0,
|
||||
// hash: utils::empty_string(),
|
||||
// mediator_kex_1: utils::empty_string(),
|
||||
// mediator_kex_2: utils::empty_string(),
|
||||
// mediator_kex_3: utils::empty_string(),
|
||||
// mediator_msig_make: utils::empty_string(),
|
||||
// mediator_msig_prepare: utils::empty_string(),
|
||||
// ship_date: 0,
|
||||
// subaddress: utils::empty_string(),
|
||||
// status: utils::empty_string(),
|
||||
// quantity: 0,
|
||||
// vend_kex_1: utils::empty_string(),
|
||||
// vend_kex_2: utils::empty_string(),
|
||||
// vend_kex_3: utils::empty_string(),
|
||||
// vend_msig_make: utils::empty_string(),
|
||||
// vend_msig_prepare: utils::empty_string(),
|
||||
// vend_msig_txset: utils::empty_string(),
|
||||
// xmr_address: utils::empty_string(),
|
||||
// };
|
||||
// debug!("insert order: {:?}", new_order);
|
||||
// let m_wallet = monero::create_wallet(String::from(&orid), &utils::empty_string()).await;
|
||||
// if !m_wallet {
|
||||
// error!("error creating msig wallet for order {}", &orid);
|
||||
// }
|
||||
// debug!("insert order: {:?}", &new_order);
|
||||
// let s = db::Interface::open();
|
||||
// let k = &new_order.orid;
|
||||
// db::Interface::write(&s.env, &s.handle, k, &models::Order::to_db(&new_order));
|
||||
// // in order to retrieve all orders, write keys to with ol
|
||||
// let list_key = format!("ol");
|
||||
// let r = db::Interface::read(&s.env, &s.handle, &String::from(&list_key));
|
||||
// if r == utils::empty_string() {
|
||||
// debug!("creating order index");
|
||||
// }
|
||||
// let order_list = [r, String::from(&orid)].join(",");
|
||||
// debug!("writing order index {} for id: {}", order_list, list_key);
|
||||
// db::Interface::write(&s.env, &s.handle, &String::from(list_key), &order_list);
|
||||
// new_order
|
||||
// }
|
||||
/// Create a intial order
|
||||
pub async fn create(j_order: Json<reqres::OrderRequest>) -> models::Order {
|
||||
info!("creating order");
|
||||
let ts = chrono::offset::Utc::now().timestamp();
|
||||
let orid: String = format!("O{}", utils::generate_rnd());
|
||||
let r_subaddress = monero::create_address().await;
|
||||
let subaddress = r_subaddress.result.address;
|
||||
let new_order = models::Order {
|
||||
orid: String::from(&orid),
|
||||
cid: String::from(&j_order.cid),
|
||||
pid: String::from(&j_order.pid),
|
||||
date: ts,
|
||||
ship_address: j_order.ship_address.iter().cloned().collect(),
|
||||
subaddress,
|
||||
status: StatusType::MultisigMissing.value(),
|
||||
quantity: j_order.quantity,
|
||||
..Default::default()
|
||||
};
|
||||
debug!("insert order: {:?}", new_order);
|
||||
let m_wallet = monero::create_wallet(String::from(&orid), &utils::empty_string()).await;
|
||||
if !m_wallet {
|
||||
error!("error creating msig wallet for order {}", &orid);
|
||||
return Default::default();
|
||||
}
|
||||
debug!("insert order: {:?}", &new_order);
|
||||
let s = db::Interface::open();
|
||||
let k = &new_order.orid;
|
||||
db::Interface::write(&s.env, &s.handle, k, &models::Order::to_db(&new_order));
|
||||
// in order to retrieve all orders, write keys to with ol
|
||||
let list_key = format!("ol");
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(&list_key));
|
||||
if r == utils::empty_string() {
|
||||
debug!("creating order index");
|
||||
}
|
||||
let order_list = [r, String::from(&orid)].join(",");
|
||||
debug!("writing order index {} for id: {}", order_list, list_key);
|
||||
db::Interface::write(&s.env, &s.handle, &String::from(list_key), &order_list);
|
||||
new_order
|
||||
}
|
||||
|
||||
// /// Lookup order
|
||||
// pub fn find(oid: String) -> models::Order {
|
||||
// let s = db::Interface::open();
|
||||
// let r = db::Interface::read(&s.env, &s.handle, &String::from(&oid));
|
||||
// if r == utils::empty_string() {
|
||||
// error!("order not found");
|
||||
// return Default::default();
|
||||
// }
|
||||
// models::Order::from_db(String::from(&oid), r)
|
||||
// }
|
||||
/// Lookup order
|
||||
pub fn find(oid: String) -> models::Order {
|
||||
info!("find order: {}", &oid);
|
||||
let s = db::Interface::open();
|
||||
let r = db::Interface::read(&s.env, &s.handle, &String::from(&oid));
|
||||
if r == utils::empty_string() {
|
||||
error!("order not found");
|
||||
return Default::default();
|
||||
}
|
||||
models::Order::from_db(String::from(&oid), r)
|
||||
}
|
||||
|
||||
// /// Lookup all orders for customer
|
||||
// pub async fn find_all_customer_orders(cid: String) -> Vec<models::Order> {
|
||||
// let i_s = db::Interface::open();
|
||||
// let i_list_key = format!("ol");
|
||||
// let i_r = db::Interface::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
||||
// if i_r == utils::empty_string() {
|
||||
// error!("order index not found");
|
||||
// }
|
||||
// let i_v_oid = i_r.split(",");
|
||||
// let i_v: Vec<String> = i_v_oid.map(|s| String::from(s)).collect();
|
||||
// let mut orders: Vec<models::Order> = Vec::new();
|
||||
// for o in i_v {
|
||||
// let order: models::Order = find(o);
|
||||
// if order.orid != utils::empty_string() && order.cid == cid {
|
||||
// orders.push(order);
|
||||
// }
|
||||
// }
|
||||
// orders
|
||||
// }
|
||||
/// Lookup all orders for customer
|
||||
pub async fn find_all_customer_orders(cid: String) -> Vec<models::Order> {
|
||||
info!("lookup orders for customer: {}", &cid);
|
||||
let i_s = db::Interface::open();
|
||||
let i_list_key = format!("ol");
|
||||
let i_r = db::Interface::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
||||
if i_r == utils::empty_string() {
|
||||
error!("order index not found");
|
||||
}
|
||||
let i_v_oid = i_r.split(",");
|
||||
let i_v: Vec<String> = i_v_oid.map(|s| String::from(s)).collect();
|
||||
let mut orders: Vec<models::Order> = Vec::new();
|
||||
for o in i_v {
|
||||
let order: models::Order = find(o);
|
||||
if order.orid != utils::empty_string() && order.cid == cid {
|
||||
orders.push(order);
|
||||
}
|
||||
}
|
||||
orders
|
||||
}
|
||||
|
|
|
@ -15,12 +15,18 @@ use nevmes_core::{
|
|||
};
|
||||
|
||||
/// Send message
|
||||
#[post("/", data = "<m_req>")]
|
||||
#[post("/<r_type>", data = "<m_req>")]
|
||||
pub async fn send_message(
|
||||
m_req: Json<Message>,
|
||||
r_type: String,
|
||||
token: proof::PaymentProof,
|
||||
) -> Custom<Json<Message>> {
|
||||
let res: Message = message::create(m_req, token.get_jwp()).await;
|
||||
let m_type: message::MessageType = if r_type == "multisig" {
|
||||
message::MessageType::Multisig
|
||||
} else {
|
||||
message::MessageType::Normal
|
||||
};
|
||||
let res: Message = message::create(m_req, token.get_jwp(), m_type).await;
|
||||
Custom(Status::Ok, Json(res))
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ pub async fn get_i2p_status() -> Custom<Json<i2p::HttpProxyStatus>> {
|
|||
}
|
||||
|
||||
/// Share your contact information
|
||||
/// TODO(c2m): configurable option to only allow adding after JWP creation
|
||||
///
|
||||
/// Protected: false
|
||||
#[get("/")]
|
||||
pub async fn share_contact_info() -> Custom<Json<models::Contact>> {
|
||||
|
@ -78,11 +78,66 @@ pub async fn gen_jwp(proof: Json<proof::TxProof>) -> Custom<Json<reqres::Jwp>> {
|
|||
// NEVMES Market APIs
|
||||
//-----------------------------------------------
|
||||
|
||||
/// Get all products by passing vendor address
|
||||
/// Get all products
|
||||
///
|
||||
/// Protected: true
|
||||
/// Protected: false
|
||||
#[get("/products")]
|
||||
pub async fn get_products(_jwp: proof::PaymentProof) -> Custom<Json<Vec<models::Product>>> {
|
||||
let m_products: Vec<models::Product> = product::find_all();
|
||||
Custom(Status::Ok, Json(m_products))
|
||||
}
|
||||
|
||||
/// Create order
|
||||
///
|
||||
/// Protected: true
|
||||
#[post("/order/create", data = "<r_order>")]
|
||||
pub async fn create_order(
|
||||
r_order: Json<reqres::OrderRequest>,
|
||||
_jwp: proof::PaymentProof) -> Custom<Json<models::Order>> {
|
||||
let m_order: models::Order = order::create(r_order).await;
|
||||
Custom(Status::Created, Json(m_order))
|
||||
}
|
||||
|
||||
/// Customer order retreival. Must send `signature`
|
||||
///
|
||||
/// which is the order id signed by the wallet.
|
||||
///
|
||||
/// Protected: true
|
||||
#[get("/order/retrieve/<orid>/<_signature>")]
|
||||
pub async fn retrieve_order(
|
||||
orid: String,
|
||||
_signature: String,
|
||||
_jwp: proof::PaymentProof) -> Custom<Json<models::Order>> {
|
||||
|
||||
// get customer address
|
||||
|
||||
// send address, orid and signature to verify()
|
||||
|
||||
let m_order: models::Order = order::find(orid);
|
||||
Custom(Status::Created, Json(m_order))
|
||||
}
|
||||
|
||||
/// Create order
|
||||
///
|
||||
/// Protected: true
|
||||
#[get("/multisig/prepare/<orid>/<contact>")]
|
||||
pub async fn get_prepare_multisig_info(
|
||||
orid: String,
|
||||
contact: String,
|
||||
_jwp: proof::PaymentProof) -> Custom<Json<models::Order>> {
|
||||
// TODO(c2m): create a multisig message
|
||||
message::send_prepare_info(orid, contact).await;
|
||||
Custom(Status::Ok, Json(Default::default()))
|
||||
}
|
||||
|
||||
/// Recieve multisig messages here
|
||||
///
|
||||
/// Protected: true
|
||||
#[post("/", data = "<message>")]
|
||||
pub async fn rx_multisig_message(
|
||||
_jwp: proof::PaymentProof,
|
||||
message: Json<models::Message>,
|
||||
) -> Custom<Json<models::Message>> {
|
||||
message::rx_multisig(message).await;
|
||||
Custom(Status::Ok, Json(Default::default()))
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ async fn rocket() -> _ {
|
|||
.register("/", catchers![internal_error, not_found, payment_required])
|
||||
.mount("/invoice", routes![controller::gen_invoice])
|
||||
.mount("/message/rx", routes![controller::rx_message])
|
||||
.mount("/message/rx/multisig", routes![controller::rx_multisig_message])
|
||||
.mount("/prove", routes![controller::gen_jwp])
|
||||
.mount("/share", routes![controller::share_contact_info])
|
||||
.mount("/i2p", routes![controller::get_i2p_status])
|
||||
|
|
Loading…
Reference in a new issue