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-auth - `internal` auth server
|
||||||
* nevmes-contact - `internal` add contacts server
|
* nevmes-contact - `internal` add contacts server
|
||||||
* nevmes-gui - primary user interface
|
* nevmes-gui - primary user interface
|
||||||
|
* nevmes-market - `internal` marketplace admin server
|
||||||
* nevmes-message - `internal` message tx/read etc. 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
|
* [monerod](https://www.getmonero.org/downloads/#cli) - (not included) monero-wallet-rpc needs this
|
||||||
* can be overriden with remote node
|
* can be overriden with remote node
|
||||||
* use the `--remote-node` flag
|
* use the `--remote-node` flag
|
||||||
|
|
|
@ -6,7 +6,7 @@ use crate::{
|
||||||
i2p,
|
i2p,
|
||||||
models::*,
|
models::*,
|
||||||
reqres,
|
reqres,
|
||||||
utils,
|
utils, monero,
|
||||||
};
|
};
|
||||||
use log::{
|
use log::{
|
||||||
debug,
|
debug,
|
||||||
|
@ -17,9 +17,25 @@ use reqwest::StatusCode;
|
||||||
use rocket::serde::json::Json;
|
use rocket::serde::json::Json;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
|
||||||
|
#[derive(PartialEq)]
|
||||||
|
pub enum MessageType {
|
||||||
|
Normal,
|
||||||
|
Multisig,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MultisigMessageData {
|
||||||
|
info: String,
|
||||||
|
sub_type: String,
|
||||||
|
orid: String,
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a new message
|
/// Create a new message
|
||||||
pub async fn create(m: Json<Message>, jwp: String) -> Message {
|
pub async fn create(m: Json<Message>, jwp: String, m_type: MessageType) -> Message {
|
||||||
let f_mid: String = format!("m{}", utils::generate_rnd());
|
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);
|
info!("creating message: {}", &f_mid);
|
||||||
let created = chrono::offset::Utc::now().timestamp();
|
let created = chrono::offset::Utc::now().timestamp();
|
||||||
// get contact public gpg key and encrypt the message
|
// 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);
|
debug!("writing message index {} for id: {}", msg_list, list_key);
|
||||||
db::Interface::write(&s.env, &s.handle, &String::from(list_key), &msg_list);
|
db::Interface::write(&s.env, &s.handle, &String::from(list_key), &msg_list);
|
||||||
info!("attempting to send message");
|
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();
|
send.unwrap();
|
||||||
new_message
|
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);
|
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
|
/// Message lookup
|
||||||
pub fn find(mid: &String) -> Message {
|
pub fn find(mid: &String) -> Message {
|
||||||
let s = db::Interface::open();
|
let s = db::Interface::open();
|
||||||
|
@ -134,18 +212,21 @@ pub fn find_all() -> Vec<Message> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tx 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 host = utils::get_i2p_http_proxy();
|
||||||
let proxy = reqwest::Proxy::http(&host)?;
|
let proxy = reqwest::Proxy::http(&host)?;
|
||||||
let client = reqwest::Client::builder().proxy(proxy).build();
|
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
|
// check if the contact is online
|
||||||
let is_online: bool = is_contact_online(&out.to, String::from(jwp))
|
let is_online: bool = is_contact_online(&out.to, String::from(jwp))
|
||||||
.await
|
.await
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
if is_online {
|
if is_online {
|
||||||
return match client?
|
return match client?
|
||||||
.post(format!("http://{}/message/rx", out.to))
|
.post(url)
|
||||||
.header("proof", jwp)
|
.header("proof", jwp)
|
||||||
.json(&out)
|
.json(&out)
|
||||||
.send()
|
.send()
|
||||||
|
@ -314,7 +395,12 @@ pub async fn retry_fts() {
|
||||||
let k = format!("{}-{}", "fts-jwp", &message.to);
|
let k = format!("{}-{}", "fts-jwp", &message.to);
|
||||||
let jwp = db::Interface::read(&s.env, &s.handle, &k);
|
let jwp = db::Interface::read(&s.env, &s.handle, &k);
|
||||||
if jwp != utils::empty_string() {
|
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 {
|
} else {
|
||||||
error!("not jwp found for fts id: {}", &message.mid);
|
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()
|
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
|
// Tests
|
||||||
//-------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -366,7 +470,7 @@ mod tests {
|
||||||
let j_message = utils::message_to_json(&message);
|
let j_message = utils::message_to_json(&message);
|
||||||
let jwp = String::from("test-jwp");
|
let jwp = String::from("test-jwp");
|
||||||
tokio::spawn(async move {
|
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();
|
let expected: Message = Default::default();
|
||||||
assert_eq!(test_message.body, expected.body);
|
assert_eq!(test_message.body, expected.body);
|
||||||
cleanup(&test_message.mid).await;
|
cleanup(&test_message.mid).await;
|
||||||
|
|
|
@ -315,17 +315,20 @@ pub struct Order {
|
||||||
pub cust_msig_txset: String,
|
pub cust_msig_txset: String,
|
||||||
pub date: i64,
|
pub date: i64,
|
||||||
pub deliver_date: i64,
|
pub deliver_date: i64,
|
||||||
|
/// Transaction hash from vendor or customer signed txset
|
||||||
pub hash: String,
|
pub hash: String,
|
||||||
pub mediator_kex_1: String,
|
pub mediator_kex_1: String,
|
||||||
pub mediator_kex_2: String,
|
pub mediator_kex_2: String,
|
||||||
pub mediator_kex_3: String,
|
pub mediator_kex_3: String,
|
||||||
pub mediator_msig_make: String,
|
pub mediator_msig_make: String,
|
||||||
pub mediator_msig_prepare: String,
|
pub mediator_msig_prepare: String,
|
||||||
|
/// Address gpg key encrypted bytes
|
||||||
|
pub ship_address: Vec<u8>,
|
||||||
pub ship_date: i64,
|
pub ship_date: i64,
|
||||||
/// This is the final destination for the payment
|
/// This is the final destination for the payment
|
||||||
pub subaddress: String,
|
pub subaddress: String,
|
||||||
pub status: String,
|
pub status: String,
|
||||||
pub quantity: i64,
|
pub quantity: u64,
|
||||||
pub vend_kex_1: String,
|
pub vend_kex_1: String,
|
||||||
pub vend_kex_2: String,
|
pub vend_kex_2: String,
|
||||||
pub vend_kex_3: String,
|
pub vend_kex_3: String,
|
||||||
|
@ -350,13 +353,14 @@ impl Default for Order {
|
||||||
cust_msig_txset: utils::empty_string(),
|
cust_msig_txset: utils::empty_string(),
|
||||||
date: 0,
|
date: 0,
|
||||||
deliver_date: 0,
|
deliver_date: 0,
|
||||||
ship_date: 0,
|
|
||||||
hash: utils::empty_string(),
|
hash: utils::empty_string(),
|
||||||
mediator_kex_1: utils::empty_string(),
|
mediator_kex_1: utils::empty_string(),
|
||||||
mediator_kex_2: utils::empty_string(),
|
mediator_kex_2: utils::empty_string(),
|
||||||
mediator_kex_3: utils::empty_string(),
|
mediator_kex_3: utils::empty_string(),
|
||||||
mediator_msig_make: utils::empty_string(),
|
mediator_msig_make: utils::empty_string(),
|
||||||
mediator_msig_prepare: utils::empty_string(),
|
mediator_msig_prepare: utils::empty_string(),
|
||||||
|
ship_address: Vec::new(),
|
||||||
|
ship_date: 0,
|
||||||
subaddress: utils::empty_string(),
|
subaddress: utils::empty_string(),
|
||||||
status: utils::empty_string(),
|
status: utils::empty_string(),
|
||||||
quantity: 0,
|
quantity: 0,
|
||||||
|
@ -372,8 +376,9 @@ impl Default for Order {
|
||||||
|
|
||||||
impl Order {
|
impl Order {
|
||||||
pub fn to_db(o: &Order) -> String {
|
pub fn to_db(o: &Order) -> String {
|
||||||
|
let ship_address = hex::encode(&o.ship_address);
|
||||||
format!(
|
format!(
|
||||||
"{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}",
|
"{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}:{}",
|
||||||
o.cid,
|
o.cid,
|
||||||
o.pid,
|
o.pid,
|
||||||
o.cust_kex_1,
|
o.cust_kex_1,
|
||||||
|
@ -390,6 +395,7 @@ impl Order {
|
||||||
o.mediator_kex_1,
|
o.mediator_kex_1,
|
||||||
o.mediator_kex_2,
|
o.mediator_kex_2,
|
||||||
o.mediator_kex_3,
|
o.mediator_kex_3,
|
||||||
|
ship_address,
|
||||||
o.ship_date,
|
o.ship_date,
|
||||||
o.subaddress,
|
o.subaddress,
|
||||||
o.status,
|
o.status,
|
||||||
|
@ -429,13 +435,14 @@ impl Order {
|
||||||
let mediator_kex_1 = v.remove(0);
|
let mediator_kex_1 = v.remove(0);
|
||||||
let mediator_kex_2 = v.remove(0);
|
let mediator_kex_2 = v.remove(0);
|
||||||
let mediator_kex_3 = 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>() {
|
let ship_date = match v.remove(0).parse::<i64>() {
|
||||||
Ok(d) => d,
|
Ok(d) => d,
|
||||||
Err(_) => 0,
|
Err(_) => 0,
|
||||||
};
|
};
|
||||||
let subaddress = v.remove(0);
|
let subaddress = v.remove(0);
|
||||||
let status = 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,
|
Ok(d) => d,
|
||||||
Err(_) => 0,
|
Err(_) => 0,
|
||||||
};
|
};
|
||||||
|
@ -464,6 +471,7 @@ impl Order {
|
||||||
mediator_kex_3,
|
mediator_kex_3,
|
||||||
mediator_msig_make,
|
mediator_msig_make,
|
||||||
mediator_msig_prepare,
|
mediator_msig_prepare,
|
||||||
|
ship_address,
|
||||||
ship_date,
|
ship_date,
|
||||||
subaddress,
|
subaddress,
|
||||||
status,
|
status,
|
||||||
|
@ -496,6 +504,7 @@ impl Order {
|
||||||
mediator_kex_3: String::from(&o.mediator_kex_3),
|
mediator_kex_3: String::from(&o.mediator_kex_3),
|
||||||
mediator_msig_make: String::from(&o.mediator_msig_make),
|
mediator_msig_make: String::from(&o.mediator_msig_make),
|
||||||
mediator_msig_prepare: String::from(&o.mediator_msig_prepare),
|
mediator_msig_prepare: String::from(&o.mediator_msig_prepare),
|
||||||
|
ship_address: o.ship_address.iter().cloned().collect(),
|
||||||
ship_date: o.ship_date,
|
ship_date: o.ship_date,
|
||||||
subaddress: String::from(&o.subaddress),
|
subaddress: String::from(&o.subaddress),
|
||||||
status: String::from(&o.status),
|
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);
|
let j_message = utils::message_to_json(&m);
|
||||||
tokio::spawn(async move {
|
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() {
|
if result.mid != utils::empty_string() {
|
||||||
log::info!("sent message: {}", result.mid);
|
log::info!("sent message: {}", result.mid);
|
||||||
let _ = tx.send(true);
|
let _ = tx.send(true);
|
||||||
|
|
|
@ -13,7 +13,7 @@ async fn rocket() -> _ {
|
||||||
..rocket::Config::debug_default()
|
..rocket::Config::debug_default()
|
||||||
};
|
};
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
log::info!("nevmes-auth is online");
|
log::info!("nevmes-market is online");
|
||||||
rocket::custom(&config)
|
rocket::custom(&config)
|
||||||
.mount(
|
.mount(
|
||||||
"/dispute",
|
"/dispute",
|
||||||
|
|
|
@ -1,109 +1,94 @@
|
||||||
// use nevmes_core::*;
|
use nevmes_core::*;
|
||||||
// use log::{debug, error, info};
|
use log::{debug, error, info};
|
||||||
// use rocket::serde::json::Json;
|
use rocket::serde::json::Json;
|
||||||
// use crate::product;
|
|
||||||
|
|
||||||
// enum StatusType {
|
enum StatusType {
|
||||||
// Delivered,
|
_Delivered,
|
||||||
// MultisigMissing,
|
MultisigMissing,
|
||||||
// MulitsigComplete,
|
_MulitsigComplete,
|
||||||
// Shipped,
|
_Shipped,
|
||||||
// }
|
}
|
||||||
|
|
||||||
// impl StatusType {
|
impl StatusType {
|
||||||
// pub fn value(&self) -> String {
|
pub fn value(&self) -> String {
|
||||||
// match *self {
|
match *self {
|
||||||
// StatusType::Delivered => String::from("Delivered"),
|
StatusType::_Delivered => String::from("Delivered"),
|
||||||
// StatusType::MultisigMissing => String::from("MultisigMissing"),
|
StatusType::MultisigMissing => String::from("MultisigMissing"),
|
||||||
// StatusType::MulitsigComplete => String::from("MulitsigComplete"),
|
StatusType::_MulitsigComplete => String::from("MulitsigComplete"),
|
||||||
// StatusType::Shipped => String::from("Shipped"),
|
StatusType::_Shipped => String::from("Shipped"),
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// /// Create a skeleton for order
|
/// Create a intial order
|
||||||
// pub fn create(cid: String, pid: String) -> models::Order {
|
pub async fn create(j_order: Json<reqres::OrderRequest>) -> models::Order {
|
||||||
// let ts = chrono::offset::Utc::now().timestamp();
|
info!("creating order");
|
||||||
// let orid: String = format!("O{}", utils::generate_rnd());
|
let ts = chrono::offset::Utc::now().timestamp();
|
||||||
// let m_product: models::Product = product::find(&pid);
|
let orid: String = format!("O{}", utils::generate_rnd());
|
||||||
// let new_order = models::Order {
|
let r_subaddress = monero::create_address().await;
|
||||||
// orid,
|
let subaddress = r_subaddress.result.address;
|
||||||
// cid: String::from(&cid),
|
let new_order = models::Order {
|
||||||
// pid: String::from(&pid),
|
orid: String::from(&orid),
|
||||||
// cust_kex_1: utils::empty_string(),
|
cid: String::from(&j_order.cid),
|
||||||
// cust_kex_2: utils::empty_string(),
|
pid: String::from(&j_order.pid),
|
||||||
// cust_kex_3: utils::empty_string(),
|
date: ts,
|
||||||
// cust_msig_make: utils::empty_string(),
|
ship_address: j_order.ship_address.iter().cloned().collect(),
|
||||||
// cust_msig_prepare: utils::empty_string(),
|
subaddress,
|
||||||
// cust_msig_txset: utils::empty_string(),
|
status: StatusType::MultisigMissing.value(),
|
||||||
// date: 0,
|
quantity: j_order.quantity,
|
||||||
// deliver_date: 0,
|
..Default::default()
|
||||||
// hash: utils::empty_string(),
|
};
|
||||||
// mediator_kex_1: utils::empty_string(),
|
debug!("insert order: {:?}", new_order);
|
||||||
// mediator_kex_2: utils::empty_string(),
|
let m_wallet = monero::create_wallet(String::from(&orid), &utils::empty_string()).await;
|
||||||
// mediator_kex_3: utils::empty_string(),
|
if !m_wallet {
|
||||||
// mediator_msig_make: utils::empty_string(),
|
error!("error creating msig wallet for order {}", &orid);
|
||||||
// mediator_msig_prepare: utils::empty_string(),
|
return Default::default();
|
||||||
// ship_date: 0,
|
}
|
||||||
// subaddress: utils::empty_string(),
|
debug!("insert order: {:?}", &new_order);
|
||||||
// status: utils::empty_string(),
|
let s = db::Interface::open();
|
||||||
// quantity: 0,
|
let k = &new_order.orid;
|
||||||
// vend_kex_1: utils::empty_string(),
|
db::Interface::write(&s.env, &s.handle, k, &models::Order::to_db(&new_order));
|
||||||
// vend_kex_2: utils::empty_string(),
|
// in order to retrieve all orders, write keys to with ol
|
||||||
// vend_kex_3: utils::empty_string(),
|
let list_key = format!("ol");
|
||||||
// vend_msig_make: utils::empty_string(),
|
let r = db::Interface::read(&s.env, &s.handle, &String::from(&list_key));
|
||||||
// vend_msig_prepare: utils::empty_string(),
|
if r == utils::empty_string() {
|
||||||
// vend_msig_txset: utils::empty_string(),
|
debug!("creating order index");
|
||||||
// xmr_address: utils::empty_string(),
|
}
|
||||||
// };
|
let order_list = [r, String::from(&orid)].join(",");
|
||||||
// debug!("insert order: {:?}", new_order);
|
debug!("writing order index {} for id: {}", order_list, list_key);
|
||||||
// let m_wallet = monero::create_wallet(String::from(&orid), &utils::empty_string()).await;
|
db::Interface::write(&s.env, &s.handle, &String::from(list_key), &order_list);
|
||||||
// if !m_wallet {
|
new_order
|
||||||
// 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
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// Lookup order
|
/// Lookup order
|
||||||
// pub fn find(oid: String) -> models::Order {
|
pub fn find(oid: String) -> models::Order {
|
||||||
// let s = db::Interface::open();
|
info!("find order: {}", &oid);
|
||||||
// let r = db::Interface::read(&s.env, &s.handle, &String::from(&oid));
|
let s = db::Interface::open();
|
||||||
// if r == utils::empty_string() {
|
let r = db::Interface::read(&s.env, &s.handle, &String::from(&oid));
|
||||||
// error!("order not found");
|
if r == utils::empty_string() {
|
||||||
// return Default::default();
|
error!("order not found");
|
||||||
// }
|
return Default::default();
|
||||||
// models::Order::from_db(String::from(&oid), r)
|
}
|
||||||
// }
|
models::Order::from_db(String::from(&oid), r)
|
||||||
|
}
|
||||||
|
|
||||||
// /// Lookup all orders for customer
|
/// Lookup all orders for customer
|
||||||
// pub async fn find_all_customer_orders(cid: String) -> Vec<models::Order> {
|
pub async fn find_all_customer_orders(cid: String) -> Vec<models::Order> {
|
||||||
// let i_s = db::Interface::open();
|
info!("lookup orders for customer: {}", &cid);
|
||||||
// let i_list_key = format!("ol");
|
let i_s = db::Interface::open();
|
||||||
// let i_r = db::Interface::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
let i_list_key = format!("ol");
|
||||||
// if i_r == utils::empty_string() {
|
let i_r = db::Interface::read(&i_s.env, &i_s.handle, &String::from(i_list_key));
|
||||||
// error!("order index not found");
|
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 i_v_oid = i_r.split(",");
|
||||||
// let mut orders: Vec<models::Order> = Vec::new();
|
let i_v: Vec<String> = i_v_oid.map(|s| String::from(s)).collect();
|
||||||
// for o in i_v {
|
let mut orders: Vec<models::Order> = Vec::new();
|
||||||
// let order: models::Order = find(o);
|
for o in i_v {
|
||||||
// if order.orid != utils::empty_string() && order.cid == cid {
|
let order: models::Order = find(o);
|
||||||
// orders.push(order);
|
if order.orid != utils::empty_string() && order.cid == cid {
|
||||||
// }
|
orders.push(order);
|
||||||
// }
|
}
|
||||||
// orders
|
}
|
||||||
// }
|
orders
|
||||||
|
}
|
||||||
|
|
|
@ -15,12 +15,18 @@ use nevmes_core::{
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Send message
|
/// Send message
|
||||||
#[post("/", data = "<m_req>")]
|
#[post("/<r_type>", data = "<m_req>")]
|
||||||
pub async fn send_message(
|
pub async fn send_message(
|
||||||
m_req: Json<Message>,
|
m_req: Json<Message>,
|
||||||
|
r_type: String,
|
||||||
token: proof::PaymentProof,
|
token: proof::PaymentProof,
|
||||||
) -> Custom<Json<Message>> {
|
) -> 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))
|
Custom(Status::Ok, Json(res))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ pub async fn get_i2p_status() -> Custom<Json<i2p::HttpProxyStatus>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Share your contact information
|
/// Share your contact information
|
||||||
/// TODO(c2m): configurable option to only allow adding after JWP creation
|
///
|
||||||
/// Protected: false
|
/// Protected: false
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
pub async fn share_contact_info() -> Custom<Json<models::Contact>> {
|
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
|
// NEVMES Market APIs
|
||||||
//-----------------------------------------------
|
//-----------------------------------------------
|
||||||
|
|
||||||
/// Get all products by passing vendor address
|
/// Get all products
|
||||||
///
|
///
|
||||||
/// Protected: true
|
/// Protected: false
|
||||||
#[get("/products")]
|
#[get("/products")]
|
||||||
pub async fn get_products(_jwp: proof::PaymentProof) -> Custom<Json<Vec<models::Product>>> {
|
pub async fn get_products(_jwp: proof::PaymentProof) -> Custom<Json<Vec<models::Product>>> {
|
||||||
let m_products: Vec<models::Product> = product::find_all();
|
let m_products: Vec<models::Product> = product::find_all();
|
||||||
Custom(Status::Ok, Json(m_products))
|
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])
|
.register("/", catchers![internal_error, not_found, payment_required])
|
||||||
.mount("/invoice", routes![controller::gen_invoice])
|
.mount("/invoice", routes![controller::gen_invoice])
|
||||||
.mount("/message/rx", routes![controller::rx_message])
|
.mount("/message/rx", routes![controller::rx_message])
|
||||||
|
.mount("/message/rx/multisig", routes![controller::rx_multisig_message])
|
||||||
.mount("/prove", routes![controller::gen_jwp])
|
.mount("/prove", routes![controller::gen_jwp])
|
||||||
.mount("/share", routes![controller::share_contact_info])
|
.mount("/share", routes![controller::share_contact_info])
|
||||||
.mount("/i2p", routes![controller::get_i2p_status])
|
.mount("/i2p", routes![controller::get_i2p_status])
|
||||||
|
|
Loading…
Reference in a new issue